From 451a3400b76511393c62a444f588a4ed15f4a549 Mon Sep 17 00:00:00 2001 From: Michael Lando Date: Sun, 19 Feb 2017 10:28:42 +0200 Subject: Initial OpenECOMP SDC commit Change-Id: I0924d5a6ae9cdc161ae17c68d3689a30d10f407b Signed-off-by: Michael Lando --- .gitignore | 99 + .gitreview | 4 + .pydevproject | 5 + LICENSE.TXT | 24 + README.md | 165 + asdc-tests/.gitignore | 4 + asdc-tests/pom.xml | 367 + .../sdc/ci/tests/api/ComponentBaseTest.java | 348 + .../ci/tests/api/ComponentInstanceBaseTest.java | 763 + .../org/openecomp/sdc/ci/tests/api/SdcTest.java | 202 + .../java/org/openecomp/sdc/ci/tests/api/Urls.java | 348 + .../org/openecomp/sdc/ci/tests/config/Config.java | 584 + .../sdc/ci/tests/config/InvokedMethodListener.java | 63 + .../ci/tests/datatypes/ArtifactAssetStructure.java | 135 + .../sdc/ci/tests/datatypes/ArtifactReqDetails.java | 226 + .../sdc/ci/tests/datatypes/AssetStructure.java | 122 + .../datatypes/ComponentInstanceReqDetails.java | 121 + .../ci/tests/datatypes/ComponentReqDetails.java | 272 + .../tests/datatypes/GroupHeatMetaDefinition.java | 60 + .../sdc/ci/tests/datatypes/ImportReqDetails.java | 332 + .../sdc/ci/tests/datatypes/ProductReqDetails.java | 88 + .../datatypes/PropertyHeatMetaDefinition.java | 53 + .../sdc/ci/tests/datatypes/PropertyReqDetails.java | 145 + .../ci/tests/datatypes/ResourceAssetStructure.java | 58 + .../datatypes/ResourceDetailedAssetStructure.java | 89 + .../datatypes/ResourceInstanceAssetStructure.java | 116 + .../sdc/ci/tests/datatypes/ResourceReqDetails.java | 220 + .../ci/tests/datatypes/ResourceRespJavaObject.java | 337 + .../ci/tests/datatypes/ServiceAssetStructure.java | 49 + .../datatypes/ServiceDetailedAssetStructure.java | 78 + .../sdc/ci/tests/datatypes/ServiceReqDetails.java | 91 + .../ci/tests/datatypes/ServiceRespJavaObject.java | 267 + .../ci/tests/datatypes/TypeHeatMetaDefinition.java | 57 + .../ci/tests/datatypes/enums/ArtifactTypeEnum.java | 75 + .../sdc/ci/tests/datatypes/enums/AssocType.java | 42 + .../sdc/ci/tests/datatypes/enums/AuditEnum.java | 51 + .../tests/datatypes/enums/AuditJsonKeysEnum.java | 40 + .../ci/tests/datatypes/enums/ComponentType.java | 37 + .../sdc/ci/tests/datatypes/enums/ErrorInfo.java | 93 + .../datatypes/enums/EsIndexTypeIdToDelete.java | 64 + .../tests/datatypes/enums/ExceptionEnumType.java | 36 + .../tests/datatypes/enums/ImportTestTypesEnum.java | 95 + .../tests/datatypes/enums/LifeCycleStatesEnum.java | 75 + .../enums/MandatoryResourceArtifactTypeEnum.java | 53 + .../enums/MandatoryServiceArtifactTypeEnum.java | 66 + .../tests/datatypes/enums/NormativeTypesEnum.java | 55 + .../ci/tests/datatypes/enums/PropertyTypeEnum.java | 105 + .../datatypes/enums/ResourceCategoryEnum.java | 56 + .../ci/tests/datatypes/enums/RespJsonKeysEnum.java | 60 + .../datatypes/enums/ServiceApiArtifactEnum.java | 40 + .../datatypes/enums/ServiceCategoriesEnum.java | 37 + .../ci/tests/datatypes/enums/ToscaKeysEnum.java | 49 + .../sdc/ci/tests/datatypes/enums/UserRoleEnum.java | 76 + .../datatypes/expected/ExpectedArtifactAudit.java | 166 + .../expected/ExpectedAuthenticationAudit.java | 90 + .../datatypes/expected/ExpectedCategoryAudit.java | 151 + .../expected/ExpectedDistDownloadAudit.java | 79 + .../expected/ExpectedEcomConsumerAudit.java | 88 + .../datatypes/expected/ExpectedExternalAudit.java | 179 + .../expected/ExpectedGetUserListAudit.java | 88 + .../datatypes/expected/ExpectedGroupingAudit.java | 121 + .../datatypes/expected/ExpectedProductAudit.java | 142 + .../expected/ExpectedResourceAuditJavaObject.java | 300 + .../datatypes/expected/ExpectedUserCRUDAudit.java | 98 + .../sdc/ci/tests/datatypes/http/HeaderData.java | 114 + .../sdc/ci/tests/datatypes/http/HeaderValue.java | 38 + .../ci/tests/datatypes/http/HttpHeaderEnum.java | 58 + .../sdc/ci/tests/datatypes/http/HttpRequest.java | 883 + .../sdc/ci/tests/datatypes/http/MustHeaders.java | 53 + .../sdc/ci/tests/datatypes/http/RestResponse.java | 84 + .../execute/TODO/ImportCapabilityTypeCITest.java | 135 + .../execute/artifacts/ArtifactServletTest.java | 656 + .../sdc/ci/tests/execute/artifacts/CrudArt.java | 1750 ++ .../execute/artifacts/DownloadComponentArt.java | 687 + .../execute/artifacts/PlaceHolderValidations.java | 696 + .../execute/artifacts/ValidateArtResponse.java | 631 + .../artifacts/ValidateHeatArtFieldsFromUI.java | 444 + .../artifacts/ValidateHeatArtFieldsTypes.java | 176 + .../attribute/ComponentInstanceAttributeTest.java | 83 + .../tests/execute/category/CatalogDataApiTest.java | 234 + .../tests/execute/category/CategoriesBaseTest.java | 49 + .../ci/tests/execute/category/CategoriesTests.java | 2289 ++ .../ci/tests/execute/category/ElementsApiTest.java | 147 + .../ci/tests/execute/category/GroupingTest.java | 2003 ++ .../tests/execute/category/SubCategoriesTest.java | 1907 ++ .../ci/tests/execute/devCI/CRUDExternalAPI.java | 1011 + .../ci/tests/execute/devCI/ImportCsarUpdate.java | 356 + .../execute/devCI/ImportCsarValidateArtifacts.java | 103 + .../ci/tests/execute/devCI/ToscaGroupInsideVF.java | 578 + .../execute/distribution/AuthanticationTests.java | 186 + .../DistributionDownloadArtifactTest.java | 542 + .../execute/externalapi/DownloadArtifactsTest.java | 338 + .../general/BasicHttpAuthenticationTest.java | 403 + .../sdc/ci/tests/execute/general/FeProxyTest.java | 53 + .../general/ManageEcompConsumerCredentials.java | 1388 ++ .../sdc/ci/tests/execute/general/UuidTest.java | 104 + .../ci/tests/execute/imports/CsarUtilsTest.java | 430 + .../ci/tests/execute/imports/ExportToscaTest.java | 333 + .../execute/imports/ImportCsarResourceTest.java | 1538 ++ .../imports/ImportGenericResourceCITest.java | 599 + .../execute/imports/ImportNewResourceCITest.java | 1431 ++ .../ImportToscaCapabilitiesWithProperties.java | 416 + .../execute/imports/ImportToscaResourceTest.java | 2404 ++ .../imports/ImportUpdateResourseCsarTest.java | 282 + .../ci/tests/execute/inputs/InputsApiTests.java | 225 + .../ci/tests/execute/lifecycle/LCSbaseTest.java | 274 + .../product/ChangeServiceInstanceVersionTest.java | 1478 ++ .../ci/tests/execute/product/ProductBaseTest.java | 195 + .../tests/execute/product/ProductCheckinTest.java | 199 + .../tests/execute/product/ProductCheckoutTest.java | 146 + .../product/ProductComponentInstanceCRUDTest.java | 1437 ++ .../product/ProductCreateWithValidationsTest.java | 1710 ++ .../ci/tests/execute/product/ProductCrudTest.java | 2197 ++ .../execute/product/ProductGetFollowedTest.java | 164 + .../execute/product/ProductLifecycleTest.java | 54 + .../ci/tests/execute/product/ProductTestBase.java | 148 + .../product/ProductToscaYamlGenerationTest.java | 83 + .../execute/product/ProductUndoCheckoutTest.java | 216 + .../property/AdditionalInformationServletTest.java | 2021 ++ .../property/ComponentInstancePropertyTest.java | 1263 + .../tests/execute/property/ComponentProperty.java | 1796 ++ .../tests/execute/property/PropertyApisTest.java | 383 + .../tests/execute/resource/CheckGetResource.java | 52 + .../resource/ComponentRelationshipInVfTest.java | 1408 ++ .../execute/resource/CreateResourceApiTest.java | 2199 ++ .../execute/resource/GetAllResourceVersions.java | 580 + .../resource/GetResourceNotAbstractApiTest.java | 326 + .../ci/tests/execute/resource/ResourceApiTest.java | 366 + .../tests/execute/resource/SampleDataProvider.java | 41 + .../execute/resource/SimultaneousApiTest.java | 102 + .../resource/UpdateResourceMetadataTest.java | 2254 ++ .../resource/VFResourceInstanceNameCRUD.java | 480 + .../execute/resource/ValidateExtendedVfData.java | 315 + .../resource/VfComponentInstanceCRUDTest.java | 1792 ++ .../ChangeServiceDistributionStatusApiTest.java | 1008 + .../service/CreateServiceMetadataApiTest.java | 1300 ++ .../execute/service/GetAllServiceVersions.java | 350 + .../execute/service/GetComponentAuditApiTest.java | 322 + .../service/GetServiceLatestVersionTest.java | 684 + .../execute/service/ReqCapOccurrencesTest.java | 1191 + .../service/ServiceComponentInstanceCRUDTest.java | 1624 ++ .../execute/service/UpdateServiceMetadataTest.java | 1984 ++ .../execute/user/ActivateDeActivateDeleteUser.java | 832 + .../ci/tests/execute/user/CreateUserApiTest.java | 1451 ++ .../execute/user/GovernorWorkspaceApiTest.java | 354 + .../distributionClient/ClientConfiguration.java | 141 + .../preRequisites/ComplexResourceBaseTest.java | 177 + .../preRequisites/DownloadArtifactBaseTest.java | 125 + .../preRequisites/SimpleOneRsrcOneServiceTest.java | 96 + .../sdc/ci/tests/rules/MyTestWatcher.java | 82 + .../sdc/ci/tests/run/ExtentReporterNG.java | 94 + .../org/openecomp/sdc/ci/tests/run/StartTest.java | 293 + .../sdc/ci/tests/run/StartTest2backup.java | 410 + .../org/openecomp/sdc/ci/tests/sanity/CrudE2E.java | 220 + .../ci/tests/sanity/MultipleResourceUpdate.java | 126 + .../ToscaCapabilitiesNodeTemplatesDefinition.java | 25 + .../ci/tests/tosca/datatypes/ToscaDefinition.java | 74 + .../ToscaGroupsTopologyTemplateDefinition.java | 78 + .../tosca/datatypes/ToscaImportsDefinition.java | 59 + .../ToscaInputsTopologyTemplateDefinition.java | 25 + ...scaNodeTemplatesTopologyTemplateDefinition.java | 83 + .../tosca/datatypes/ToscaNodeTypesDefinition.java | 54 + .../ToscaPropertiesNodeTemplatesDefinition.java | 53 + .../ToscaRequirementsNodeTemplatesDefinition.java | 72 + .../datatypes/ToscaTopologyTemplateDefinition.java | 77 + .../ci/tests/users/AddUserAuditMessageInfo.java | 113 + .../sdc/ci/tests/users/UserAuditJavaObject.java | 133 + .../sdc/ci/tests/users/UserHeaderData.java | 59 + .../ci/tests/users/UserResponseMessageEnum.java | 48 + .../sdc/ci/tests/users/WebSealUserDetails.java | 74 + .../sdc/ci/tests/utils/ArtifactUtils.java | 43 + .../org/openecomp/sdc/ci/tests/utils/DbUtils.java | 306 + .../org/openecomp/sdc/ci/tests/utils/Decoder.java | 62 + .../org/openecomp/sdc/ci/tests/utils/ReqCap.java | 630 + .../sdc/ci/tests/utils/ToscaParserUtils.java | 267 + .../org/openecomp/sdc/ci/tests/utils/Utils.java | 233 + .../ci/tests/utils/cassandra/CassandraUtils.java | 213 + .../ci/tests/utils/cassandra/CassandraUtils2.java | 172 + .../tests/utils/general/AtomicOperationUtils.java | 627 + .../sdc/ci/tests/utils/general/Convertor.java | 309 + .../sdc/ci/tests/utils/general/ElementFactory.java | 873 + .../sdc/ci/tests/utils/general/FileUtils.java | 136 + .../sdc/ci/tests/utils/general/ImportUtils.java | 56 + .../sdc/ci/tests/utils/rest/ArtifactRestUtils.java | 689 + .../sdc/ci/tests/utils/rest/AssetRestUtils.java | 510 + .../sdc/ci/tests/utils/rest/BaseRestUtils.java | 256 + .../sdc/ci/tests/utils/rest/CatalogRestUtils.java | 75 + .../sdc/ci/tests/utils/rest/CategoryRestUtils.java | 298 + .../utils/rest/ComponentInstanceRestUtils.java | 276 + .../ci/tests/utils/rest/ComponentRestUtils.java | 62 + .../sdc/ci/tests/utils/rest/ConsumerRestUtils.java | 206 + .../ci/tests/utils/rest/EcompUserRestUtils.java | 255 + .../sdc/ci/tests/utils/rest/GroupRestUtils.java | 61 + .../sdc/ci/tests/utils/rest/ImportRestUtils.java | 339 + .../sdc/ci/tests/utils/rest/InputsRestUtils.java | 122 + .../ci/tests/utils/rest/LifecycleRestUtils.java | 360 + .../sdc/ci/tests/utils/rest/ProductRestUtils.java | 185 + .../sdc/ci/tests/utils/rest/PropertyRestUtils.java | 310 + .../sdc/ci/tests/utils/rest/ResourceRestUtils.java | 575 + .../sdc/ci/tests/utils/rest/ResponseParser.java | 541 + .../sdc/ci/tests/utils/rest/ServiceRestUtils.java | 262 + .../sdc/ci/tests/utils/rest/UserRestUtils.java | 282 + .../utils/validation/ArtifactValidationUtils.java | 228 + .../utils/validation/AuditValidationUtils.java | 1328 ++ .../utils/validation/BaseValidationUtils.java | 116 + .../utils/validation/CategoryValidationUtils.java | 126 + .../utils/validation/CsarValidationUtils.java | 274 + .../utils/validation/ErrorValidationUtils.java | 112 + .../utils/validation/ProductValidationUtils.java | 239 + .../utils/validation/ResourceValidationUtils.java | 354 + .../utils/validation/ServiceValidationUtils.java | 130 + .../utils/validation/UserValidationUtils.java | 279 + .../sdc/ci/tests/webSealAccess/NeoJavaObject.java | 111 + .../sdc/externalApis/GetAssetServlet.java | 351 + .../sdc/externalApis/GetFilteredAssetServlet.java | 438 + .../GetSpecificAssetMetadataServlet.java | 773 + .../main/java/org/openecomp/sdc/post/Install.java | 69 + .../src/main/resources/ci/conf/log4j.properties | 34 + .../src/main/resources/ci/conf/sdc-packages.yaml | 12 + asdc-tests/src/main/resources/ci/conf/sdc.yaml | 88 + .../src/main/resources/ci/conf/testngLifeCycle.xml | 27 + .../src/main/resources/ci/conf/titan.properties | 8 + asdc-tests/src/main/resources/ci/conf/truststore | Bin 0 -> 971 bytes .../src/main/resources/ci/scripts/startTest.sh | 88 + .../src/main/resources/ci/testSuites/artifacts.xml | 19 + .../src/main/resources/ci/testSuites/category.xml | 11 + .../src/main/resources/ci/testSuites/ciFull.xml | 221 + .../main/resources/ci/testSuites/externalApis.xml | 11 + .../src/main/resources/ci/testSuites/general.xml | 11 + .../src/main/resources/ci/testSuites/imports.xml | 12 + .../src/main/resources/ci/testSuites/product.xml | 14 + .../src/main/resources/ci/testSuites/property.xml | 11 + .../src/main/resources/ci/testSuites/resource.xml | 336 + .../src/main/resources/ci/testSuites/sanity.xml | 389 + .../src/main/resources/ci/testSuites/service.xml | 15 + .../resources/ci/testSuites/testngLifeCycle.xml | 27 + .../src/main/resources/ci/testSuites/user.xml | 18 + .../resources/CI/components/apache/apache-type.yml | 50 + .../CI/components/apache/images/apache.png | Bin 0 -> 10518 bytes .../CI/components/apache/scripts/install_apache.sh | 53 + .../CI/components/apache/scripts/start_apache.sh | 10 + .../normativeTypes/DBMS/images/relational_db.png | Bin 0 -> 51853 bytes .../normativeTypes/DBMS/normative-types-DBMS.yml | 36 + .../normativeTypes/blockStorage/images/volume.png | Bin 0 -> 16643 bytes .../blockStorage/normative-types-blockStorage.yml | 40 + .../normativeTypes/compute/images/compute.png | Bin 0 -> 61345 bytes .../compute/normative-types-compute.yml | 77 + .../database/images/relational_db.png | Bin 0 -> 51853 bytes .../database/normative-types-database.yml | 41 + .../normativeTypes/network/images/network.png | Bin 0 -> 159707 bytes .../network/normative-types-network.yml | 39 + .../objectStorage/images/objectstore.png | Bin 0 -> 4354 bytes .../normative-types-objectStorage.yml | 35 + .../components/normativeTypes/root/images/root.png | Bin 0 -> 5335 bytes .../normativeTypes/root/normative-types-root.yml | 168 + .../softwareComponent/images/software.png | Bin 0 -> 55407 bytes .../normative-types-softwareComponent.yml | 25 + .../webApplication/images/network.png | Bin 0 -> 159707 bytes .../normative-types-webApplication.yml | 21 + .../webServer/normative-types-webServer.yml | 24 + .../src/test/resources/CI/configuration.yaml | 382 + .../test/resources/CI/csars/FCGI_with_inputs.csar | Bin 0 -> 35433 bytes .../test/resources/CI/csars/LDSA1_with_inputs.csar | Bin 0 -> 28243 bytes .../CI/csars/VF_RI2_G4_withArtifacts.csar | Bin 0 -> 36440 bytes .../CI/csars/VF_RI2_G4_withArtifacts_a.csar | Bin 0 -> 36440 bytes .../CI/csars/VF_RI2_G4_withArtifacts_b.csar | Bin 0 -> 36444 bytes .../VF_RI2_G4_withArtifacts_group_naming.csar | Bin 0 -> 35872 bytes .../VF_RI2_G4_withArtifacts_group_naming_a.csar | Bin 0 -> 35874 bytes ...2_G4_withArtifacts_group_naming_add_update.csar | Bin 0 -> 35854 bytes ...4_withArtifacts_group_naming_delete_update.csar | Bin 0 -> 35852 bytes .../CI/csars/VF_RI2_G4_withArtifacts_update.csar | Bin 0 -> 36436 bytes .../resources/CI/csars/jsonPropertyTypeTest.csar | Bin 0 -> 24762 bytes .../src/test/resources/CI/csars/mycompute.yml | 18 + .../src/test/resources/CI/csars/mycompute2.yml | 18 + .../test/resources/CI/csars/mycompute_failed.yml | 18 + asdc-tests/src/test/resources/CI/csars/orig2G.csar | Bin 0 -> 38900 bytes .../src/test/resources/CI/csars/orig2GV001.csar | Bin 0 -> 38994 bytes .../src/test/resources/CI/csars/orig2GV001_a.csar | Bin 0 -> 38994 bytes .../orig2GV006-remove-all-nested-artifacts.csar | Bin 0 -> 38993 bytes .../orig2GV008-change-nested-oam-fileContent.csar | Bin 0 -> 39005 bytes .../src/test/resources/CI/csars/orig2G_a.csar | Bin 0 -> 38900 bytes .../test/resources/CI/csars/orig2G_updated.csar | Bin 0 -> 38775 bytes .../src/test/resources/CI/csars/valid_vf.csar | Bin 0 -> 1316 bytes .../src/test/resources/CI/csars/valid_vf_a.csar | Bin 0 -> 1316 bytes .../src/test/resources/CI/csars/valid_vf_b.csar | Bin 0 -> 1244 bytes .../src/test/resources/CI/csars/valid_vf_c.csar | Bin 0 -> 1316 bytes .../src/test/resources/CI/csars/valid_vf_d.csar | Bin 0 -> 1406 bytes .../src/test/resources/CI/csars/valid_vf_f.csar | Bin 0 -> 1443 bytes .../resources/CI/csars/vf_relate_by_cap_name.csar | Bin 0 -> 25963 bytes .../vf_with_cap_prop_override_cap_type_prop.csar | Bin 0 -> 1411 bytes .../vf_with_cap_prop_override_cap_type_prop1.csar | Bin 0 -> 1548 bytes ...th_cap_prop_override_cap_type_prop1_failed.csar | Bin 0 -> 1546 bytes ...ith_cap_prop_override_cap_type_prop_failed.csar | Bin 0 -> 1412 bytes .../CI/csars/vmmc_relate_by_cap_name.csar | Bin 0 -> 35606 bytes .../LAN_Connector/LAN_Connector.json | 11 + .../LAN_Connector/LAN_Connector.yml | 23 + .../LAN_Connector/LAN_Connector.zip | Bin 0 -> 530 bytes .../resources/CI/demoResourcesWanLan/VNF/VNF.json | 11 + .../resources/CI/demoResourcesWanLan/VNF/VNF.yml | 16 + .../resources/CI/demoResourcesWanLan/VNF/VNF.zip | Bin 0 -> 449 bytes .../VNF_Container/VNF_Container.json | 11 + .../VNF_Container/VNF_Container.yml | 10 + .../VNF_Container/VNF_Container.zip | Bin 0 -> 394 bytes .../WAN_Connector/WAN_Connector.json | 11 + .../WAN_Connector/WAN_Connector.yml | 25 + .../WAN_Connector/WAN_Connector.zip | Bin 0 -> 505 bytes .../demoResourcesWanLan/capabilityTypesWanLan.yml | 4 + .../demoResourcesWanLan/capabilityTypesWanLan.zip | Bin 0 -> 269 bytes .../demoResourcesWanLan/connector/connector.json | 11 + .../CI/demoResourcesWanLan/connector/connector.yml | 10 + .../CI/demoResourcesWanLan/connector/connector.zip | Bin 0 -> 423 bytes .../deleteResourcesLanWanDemo.sh | 36 + .../importResourcesLanWanDemo.sh | 49 + .../CI/demoResourcesWanLan/root/root.json | 11 + .../resources/CI/demoResourcesWanLan/root/root.yml | 3 + .../resources/CI/demoResourcesWanLan/root/root.zip | Bin 0 -> 242 bytes .../CI/demoResourcesWanLan/router/router.json | 11 + .../CI/demoResourcesWanLan/router/router.yml | 13 + .../CI/demoResourcesWanLan/router/router.zip | Bin 0 -> 455 bytes .../src/test/resources/CI/error-configuration.yaml | 1576 ++ .../resources/CI/importAttResources/HSS/HSS.json | 11 + .../resources/CI/importAttResources/HSS/HSS.yml | 18 + .../CI/importAttResources/HSS/HSS.yml.old | 28 + .../resources/CI/importAttResources/HSS/HSS.zip | Bin 0 -> 357 bytes .../CI/importAttResources/ICSCF/ICSCF.json | 11 + .../CI/importAttResources/ICSCF/ICSCF.yml | 13 + .../CI/importAttResources/ICSCF/ICSCF.yml.old | 24 + .../CI/importAttResources/ICSCF/ICSCF.zip | Bin 0 -> 347 bytes .../CI/importAttResources/PCSCF/PCSCF.json | 11 + .../CI/importAttResources/PCSCF/PCSCF.yml | 13 + .../CI/importAttResources/PCSCF/PCSCF.zip | Bin 0 -> 343 bytes .../CI/importAttResources/SCSCF/SCSCF.json | 11 + .../CI/importAttResources/SCSCF/SCSCF.yml | 13 + .../CI/importAttResources/SCSCF/SCSCF.yml.old | 23 + .../CI/importAttResources/SCSCF/SCSCF.zip | Bin 0 -> 346 bytes .../CI/importAttResources/compute/compute.json | 15 + .../CI/importAttResources/compute/compute.yml | 35 + .../CI/importAttResources/compute/compute.zip | Bin 0 -> 477 bytes .../CI/importAttResources/deleteResourcesDemo.sh | 36 + .../CI/importAttResources/importResourcesDemo.sh | 39 + .../loadBalancer/loadBalancer.json | 11 + .../loadBalancer/loadBalancer.yml | 16 + .../loadBalancer/loadBalancer.zip | Bin 0 -> 384 bytes .../resources/CI/importAttResources/root/root.json | 11 + .../resources/CI/importAttResources/root/root.yml | 21 + .../resources/CI/importAttResources/root/root.zip | Bin 0 -> 378 bytes .../softwareComponent/softwareComponent.json | 11 + .../softwareComponent/softwareComponent.yml | 15 + .../softwareComponent/softwareComponent.zip | Bin 0 -> 358 bytes .../CI/importResource-MMSC/asdc.capabilities.yaml | 13 + .../asdc.nodes.Module/asdc.nodes.Module.json | 11 + .../asdc.nodes.Module/asdc.nodes.Module.yml | 2 + .../asdc.nodes.Module/asdc.nodes.Module.zip | Bin 0 -> 230 bytes .../asdc.nodes.Network/asdc.nodes.Network.json | 11 + .../asdc.nodes.Network/asdc.nodes.Network.yml | 2 + .../asdc.nodes.Network/asdc.nodes.Network.zip | Bin 0 -> 194 bytes .../asdc.nodes.Root/asdc.nodes.Root.json | 13 + .../asdc.nodes.Root/asdc.nodes.Root.yml | 3 + .../asdc.nodes.Root/asdc.nodes.Root.zip | Bin 0 -> 180 bytes .../asdc.nodes.module.ECA_OAM.json | 12 + .../asdc.nodes.module.ECA_OAM.yml | 9 + .../asdc.nodes.module.ECA_OAM.zip | Bin 0 -> 336 bytes .../asdc.nodes.module.ECA_TRX.json | 12 + .../asdc.nodes.module.ECA_TRX.yml | 12 + .../asdc.nodes.module.ECA_TRX.zip | Bin 0 -> 350 bytes .../asdc.nodes.module.F5_LTM.json | 12 + .../asdc.nodes.module.F5_LTM.yml | 12 + .../asdc.nodes.module.F5_LTM.zip | Bin 0 -> 347 bytes .../asdc.nodes.module.MMSC.json | 12 + .../asdc.nodes.module.MMSC.yml | 12 + .../asdc.nodes.module.MMSC.zip | Bin 0 -> 340 bytes .../asdc.nodes.module.NEMS_BE.json | 12 + .../asdc.nodes.module.NEMS_BE.yml | 9 + .../asdc.nodes.module.NEMS_BE.zip | Bin 0 -> 337 bytes .../asdc.nodes.module.NEMS_FE.json | 11 + .../asdc.nodes.module.NEMS_FE.yml | 15 + .../asdc.nodes.module.NEMS_FE.zip | Bin 0 -> 359 bytes .../asdc.nodes.network.Cinder.json | 12 + .../asdc.nodes.network.Cinder.yml | 5 + .../asdc.nodes.network.Cinder.zip | Bin 0 -> 262 bytes .../asdc.nodes.network.Core.json | 12 + .../asdc.nodes.network.Core.yml | 5 + .../asdc.nodes.network.Core.zip | Bin 0 -> 256 bytes .../asdc.nodes.network.DMZ.json | 12 + .../asdc.nodes.network.DMZ.yml | 5 + .../asdc.nodes.network.DMZ.zip | Bin 0 -> 255 bytes .../asdc.nodes.network.Internal.json | 11 + .../asdc.nodes.network.Internal.yml | 5 + .../asdc.nodes.network.Internal.zip | Bin 0 -> 302 bytes .../asdc.nodes.network.OAM.json | 12 + .../asdc.nodes.network.OAM.yml | 5 + .../asdc.nodes.network.OAM.zip | Bin 0 -> 254 bytes .../asdc.nodes.network.Traffic.json | 11 + .../asdc.nodes.network.Traffic.yml | 5 + .../asdc.nodes.network.Traffic.zip | Bin 0 -> 300 bytes .../CI/importResource-MMSC/capabilityTypes.zip | Bin 0 -> 320 bytes .../CI/importResource-MMSC/deleteNormative.sh | 35 + .../CI/importResource-MMSC/importNormative.sh | 85 + .../VCE_Brocade_Tosca.yaml | 834 + .../importResource-VCE-Brocade/capabilityTypes.zip | Bin 0 -> 1158 bytes .../importResource-VCE-Brocade/importVceBrocade.sh | 89 + ...necomp.resource.nfv.CP.IPAG_VLAN_Connector.json | 11 + ...necomp.resource.nfv.CP.IPAG_VLAN_Connector.yaml | 48 + ...enecomp.resource.nfv.CP.IPAG_VLAN_Connector.zip | Bin 0 -> 805 bytes ...enecomp.resource.nfv.CP.OAM_VLAN_Connector.json | 11 + ...enecomp.resource.nfv.CP.OAM_VLAN_Connector.yaml | 48 + ...penecomp.resource.nfv.CP.OAM_VLAN_Connector.zip | Bin 0 -> 795 bytes ...enecomp.resource.nfv.CP.VPE_VLAN_Connector.json | 11 + ...enecomp.resource.nfv.CP.VPE_VLAN_Connector.yaml | 48 + ...penecomp.resource.nfv.CP.VPE_VLAN_Connector.zip | Bin 0 -> 796 bytes .../org.openecomp.resource.nfv.CP.json | 11 + .../org.openecomp.resource.nfv.CP.yaml | 7 + .../org.openecomp.resource.nfv.CP.zip | Bin 0 -> 339 bytes ...necomp.resource.nfv.VDU.RoutingCategoryVDU.json | 11 + ...necomp.resource.nfv.VDU.RoutingCategoryVDU.yaml | 7 + ...enecomp.resource.nfv.VDU.RoutingCategoryVDU.zip | Bin 0 -> 395 bytes ...openecomp.resource.nfv.VDU.VCE_Brocade_VDU.json | 11 + ...openecomp.resource.nfv.VDU.VCE_Brocade_VDU.yaml | 156 + ....openecomp.resource.nfv.VDU.VCE_Brocade_VDU.zip | Bin 0 -> 1751 bytes .../org.openecomp.resource.nfv.VDU.json | 11 + .../org.openecomp.resource.nfv.VDU.yaml | 5 + .../org.openecomp.resource.nfv.VDU.zip | Bin 0 -> 344 bytes ...openecomp.resource.nfv.VDU.DHCPCategoryVDU.json | 11 + ...openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml | 10 + ....openecomp.resource.nfv.VDU.DHCPCategoryVDU.zip | Bin 0 -> 480 bytes ....openecomp.resource.nfv.VDU.DNSCategoryVDU.json | 11 + ....openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml | 10 + ...g.openecomp.resource.nfv.VDU.DNSCategoryVDU.zip | Bin 0 -> 475 bytes ...ecomp.resource.nfv.VDU.FirewallCategoryVDU.json | 11 + ...ecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml | 10 + ...necomp.resource.nfv.VDU.FirewallCategoryVDU.zip | Bin 0 -> 489 bytes ...mp.resource.nfv.VDU.NetworkAddrCategoryVDU.json | 11 + ...mp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml | 10 + ...omp.resource.nfv.VDU.NetworkAddrCategoryVDU.zip | Bin 0 -> 550 bytes ...ecomp.resource.nfv.VDU.PortAddrCategoryVDU.json | 11 + ...ecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml | 10 + ...necomp.resource.nfv.VDU.PortAddrCategoryVDU.zip | Bin 0 -> 538 bytes .../org.openecomp.resource.nfv.VL.json | 11 + .../org.openecomp.resource.nfv.VL.yaml | 7 + .../org.openecomp.resource.nfv.VL.zip | Bin 0 -> 310 bytes ...openecomp.resource.nfv.VNF.VCE_Brocade_VNF.json | 11 + ...openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml | 32 + ....openecomp.resource.nfv.VNF.VCE_Brocade_VNF.zip | Bin 0 -> 592 bytes .../org.openecomp.resource.nfv.VNF.json | 11 + .../org.openecomp.resource.nfv.VNF.yaml | 5 + .../org.openecomp.resource.nfv.VNF.zip | Bin 0 -> 309 bytes .../tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.json | 11 + .../tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.yaml | 16 + .../tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.zip | Bin 0 -> 414 bytes .../tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.json | 11 + .../tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.yaml | 30 + .../tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.zip | Bin 0 -> 532 bytes .../tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.json | 11 + .../tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.yaml | 24 + .../tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.zip | Bin 0 -> 462 bytes .../tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.json | 11 + .../tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.yaml | 28 + .../tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.zip | Bin 0 -> 502 bytes .../vce.brocade.capabilities.yaml | 191 + .../resources/CI/importResource/DBMS/DBMS.json | 20 + .../DBMS/normative-types-new-DBMS.yml | 17 + .../DBMS/normative-types-new-DBMS.zip | Bin 0 -> 422 bytes .../importResource/blockStorage/blockStorage.json | 20 + .../normative-types-new-blockStorage.yml | 18 + .../normative-types-new-blockStorage.zip | Bin 0 -> 392 bytes .../CI/importResource/capabilityTypes.yml | 148 + .../CI/importResource/capabilityTypes.zip | Bin 0 -> 1018 bytes .../CI/importResource/capabilityTypesCi.zip | Bin 0 -> 990 bytes .../resources/CI/importResource/categoryTypes.yml | 89 + .../resources/CI/importResource/categoryTypes.zip | Bin 0 -> 710 bytes .../CI/importResource/compute/compute.json | 24 + .../compute/normative-types-new-compute.yml | 35 + .../compute/normative-types-new-compute.zip | Bin 0 -> 559 bytes .../containerApplication/containerApplication.json | 20 + .../normative-types-new-containerApplication.yml | 9 + .../normative-types-new-containerApplication.zip | Bin 0 -> 358 bytes .../containerRuntime/containerRuntime.json | 20 + .../normative-types-new-containerRuntime.yml | 9 + .../normative-types-new-containerRuntime.zip | Bin 0 -> 335 bytes .../CI/importResource/database/database.json | 20 + .../database/normative-types-new-database.yml | 27 + .../database/normative-types-new-database.zip | Bin 0 -> 517 bytes .../resources/CI/importResource/deleteNormative.sh | 49 + .../resources/CI/importResource/importNormative.sh | 89 + .../CI/importResource/interfaceLifecycleTypes.yml | 11 + .../CI/importResource/interfaceLifecycleTypes.zip | Bin 0 -> 273 bytes .../importResource/loadBalancer/loadBalancer.json | 20 + .../normative-types-new-loadBalancer.yml | 18 + .../normative-types-new-loadBalancer.zip | Bin 0 -> 468 bytes .../CI/importResource/network/network.json | 21 + .../network/normative-types-new-network.yml | 41 + .../network/normative-types-new-network.zip | Bin 0 -> 461 bytes .../normative-port/normative-types-new-port.yml | 31 + .../normative-port/normative-types-new-port.zip | Bin 0 -> 454 bytes .../CI/importResource/normative-port/port.json | 20 + .../importResource/notmative-network/network.json | 20 + .../normative-types-new-network.yml | 41 + .../normative-types-new-network.zip | Bin 0 -> 450 bytes .../normative-types-new-objectStorage.yml | 18 + .../normative-types-new-objectStorage.zip | Bin 0 -> 386 bytes .../objectStorage/objectStorage.json | 20 + .../port/normative-types-new-port.yml | 31 + .../port/normative-types-new-port.zip | Bin 0 -> 467 bytes .../resources/CI/importResource/port/port.json | 21 + .../root/normative-types-new-root.yml | 23 + .../root/normative-types-new-root.zip | Bin 0 -> 457 bytes .../resources/CI/importResource/root/root.json | 20 + .../normative-types-new-softwareComponent.yml | 17 + .../normative-types-new-softwareComponent.zip | Bin 0 -> 435 bytes .../softwareComponent/softwareComponent.json | 20 + .../normative-types-new-webApplication.yml | 15 + .../normative-types-new-webApplication.zip | Bin 0 -> 398 bytes .../webApplication/webApplication.json | 20 + .../webServer/normative-types-new-webServer.yml | 11 + .../webServer/normative-types-new-webServer.zip | Bin 0 -> 380 bytes .../CI/importResource/webServer/webServer.json | 20 + .../CI/importResourceTests/csars/VSPPackage.csar | Bin 0 -> 26339 bytes .../csars/caseSensitiveTest_1.csar | Bin 0 -> 1316 bytes .../csars/caseSensitiveTest_2.csar | Bin 0 -> 1316 bytes .../CI/importResourceTests/csars/csars.zip | Bin 0 -> 34892 bytes .../csars/fiveLinesAsBlock0.csar | Bin 0 -> 1325 bytes .../csars/invalidCsarVersion.csar | Bin 0 -> 1317 bytes .../csars/invalidCsarVersion2.csar | Bin 0 -> 1315 bytes .../csars/invalidCsarVersion3.csar | Bin 0 -> 1317 bytes .../csars/invalidCsarVersion4.csar | Bin 0 -> 1317 bytes .../csars/invalidCsarVersion5.csar | Bin 0 -> 1319 bytes .../csars/longNamesInToscaMetaFile1.csar | Bin 0 -> 1322 bytes .../csars/longNamesInToscaMetaFile2.csar | Bin 0 -> 1322 bytes .../csars/longNamesInToscaMetaFile3.csar | Bin 0 -> 1319 bytes .../csars/longNamesInToscaMetaFile4.csar | Bin 0 -> 1319 bytes .../csars/longNamesInToscaMetaFile5.csar | Bin 0 -> 1319 bytes .../csars/missingEntryDefintionPair.csar | Bin 0 -> 1285 bytes .../csars/missingOneLineInToscaMeta.csar | Bin 0 -> 1295 bytes .../CI/importResourceTests/csars/mock_vf.csar | Bin 0 -> 1316 bytes .../CI/importResourceTests/csars/mock_vf2.csar | Bin 0 -> 1314 bytes .../csars/moreThanOneMetaFile.csar | Bin 0 -> 1808 bytes .../csars/moreThenOneYamlFile.csar | Bin 0 -> 2470 bytes .../importResourceTests/csars/noCSARVersion.csar | Bin 0 -> 1316 bytes .../csars/noCreatedByValue.csar | Bin 0 -> 1304 bytes .../csars/noEntryDefinitionsValue.csar | Bin 0 -> 1296 bytes .../csars/noNewLineAfterBLock0.csar | Bin 0 -> 1316 bytes .../csars/noTOSCAMetaFileVersionValue.csar | Bin 0 -> 1315 bytes .../csars/notContainYamlAndMetaFiles.csar | Bin 0 -> 490 bytes .../csars/notContainYamlFile.csar | Bin 0 -> 757 bytes .../csars/someValueAfterBlock0.csar | Bin 0 -> 1322 bytes .../csars/toscaFolderNotExists.csar | Bin 0 -> 907 bytes .../csars/toscaMetaFileNotExists.csar | Bin 0 -> 1049 bytes .../csars/toscaMetaOutsideTheFolder.csar | Bin 0 -> 1286 bytes .../csars/underscoreInsteadOfDash.csar | Bin 0 -> 1316 bytes .../csars/validCsarVersion.csar | Bin 0 -> 1320 bytes .../CI/importResourceTests/csars/valid_vf.csar | Bin 0 -> 1316 bytes .../CI/importResourceTests/csars/valid_vf_zip.zip | Bin 0 -> 1316 bytes .../empty_category/empty_category.json | 22 + .../normative-types-new-empty_category.yml | 16 + .../normative-types-new-empty_category.zip | Bin 0 -> 394 bytes .../empty_contact/empty_contact.json | 22 + .../normative-types-new-empty_contact.yml | 18 + .../normative-types-new-empty_contact.zip | Bin 0 -> 445 bytes .../importResourceTests/empty_desc/empty_desc.json | 22 + .../empty_desc/normative-types-new-empty_desc.yml | 16 + .../empty_desc/normative-types-new-empty_desc.zip | Bin 0 -> 386 bytes .../importResourceTests/empty_icon/empty_icon.json | 22 + .../empty_icon/normative-types-new-empty_icon.yml | 16 + .../empty_icon/normative-types-new-empty_icon.zip | Bin 0 -> 386 bytes .../empty_payloadName/empty_payloadName.json | 22 + .../normative-types-new-empty_payloadName.yml | 16 + .../normative-types-new-empty_payloadName.zip | Bin 0 -> 400 bytes .../empty_resource_name/empty_resource_name.json | 16 + .../normative-types-new-empty_resource_name.yml | 18 + .../normative-types-new-empty_resource_name.zip | Bin 0 -> 456 bytes .../importResourceTests/empty_tag/empty_tag.json | 16 + .../empty_tag/normative-types-new-empty_tag.yml | 18 + .../empty_tag/normative-types-new-empty_tag.zip | Bin 0 -> 436 bytes .../import _multiple_tags.json | 18 + .../normative-types-new-import _multiple_tags.yml | 16 + .../normative-types-new-import _multiple_tags.zip | Bin 0 -> 408 bytes .../importResource4test/importResource4test.json | 16 + .../normative-types-new-importResource4test.yml | 30 + .../normative-types-new-importResource4test.zip | Bin 0 -> 630 bytes .../importResource4testCP.json | 17 + .../normative-types-new-importResource4testCP.yml | 30 + .../normative-types-new-importResource4testCP.zip | Bin 0 -> 637 bytes .../importResource4testMissingNameSpace.json | 17 + ...pes-new-importResource4testMissingNameSpace.yml | 30 + ...pes-new-importResource4testMissingNameSpace.zip | Bin 0 -> 662 bytes .../importResource4testUnknown.json | 17 + ...mative-types-new-importResource4testUnknown.yml | 30 + ...mative-types-new-importResource4testUnknown.zip | Bin 0 -> 651 bytes ...rtResource4testUpdateVendorNameAndCategory.json | 16 + ...ortResource4testUpdateVendorNameAndCategory.yml | 12 + ...ortResource4testUpdateVendorNameAndCategory.zip | Bin 0 -> 447 bytes .../importResource4testUpdateWithoutReqCap.json | 17 + ...-new-importResource4testUpdateWithoutReqCap.yml | 12 + ...-new-importResource4testUpdateWithoutReqCap.zip | Bin 0 -> 460 bytes .../importResource4testVF.json | 17 + .../normative-types-new-importResource4testVF.yml | 30 + .../normative-types-new-importResource4testVF.zip | Bin 0 -> 637 bytes .../importResource4testVFC.json | 17 + .../normative-types-new-importResource4testVFC.yml | 30 + .../normative-types-new-importResource4testVFC.zip | Bin 0 -> 641 bytes .../importResource4testVL.json | 17 + .../normative-types-new-importResource4testVL.yml | 30 + .../normative-types-new-importResource4testVL.zip | Bin 0 -> 637 bytes .../import_capabilitiesTypes/capabilityTypes.yml | 141 + .../import_capabilitiesTypes/capabilityTypes.zip | Bin 0 -> 979 bytes .../import_capabilitiesTypes/capabilityTypesCi.zip | Bin 0 -> 990 bytes .../capabilityTypesCi_MissingDerivedFrom.yml | 132 + .../capabilityTypesCi_WithoutRoot.yml | 141 + .../missing_category/missing_category.json | 12 + .../normative-types-new-missing_category.yml | 18 + .../normative-types-new-missing_category.zip | Bin 0 -> 450 bytes .../missing_contact/missing_contact.json | 21 + .../normative-types-new-missing_contact.yml | 18 + .../normative-types-new-missing_contact.zip | Bin 0 -> 449 bytes .../missing_derived_from/missing_derived_from.json | 16 + .../normative-types-new-missing_derived_from.yml | 15 + .../normative-types-new-missing_derived_from.zip | Bin 0 -> 391 bytes .../missing_desc/missing_desc.json | 15 + .../normative-types-new-missing_desc.yml | 18 + .../normative-types-new-missing_desc.zip | Bin 0 -> 442 bytes .../missing_icon/missing_icon.json | 15 + .../normative-types-new-missing_icon.yml | 18 + .../normative-types-new-missing_icon.zip | Bin 0 -> 442 bytes .../missing_payloadName/missing_payloadName.json | 15 + .../normative-types-new-missing_payloadName.yml | 18 + .../normative-types-new-missing_payloadName.zip | Bin 0 -> 456 bytes .../missing_resource_name.json | 16 + .../normative-types-new-missing_resource_name.yml | 18 + .../normative-types-new-missing_resource_name.zip | Bin 0 -> 460 bytes .../missing_tags/missing_tags.json | 15 + .../normative-types-new-missing_tags.yml | 18 + .../normative-types-new-missing_tags.zip | Bin 0 -> 442 bytes .../importResourceTests/myCompute/myCompute.json | 24 + .../myCompute/normative-types-new-myCompute.yml | 35 + .../myCompute/normative-types-new-myCompute.zip | Bin 0 -> 567 bytes ...normative-types-new-portInvalidDefaultValue.yml | 29 + ...normative-types-new-portInvalidDefaultValue.zip | Bin 0 -> 470 bytes .../portInvalidDefaultValue.json | 16 + .../normative-types-new-userCompute.yml | 35 + .../normative-types-new-userCompute.zip | Bin 0 -> 610 bytes .../userCompute/userCompute.json | 26 + .../normative-types-new-userUpdateCompute.yml | 29 + .../normative-types-new-userUpdateCompute.zip | Bin 0 -> 580 bytes .../userUpdateCompute/userUpdateCompute.json | 22 + ...types-new-validateProporties_happyScenarios.yml | 39 + ...types-new-validateProporties_happyScenarios.zip | Bin 0 -> 591 bytes .../validateProporties_happyScenarios.json | 14 + ...ew-validateProporties_typeBoolean_valueInit.yml | 21 + ...ew-validateProporties_typeBoolean_valueInit.zip | Bin 0 -> 578 bytes .../validateProporties_typeBoolean_valueInit.json | 14 + ...-validateProporties_typeBoolean_valueString.yml | 21 + ...-validateProporties_typeBoolean_valueString.zip | Bin 0 -> 579 bytes ...validateProporties_typeBoolean_valueString.json | 14 + ...w-validateProporties_typeFloat_valueBoolean.yml | 21 + ...w-validateProporties_typeFloat_valueBoolean.zip | Bin 0 -> 575 bytes .../validateProporties_typeFloat_valueBoolean.json | 14 + ...ew-validateProporties_typeFloat_valueString.yml | 21 + ...ew-validateProporties_typeFloat_valueString.zip | Bin 0 -> 574 bytes .../validateProporties_typeFloat_valueString.json | 14 + ...ew-validateProporties_typeInit_valueBoolean.yml | 21 + ...ew-validateProporties_typeInit_valueBoolean.zip | Bin 0 -> 574 bytes .../validateProporties_typeInit_valueBoolean.json | 16 + ...-new-validateProporties_typeInit_valueFloat.yml | 21 + ...-new-validateProporties_typeInit_valueFloat.zip | Bin 0 -> 572 bytes .../validateProporties_typeInit_valueFloat.json | 16 + ...new-validateProporties_typeInit_valueString.yml | 21 + ...new-validateProporties_typeInit_valueString.zip | Bin 0 -> 572 bytes .../validateProporties_typeInit_valueString.json | 16 + ...idateProporties_typeList_valueUrlCredential.yml | 50 + ...idateProporties_typeList_valueUrlCredential.zip | Bin 0 -> 717 bytes ...dateProporties_typeList_valueUrlCredential.json | 16 + ...lidateProporties_typeMap_valueUrlCredential.yml | 29 + ...lidateProporties_typeMap_valueUrlCredential.zip | Bin 0 -> 628 bytes ...idateProporties_typeMap_valueUrlCredential.json | 16 + ...orties_typeString_valueString_special_chars.yml | 19 + ...rties_typeString_valueString_special_chars.json | 16 + ...eProporties_typeString_valueString_trimming.yml | 19 + ...Proporties_typeString_valueString_trimming.json | 16 + ...mative-types-new-validateProporties_typeMap.yml | 32 + ...mative-types-new-validateProporties_typeMap.zip | Bin 0 -> 638 bytes .../validateProporties_typeTestDataType.json | 16 + .../CI/importTypesTest/categoryTypesTest.yml | 23 + .../CI/importTypesTest/categoryTypesTest.zip | Bin 0 -> 333 bytes .../importTypesTest/myHeatStack1/myHeatStack1.yml | 13 + .../importTypesTest/myHeatStack1/myHeatStack1.zip | Bin 0 -> 401 bytes .../importTypesTest/myHeatStack2/myHeatStack2.yml | 14 + .../importTypesTest/myHeatStack2/myHeatStack2.zip | Bin 0 -> 386 bytes .../src/test/resources/CI/other/mapping.json | 182 + .../addYangXmlArtifactToResource.xml | 32 + .../HeatDeploymentArtifacts/asc_heat 0 2.yaml | 787 + .../tests/HeatDeploymentArtifacts/asc_heat 0 2.zip | Bin 0 -> 2420 bytes .../HeatDeploymentArtifacts/asc_heat_net 0 2.yaml | 787 + .../tests/HeatDeploymentArtifacts/heatEnvfile.env | 787 + .../HeatDeploymentArtifacts/heatInvalidFormat.yaml | 9 + .../tests/HeatDeploymentArtifacts/heat_mini.yaml | 13 + .../tests/HeatDeploymentArtifacts/invalidJson.json | 11 + .../HeatDeploymentArtifacts/invalidYamlFormat.yaml | 787 + .../HeatDeploymentArtifacts/invalidYangXml.xml | 35 + .../HeatDeploymentArtifacts/jsonArtifact.json | 22 + .../CI/tests/HeatDeploymentArtifacts/other.txt | 3 + .../bluePrintSampleArtifact.xml | 3 + .../docSampleArtifact.docx | Bin 0 -> 11307 bytes .../emfSampleArtifact.emf | 2 + .../emfSampleArtifact.xml | 3 + .../eventSampleArtifact.xml | 3 + .../jsonSampleArtifact.json | 3 + .../toscaSampleArtifact.yml | 5 + .../asc_heat 0 2.yaml | 787 + .../org.openstack.Rally.zip | Bin 0 -> 11590 bytes .../images/mysql.png | Bin 0 -> 63119 bytes .../getResourceArtifactFileContentTest/mysql.yml | 85 + .../scripts/install_mysql.sh | 28 + .../scripts/start_mysql.sh | 105 + .../getResourceArtifactListNoContentTest/mysql.yml | 85 + .../getResourceArtifactListTest/images/mysql.png | Bin 0 -> 63119 bytes .../CI/tests/getResourceArtifactListTest/mysql.yml | 85 + .../scripts/install_mysql.sh | 28 + .../scripts/start_mysql.sh | 105 + .../mysql.yml | 85 + .../images/mysql.png | Bin 0 -> 63119 bytes .../getResourceArtifactMetadataTest/mysql.yml | 85 + .../scripts/install_mysql.sh | 28 + .../scripts/start_mysql.sh | 105 + .../mysql.yml | 85 + .../resource1/images/mysql.png | Bin 0 -> 63119 bytes .../resource1/mysql.yml | 85 + .../resource1/scripts/install_mysql.sh | 28 + .../resource1/scripts/start_mysql.sh | 105 + .../resource2/images/mysql.png | Bin 0 -> 63119 bytes .../resource2/mysql.yml | 85 + .../resource2/scripts/install_mysql2.sh | 28 + .../resource2/scripts/start_mysql2.sh | 105 + .../topology.txt | 1 + .../topologyTemplate.txt | 2 + .../resource1/images/mysql.png | Bin 0 -> 63119 bytes .../resource1/mysql.yml | 85 + .../resource2/images/mysql.png | Bin 0 -> 63119 bytes .../resource2/mysql.yml | 85 + .../topology.txt | 1 + .../topologyTemplate.txt | 2 + .../resource1/images/mysql.png | Bin 0 -> 63119 bytes .../getServiceArtifactListTest/resource1/mysql.yml | 85 + .../resource1/scripts/install_mysql.sh | 28 + .../resource1/scripts/start_mysql.sh | 105 + .../resource2/images/mysql.png | Bin 0 -> 63119 bytes .../getServiceArtifactListTest/resource2/mysql.yml | 85 + .../resource2/scripts/install_mysql2.sh | 28 + .../resource2/scripts/start_mysql2.sh | 105 + .../tests/getServiceArtifactListTest/topology.txt | 1 + .../topologyTemplate.txt | 2 + .../Service1/resource1/images/mysql.png | Bin 0 -> 63119 bytes .../Service1/resource1/mysql.yml | 85 + .../Service1/resource1/scripts/install_mysql.sh | 28 + .../Service1/resource1/scripts/start_mysql.sh | 105 + .../Service1/resource2/images/mysql.png | Bin 0 -> 63119 bytes .../Service1/resource2/mysql.yml | 85 + .../Service1/resource2/scripts/install_mysql2.sh | 28 + .../Service1/resource2/scripts/start_mysql2.sh | 105 + .../tests/getServiceListTest/Service1/topology.txt | 1 + .../Service1/topologyTemplate.txt | 2 + .../Service2/resource1/images/mysql.png | Bin 0 -> 63119 bytes .../Service2/resource1/mysql.yml | 85 + .../Service2/resource2/images/mysql.png | Bin 0 -> 63119 bytes .../Service2/resource2/mysql.yml | 85 + .../tests/getServiceListTest/Service2/topology.txt | 1 + .../Service2/topologyTemplate.txt | 2 + .../heatWithParamsMissingDefault.yaml | 603 + .../heatWithParamsMissingDesc.yaml | 603 + .../heatWithParamsMissingType.yaml | 603 + .../heatWithValidParams.yaml | 787 + .../resources/CI/tests/heatEnv/artifact_1.yaml | 144 + .../resources/CI/tests/heatEnv/artifact_2.yaml | 469 + .../src/test/resources/CI/tests/heatEnv/yuli.yaml | 144 + .../BindingAsset.yml | 14 + .../CPHasNoReqCap.yml | 9 + .../CPHasNoReqCap_DerivedFromMyCompute1.yml | 9 + .../CPWithAttributes.yml | 59 + .../CaseInsensitiveCapTest_1.yml | 34 + .../CaseInsensitiveCapTest_2.yml | 34 + .../CaseInsensitiveReqTest_1.yml | 34 + .../CaseInsensitiveReqTest_2.yml | 34 + .../DerivedFromCPWithOwnReq.yml | 14 + .../DerivedFromWebApplication_HasNoReqType.yml | 27 + .../DifferentCapFromRoot.yml | 26 + .../DifferentReqAndCap.yml | 34 + .../DifferentReqCapFromCompute1.yml | 22 + .../DifferentReqCapFromCompute2.yml | 25 + .../DifferentReqFromCompute.yml | 32 + .../FatherHasNoReqCap.yml | 9 + .../ListPropertyFalure01.yml | 17 + .../ListPropertyFalure02.yml | 17 + .../ListPropertyFalure03.yml | 17 + .../ListPropertyFalure04.yml | 17 + .../ListPropertyFalure05.yml | 17 + .../ListPropertyFalure06.yml | 17 + .../ListPropertyFalure07.yml | 17 + .../ListPropertyFalure08.yml | 17 + .../ListPropertyFalure09.yml | 17 + .../ListPropertyFalure10.yml | 17 + .../ListPropertyFalure11.yml | 17 + .../ListPropertyFalure12.yml | 17 + .../ListPropertyFalure13.yml | 17 + .../ListPropertyFalure14.yml | 18 + .../ListPropertyFalure15.yml | 19 + .../ListPropertyFalure16.yml | 17 + .../MapPropertyFalure01.yml | 17 + .../MapPropertyFalure02.yml | 17 + .../MapPropertyFalure03.yml | 17 + .../MapPropertyFalure04.yml | 17 + .../MapPropertyFalure05.yml | 17 + .../MapPropertyFalure06.yml | 17 + .../MapPropertyFalure07.yml | 17 + .../MapPropertyFalure08.yml | 17 + .../MapPropertyFalure09.yml | 17 + .../MapPropertyFalure10.yml | 17 + .../MapPropertyFalure11.yml | 17 + .../MapPropertyFalure12.yml | 17 + .../MapPropertyFalure13.yml | 17 + .../MapPropertyFalure14.yml | 18 + .../MapPropertyFalure15.yml | 19 + .../MapPropertyFalure16.yml | 17 + .../MyFatherCompute_NoReqCap.yml | 17 + .../SameCapAsCompute.yml | 26 + .../SameReqAsCompute.yml | 23 + .../SameReqAsCompute_DerivedFromMyCompute1.yml | 23 + .../computeCap11.yml | 35 + .../computeCap1UNBOUNDED.yml | 35 + .../derivedFromMyCompute.yml | 35 + .../derivedFromWebAppDerivedReqCap.yml | 15 + .../importAttributeSuccessFlow.yml | 53 + .../importCapabilityNameExistsOnParent.yml | 35 + .../importDuplicateCapability.yml | 42 + .../importDuplicateRequirements.yml | 40 + .../importListPropertyBadDefault.yml | 17 + .../importListPropertyGoodDefault.yml | 17 + .../importListPropertySuccessFlow.yml | 198 + .../importMapPropertySuccessFlow.yml | 452 + .../importRequirementNameExistsOnParent.yml | 34 + ...entNameExistsOnParent_DerivedFromMyCompute1.yml | 34 + .../missingCapInCapDefinition.yml | 37 + .../missingCapInReqDefinition.yml | 25 + .../myChildCompute_NoReqCap.yml | 17 + .../myChildWebApp_DerivedFromContainer.yml | 15 + .../importToscaResourceByCreateUrl/myCompute.yml | 35 + .../myComputeDerivedFromNotExists.yml | 35 + .../myComputeIncorrectDefenitionVersionValue.yml | 35 + .../myComputeIncorrectNameSpaceFormat.yml | 35 + .../myComputeNoDefenitionVersion.yml | 34 + .../myComputeOccurencySuccess.yml | 77 + .../myComputeParssingFalure.yml | 35 + .../myComputeReqNameExistsOnDerived.yml | 34 + .../importToscaResourceByCreateUrl/myComputeVF.yml | 35 + .../myComputeWithNodeTypesTwice.yml | 42 + .../myComputeWithTopologyTemplate.yml | 44 + .../myFatherWebApp_derviedFromDocker.yml | 16 + .../importToscaResourceByCreateUrl/myLinkVL.yml | 35 + .../importToscaResourceByCreateUrl/myPortCP.yml | 35 + .../importToscaResourceByCreateUrl/noContent.yml | 0 .../occurencyFalure01.yml | 35 + .../occurencyFalure02.yml | 35 + .../occurencyFalure03.yml | 35 + .../occurencyFalure04.yml | 35 + .../occurencyFalure05.yml | 35 + .../occurencyFalure06.yml | 35 + .../occurencyFalure07.yml | 35 + .../occurencyFalure08.yml | 35 + .../occurencyFalure09.yml | 35 + .../occurencyFalure10.yml | 35 + .../occurencyFalure11.yml | 35 + .../occurencyFalure31.yml | 35 + .../occurencyFalure32.yml | 35 + .../occurencyFalure33.yml | 35 + .../occurencyFalure34.yml | 35 + .../occurencyFalure35.yml | 35 + .../occurencyFalure36.yml | 35 + .../occurencyFalure37.yml | 35 + .../occurencyFalure38.yml | 35 + .../occurencyFalure39.yml | 35 + .../occurencyFalure40.yml | 35 + .../occurencyFalure41.yml | 35 + .../softwareComponentReq11.yml | 17 + .../softwareComponentReq12.yml | 17 + .../resources/CI/tests/testCsarAPI/topology.txt | 1 + .../CI/tests/testCsarAPI/topologyTemplate.txt | 1 + .../tests/tmp/positive_artifact_bool10_false.yaml | 140 + .../tests/tmp/positive_artifact_bool11_false.yaml | 140 + .../tests/tmp/positive_artifact_bool12_false.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool1_true.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool2_true.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool3_true.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool4_true.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool5_true.yaml | 140 + .../CI/tests/tmp/positive_artifact_bool6_true.yaml | 140 + .../tests/tmp/positive_artifact_bool7_false.yaml | 140 + .../tests/tmp/positive_artifact_bool8_false.yaml | 140 + .../tests/tmp/positive_artifact_bool9_false.yaml | 140 + .../CI/tests/tmp/positive_artifact_number1.yaml | 140 + .../CI/tests/tmp/positive_artifact_number2.yaml | 140 + .../CI/tests/uploadComponent/images/mysql.png | Bin 0 -> 63119 bytes .../resources/CI/tests/uploadComponent/mysql.yml | 85 + .../tests/uploadComponent/scripts/install_mysql.sh | 28 + .../tests/uploadComponent/scripts/start_mysql.sh | 105 + .../yamlFieldsValidation/artifact_unsupported.yaml | 140 + .../negative_artifact_bool1.yaml | 140 + .../negative_artifact_bool2.yaml | 140 + .../negative_artifact_number1.yaml | 140 + .../negative_artifact_number2.yaml | 140 + .../negative_artifact_string1.yaml | 140 + asdc-tests/src/test/resources/config.json | 12 + asdc-tests/src/test/resources/logback-test.xml | 13 + asdc-tests/tarball.xml | 71 + asdc-tests/testng.xml | 15 + asdc-tests/testngLifeCycle.xml | 27 + asdctool/.gitignore | 3 + asdctool/.pydevproject | 5 + asdctool/pom.xml | 434 + .../java/org/openecomp/sdc/asdctool/Utils.java | 152 + .../openecomp/sdc/asdctool/impl/DataMigration.java | 830 + .../impl/EsToCassandraDataMigrationConfig.java | 51 + .../sdc/asdctool/impl/GraphMLConverter.java | 694 + .../sdc/asdctool/impl/GraphMLDataAnalyzer.java | 364 + .../sdc/asdctool/impl/PopulateComponentCache.java | 388 + .../openecomp/sdc/asdctool/impl/ProductLogic.java | 103 + .../org/openecomp/sdc/asdctool/impl/RestUtils.java | 83 + .../sdc/asdctool/impl/UpdatePropertyOnVertex.java | 180 + .../impl/migration/v1604/AddGroupUuid.java | 132 + .../impl/migration/v1604/AllowMultipleHeats.java | 144 + .../asdctool/impl/migration/v1604/AppConfig.java | 538 + .../impl/migration/v1604/DerivedFromAlignment.java | 232 + .../impl/migration/v1604/GroupsAlignment.java | 201 + .../impl/migration/v1604/MigrationCategory.java | 48 + .../impl/migration/v1604/MigrationSubCategory.java | 36 + .../impl/migration/v1604/ServiceMigration.java | 1703 ++ .../impl/migration/v1604/VfcNamingAlignment.java | 185 + .../impl/migration/v1607/CsarMigration.java | 93 + .../impl/migration/v1610/TitanFixUtils.java | 387 + .../migration/v1610/ToscaArtifactsAlignment.java | 461 + .../sdc/asdctool/main/DataSchemaMenu.java | 97 + .../main/EsToCassandraDataMigrationMenu.java | 109 + .../sdc/asdctool/main/ExportImportMenu.java | 169 + .../openecomp/sdc/asdctool/main/MigrationMenu.java | 251 + .../openecomp/sdc/asdctool/main/RemoveUtils.java | 78 + .../sdc/asdctool/main/UpdateIsVnfMenu.java | 122 + .../src/main/resources/application-context.xml | 11 + .../main/resources/config/categoryMigration.yaml | 113 + .../src/main/resources/config/configuration.yaml | 376 + .../src/main/resources/config/elasticsearch.yml | 392 + .../main/resources/config/error-configuration.yaml | 1671 ++ asdctool/src/main/resources/config/logback.xml | 44 + .../src/main/resources/config/titan.properties | 3 + .../src/main/resources/es-resources/README.txt | 43 + .../main/resources/es-resources/auditMappings.txt | 169 + .../resources/es-resources/audit_migration_1602.py | 132 + .../resources/es-resources/config_properties.py | 11 + .../src/main/resources/es-resources/file_utils.py | 21 + .../src/main/resources/es-resources/get-pip.py | 17759 ++++++++++++++ .../src/main/resources/es-resources/index_ops.py | 151 + .../types/auditinggetuebclusterevent.txt | 8 + .../es-resources/types/distributiondeployevent.txt | 14 + .../types/distributiondownloadevent.txt | 9 + .../es-resources/types/distributionengineevent.txt | 13 + .../types/distributionnotificationevent.txt | 16 + .../es-resources/types/distributionstatusevent.txt | 12 + .../es-resources/types/resourceadminevent.txt | 21 + .../es-resources/types/useraccessevent.txt | 10 + .../es-resources/types/useradminevent.txt | 20 + .../src/main/resources/scripts/baseOperation.sh | 33 + asdctool/src/main/resources/scripts/cleanCsar.sh | 33 + .../src/main/resources/scripts/dataMigration.sh | 33 + .../main/resources/scripts/dataMigration1607.sh | 33 + .../main/resources/scripts/dataMigration1610.sh | 41 + .../main/resources/scripts/deleteAllProducts.sh | 33 + .../main/resources/scripts/derivedFromAlignment.sh | 33 + .../resources/scripts/esToCassandraMigration.sh | 29 + .../scripts/esToCassandraMigrationExportOnly.sh | 29 + .../scripts/esToCassandraMigrationImportOnly.sh | 29 + asdctool/src/main/resources/scripts/exportGraph.sh | 29 + .../main/resources/scripts/exportGraphAsGraphMl.sh | 29 + asdctool/src/main/resources/scripts/exportUsers.sh | 33 + asdctool/src/main/resources/scripts/fix_icons.sh | 31 + asdctool/src/main/resources/scripts/fix_issue.sh | 33 + .../src/main/resources/scripts/groupsAlignment.sh | 33 + asdctool/src/main/resources/scripts/importGraph.sh | 29 + .../resources/scripts/populateComponentCache.sh | 33 + .../main/resources/scripts/python/duplicates.py | 47 + .../scripts/python/duplicatesAndRemove.py | 136 + .../src/main/resources/scripts/python/graphSize.py | 56 + .../resources/scripts/python/user/exportUsers.py | 122 + .../resources/scripts/python/user/importUsers.py | 215 + .../src/main/resources/scripts/schemaCreation.sh | 33 + asdctool/src/main/resources/scripts/updateIsVnf.sh | 36 + .../src/main/resources/scripts/vfcNameAlignment.sh | 33 + asdctool/tarball.xml | 26 + catalog-be/.gitignore | 8 + catalog-be/.pydevproject | 5 + catalog-be/README.txt | 41 + catalog-be/normatives.xml | 18 + catalog-be/pom.xml | 790 + .../sdc/be/auditing/api/IAuditingManager.java | 31 + .../auditing/impl/AuditingLogFormatConstants.java | 258 + .../be/auditing/impl/AuditingLogFormatUtil.java | 268 + .../sdc/be/auditing/impl/AuditingManager.java | 137 + .../clean/AsdcComponentsCleanerTask.java | 175 + .../clean/ComponentsCleanBusinessLogic.java | 89 + .../distribution/engine/ArtifactInfoImpl.java | 196 + .../distribution/engine/CambriaErrorResponse.java | 86 + .../distribution/engine/CambriaHandler.java | 610 + .../distribution/engine/DeConfigurationStatus.java | 40 + .../distribution/engine/DistributionEngine.java | 367 + .../engine/DistributionEngineClusterHealth.java | 356 + .../engine/DistributionEngineInitTask.java | 293 + .../engine/DistributionEnginePollingTask.java | 207 + .../engine/DistributionNotificationSender.java | 127 + .../engine/DistributionStatusNotification.java | 84 + .../engine/DistributionStatusNotificationEnum.java | 26 + .../distribution/engine/IArtifactInfo.java | 63 + .../distribution/engine/IDistributionEngine.java | 45 + .../distribution/engine/INotificationData.java | 102 + .../distribution/engine/IResourceArtifactInfo.java | 39 + .../distribution/engine/IServiceArtifactInfo.java | 25 + .../engine/JsonContainerResourceInstance.java | 108 + .../distribution/engine/NotificationDataImpl.java | 118 + .../engine/NotificationExecutorService.java | 81 + .../engine/PublishNotificationRunnable.java | 156 + .../engine/ResourceArtifactInfoImpl.java | 58 + .../engine/ServiceArtifactInfoImpl.java | 30 + .../ServiceDistributionArtifactsBuilder.java | 268 + .../distribution/engine/SubscriberTypeEnum.java | 26 + .../components/distribution/engine/TestQueue.java | 188 + .../distribution/engine/UebHealthCheckCall.java | 77 + .../engine/VfModuleArtifactPayload.java | 71 + .../impl/AdditionalInformationBusinessLogic.java | 573 + .../be/components/impl/ArtifactsBusinessLogic.java | 4127 ++++ .../be/components/impl/AttributeBusinessLogic.java | 295 + .../sdc/be/components/impl/BaseBusinessLogic.java | 571 + .../impl/CapabilityTypeImportManager.java | 123 + .../components/impl/CategoriesImportManager.java | 274 + .../be/components/impl/CommonImportManager.java | 309 + .../be/components/impl/ComponentBusinessLogic.java | 860 + .../impl/ComponentInstanceBusinessLogic.java | 1661 ++ .../components/impl/CompositionBusinessLogic.java | 285 + .../be/components/impl/ConsumerBusinessLogic.java | 313 + .../be/components/impl/CsarValidationUtils.java | 265 + .../be/components/impl/DataTypeImportManager.java | 255 + .../impl/DistributionMonitoringBusinessLogic.java | 214 + .../be/components/impl/ElementBusinessLogic.java | 1125 + .../sdc/be/components/impl/GroupBusinessLogic.java | 1512 ++ .../be/components/impl/GroupTypeImportManager.java | 151 + .../components/impl/HealthCheckBusinessLogic.java | 441 + .../impl/IDeploymentArtifactTypeConfigGetter.java | 27 + .../sdc/be/components/impl/ImportUtils.java | 722 + .../InformationDeployedArtifactsBusinessLogic.java | 117 + .../be/components/impl/InputsBusinessLogic.java | 526 + .../impl/InterfaceLifecycleTypeImportManager.java | 124 + .../components/impl/MonitoringBusinessLogic.java | 71 + .../components/impl/PolicyTypeImportManager.java | 130 + .../be/components/impl/ProductBusinessLogic.java | 887 + .../ProductComponentInstanceBusinessLogic.java | 59 + .../be/components/impl/PropertyBusinessLogic.java | 391 + .../components/impl/RequirementsBusinessLogic.java | 94 + .../be/components/impl/ResourceBusinessLogic.java | 5475 +++++ .../be/components/impl/ResourceImportManager.java | 921 + .../be/components/impl/ResponseFormatManager.java | 80 + .../be/components/impl/ServiceBusinessLogic.java | 1768 ++ .../ServiceComponentInstanceBusinessLogic.java | 58 + .../impl/VFComponentInstanceBusinessLogic.java | 72 + .../lifecycle/CertificationChangeTransition.java | 209 + .../lifecycle/CertificationRequestTransition.java | 409 + .../be/components/lifecycle/CheckinTransition.java | 119 + .../components/lifecycle/CheckoutTransition.java | 141 + .../components/lifecycle/LifeCycleTransition.java | 160 + .../lifecycle/LifecycleBusinessLogic.java | 572 + .../lifecycle/LifecycleChangeInfoBase.java | 42 + .../lifecycle/LifecycleChangeInfoWithAction.java | 50 + .../lifecycle/StartCertificationTransition.java | 119 + .../lifecycle/UndoCheckoutTransition.java | 170 + .../sdc/be/datamodel/api/CategoryTypeEnum.java | 39 + .../sdc/be/datamodel/api/HighestFilterEnum.java | 27 + .../sdc/be/datamodel/utils/ArtifactUtils.java | 58 + .../be/datamodel/utils/NodeTypeConvertUtils.java | 76 + .../sdc/be/distribution/AuditHandler.java | 65 + .../be/distribution/DistributionBusinessLogic.java | 243 + .../api/client/CambriaOperationStatus.java | 25 + .../api/client/RegistrationRequest.java | 40 + .../api/client/ServerListResponse.java | 36 + .../api/client/TopicRegistrationResponse.java | 42 + .../api/client/TopicUnregistrationResponse.java | 52 + .../servlet/DistributionCatalogServlet.java | 230 + .../distribution/servlet/DistributionServlet.java | 279 + .../org/openecomp/sdc/be/ecomp/EcompIntImpl.java | 376 + .../be/ecomp/converters/EcompRoleConverter.java | 53 + .../be/ecomp/converters/EcompUserConverter.java | 118 + .../servlet/ArtifactExternalServlet.java | 646 + .../servlet/AssetMetadataConverter.java | 381 + .../be/externalapi/servlet/AssetsDataServlet.java | 300 + .../servlet/representation/ArtifactMetadata.java | 106 + .../servlet/representation/AssetMetadata.java | 129 + .../servlet/representation/IAssetMetadata.java | 45 + .../representation/ProductAssetMetadata.java | 72 + .../ProductCategoryGroupMetadata.java | 57 + .../ResourceAssetDetailedMetadata.java | 63 + .../representation/ResourceAssetMetadata.java | 69 + .../representation/ResourceInstanceMetadata.java | 89 + .../ServiceAssetDetailedMetadata.java | 53 + .../representation/ServiceAssetMetadata.java | 60 + .../sdc/be/filters/BasicAuthenticationFilter.java | 225 + .../openecomp/sdc/be/filters/BeServletFilter.java | 202 + .../be/filters/ComponentsAvailabilityFilter.java | 122 + .../org/openecomp/sdc/be/impl/ComponentsUtils.java | 1461 ++ .../sdc/be/impl/DownloadArtifactLogic.java | 166 + .../org/openecomp/sdc/be/impl/ServletUtils.java | 49 + .../sdc/be/impl/WebAppContextWrapper.java | 35 + .../openecomp/sdc/be/info/ArtifactAccessInfo.java | 159 + .../openecomp/sdc/be/info/ArtifactAccessList.java | 40 + .../sdc/be/info/ArtifactDefinitionInfo.java | 84 + .../sdc/be/info/ArtifactTemplateInfo.java | 352 + .../openecomp/sdc/be/info/ArtifactTypesInfo.java | 48 + .../sdc/be/info/CreateAndAssotiateInfo.java | 52 + .../openecomp/sdc/be/info/DistributionStatus.java | 62 + .../sdc/be/info/DistributionStatusInfo.java | 91 + .../be/info/DistributionStatusListResponse.java | 37 + .../be/info/DistributionStatusOfServiceInfo.java | 74 + .../DistributionStatusOfServiceListResponce.java | 37 + .../openecomp/sdc/be/info/GroupDefinitionInfo.java | 130 + .../openecomp/sdc/be/info/GroupTemplateInfo.java | 60 + .../openecomp/sdc/be/info/MergedArtifactInfo.java | 151 + .../org/openecomp/sdc/be/info/ServiceInfo.java | 51 + .../openecomp/sdc/be/info/ServiceVersionInfo.java | 53 + .../org/openecomp/sdc/be/info/ServicesWrapper.java | 35 + .../openecomp/sdc/be/info/ServletJsonResponse.java | 44 + .../openecomp/sdc/be/info/ToscaNodeTypeInfo.java | 69 + .../sdc/be/info/ToscaNodeTypeInterface.java | 37 + .../sdc/be/listen/BEAppContextListener.java | 132 + .../org/openecomp/sdc/be/monitoring/EsGateway.java | 109 + .../be/servlets/AbstractValidationsServlet.java | 843 + .../be/servlets/AdditionalInformationServlet.java | 472 + .../openecomp/sdc/be/servlets/ArtifactServlet.java | 564 + .../sdc/be/servlets/AttributeServlet.java | 278 + .../sdc/be/servlets/BeGenericServlet.java | 226 + .../sdc/be/servlets/BeMonitoringServlet.java | 203 + .../sdc/be/servlets/ComponentInstanceServlet.java | 744 + .../sdc/be/servlets/ComponentServlet.java | 270 + .../sdc/be/servlets/ConfigMgrServlet.java | 125 + .../openecomp/sdc/be/servlets/ConfigServlet.java | 81 + .../openecomp/sdc/be/servlets/ConsumerServlet.java | 227 + .../sdc/be/servlets/CsarBuildServlet.java | 296 + .../be/servlets/DistributionServiceServlet.java | 169 + .../openecomp/sdc/be/servlets/ElementServlet.java | 611 + .../openecomp/sdc/be/servlets/GroupServlet.java | 182 + .../openecomp/sdc/be/servlets/InputsServlet.java | 320 + .../sdc/be/servlets/LifecycleServlet.java | 216 + .../openecomp/sdc/be/servlets/ProductServlet.java | 311 + .../openecomp/sdc/be/servlets/PropertyServlet.java | 562 + .../sdc/be/servlets/RepresentationUtils.java | 124 + .../sdc/be/servlets/RequirementsServlet.java | 84 + .../servlets/ResourceArtifactDownloadServlet.java | 188 + .../sdc/be/servlets/ResourceUploadServlet.java | 180 + .../sdc/be/servlets/ResourcesServlet.java | 692 + .../openecomp/sdc/be/servlets/ServiceServlet.java | 728 + .../openecomp/sdc/be/servlets/ToscaDaoServlet.java | 92 + .../sdc/be/servlets/TypesFetchServlet.java | 122 + .../sdc/be/servlets/TypesUploadServlet.java | 317 + .../sdc/be/servlets/UserAdminServlet.java | 516 + .../be/switchover/detector/SwitchoverDetector.java | 315 + .../org/openecomp/sdc/be/tosca/ArtifactTypes.java | 37 + .../java/org/openecomp/sdc/be/tosca/CSARTool.java | 45 + .../be/tosca/CapabiltyRequirementConvertor.java | 261 + .../java/org/openecomp/sdc/be/tosca/CsarUtils.java | 649 + .../openecomp/sdc/be/tosca/PropertyConvertor.java | 189 + .../org/openecomp/sdc/be/tosca/ToscaError.java | 26 + .../openecomp/sdc/be/tosca/ToscaExportHandler.java | 629 + .../sdc/be/tosca/ToscaRepresentation.java | 49 + .../org/openecomp/sdc/be/tosca/ToscaUtils.java | 69 + .../openecomp/sdc/be/tosca/model/EntrySchema.java | 43 + .../sdc/be/tosca/model/IToscaMetadata.java | 33 + .../sdc/be/tosca/model/SubstitutionMapping.java | 60 + .../sdc/be/tosca/model/ToscaCapability.java | 80 + .../sdc/be/tosca/model/ToscaGroupTemplate.java | 69 + .../sdc/be/tosca/model/ToscaMetadata.java | 137 + .../sdc/be/tosca/model/ToscaNodeTemplate.java | 73 + .../sdc/be/tosca/model/ToscaNodeType.java | 87 + .../sdc/be/tosca/model/ToscaProperty.java | 83 + .../sdc/be/tosca/model/ToscaRequirement.java | 45 + .../sdc/be/tosca/model/ToscaTemplate.java | 90 + .../be/tosca/model/ToscaTemplateCapability.java | 46 + .../be/tosca/model/ToscaTemplateRequirement.java | 68 + .../sdc/be/tosca/model/ToscaTopolgyTemplate.java | 63 + .../sdc/be/tosca/model/VfModuleToscaMetadata.java | 66 + .../openecomp/sdc/be/user/IUserBusinessLogic.java | 51 + .../main/java/org/openecomp/sdc/be/user/Role.java | 29 + .../org/openecomp/sdc/be/user/UserAdminAction.java | 27 + .../openecomp/sdc/be/user/UserAdminValidator.java | 69 + .../openecomp/sdc/be/user/UserBusinessLogic.java | 714 + .../sdc/common/transaction/api/ICommitHandler.java | 27 + .../sdc/common/transaction/api/IDBAction.java | 25 + .../sdc/common/transaction/api/IDBType.java | 27 + .../common/transaction/api/ITransactionSdnc.java | 40 + .../common/transaction/api/RollbackHandler.java | 121 + .../common/transaction/api/TransactionUtils.java | 85 + .../sdc/common/transaction/impl/ESAction.java | 58 + .../common/transaction/impl/ESRollbackHandler.java | 92 + .../transaction/impl/TitanCommitHandler.java | 52 + .../transaction/impl/TitanRollbackHandler.java | 55 + .../sdc/common/transaction/mngr/CommitManager.java | 87 + .../common/transaction/mngr/RollbackManager.java | 107 + .../transaction/mngr/TransactionManager.java | 98 + .../transaction/mngr/TransactionSdncImpl.java | 313 + .../src/main/resources/application-context.xml | 64 + .../src/main/resources/config/configuration.yaml | 478 + .../config/distribution-engine-configuration.yaml | 46 + .../config/ecomp-error-configuration.yaml | 383 + .../main/resources/config/error-configuration.yaml | 1694 ++ catalog-be/src/main/resources/config/logback.xml | 226 + .../config/neo4j-errors-configuration.yaml | 60 + .../src/main/resources/config/titan.properties | 10 + catalog-be/src/main/resources/elasticsearch.yml | 393 + .../tosca/capability-types/capabilityTypes.yml | 204 + .../tosca/capability-types/capabilityTypes.zip | Bin 0 -> 1385 bytes .../import/tosca/categories/categoryTypes.yml | 116 + .../import/tosca/categories/categoryTypes.zip | Bin 0 -> 848 bytes .../import/tosca/data-types/dataTypes.yml | 821 + .../import/tosca/data-types/dataTypes.zip | Bin 0 -> 3456 bytes .../import/tosca/group-types/groupTypes.yml | 30 + .../import/tosca/group-types/groupTypes.zip | Bin 0 -> 523 bytes .../abstractSubstitute/abstractSubstitute.json | 21 + .../abstractSubstitute/abstractSubstitute.yml | 17 + .../abstractSubstitute/abstractSubstitute.zip | Bin 0 -> 469 bytes .../heat-types/cinderVolume/cinderVolume.json | 20 + .../tosca/heat-types/cinderVolume/cinderVolume.yml | 177 + .../tosca/heat-types/cinderVolume/cinderVolume.zip | Bin 0 -> 1425 bytes .../contrailAbstractSubstitute.json | 17 + .../contrailAbstractSubstitute.yml | 137 + .../contrailAbstractSubstitute.zip | Bin 0 -> 1017 bytes .../contrailCompute/contrailCompute.json | 15 + .../heat-types/contrailCompute/contrailCompute.yml | 89 + .../heat-types/contrailCompute/contrailCompute.zip | Bin 0 -> 781 bytes .../contrailNetworkRules/contrailNetworkRules.json | 21 + .../contrailNetworkRules/contrailNetworkRules.yml | 49 + .../contrailNetworkRules/contrailNetworkRules.zip | Bin 0 -> 675 bytes .../heat-types/contrailPort/contrailPort.json | 21 + .../tosca/heat-types/contrailPort/contrailPort.yml | 64 + .../tosca/heat-types/contrailPort/contrailPort.zip | Bin 0 -> 720 bytes .../contrailV2NetworkRules.json | 21 + .../contrailV2NetworkRules.yml | 35 + .../contrailV2NetworkRules.zip | Bin 0 -> 638 bytes .../contrailV2VirtualMachineInterface.json | 15 + .../contrailV2VirtualMachineInterface.yml | 59 + .../contrailV2VirtualMachineInterface.zip | Bin 0 -> 718 bytes .../contrailV2VirtualNetwork.json | 21 + .../contrailV2VirtualNetwork.yml | 76 + .../contrailV2VirtualNetwork.zip | Bin 0 -> 764 bytes .../contrailVirtualNetwork.json | 21 + .../contrailVirtualNetwork.yml | 84 + .../contrailVirtualNetwork.zip | Bin 0 -> 826 bytes .../import/tosca/heat-types/eline/eline.json | 21 + .../import/tosca/heat-types/eline/eline.yml | 9 + .../import/tosca/heat-types/eline/eline.zip | Bin 0 -> 321 bytes .../tosca/heat-types/neutronNet/neutronNet.json | 21 + .../tosca/heat-types/neutronNet/neutronNet.yml | 97 + .../tosca/heat-types/neutronNet/neutronNet.zip | Bin 0 -> 972 bytes .../tosca/heat-types/neutronPort/neutronPort.json | 21 + .../tosca/heat-types/neutronPort/neutronPort.yml | 136 + .../tosca/heat-types/neutronPort/neutronPort.zip | Bin 0 -> 1192 bytes .../tosca/heat-types/novaServer/novaServer.json | 24 + .../tosca/heat-types/novaServer/novaServer.yml | 249 + .../tosca/heat-types/novaServer/novaServer.zip | Bin 0 -> 1840 bytes .../heat-types/securityRules/securityRules.json | 21 + .../heat-types/securityRules/securityRules.yml | 42 + .../heat-types/securityRules/securityRules.zip | Bin 0 -> 692 bytes .../resources/import/tosca/heat-types/vl/vl.json | 21 + .../resources/import/tosca/heat-types/vl/vl.yml | 18 + .../resources/import/tosca/heat-types/vl/vl.zip | Bin 0 -> 355 bytes .../interfaceLifecycleTypes.yml | 11 + .../interfaceLifecycleTypes.zip | Bin 0 -> 273 bytes .../import/tosca/normative-types/DBMS/DBMS.json | 20 + .../import/tosca/normative-types/DBMS/DBMS.yml | 17 + .../import/tosca/normative-types/DBMS/DBMS.zip | Bin 0 -> 382 bytes .../normative-types/blockStorage/blockStorage.json | 20 + .../normative-types/blockStorage/blockStorage.yml | 18 + .../normative-types/blockStorage/blockStorage.zip | Bin 0 -> 352 bytes .../tosca/normative-types/compute/compute.json | 24 + .../tosca/normative-types/compute/compute.yml | 35 + .../tosca/normative-types/compute/compute.zip | Bin 0 -> 519 bytes .../containerApplication/containerApplication.json | 20 + .../containerApplication/containerApplication.yml | 9 + .../containerApplication/containerApplication.zip | Bin 0 -> 318 bytes .../containerRuntime/containerRuntime.json | 20 + .../containerRuntime/containerRuntime.yml | 9 + .../containerRuntime/containerRuntime.zip | Bin 0 -> 295 bytes .../tosca/normative-types/database/database.json | 20 + .../tosca/normative-types/database/database.yml | 27 + .../tosca/normative-types/database/database.zip | Bin 0 -> 477 bytes .../normative-types/loadBalancer/loadBalancer.json | 20 + .../normative-types/loadBalancer/loadBalancer.yml | 20 + .../normative-types/loadBalancer/loadBalancer.zip | Bin 0 -> 428 bytes .../tosca/normative-types/network/network.json | 21 + .../tosca/normative-types/network/network.yml | 45 + .../tosca/normative-types/network/network.zip | Bin 0 -> 463 bytes .../objectStorage/objectStorage.json | 20 + .../objectStorage/objectStorage.yml | 18 + .../objectStorage/objectStorage.zip | Bin 0 -> 346 bytes .../import/tosca/normative-types/port/port.json | 21 + .../import/tosca/normative-types/port/port.yml | 31 + .../import/tosca/normative-types/port/port.zip | Bin 0 -> 414 bytes .../import/tosca/normative-types/root/root.json | 20 + .../import/tosca/normative-types/root/root.yml | 23 + .../import/tosca/normative-types/root/root.zip | Bin 0 -> 417 bytes .../softwareComponent/softwareComponent.json | 20 + .../softwareComponent/softwareComponent.yml | 17 + .../softwareComponent/softwareComponent.zip | Bin 0 -> 395 bytes .../webApplication/webApplication.json | 20 + .../webApplication/webApplication.yml | 15 + .../webApplication/webApplication.zip | Bin 0 -> 358 bytes .../tosca/normative-types/webServer/webServer.json | 20 + .../tosca/normative-types/webServer/webServer.yml | 11 + .../tosca/normative-types/webServer/webServer.zip | Bin 0 -> 340 bytes .../import/tosca/policy-types/policyTypes.yml | 94 + .../import/tosca/policy-types/policyTypes.zip | Bin 0 -> 673 bytes .../resources/import/tosca/users/importUsers.yaml | 13 + catalog-be/src/main/resources/jetty-ssl.xml | 51 + catalog-be/src/main/resources/keystore/README.txt | 16 + .../src/main/resources/keystore/catalogbe.jks | Bin 0 -> 2201 bytes .../src/main/resources/keystore/catalogbe.jks.pwd | 1 + catalog-be/src/main/resources/portal.properties | 25 + .../scripts/import/tosca/importCategoryTypes.py | 74 + .../resources/scripts/import/tosca/importCommon.py | 43 + .../scripts/import/tosca/importDataTypes.py | 74 + .../scripts/import/tosca/importGroupTypes.py | 74 + .../scripts/import/tosca/importHeatTypes.py | 113 + .../scripts/import/tosca/importNodeType.py | 156 + .../scripts/import/tosca/importNormativeAll.py | 135 + .../import/tosca/importNormativeCapabilities.py | 77 + .../import/tosca/importNormativeElements.py | 65 + .../importNormativeInterfaceLifecycleTypes.py | 75 + .../scripts/import/tosca/importNormativeTypes.py | 159 + .../scripts/import/tosca/importPolicyTypes.py | 74 + .../scripts/import/tosca/importUsersFromYaml.py | 221 + .../scripts/import/tosca/upgradeNormative.py | 114 + .../import/tosca/upgradeNormativeVersion.py | 143 + .../import/tosca/upgradeNormativeVersionAll.py | 93 + .../src/main/resources/swagger/css/print.css | 1155 + .../src/main/resources/swagger/css/reset.css | 125 + .../src/main/resources/swagger/css/screen.css | 1256 + .../src/main/resources/swagger/css/typography.css | 26 + .../swagger/fonts/droid-sans-v6-latin-700.eot | Bin 0 -> 22922 bytes .../swagger/fonts/droid-sans-v6-latin-700.svg | 411 + .../swagger/fonts/droid-sans-v6-latin-700.ttf | Bin 0 -> 40513 bytes .../swagger/fonts/droid-sans-v6-latin-700.woff | Bin 0 -> 25992 bytes .../swagger/fonts/droid-sans-v6-latin-700.woff2 | Bin 0 -> 11480 bytes .../swagger/fonts/droid-sans-v6-latin-regular.eot | Bin 0 -> 22008 bytes .../swagger/fonts/droid-sans-v6-latin-regular.svg | 403 + .../swagger/fonts/droid-sans-v6-latin-regular.ttf | Bin 0 -> 39069 bytes .../swagger/fonts/droid-sans-v6-latin-regular.woff | Bin 0 -> 24868 bytes .../fonts/droid-sans-v6-latin-regular.woff2 | Bin 0 -> 11304 bytes .../resources/swagger/images/explorer_icons.png | Bin 0 -> 5763 bytes .../resources/swagger/images/favicon-16x16.png | Bin 0 -> 645 bytes .../resources/swagger/images/favicon-32x32.png | Bin 0 -> 1654 bytes .../src/main/resources/swagger/images/favicon.ico | Bin 0 -> 5430 bytes .../main/resources/swagger/images/logo_small.png | Bin 0 -> 770 bytes .../resources/swagger/images/pet_store_api.png | Bin 0 -> 824 bytes .../src/main/resources/swagger/images/throbber.gif | Bin 0 -> 9257 bytes .../main/resources/swagger/images/wordnik_api.png | Bin 0 -> 980 bytes catalog-be/src/main/resources/swagger/index.html | 123 + .../src/main/resources/swagger/lib/backbone-min.js | 35 + .../main/resources/swagger/lib/handlebars-2.0.0.js | 48 + .../resources/swagger/lib/highlight.7.3.pack.js | 21 + .../main/resources/swagger/lib/jquery-1.8.0.min.js | 22 + .../resources/swagger/lib/jquery.ba-bbq.min.js | 38 + .../resources/swagger/lib/jquery.slideto.min.js | 21 + .../resources/swagger/lib/jquery.wiggle.min.js | 28 + .../src/main/resources/swagger/lib/marked.js | 1292 ++ .../main/resources/swagger/lib/swagger-oauth.js | 304 + .../main/resources/swagger/lib/underscore-min.js | 26 + .../main/resources/swagger/lib/underscore-min.map | 1 + catalog-be/src/main/resources/swagger/o2c.html | 20 + .../src/main/resources/swagger/swagger-ui.js | 21738 ++++++++++++++++++ .../src/main/resources/swagger/swagger-ui.min.js | 28 + catalog-be/src/main/webapp/META-INF/MANIFEST.MF | 9 + catalog-be/src/main/webapp/WEB-INF/jetty-web.xml | 8 + catalog-be/src/main/webapp/WEB-INF/web.xml | 131 + catalog-be/src/main/webapp/index.html | 7 + catalog-be/src/main/webapp/index.jsp | 5 + .../org/openecomp/sdc/AuditingMockManager.java | 44 + .../org/openecomp/sdc/ElementOperationMock.java | 266 + .../org/openecomp/sdc/ErrorConfigurationTest.java | 77 + .../openecomp/sdc/TestExternalConfiguration.java | 63 + .../src/test/java/org/openecomp/sdc/ZipUtil.java | 132 + .../sdc/be/components/AuditingManagerTest.java | 79 + .../sdc/be/components/BaseConfDependentTest.java | 48 + .../be/components/ComponentBusinessLogicTest.java | 61 + .../components/HealthCheckBusinessLogicTest.java | 91 + .../be/components/PropertyBusinessLogicTest.java | 189 + .../be/components/ResourceImportManagerTest.java | 369 + .../sdc/be/components/ResourceTestUtils.java | 90 + .../be/components/ServiceBusinessLogicTest.java | 931 + .../engine/DistributionEngineConfigTest.java | 168 + .../engine/DistributionEngineHealthCheckTest.java | 138 + .../engine/DistributionEngineInitTaskTest.java | 269 + .../components/impl/ArtifactBusinessLogicTest.java | 234 + .../impl/CapabilityTypeImportManagerTest.java | 105 + .../impl/CategoriesImportManagerTest.java | 111 + .../impl/CompositionBusinessLogicTest.java | 155 + .../components/impl/CsarValidationUtilsTest.java | 37 + .../sdc/be/components/impl/ImportUtilsTest.java | 509 + .../InterfaceLifecycleTypeImportManagerTest.java | 94 + .../components/impl/ResourceBusinessLogicTest.java | 1423 ++ .../impl/ResourceInstanceBusinessLogicTest.java | 284 + .../CertificationChangeTransitionTest.java | 169 + .../lifecycle/CertificationRequestTest.java | 230 + .../sdc/be/components/lifecycle/CheckinTest.java | 170 + .../sdc/be/components/lifecycle/CheckoutTest.java | 188 + .../be/components/lifecycle/LifecycleTestBase.java | 215 + .../be/components/lifecycle/UndoCheckoutTest.java | 125 + .../DistributionBusinessLogicTest.java | 192 + .../servlet/DistributionServletTest.java | 159 + .../sdc/be/ecomp/GenerateEcompErrorFileTest.java | 77 + .../servlets/AbstractValidationsServletTest.java | 72 + .../sdc/be/servlets/ApplicationConfig.java | 62 + .../sdc/be/servlets/ResourceServletTest.java | 268 + .../sdc/be/servlets/ResourceUploadServletTest.java | 189 + .../sdc/be/servlets/TypesUploadServletTest.java | 154 + .../sdc/be/servlets/UserAdminServletTest.java | 148 + .../sdc/be/user/UserAdminManagerTest.java | 91 + .../transaction/mngr/SdncTransactionTest.java | 437 + .../resources/config/catalog-be/configuration.yaml | 427 + .../distribution-engine-configuration.yaml | 43 + .../catalog-be/ecomp-error-configuration.yaml | 383 + .../config/catalog-be/error-configuration.yaml | 1583 ++ .../catalog-be/neo4j-errors-configuration.yaml | 60 + .../config/catalog-be/users-configuration.yaml | 2 + .../src/test/resources/config/configuration1.yaml | 17 + .../src/test/resources/config/elasticsearch.yml | 387 + .../test/resources/config/elasticsearch.yml.bak | 387 + .../resources/config/mysql-type-empty-nodes.zip | Bin 0 -> 1894 bytes .../test/resources/config/mysql-type-no-nodes.zip | Bin 0 -> 448 bytes .../resources/config/mysql-type-no-version.zip | Bin 0 -> 1142 bytes .../test/resources/config/mysql-type-only-yaml.zip | Bin 0 -> 1129 bytes .../resources/config/mysql-type-with-scripts.zip | Bin 0 -> 66267 bytes .../src/test/resources/config/mysql-type.yml | 82 + .../src/test/resources/config/mysql-type.zip | Bin 0 -> 1129 bytes .../test/resources/config/normative-types-root.zip | Bin 0 -> 1638 bytes catalog-be/src/test/resources/config/sample.yaml | 17 + .../test/resources/config/sampleNoProtocol.yaml | 17 + catalog-be/src/test/resources/elasticsearch.yml | 391 + catalog-be/src/test/resources/logback-test.xml | 13 + catalog-be/src/test/resources/mock_vf.csar | Bin 0 -> 1316 bytes .../normativeTypes/importToscaProperties.yml | 452 + .../normativeTypes/importToscaWithAttribute.yml | 41 + .../normative-types-all-map-test.yml | 30 + .../normativeTypes/normative-types-new-DBMS.yml | 17 + .../normativeTypes/normative-types-new-Root.yml | 23 + .../normative-types-new-blockStorage.yml | 18 + .../normativeTypes/normative-types-new-compute.yml | 35 + .../normative-types-new-database.yml | 27 + .../normativeTypes/normative-types-new-port.yml | 31 + .../normative-types-new-softwareComponent.yml | 17 + .../normative-types-new-webServer.yml | 11 + .../normative-types-string-list-test.yml | 29 + .../topology_template_duplicateNode.yml | 23 + .../normativeTypes/topology_template_empty.yml | 17 + .../normativeTypes/topology_template_inputs.yml | 103 + .../normativeTypes/topology_template_nodeEmpty.yml | 18 + .../normativeTypes/topology_template_nodeVF.yml | 38 + .../topology_template_notValidNode.yml | 36 + .../topology_template_notValidRelationNode.yml | 36 + .../normativeTypes/topology_template_sample.yml | 36 + .../src/test/resources/types/capabilityTypes.yml | 148 + .../src/test/resources/types/capabilityTypes.zip | Bin 0 -> 979 bytes .../src/test/resources/types/categoryTypes.yml | 74 + .../src/test/resources/types/categoryTypes.zip | Bin 0 -> 403 bytes .../dataTypeDeriveFromIntegerWithProperty.yml | 8 + .../dataTypeDerivedFromRootNoProperties.yml | 4 + .../types/datatypes/dataTypeDuplicateProperty.yml | 11 + .../resources/types/datatypes/dataTypeForGroup.yml | 40 + .../dataTypeUpdatePropertyRemoved_part1.yml | 15 + .../dataTypeUpdatePropertyRemoved_part2.yml | 12 + ...ypeUpdateWithDifferentDerivedDataType_part1.yml | 19 + ...ypeUpdateWithDifferentDerivedDataType_part2.yml | 19 + .../dataTypeUpdateWithDifferentEntryType_part1.yml | 20 + .../dataTypeUpdateWithDifferentEntryType_part2.yml | 20 + ...taTypeUpdateWithDifferentPropertyType_part1.yml | 22 + ...taTypeUpdateWithDifferentPropertyType_part2.yml | 19 + ...ateWithExistingPropertyNameInAncestor_part1.yml | 19 + ...ateWithExistingPropertyNameInAncestor_part2.yml | 25 + .../dataTypeWithPropertyTypeThisDataType.yml | 9 + .../test/resources/types/datatypes/dataTypes.yml | 129 + .../types/datatypes/derived3levelDataType.yml | 37 + .../resources/types/datatypes/derivedDataType.yml | 19 + .../datatypes/derivedDataTypeNoProperties.yml | 15 + .../types/datatypes/derivedInvalidDataType.yml | 15 + .../resources/types/datatypes/emptyDataType.yml | 4 + .../datatypes/emptyDataTypeNoPropertiesTag.yml | 3 + .../types/datatypes/exitingPropertyAtAncestor.yml | 19 + .../resources/types/datatypes/invalidDataType.yml | 1 + .../test/resources/types/datatypes/oneDataType.yml | 9 + .../resources/types/interfaceLifecycleTypes.yml | 11 + .../resources/types/interfaceLifecycleTypes.zip | Bin 0 -> 273 bytes catalog-be/src/test/resources/valid_vf.csar | Bin 0 -> 1316 bytes catalog-be/tarball.xml | 54 + catalog-dao/.gitignore | 1 + catalog-dao/pom.xml | 335 + .../java/org/openecomp/sdc/be/dao/Account.java | 86 + .../org/openecomp/sdc/be/dao/api/ActionStatus.java | 88 + .../org/openecomp/sdc/be/dao/api/BasicDao.java | 182 + .../openecomp/sdc/be/dao/api/ESGenericIdDAO.java | 171 + .../sdc/be/dao/api/ESGenericSearchDAO.java | 132 + .../org/openecomp/sdc/be/dao/api/IBasicDAO.java | 65 + .../org/openecomp/sdc/be/dao/api/ICatalogDAO.java | 72 + .../org/openecomp/sdc/be/dao/api/IElementDAO.java | 36 + .../sdc/be/dao/api/IEsHealthCheckDao.java | 29 + .../openecomp/sdc/be/dao/api/IGenericIdDAO.java | 66 + .../sdc/be/dao/api/IGenericSearchDAO.java | 42 + .../org/openecomp/sdc/be/dao/api/IPropertyDAO.java | 28 + .../org/openecomp/sdc/be/dao/api/IResourceDAO.java | 57 + .../org/openecomp/sdc/be/dao/api/IUsersDAO.java | 37 + .../sdc/be/dao/api/ResourceUploadStatus.java | 25 + .../sdc/be/dao/cassandra/ArtifactCassandraDao.java | 110 + .../sdc/be/dao/cassandra/AuditAccessor.java | 75 + .../sdc/be/dao/cassandra/AuditCassandraDao.java | 383 + .../sdc/be/dao/cassandra/CassandraClient.java | 207 + .../sdc/be/dao/cassandra/CassandraDao.java | 65 + .../be/dao/cassandra/CassandraOperationStatus.java | 26 + .../be/dao/cassandra/ComponentCacheAccessor.java | 48 + .../be/dao/cassandra/ComponentCassandraDao.java | 293 + .../be/dao/cassandra/schema/ITableDescription.java | 46 + .../be/dao/cassandra/schema/SdcSchemaBuilder.java | 425 + .../sdc/be/dao/cassandra/schema/Table.java | 71 + .../schema/tables/ArtifactTableDescription.java | 95 + .../schema/tables/AuthEventTableDescription.java | 103 + .../tables/CategoryEventTableDescription.java | 105 + .../tables/ComponentCacheTableDescription.java | 95 + .../tables/ConsumerEventTableDefinition.java | 101 + .../schema/tables/DistribDeployEventTableDesc.java | 104 + .../tables/DistribDownloadEventTableDesc.java | 100 + .../schema/tables/DistribEngineEventTableDesc.java | 103 + .../schema/tables/DistribNotifEventTableDesc.java | 104 + .../schema/tables/DistribStatusEventTableDesc.java | 102 + .../schema/tables/ExternalApiEventTableDesc.java | 104 + .../schema/tables/GetCatHierEventTableDesc.java | 99 + .../schema/tables/GetUebClusterEventTableDesc.java | 101 + .../schema/tables/GetUsersListEventTableDesc.java | 99 + .../tables/ResAdminEventTableDescription.java | 132 + .../tables/UserAccessEventTableDescription.java | 104 + .../tables/UserAdminEventTableDescription.java | 102 + .../sdc/be/dao/es/ElasticSearchClient.java | 226 + .../sdc/be/dao/graph/GraphElementFactory.java | 264 + .../sdc/be/dao/graph/datatype/ActionEnum.java | 25 + .../graph/datatype/AdditionalInformationEnum.java | 25 + .../sdc/be/dao/graph/datatype/GraphEdge.java | 94 + .../sdc/be/dao/graph/datatype/GraphElement.java | 58 + .../dao/graph/datatype/GraphElementTypeEnum.java | 25 + .../sdc/be/dao/graph/datatype/GraphNode.java | 77 + .../sdc/be/dao/graph/datatype/GraphRelation.java | 106 + .../be/dao/graph/datatype/RelationEndPoint.java | 100 + .../org/openecomp/sdc/be/dao/impl/AuditingDao.java | 264 + .../openecomp/sdc/be/dao/impl/ESCatalogDAO.java | 214 + .../openecomp/sdc/be/dao/impl/ESTimeBasedDao.java | 305 + .../sdc/be/dao/impl/EsHealthCheckDao.java | 50 + .../openecomp/sdc/be/dao/impl/MonitoringDao.java | 41 + .../openecomp/sdc/be/dao/impl/Neo4jElementDAO.java | 112 + .../sdc/be/dao/impl/Neo4jPropertyDAO.java | 99 + .../sdc/be/dao/impl/Neo4jResourceDAO.java | 242 + .../openecomp/sdc/be/dao/impl/Neo4jUsersDAO.java | 169 + .../sdc/be/dao/model/FacetedSearchFacet.java | 55 + .../sdc/be/dao/model/FacetedSearchResult.java | 72 + .../openecomp/sdc/be/dao/model/FetchContext.java | 32 + .../sdc/be/dao/model/GetMultipleDataResult.java | 113 + .../openecomp/sdc/be/dao/neo4j/BatchBuilder.java | 83 + .../sdc/be/dao/neo4j/CypherTemplates.java | 52 + .../sdc/be/dao/neo4j/CypherTranslator.java | 251 + .../sdc/be/dao/neo4j/GraphEdgeLabels.java | 101 + .../dao/neo4j/GraphEdgePropertiesDictionary.java | 80 + .../sdc/be/dao/neo4j/GraphNeighbourTable.java | 64 + .../be/dao/neo4j/GraphPropertiesDictionary.java | 212 + .../openecomp/sdc/be/dao/neo4j/Neo4jClient.java | 1004 + .../org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java | 69 + .../sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java | 194 + .../sdc/be/dao/neo4j/Neo4jOperationStatus.java | 77 + .../openecomp/sdc/be/dao/neo4j/NodeRelation.java | 65 + .../sdc/be/dao/neo4j/filters/MatchFilter.java | 51 + .../neo4j/filters/RecursiveByRelationFilter.java | 81 + .../sdc/be/dao/neo4j/filters/RecursiveFilter.java | 68 + .../sdc/be/dao/neo4j/filters/UpdateFilter.java | 56 + .../openecomp/sdc/be/dao/rest/HttpRestClient.java | 403 + .../sdc/be/dao/rest/RestConfigurationInfo.java | 110 + .../org/openecomp/sdc/be/dao/titan/QueryType.java | 28 + .../sdc/be/dao/titan/TitanGenericDao.java | 1848 ++ .../sdc/be/dao/titan/TitanGraphClient.java | 872 + .../sdc/be/dao/titan/TitanOperationStatus.java | 26 + .../sdc/be/dao/utils/CollectionUtils.java | 125 + .../org/openecomp/sdc/be/dao/utils/Constants.java | 38 + .../org/openecomp/sdc/be/dao/utils/DaoUtils.java | 59 + .../sdc/be/dao/utils/ElasticSearchUtil.java | 48 + .../org/openecomp/sdc/be/dao/utils/Exceptions.java | 35 + .../openecomp/sdc/be/dao/utils/ImageQuality.java | 40 + .../sdc/be/dao/utils/ImageResizeUtil.java | 142 + .../org/openecomp/sdc/be/dao/utils/JsonUtil.java | 209 + .../org/openecomp/sdc/be/dao/utils/MapEntry.java | 55 + .../org/openecomp/sdc/be/dao/utils/MapUtil.java | 86 + .../org/openecomp/sdc/be/dao/utils/TypeMap.java | 63 + .../openecomp/sdc/be/dao/utils/UserStatusEnum.java | 40 + .../sdc/be/resources/api/ArtifactDataEnum.java | 26 + .../sdc/be/resources/api/IResourceUploader.java | 76 + .../data/AdditionalInfoParameterData.java | 155 + .../sdc/be/resources/data/ArtifactData.java | 183 + .../sdc/be/resources/data/AttributeData.java | 131 + .../sdc/be/resources/data/AttributeValueData.java | 145 + .../sdc/be/resources/data/CapabilityData.java | 182 + .../sdc/be/resources/data/CapabilityInstData.java | 128 + .../sdc/be/resources/data/CapabilityTypeData.java | 131 + .../sdc/be/resources/data/CategoryData.java | 114 + .../sdc/be/resources/data/ComponentCacheData.java | 153 + .../be/resources/data/ComponentInstanceData.java | 114 + .../be/resources/data/ComponentMetadataData.java | 147 + .../sdc/be/resources/data/ConsumerData.java | 92 + .../sdc/be/resources/data/DataTypeData.java | 106 + .../sdc/be/resources/data/ESArtifactData.java | 106 + .../openecomp/sdc/be/resources/data/EntryData.java | 52 + .../sdc/be/resources/data/GraphNodeLock.java | 79 + .../openecomp/sdc/be/resources/data/GroupData.java | 97 + .../sdc/be/resources/data/GroupTypeData.java | 130 + .../sdc/be/resources/data/HeatParameterData.java | 172 + .../be/resources/data/HeatParameterValueData.java | 91 + .../sdc/be/resources/data/InputValueData.java | 145 + .../sdc/be/resources/data/InputsData.java | 149 + .../sdc/be/resources/data/InterfaceData.java | 91 + .../sdc/be/resources/data/OperationData.java | 88 + .../sdc/be/resources/data/PolicyTypeData.java | 130 + .../sdc/be/resources/data/ProductMetadataData.java | 77 + .../sdc/be/resources/data/PropertyData.java | 149 + .../sdc/be/resources/data/PropertyValueData.java | 158 + .../be/resources/data/RelationshipInstData.java | 164 + .../be/resources/data/RelationshipTypeData.java | 128 + .../sdc/be/resources/data/RequirementData.java | 158 + .../sdc/be/resources/data/RequirementImplData.java | 141 + .../be/resources/data/ResourceCategoryData.java | 72 + .../be/resources/data/ResourceMetadataData.java | 80 + .../data/ServiceArtifactsDataCollection.java | 45 + .../sdc/be/resources/data/ServiceCategoryData.java | 47 + .../sdc/be/resources/data/ServiceMetadataData.java | 62 + .../openecomp/sdc/be/resources/data/TagData.java | 112 + .../sdc/be/resources/data/UniqueIdData.java | 47 + .../openecomp/sdc/be/resources/data/UserData.java | 228 + .../be/resources/data/UserFunctionalMenuData.java | 95 + .../data/auditing/AuditRecordFactory.java | 84 + .../data/auditing/AuditingActionEnum.java | 135 + .../data/auditing/AuditingGenericEvent.java | 91 + .../data/auditing/AuditingGetUebClusterEvent.java | 191 + .../data/auditing/AuditingTypesConstants.java | 49 + .../sdc/be/resources/data/auditing/AuthEvent.java | 209 + .../be/resources/data/auditing/CategoryEvent.java | 240 + .../be/resources/data/auditing/ConsumerEvent.java | 184 + .../data/auditing/DistributionDeployEvent.java | 253 + .../data/auditing/DistributionDownloadEvent.java | 205 + .../data/auditing/DistributionEngineEvent.java | 273 + .../auditing/DistributionNotificationEvent.java | 286 + .../data/auditing/DistributionStatusEvent.java | 254 + .../resources/data/auditing/ExternalApiEvent.java | 279 + .../data/auditing/GetCategoryHierarchyEvent.java | 182 + .../resources/data/auditing/GetUsersListEvent.java | 186 + .../data/auditing/ResourceAdminEvent.java | 437 + .../resources/data/auditing/UserAccessEvent.java | 179 + .../be/resources/data/auditing/UserAdminEvent.java | 224 + .../be/resources/data/category/CategoryData.java | 90 + .../be/resources/data/category/GroupingData.java | 73 + .../resources/data/category/SubCategoryData.java | 86 + .../exception/DeleteDeployedException.java | 42 + .../exception/InitializationException.java | 32 + .../resources/exception/ResourceDAOException.java | 58 + .../sdc/be/resources/impl/ResourceUploader.java | 206 + .../sdc/be/resources/ArtifactDaoTest.java | 577 + .../sdc/be/resources/AuditingDaoTest.java | 463 + .../openecomp/sdc/be/resources/CassandraTest.java | 74 + .../openecomp/sdc/be/resources/ESUsersDAOTest.java | 64 + .../sdc/be/resources/TitanGenericDaoTest.java | 721 + .../test/resources/application-context-test.xml | 22 + catalog-dao/src/test/resources/cassandra.yaml | 801 + .../config/catalog-dao/configuration.yaml | 120 + .../catalog-dao/ecomp-error-configuration.yaml | 383 + catalog-dao/src/test/resources/elasticsearch.yml | 392 + catalog-dao/src/test/resources/images/apache.png | Bin 0 -> 10518 bytes catalog-dao/src/test/resources/log4j.properties | 8 + catalog-dao/src/test/resources/logback-test.xml | 13 + catalog-fe/.gitignore | 5 + catalog-fe/pom.xml | 441 + catalog-fe/readMe.txt | 14 + .../main/java/org/openecomp/sdc/fe/Constants.java | 15 + .../org/openecomp/sdc/fe/client/BackendClient.java | 179 + .../main/java/org/openecomp/sdc/fe/impl/Audit.java | 73 + .../org/openecomp/sdc/fe/impl/CrudOperation.java | 26 + .../org/openecomp/sdc/fe/impl/HttpRequestInfo.java | 77 + .../org/openecomp/sdc/fe/impl/ImportMetadata.java | 80 + .../sdc/fe/listen/FEAppContextListener.java | 85 + .../sdc/fe/listen/MyObjectMapperProvider.java | 49 + .../sdc/fe/servlets/ConfigMgrServlet.java | 88 + .../openecomp/sdc/fe/servlets/ConfigServlet.java | 114 + .../sdc/fe/servlets/FeHealthCheckServlet.java | 49 + .../openecomp/sdc/fe/servlets/FeProxyServlet.java | 214 + .../sdc/fe/servlets/HealthCheckService.java | 219 + .../openecomp/sdc/fe/servlets/KibanaServlet.java | 98 + .../openecomp/sdc/fe/servlets/PortalServlet.java | 279 + .../openecomp/sdc/fe/servlets/SSLProxyServlet.java | 108 + .../src/main/resources/application-context.xml | 23 + .../src/main/resources/config/configuration.yaml | 78 + .../config/ecomp-error-configuration.yaml | 48 + catalog-fe/src/main/resources/config/logback.xml | 125 + .../resources/config/rest-configuration-info.yaml | 12 + catalog-fe/src/main/resources/jetty-ipaccess.xml | 30 + catalog-fe/src/main/resources/portal.properties | 28 + catalog-fe/src/main/resources/scripts/install.sh | 61 + .../src/main/resources/scripts/installJettyBase.sh | 14 + .../src/main/resources/scripts/jvm.properties | 5 + .../src/main/resources/scripts/startJetty.sh | 10 + .../src/main/resources/scripts/updateSslParams.sh | 33 + catalog-fe/src/main/webapp/META-INF/MANIFEST.MF | 9 + catalog-fe/src/main/webapp/WEB-INF/jetty-web.xml | 8 + catalog-fe/src/main/webapp/WEB-INF/web.xml | 280 + catalog-fe/src/test/SpecRunner.html | 36 + .../src/test/jasmine-standalone-2.0.0/MIT.LICENSE | 20 + .../test/jasmine-standalone-2.0.0/SpecRunner.html | 26 + .../lib/jasmine-2.0.0/boot.js | 201 + .../lib/jasmine-2.0.0/console.js | 180 + .../lib/jasmine-2.0.0/jasmine-html.js | 379 + .../lib/jasmine-2.0.0/jasmine.css | 55 + .../lib/jasmine-2.0.0/jasmine.js | 2422 ++ .../lib/jasmine-2.0.0/jasmine_favicon.png | Bin 0 -> 2057 bytes .../jasmine-standalone-2.0.0/spec/PlayerSpec.js | 78 + .../jasmine-standalone-2.0.0/spec/SpecHelper.js | 35 + .../test/jasmine-standalone-2.0.0/src/Player.js | 42 + .../src/test/jasmine-standalone-2.0.0/src/Song.js | 27 + .../java/org/openecomp/sdc/ApplicationConfig.java | 41 + .../sdc/ContentDisposiotionDelegator.java | 35 + .../src/test/java/org/openecomp/sdc/Main.java | 63 + .../openecomp/sdc/TestExternalConfiguration.java | 66 + .../openecomp/sdc/servlets/FeProxyServletTest.java | 140 + .../openecomp/sdc/servlets/PortalServletTest.java | 159 + catalog-fe/src/test/resources/CI/ReadMe.txt | 5 + .../resources/CI/originalResources/apache-type.yml | 50 + .../CI/originalResources/images/apache.png | Bin 0 -> 10518 bytes .../CI/originalResources/images/compute.png | Bin 0 -> 61345 bytes .../CI/originalResources/images/loadbalancer.png | Bin 0 -> 26899 bytes .../CI/originalResources/images/network.png | Bin 0 -> 159707 bytes .../CI/originalResources/images/objectstore.png | Bin 0 -> 4354 bytes .../CI/originalResources/images/relational_db.png | Bin 0 -> 51853 bytes .../resources/CI/originalResources/images/root.png | Bin 0 -> 5335 bytes .../CI/originalResources/images/router.png | Bin 0 -> 26404 bytes .../CI/originalResources/images/software.png | Bin 0 -> 55407 bytes .../CI/originalResources/images/volume.png | Bin 0 -> 16643 bytes .../CI/originalResources/normative-types-DBMS.yml | 36 + .../normative-types-blockStorage.yml | 40 + .../originalResources/normative-types-compute.yml | 77 + .../originalResources/normative-types-database.yml | 41 + .../originalResources/normative-types-network.yml | 39 + .../normative-types-objectStorage.yml | 35 + .../CI/originalResources/normative-types-root.yml | 168 + .../normative-types-softwareComponent.yml | 25 + .../normative-types-webApplication.yml | 21 + .../normative-types-webServer.yml | 24 + .../scripts/apache_start_detection.groovy | 6 + .../CI/originalResources/scripts/install_apache.sh | 53 + .../CI/originalResources/scripts/start_apache.sh | 10 + .../CI/tests/01_NormativeTypeCI-root/body.txt | 1 + .../CI/tests/01_NormativeTypeCI-root/command | 15 + .../CI/tests/01_NormativeTypeCI-root/commandTrial | 12 + .../tests/01_NormativeTypeCI-root/contentMD5.txt | 1 + .../CI/tests/01_NormativeTypeCI-root/headers | 8 + .../CI/tests/01_NormativeTypeCI-root/results | 1 + .../CI/tests/01_NormativeTypeCI-root/toExec | 1 + .../CI/tests/02_NormativeTypeCI-compute/body.txt | 1 + .../CI/tests/02_NormativeTypeCI-compute/command | 15 + .../tests/02_NormativeTypeCI-compute/commandTrial | 12 + .../02_NormativeTypeCI-compute/contentMD5.txt | 1 + .../CI/tests/02_NormativeTypeCI-compute/headers | 8 + .../CI/tests/02_NormativeTypeCI-compute/results | 1 + .../CI/tests/02_NormativeTypeCI-compute/toExec | 1 + .../tests/03_NormativeTypeCI-blockStorage/body.txt | 1 + .../tests/03_NormativeTypeCI-blockStorage/command | 15 + .../03_NormativeTypeCI-blockStorage/commandTrial | 12 + .../03_NormativeTypeCI-blockStorage/contentMD5.txt | 1 + .../tests/03_NormativeTypeCI-blockStorage/headers | 8 + .../tests/03_NormativeTypeCI-blockStorage/results | 1 + .../tests/03_NormativeTypeCI-blockStorage/toExec | 1 + .../04_NormativeTypeCI-objectStorage/body.txt | 1 + .../tests/04_NormativeTypeCI-objectStorage/command | 15 + .../04_NormativeTypeCI-objectStorage/commandTrial | 12 + .../contentMD5.txt | 1 + .../tests/04_NormativeTypeCI-objectStorage/headers | 8 + .../tests/04_NormativeTypeCI-objectStorage/results | 1 + .../tests/04_NormativeTypeCI-objectStorage/toExec | 1 + .../05_NormativeTypeCI-softwareComponent/body.txt | 1 + .../05_NormativeTypeCI-softwareComponent/command | 15 + .../commandTrial | 12 + .../contentMD5.txt | 1 + .../05_NormativeTypeCI-softwareComponent/headers | 8 + .../05_NormativeTypeCI-softwareComponent/results | 1 + .../05_NormativeTypeCI-softwareComponent/toExec | 1 + .../CI/tests/06_NormativeTypeCI-webServer/body.txt | 1 + .../CI/tests/06_NormativeTypeCI-webServer/command | 15 + .../06_NormativeTypeCI-webServer/commandTrial | 12 + .../06_NormativeTypeCI-webServer/contentMD5.txt | 1 + .../CI/tests/06_NormativeTypeCI-webServer/headers | 8 + .../CI/tests/06_NormativeTypeCI-webServer/results | 1 + .../CI/tests/06_NormativeTypeCI-webServer/toExec | 1 + .../07_NormativeTypeCI-webApplication/body.txt | 1 + .../07_NormativeTypeCI-webApplication/command | 15 + .../07_NormativeTypeCI-webApplication/commandTrial | 12 + .../contentMD5.txt | 1 + .../07_NormativeTypeCI-webApplication/headers | 8 + .../07_NormativeTypeCI-webApplication/results | 1 + .../tests/07_NormativeTypeCI-webApplication/toExec | 1 + .../CI/tests/08_NormativeTypeCI-DBMS/body.txt | 1 + .../CI/tests/08_NormativeTypeCI-DBMS/command | 15 + .../CI/tests/08_NormativeTypeCI-DBMS/commandTrial | 12 + .../tests/08_NormativeTypeCI-DBMS/contentMD5.txt | 1 + .../CI/tests/08_NormativeTypeCI-DBMS/headers | 8 + .../CI/tests/08_NormativeTypeCI-DBMS/results | 1 + .../CI/tests/08_NormativeTypeCI-DBMS/toExec | 1 + .../CI/tests/09_NormativeTypeCI-database/body.txt | 1 + .../CI/tests/09_NormativeTypeCI-database/command | 15 + .../tests/09_NormativeTypeCI-database/commandTrial | 12 + .../09_NormativeTypeCI-database/contentMD5.txt | 1 + .../CI/tests/09_NormativeTypeCI-database/headers | 8 + .../CI/tests/09_NormativeTypeCI-database/results | 1 + .../CI/tests/09_NormativeTypeCI-database/toExec | 1 + .../CI/tests/10_NormativeTypeCI-network/body.txt | 1 + .../CI/tests/10_NormativeTypeCI-network/command | 15 + .../tests/10_NormativeTypeCI-network/commandTrial | 12 + .../10_NormativeTypeCI-network/contentMD5.txt | 1 + .../CI/tests/10_NormativeTypeCI-network/headers | 8 + .../CI/tests/10_NormativeTypeCI-network/results | 1 + .../CI/tests/10_NormativeTypeCI-network/toExec | 1 + .../resources/CI/tests/11_AlienApacheType/body.txt | 1 + .../resources/CI/tests/11_AlienApacheType/command | 15 + .../CI/tests/11_AlienApacheType/commandTrial | 12 + .../CI/tests/11_AlienApacheType/contentMD5.txt | 1 + .../resources/CI/tests/11_AlienApacheType/headers | 8 + .../resources/CI/tests/11_AlienApacheType/results | 1 + .../resources/CI/tests/11_AlienApacheType/toExec | 1 + .../CI/tests/12_DatabaseType-GetArtifacts/body.txt | 0 .../CI/tests/12_DatabaseType-GetArtifacts/command | 13 + .../12_DatabaseType-GetArtifacts/commandTrial | 12 + .../12_DatabaseType-GetArtifacts/contentMD5.txt | 1 + .../CI/tests/12_DatabaseType-GetArtifacts/headers | 8 + .../CI/tests/12_DatabaseType-GetArtifacts/results | 1 + .../CI/tests/12_DatabaseType-GetArtifacts/toExec | 1 + .../CI/tests/13_ApacheType-GetMetadata/body.txt | 0 .../CI/tests/13_ApacheType-GetMetadata/command | 13 + .../tests/13_ApacheType-GetMetadata/commandTrial | 12 + .../tests/13_ApacheType-GetMetadata/contentMD5.txt | 1 + .../CI/tests/13_ApacheType-GetMetadata/headers | 8 + .../CI/tests/13_ApacheType-GetMetadata/results | 1 + .../CI/tests/13_ApacheType-GetMetadata/toExec | 1 + .../CI/tests/14_ApacheType-GetArtifacts/body.txt | 0 .../CI/tests/14_ApacheType-GetArtifacts/command | 13 + .../tests/14_ApacheType-GetArtifacts/commandTrial | 12 + .../14_ApacheType-GetArtifacts/contentMD5.txt | 1 + .../CI/tests/14_ApacheType-GetArtifacts/headers | 8 + .../CI/tests/14_ApacheType-GetArtifacts/results | 1 + .../tests/14_ApacheType-GetArtifacts/results.json | 12 + .../CI/tests/14_ApacheType-GetArtifacts/toExec | 1 + .../tests/15_ApacheType-DownloadArtifact/body.txt | 0 .../tests/15_ApacheType-DownloadArtifact/command | 13 + .../15_ApacheType-DownloadArtifact/commandTrial | 12 + .../15_ApacheType-DownloadArtifact/contentMD5.txt | 1 + .../tests/15_ApacheType-DownloadArtifact/headers | 8 + .../tests/15_ApacheType-DownloadArtifact/results | 1 + .../CI/tests/15_ApacheType-DownloadArtifact/toExec | 1 + catalog-fe/src/test/resources/CI/tests/env/env.sh | 11 + catalog-fe/src/test/resources/CI/tests/runTests.sh | 90 + .../resources/config/catalog-fe/configuration.yaml | 69 + .../config/catalog-fe/rest-configuration-info.yaml | 12 + .../src/test/resources/config/configuration1.yaml | 17 + catalog-fe/src/test/resources/config/sample.yaml | 17 + .../test/resources/config/sampleNoProtocol.yaml | 17 + catalog-fe/src/test/resources/logback-test.xml | 2 + catalog-fe/src/test/spec/codeSpec.js | 197 + catalog-fe/src/test/testScripts/filesContents.js | 207 + catalog-fe/src/test/testScripts/jasmine-fixture.js | 453 + catalog-fe/tarball.xml | 32 + catalog-model/.gitignore | 2 + catalog-model/pom.xml | 267 + .../sdc/be/model/AdditionalInfoParameterInfo.java | 82 + .../be/model/AdditionalInformationDefinition.java | 80 + .../openecomp/sdc/be/model/ArtifactDefinition.java | 138 + .../org/openecomp/sdc/be/model/ArtifactType.java | 64 + .../sdc/be/model/ArtifactUiDownloadData.java | 45 + .../sdc/be/model/AttributeDefinition.java | 71 + .../java/org/openecomp/sdc/be/model/CapReqDef.java | 56 + .../sdc/be/model/CapabilityDefinition.java | 266 + .../sdc/be/model/CapabilityTypeDefinition.java | 65 + .../openecomp/sdc/be/model/CapabiltyInstance.java | 52 + .../java/org/openecomp/sdc/be/model/Category.java | 65 + .../java/org/openecomp/sdc/be/model/Component.java | 598 + .../sdc/be/model/ComponentInstInputsMap.java | 37 + .../openecomp/sdc/be/model/ComponentInstance.java | 109 + .../sdc/be/model/ComponentInstanceAttribute.java | 74 + .../sdc/be/model/ComponentInstanceInput.java | 137 + .../sdc/be/model/ComponentInstanceProperty.java | 117 + .../sdc/be/model/ComponentMetadataDefinition.java | 74 + .../sdc/be/model/ComponentParametersView.java | 316 + .../openecomp/sdc/be/model/ConsumerDefinition.java | 35 + .../openecomp/sdc/be/model/DataTypeDefinition.java | 86 + .../sdc/be/model/DistributionStatusEnum.java | 50 + .../sdc/be/model/DistributionTransitionEnum.java | 54 + .../openecomp/sdc/be/model/FunctionalMenuInfo.java | 44 + .../openecomp/sdc/be/model/GetInputValueInfo.java | 71 + .../openecomp/sdc/be/model/GroupDefinition.java | 133 + .../org/openecomp/sdc/be/model/GroupProperty.java | 76 + .../sdc/be/model/GroupTypeDefinition.java | 61 + .../sdc/be/model/HeatParameterDefinition.java | 42 + .../sdc/be/model/IComplexDefaultValue.java | 35 + .../model/IComponentInstanceConnectedElement.java | 29 + .../sdc/be/model/IOperationParameter.java | 37 + .../sdc/be/model/ImplementationArtifact.java | 67 + .../openecomp/sdc/be/model/InputDefinition.java | 89 + .../sdc/be/model/InterfaceDefinition.java | 89 + .../sdc/be/model/LifeCycleTransitionEnum.java | 83 + .../openecomp/sdc/be/model/LifecycleStateEnum.java | 44 + .../java/org/openecomp/sdc/be/model/Operation.java | 105 + .../sdc/be/model/ParsedToscaYamlInfo.java | 61 + .../java/org/openecomp/sdc/be/model/Point.java | 59 + .../sdc/be/model/PolicyTypeDefinition.java | 55 + .../java/org/openecomp/sdc/be/model/Product.java | 80 + .../sdc/be/model/ProductMetadataDefinition.java | 35 + .../openecomp/sdc/be/model/PropertyConstraint.java | 34 + .../openecomp/sdc/be/model/PropertyDefinition.java | 175 + .../org/openecomp/sdc/be/model/PropertyScope.java | 64 + .../sdc/be/model/PropertyValueDefinition.java | 44 + .../openecomp/sdc/be/model/RelationshipImpl.java | 47 + .../be/model/RequirementAndRelationshipPair.java | 122 + .../sdc/be/model/RequirementCapabilityRelDef.java | 47 + .../sdc/be/model/RequirementDefinition.java | 241 + .../openecomp/sdc/be/model/RequirementImplDef.java | 76 + .../sdc/be/model/RequirementInstance.java | 59 + .../java/org/openecomp/sdc/be/model/Resource.java | 273 + .../be/model/ResourceInstanceHeatParameter.java | 48 + .../sdc/be/model/ResourceMetadataDefinition.java | 37 + .../java/org/openecomp/sdc/be/model/Schema.java | 42 + .../java/org/openecomp/sdc/be/model/Service.java | 100 + .../sdc/be/model/ServiceMetadataDefinition.java | 36 + .../main/java/org/openecomp/sdc/be/model/Tag.java | 65 + .../sdc/be/model/TargetCapabilityRelDef.java | 80 + .../org/openecomp/sdc/be/model/UploadCapInfo.java | 58 + .../sdc/be/model/UploadComponentInstanceInfo.java | 73 + .../org/openecomp/sdc/be/model/UploadInfo.java | 45 + .../org/openecomp/sdc/be/model/UploadPropInfo.java | 68 + .../org/openecomp/sdc/be/model/UploadReqInfo.java | 50 + .../openecomp/sdc/be/model/UploadResourceInfo.java | 304 + .../main/java/org/openecomp/sdc/be/model/User.java | 205 + .../sdc/be/model/cache/ApplicationCache.java | 35 + .../be/model/cache/ApplicationDataTypeCache.java | 335 + .../sdc/be/model/cache/ComponentCache.java | 997 + .../org/openecomp/sdc/be/model/cache/DaoInfo.java | 56 + .../sdc/be/model/cache/jobs/CheckAndUpdateJob.java | 131 + .../sdc/be/model/cache/jobs/DeleteJob.java | 64 + .../org/openecomp/sdc/be/model/cache/jobs/Job.java | 109 + .../sdc/be/model/cache/jobs/OverrideJob.java | 74 + .../sdc/be/model/cache/jobs/StoreJob.java | 61 + .../sdc/be/model/cache/workers/CacheWorker.java | 93 + .../sdc/be/model/cache/workers/IWorker.java | 28 + .../sdc/be/model/cache/workers/SyncWorker.java | 266 + .../sdc/be/model/category/CategoryDefinition.java | 66 + .../sdc/be/model/category/GroupingDefinition.java | 35 + .../be/model/category/SubCategoryDefinition.java | 60 + .../sdc/be/model/heat/HeatParameterType.java | 95 + .../api/IAdditionalInformationOperation.java | 94 + .../model/operations/api/IArtifactOperation.java | 70 + .../model/operations/api/IAttributeOperation.java | 71 + .../operations/api/ICacheMangerOperation.java | 44 + .../api/ICapabilityInstanceOperation.java | 143 + .../model/operations/api/ICapabilityOperation.java | 79 + .../operations/api/ICapabilityTypeOperation.java | 47 + .../api/IComponentInstanceOperation.java | 246 + .../model/operations/api/IComponentOperation.java | 50 + .../model/operations/api/IConsumerOperation.java | 107 + .../model/operations/api/IDataTypeOperation.java | 46 + .../be/model/operations/api/IElementOperation.java | 104 + .../model/operations/api/IGraphLockOperation.java | 36 + .../be/model/operations/api/IGroupOperation.java | 114 + .../model/operations/api/IGroupTypeOperation.java | 61 + .../operations/api/IHeatParametersOperation.java | 46 + .../be/model/operations/api/IInputsOperation.java | 81 + .../api/IInterfaceLifecycleOperation.java | 92 + .../model/operations/api/ILifecycleOperation.java | 65 + .../model/operations/api/IPolicyTypeOperation.java | 38 + .../be/model/operations/api/IProductOperation.java | 47 + .../model/operations/api/IPropertyOperation.java | 110 + .../operations/api/IRequirementOperation.java | 85 + .../model/operations/api/IResourceOperation.java | 131 + .../be/model/operations/api/IServiceOperation.java | 88 + .../model/operations/api/IUserAdminOperation.java | 58 + .../operations/api/StorageOperationStatus.java | 27 + .../model/operations/impl/AbstractOperation.java | 413 + .../impl/AdditionalInformationOperation.java | 960 + .../model/operations/impl/AllOperationsUtil.java | 56 + .../model/operations/impl/ArtifactOperation.java | 1202 + .../model/operations/impl/AttributeOperation.java | 463 + .../operations/impl/CacheMangerOperation.java | 213 + .../impl/CapabilityInstanceOperation.java | 1215 + .../model/operations/impl/CapabilityOperation.java | 1196 + .../operations/impl/CapabilityTypeOperation.java | 416 + .../impl/ComponentInstanceOperation.java | 5852 +++++ .../model/operations/impl/ComponentOperation.java | 2886 +++ .../model/operations/impl/ConsumerOperation.java | 151 + .../be/model/operations/impl/CsarOperation.java | 115 + .../model/operations/impl/DaoStatusConverter.java | 141 + .../be/model/operations/impl/ElementOperation.java | 902 + .../model/operations/impl/GraphLockOperation.java | 234 + .../be/model/operations/impl/GroupOperation.java | 2093 ++ .../model/operations/impl/GroupTypeOperation.java | 385 + .../operations/impl/HeatParametersOperation.java | 492 + .../be/model/operations/impl/InputsOperation.java | 1184 + .../impl/InterfaceLifecycleOperation.java | 1308 ++ .../model/operations/impl/LifecycleOperation.java | 1143 + .../operations/impl/Neo4jStatusConverter.java | 78 + .../be/model/operations/impl/OnboardingClient.java | 190 + .../model/operations/impl/PolicyTypeOperation.java | 230 + .../be/model/operations/impl/ProductOperation.java | 1067 + .../model/operations/impl/PropertyOperation.java | 2788 +++ .../operations/impl/RequirementOperation.java | 1674 ++ .../model/operations/impl/ResourceOperation.java | 3089 +++ .../be/model/operations/impl/ServiceOperation.java | 1566 ++ .../be/model/operations/impl/UniqueIdBuilder.java | 244 + .../model/operations/impl/UserAdminOperation.java | 501 + .../operations/utils/ComponentValidationUtils.java | 123 + .../be/model/operations/utils/GraphDeleteUtil.java | 119 + .../sdc/be/model/tosca/ToscaPropertyType.java | 199 + .../openecomp/sdc/be/model/tosca/ToscaType.java | 120 + .../openecomp/sdc/be/model/tosca/VersionUtil.java | 94 + .../AbstractComparablePropertyConstraint.java | 72 + .../constraints/AbstractPropertyConstraint.java | 46 + .../AbstractStringPropertyConstraint.java | 53 + .../be/model/tosca/constraints/ConstraintType.java | 60 + .../be/model/tosca/constraints/ConstraintUtil.java | 145 + .../model/tosca/constraints/EqualConstraint.java | 77 + .../constraints/GreaterOrEqualConstraint.java | 56 + .../tosca/constraints/GreaterThanConstraint.java | 66 + .../model/tosca/constraints/InRangeConstraint.java | 130 + .../model/tosca/constraints/LengthConstraint.java | 54 + .../tosca/constraints/LessOrEqualConstraint.java | 70 + .../tosca/constraints/LessThanConstraint.java | 58 + .../tosca/constraints/MaxLengthConstraint.java | 61 + .../tosca/constraints/MinLengthConstraint.java | 62 + .../model/tosca/constraints/PatternConstraint.java | 56 + .../tosca/constraints/ValidValuesConstraint.java | 92 + .../exception/ConstraintFunctionalException.java | 51 + .../ConstraintRequiredParameterException.java | 50 + .../exception/ConstraintTechnicalException.java | 41 + ...traintValueDoNotMatchPropertyTypeException.java | 49 + .../exception/ConstraintViolationException.java | 49 + .../constraints/exception/FunctionalException.java | 41 + ...dPropertyConstraintImplementationException.java | 40 + .../constraints/exception/TechnicalException.java | 40 + .../model/tosca/converters/BooleanConverter.java | 42 + .../model/tosca/converters/DefaultConverter.java | 43 + .../be/model/tosca/converters/FloatConverter.java | 42 + .../tosca/converters/HeatBooleanConverter.java | 54 + .../HeatCommaDelimitedListConverter.java | 50 + .../model/tosca/converters/HeatJsonConverter.java | 50 + .../tosca/converters/HeatNumberConverter.java | 50 + .../tosca/converters/HeatStringConverter.java | 51 + .../model/tosca/converters/IntegerConverter.java | 44 + .../be/model/tosca/converters/JsonConverter.java | 62 + .../be/model/tosca/converters/ListConverter.java | 217 + .../model/tosca/converters/LowerCaseConverter.java | 48 + .../be/model/tosca/converters/MapConverter.java | 249 + .../tosca/converters/PropertyValueConverter.java | 31 + .../be/model/tosca/converters/StringConvertor.java | 55 + .../tosca/converters/ToscaBooleanConverter.java | 54 + .../tosca/converters/ToscaFloatConverter.java | 50 + .../tosca/converters/ToscaJsonValueConverter.java | 56 + .../tosca/converters/ToscaListValueConverter.java | 182 + .../tosca/converters/ToscaMapValueConverter.java | 184 + .../tosca/converters/ToscaStringConvertor.java | 43 + .../tosca/converters/ToscaValueBaseConverter.java | 153 + .../tosca/converters/ToscaValueConverter.java | 30 + .../converters/ToscaValueDefaultConverter.java | 43 + .../model/tosca/validators/BooleanValidator.java | 55 + .../validators/DataTypeValidatorConverter.java | 499 + .../be/model/tosca/validators/FloatValidator.java | 60 + .../tosca/validators/HeatBooleanValidator.java | 61 + .../HeatCommaDelimitedListValidator.java | 55 + .../tosca/validators/HeatNumberValidator.java | 61 + .../tosca/validators/HeatStringValidator.java | 55 + .../model/tosca/validators/IntegerValidator.java | 85 + .../be/model/tosca/validators/JsonValidator.java | 76 + .../be/model/tosca/validators/KeyValidator.java | 61 + .../be/model/tosca/validators/ListValidator.java | 160 + .../be/model/tosca/validators/MapValidator.java | 184 + .../tosca/validators/PropertyTypeValidator.java | 46 + .../be/model/tosca/validators/StringValidator.java | 85 + .../tosca/validators/ToscaBooleanValidator.java | 56 + .../tosca/version/ApplicationVersionException.java | 36 + .../be/model/tosca/version/ComparableVersion.java | 463 + .../sdc/be/model/tosca/version/Version.java | 192 + .../sdc/be/unittests/utils/FactoryUtils.java | 233 + .../org/openecomp/sdc/be/model/ModelTestBase.java | 46 + .../sdc/be/model/operations/JsonObjectTest.java | 80 + .../impl/AdditionalInformationOperationTest.java | 216 + .../operations/impl/ArtifactOperationTest.java | 574 + .../impl/CapabilityTypeOperationTest.java | 345 + .../impl/ComponentInstanceOperationSpringTest.java | 543 + .../impl/ComponentInstanceOperationTest.java | 136 + .../operations/impl/ComponentOperationTest.java | 395 + .../operations/impl/ElementOperationTest.java | 109 + .../impl/HeatParametersOperationTest.java | 289 + .../operations/impl/InterfaceOperationTest.java | 272 + .../operations/impl/LifecycleOperationTest.java | 1991 ++ .../operations/impl/PolicyTypeOperationTest.java | 120 + .../operations/impl/PropertyOperationTest.java | 548 + .../operations/impl/RequirementOperationTest.java | 236 + .../impl/ResourceInstanceOperationTest.java | 2511 ++ .../operations/impl/ResourceOperationTest.java | 734 + .../operations/impl/ServiceOperationTest.java | 964 + .../operations/impl/UserAdminOperationTest.java | 239 + .../impl/util/DataTypeValidatorTest.java | 1004 + .../operations/impl/util/OperationTestsUtil.java | 95 + .../be/model/operations/impl/util/PrintGraph.java | 461 + .../impl/util/ResourceCreationUtils.java | 36 + .../model/serialize/TestResourceSerialization.java | 222 + .../tosca/validators/IntegerValidatorTest.java | 75 + .../test/resources/application-context-test.xml | 17 + .../config/ecomp-error-configuration.yaml | 308 + catalog-model/src/test/resources/logback-test.xml | 13 + catalog-ui/Gruntfile.js | 807 + catalog-ui/SETTING-ENVIRONMENT.md | 36 + catalog-ui/SETTING-MOCK-SERVER.md | 53 + catalog-ui/app/_favicon.png | Bin 0 -> 6364 bytes catalog-ui/app/index.html | 392 + catalog-ui/app/languages/en_US_OS.json | 420 + catalog-ui/app/scripts/app.ts | 936 + .../clicked-outside/clicked-outside-directive.ts | 131 + .../custom-validation/custom-validation.ts | 55 + .../download-artifact/download-artifact.ts | 141 + .../directives/ecomp-header/ecomp-header.html | 73 + .../directives/ecomp-header/ecomp-header.less | 296 + .../directives/ecomp-header/ecomp-header.ts | 235 + .../edit-module-name-popover.html | 31 + .../edit-name-popover-directive.ts | 98 + .../edit-name-popover/edit-name-popover-view.html | 1 + .../edit-name-popover/edit-name-popover.less | 71 + .../directives/elements/checkbox/checkbox.html | 13 + .../directives/elements/checkbox/checkbox.less | 35 + .../directives/elements/checkbox/checkbox.ts | 66 + .../elements/radiobutton/radiobutton.html | 5 + .../elements/radiobutton/radiobutton.less | 0 .../directives/elements/radiobutton/radiobutton.ts | 71 + .../directives/ellipsis/ellipsis-directive.html | 7 + .../directives/ellipsis/ellipsis-directive.less | 10 + .../directives/ellipsis/ellipsis-directive.ts | 80 + .../events/on-last-repeat/on-last-repeat.ts | 61 + .../directives/file-opener/file-opener.html | 3 + .../scripts/directives/file-opener/file-opener.ts | 77 + .../app/scripts/directives/file-type/file-type.ts | 66 + .../directives/file-upload/file-upload.html | 22 + .../directives/file-upload/file-upload.less | 75 + .../scripts/directives/file-upload/file-upload.ts | 134 + .../graphs-v2/common/common-graph-utils.ts | 361 + .../style/component-instances-nodes-style.ts | 259 + .../graphs-v2/common/style/module-node-style.ts | 92 + .../composition-graph.directive.ts | 555 + .../composition-graph/composition-graph.html | 22 + .../composition-graph/composition-graph.less | 14 + .../utils/composition-graph-general-utils.ts | 243 + .../utils/composition-graph-links-utils.ts | 347 + .../utils/composition-graph-nodes-utils.ts | 220 + .../utils/match-capability-requierment-utils.ts | 265 + .../deployment-graph/deployment-graph.directive.ts | 114 + .../deployment-graph/deployment-graph.html | 2 + .../deployment-graph/deployment-graph.less | 14 + .../deployment-graph-general-utils.ts | 24 + .../image-creator/image-creator.service.ts | 46 + .../palette/interfaces/i-dragdrop-event.d.ts | 7 + .../graphs-v2/palette/palette.directive.ts | 327 + .../directives/graphs-v2/palette/palette.html | 59 + .../directives/graphs-v2/palette/palette.less | 92 + .../graphs-v2/relation-menu/relation-menu.html | 63 + .../graphs-v2/relation-menu/relation-menu.less | 118 + .../graphs-v2/relation-menu/relation-menu.ts | 113 + .../directives/info-tooltip/info-tooltip.html | 10 + .../directives/info-tooltip/info-tooltip.less | 39 + .../directives/info-tooltip/info-tooltip.ts | 60 + .../invalid-characters/invalid-characters.ts | 72 + .../scripts/directives/layout/top-nav/top-nav.html | 54 + .../scripts/directives/layout/top-nav/top-nav.less | 218 + .../scripts/directives/layout/top-nav/top-nav.ts | 155 + .../layout/top-progress/top-progress.html | 22 + .../layout/top-progress/top-progress.less | 58 + .../directives/layout/top-progress/top-progress.ts | 57 + .../directives/loader/loader-directive.html | 4 + .../directives/loader/loader-directive.less | 74 + .../scripts/directives/loader/loader-directive.ts | 155 + .../app/scripts/directives/modal/sdc-modal.html | 18 + .../app/scripts/directives/modal/sdc-modal.less | 10 + .../app/scripts/directives/modal/sdc-modal.ts | 103 + .../directives/page-scroller/page-scroller.html | 22 + .../directives/page-scroller/page-scroller.less | 98 + .../directives/page-scroller/page-scroller.ts | 247 + .../perfect-scrollbar/angular-perfect-scrollbar.ts | 159 + .../print-graph-screen/print-graph-screen.ts | 211 + .../data-type-fields-structure.html | 82 + .../data-type-fields-structure.less | 90 + .../data-type-fields-structure.ts | 165 + .../type-list/type-list-directive.html | 57 + .../type-list/type-list-directive.less | 85 + .../type-list/type-list-directive.ts | 130 + .../type-map/type-map-directive.html | 70 + .../type-map/type-map-directive.less | 83 + .../property-types/type-map/type-map-directive.ts | 157 + .../app/scripts/directives/punch-out/punch-out.ts | 99 + .../sdc-single-tab/sdc-single-tab-directive.ts | 67 + .../sdc-tabs/sdc-single-tab/sdc-single-tab.less | 1 + .../sdc-tabs/sdc-tabs-directive-view.html | 17 + .../directives/sdc-tabs/sdc-tabs-directive.ts | 69 + .../app/scripts/directives/sdc-tabs/sdc-tabs.less | 68 + .../structure-tree/structure-tree-directive.html | 54 + .../structure-tree/structure-tree-directive.less | 68 + .../structure-tree/structure-tree-directive.ts | 197 + .../app/scripts/directives/tag/tag-directive.html | 10 + .../app/scripts/directives/tag/tag-directive.less | 51 + .../app/scripts/directives/tag/tag-directive.ts | 71 + .../directives/tutorial/image-template.html | 7 + .../scripts/directives/tutorial/text-template.html | 4 + .../directives/tutorial/tutorial-directive.html | 22 + .../directives/tutorial/tutorial-directive.less | 213 + .../directives/tutorial/tutorial-directive.ts | 147 + .../user-header-details-directive.html | 9 + .../user-header-details-directive.less | 62 + .../user-header-details-directive.ts | 72 + .../expand-collaps-menu-box.ts | 66 + .../expand-collapse-menu-box.html | 15 + .../expand-collapse-menu-box.less | 55 + .../utils/expand-collapse/expand-collapse.html | 1 + .../utils/expand-collapse/expand-collapse.less | 10 + .../utils/expand-collapse/expand-collapse.ts | 136 + .../utils/page-selector/page-selector.html | 9 + .../utils/page-selector/page-selector.less | 51 + .../utils/page-selector/page-selector.ts | 106 + .../sdc-keyboard-events/sdc-keyboard-events.ts | 106 + .../directives/utils/sdc-tags/sdc-tags.html | 27 + .../directives/utils/sdc-tags/sdc-tags.less | 61 + .../scripts/directives/utils/sdc-tags/sdc-tags.ts | 97 + .../utils/sdc_error_tooltip/sdc_error_tooltip.html | 6 + .../utils/sdc_error_tooltip/sdc_error_tooltip.ts | 109 + .../directives/utils/sdc_messages/sdc-message.ts | 179 + .../utils/sdc_messages/sdc-messages.less | 10 + .../directives/utils/sdc_messages/sdc-messages.ts | 245 + .../utils/sdc_messages/sdc_messages.html | 1 + .../utils/smart-tooltip/smart-tooltip.ts | 85 + .../utils/wizard_steps/sdc-wizard-steps.html | 16 + .../utils/wizard_steps/sdc-wizard-steps.less | 69 + .../utils/wizard_steps/sdc-wizard-steps.ts | 139 + .../app/scripts/filters/_category-name-filter.ts | 40 + .../app/scripts/filters/capitalize-filter.ts | 43 + .../app/scripts/filters/catalog-status-filter.ts | 41 + .../app/scripts/filters/category-icon-filter.ts | 54 + .../app/scripts/filters/category-type-filter.ts | 45 + .../scripts/filters/clear-whitespaces-filter.ts | 39 + catalog-ui/app/scripts/filters/entity-filter.ts | 117 + .../scripts/filters/graph-resource-name-filter.ts | 47 + .../filters/product-category-name-filter.ts | 39 + .../filters/product-subcategory-name-filter.ts | 39 + .../app/scripts/filters/relation-name-fllter.ts | 53 + .../app/scripts/filters/resource-name-filter.ts | 45 + .../app/scripts/filters/resource-type-filter.ts | 38 + .../app/scripts/filters/string-to-date-filter.ts | 34 + catalog-ui/app/scripts/filters/tests-id-filter.ts | 33 + catalog-ui/app/scripts/filters/trim-filter.ts | 39 + catalog-ui/app/scripts/filters/truncate-filter.ts | 48 + .../app/scripts/filters/underscoreless-filter.ts | 33 + catalog-ui/app/scripts/models/activity.ts | 48 + .../app/scripts/models/additional-information.ts | 44 + catalog-ui/app/scripts/models/app-config.ts | 232 + catalog-ui/app/scripts/models/artifacts.ts | 115 + catalog-ui/app/scripts/models/aschema-property.ts | 63 + catalog-ui/app/scripts/models/attributes.ts | 139 + catalog-ui/app/scripts/models/capability.ts | 116 + catalog-ui/app/scripts/models/category.ts | 67 + catalog-ui/app/scripts/models/comments.ts | 33 + .../app/scripts/models/components/component.ts | 828 + .../scripts/models/components/displayComponent.ts | 98 + .../app/scripts/models/components/product.ts | 109 + .../app/scripts/models/components/resource.ts | 185 + .../app/scripts/models/components/service.ts | 147 + .../componentsInstances/componentInstance.ts | 126 + .../models/componentsInstances/productInstance.ts | 34 + .../models/componentsInstances/resourceInstance.ts | 36 + .../models/componentsInstances/serviceInstance.ts | 35 + catalog-ui/app/scripts/models/csar-component.ts | 36 + .../app/scripts/models/data-type-properties.ts | 65 + catalog-ui/app/scripts/models/data-types-map.ts | 39 + catalog-ui/app/scripts/models/data-types.ts | 55 + catalog-ui/app/scripts/models/distribution.ts | 66 + catalog-ui/app/scripts/models/file-download.ts | 28 + catalog-ui/app/scripts/models/graph/d2-node.ts | 31 + .../models/graph/graph-links/common-base-link.ts | 53 + .../graph/graph-links/common-ci-link-base.ts | 50 + .../composition-ci-link-base.ts | 46 + .../composition-ci-simple-link.ts | 31 + .../composition-ci-ucpe-host-link.ts | 33 + .../composition-ci-ucpe-link.ts | 37 + .../composition-ci-vl-link.ts | 34 + .../composition-ci-vl-ucpe-link.ts | 33 + .../models/graph/graph-links/links-factory.ts | 80 + .../module-graph-links/module-ci-link-base.ts | 38 + .../module-graph-links/module-ci-vl-link.ts | 37 + .../app/scripts/models/graph/graphTooltip.ts | 38 + catalog-ui/app/scripts/models/graph/link-menu.ts | 38 + .../app/scripts/models/graph/match-relation.ts | 109 + .../scripts/models/graph/nodes/base-common-node.ts | 73 + .../models/graph/nodes/common-ci-node-base.ts | 46 + .../composition-ci-node-base.ts | 72 + .../composition-ci-node-cp.ts | 48 + .../composition-ci-node-service.ts | 42 + .../composition-ci-node-ucpe-cp.ts | 39 + .../composition-ci-node-ucpe.ts | 50 + .../composition-ci-node-vf.ts | 41 + .../composition-ci-node-vfc.ts | 33 + .../composition-ci-node-vl.ts | 54 + .../nodes/modules-graph-nodes/module-node-base.ts | 52 + .../scripts/models/graph/nodes/nodes-factory.ts | 63 + catalog-ui/app/scripts/models/graph/point.ts | 26 + .../scripts/models/graph/relationMenuObjects.ts | 138 + .../app/scripts/models/graph/relationship.ts | 107 + catalog-ui/app/scripts/models/inputs.ts | 74 + .../models/instance-inputs-properties-map.ts | 39 + .../app/scripts/models/instances-inputs-map.ts | 39 + catalog-ui/app/scripts/models/left-panel.ts | 33 + catalog-ui/app/scripts/models/member.ts | 39 + .../app/scripts/models/modules/base-module.ts | 108 + catalog-ui/app/scripts/models/properties.ts | 176 + catalog-ui/app/scripts/models/requirement.ts | 91 + catalog-ui/app/scripts/models/schema-attribute.ts | 37 + catalog-ui/app/scripts/models/tab.ts | 47 + catalog-ui/app/scripts/models/tooltip-data.ts | 28 + catalog-ui/app/scripts/models/user.ts | 117 + catalog-ui/app/scripts/models/validate.ts | 29 + catalog-ui/app/scripts/modules/directive-module.ts | 106 + catalog-ui/app/scripts/modules/filters.ts | 44 + catalog-ui/app/scripts/modules/service-module.ts | 64 + catalog-ui/app/scripts/modules/utils.ts | 39 + .../app/scripts/modules/view-model-module.ts | 96 + .../app/scripts/services/activity-log-service.ts | 48 + .../scripts/services/angular-js-bridge-service.ts | 22 + .../scripts/services/available-icons-service.ts | 105 + catalog-ui/app/scripts/services/cache-service.ts | 58 + .../scripts/services/category-resource-service.ts | 83 + .../services/components/component-service.ts | 698 + .../scripts/services/components/product-service.ts | 61 + .../services/components/resource-service.ts | 61 + .../scripts/services/components/service-service.ts | 97 + .../utils/composition-left-palette-service.ts | 248 + .../scripts/services/configuration-ui-service.ts | 49 + catalog-ui/app/scripts/services/cookie-service.ts | 95 + .../app/scripts/services/data-types-service.ts | 129 + catalog-ui/app/scripts/services/ecomp-service.ts | 54 + catalog-ui/app/scripts/services/entity-service.ts | 114 + .../app/scripts/services/event-listener-service.ts | 78 + .../app/scripts/services/header-interceptor.ts | 93 + .../app/scripts/services/http-error-interceptor.ts | 118 + catalog-ui/app/scripts/services/loader-service.ts | 26 + .../app/scripts/services/onboarding-service.ts | 103 + .../app/scripts/services/progress-service.ts | 112 + .../app/scripts/services/relation-icons-service.ts | 61 + .../app/scripts/services/sdc-version-service.ts | 48 + catalog-ui/app/scripts/services/sharing-service.ts | 41 + .../app/scripts/services/url-tobase64-service.ts | 52 + .../app/scripts/services/user-resource-service.ts | 123 + catalog-ui/app/scripts/utils/artifacts-utils.ts | 121 + .../utils/change-lifecycle-state-handler.ts | 151 + catalog-ui/app/scripts/utils/common-utils.ts | 81 + catalog-ui/app/scripts/utils/component-factory.ts | 181 + .../scripts/utils/component-instance-factory.ts | 85 + catalog-ui/app/scripts/utils/constants.ts | 247 + .../app/scripts/utils/dictionary/dictionary.ts | 257 + catalog-ui/app/scripts/utils/file-utils.ts | 73 + catalog-ui/app/scripts/utils/functions.ts | 58 + catalog-ui/app/scripts/utils/menu-handler.ts | 145 + catalog-ui/app/scripts/utils/modals-handler.ts | 275 + catalog-ui/app/scripts/utils/prototypes.ts | 155 + catalog-ui/app/scripts/utils/validation-utils.ts | 173 + .../add-category-modal-view-model.ts | 94 + .../add-category-modal-view.html | 41 + .../add-category-modal-view.less | 3 + .../admin-dashboard/admin-dashboard-view-model.ts | 82 + .../admin-dashboard/admin-dashboard-view.html | 24 + .../admin-dashboard/admin-dashboard.less | 49 + .../category-management-view-model.ts | 197 + .../category-management-view.html | 53 + .../category-management/category-management.less | 118 + .../admin-dashboard/ecomp/ecomp-view.html | 1 + .../user-management/user-management-view-model.ts | 220 + .../user-management/user-management-view.html | 102 + .../user-management/user-management.less | 251 + .../view-models/catalog/catalog-view-model.ts | 312 + .../view-models/catalog/catalog-view-tests.ts | 309 + .../scripts/view-models/catalog/catalog-view.html | 190 + .../app/scripts/view-models/catalog/catalog.less | 304 + .../activity-log/activity-log-view.html | 16 + .../activity-log/activity-log-view.less | 18 + .../component-viewer-view-model.ts | 211 + .../component-viewer/component-viewer.html | 55 + .../component-viewer/component-viewer.less | 148 + .../properties/product-properties-view.html | 76 + .../properties/properties-view.less | 128 + .../properties/resource-properties-view.html | 169 + .../properties/service-properties-view.html | 167 + .../dashboard/cover/dashboard-cover-view-model.ts | 91 + .../dashboard/cover/dashboard-cover-view.html | 1 + .../dashboard/dashboard-view-model-tests.ts | 276 + .../view-models/dashboard/dashboard-view-model.ts | 415 + .../view-models/dashboard/dashboard-view.html | 106 + .../scripts/view-models/dashboard/dashboard.less | 420 + .../artifact-form/artifact-form-view-model.ts | 354 + .../forms/artifact-form/artifact-form-view.html | 169 + .../forms/artifact-form/artifact-form.less | 44 + .../forms/attribute-form/attribute-form-view.html | 153 + .../attribute-form/attribute-from-view-model.ts | 255 + .../env-parameters-form/env-parameters-form.html | 39 + .../env-parameters-form/env-parameters-form.less | 74 + .../env-parameters-form/env-parameters-form.ts | 149 + .../property-form/property-form-view-model.ts | 330 + .../forms/property-form/property-form-view.html | 219 + .../forms/property-form/property-form.less | 63 + .../resource-instance-name-model.ts | 105 + .../resource-instance-name-view.html | 72 + .../resource-instance-name.less | 29 + .../confirmation-modal-view-model.ts | 96 + .../confirmation-modal-view.html | 29 + .../confirmation-modal/confirmation-modal.less | 30 + .../modals/email-modal/email-modal-view-model.ts | 117 + .../modals/email-modal/email-modal-view.html | 79 + .../modals/email-modal/email-modal.less | 56 + .../modals/error-modal/error-403-view.html | 4 + .../modals/error-modal/error-view-model.ts | 43 + .../view-models/modals/error-modal/error.less | 13 + .../message-modal/message-base-modal-model.ts | 64 + .../client-message-modal-view-model.ts | 43 + .../client-message-modal-view.html | 16 + .../message-client-modal/client-message-modal.less | 0 .../server-message-modal-view-model.ts | 45 + .../server-message-modal-view.html | 17 + .../message-server-modal/server-message-modal.less | 0 .../onboarding-modal-view-model.ts | 249 + .../onboarding-modal/onboarding-modal-view.html | 142 + .../modals/onboarding-modal/onboarding-modal.less | 148 + .../onboard-vendor/onboard-vendor-view-model.ts | 148 + .../onboard-vendor/onboard-vendor-view.html | 14 + .../view-models/onboard-vendor/onboard-vendor.less | 303 + .../view-models/preloading/preloading-view.html | 9 + .../view-models/preloading/preloading-view.less | 107 + .../view-models/preloading/preloading-view.ts | 47 + .../view-models/support/support-view-model.ts | 38 + .../scripts/view-models/support/support-view.html | 33 + .../app/scripts/view-models/support/support.less | 8 + .../app/scripts/view-models/tabs/general-tab.less | 131 + .../tabs/hierarchy/hierarchy-view-model.ts | 99 + .../view-models/tabs/hierarchy/hierarchy-view.html | 57 + .../view-models/tabs/hierarchy/hierarchy.less | 71 + .../view-models/tutorial-end/tutorial-end.html | 10 + .../view-models/tutorial-end/tutorial-end.less | 41 + .../view-models/tutorial-end/tutorial-end.ts | 42 + .../app/scripts/view-models/welcome/slide0.html | 50 + .../app/scripts/view-models/welcome/slide1.html | 34 + .../app/scripts/view-models/welcome/slide2.html | 26 + .../app/scripts/view-models/welcome/slide3.html | 27 + .../app/scripts/view-models/welcome/slide4.html | 29 + .../app/scripts/view-models/welcome/slide5.html | 27 + .../app/scripts/view-models/welcome/slide6.html | 26 + .../welcome/welcome-steps-controller.ts | 74 + .../scripts/view-models/welcome/welcome-view.html | 22 + .../scripts/view-models/welcome/welcome-view.ts | 267 + .../app/scripts/view-models/wizard/ReadMe.txt | 54 + .../artifact-deployment-step.html | 137 + .../artifact-deployment-step.less | 107 + .../artifact-deployment-step.ts | 228 + .../artifact-form-step-view-model.ts | 304 + .../artifact-form-step-view.html | 147 + .../artifact-form-step/artifact-form-step.less | 45 + .../artifact-information-step.html | 48 + .../artifact-information-step.less | 50 + .../artifact-information-step.ts | 168 + .../wizard/general-step/general-step.html | 270 + .../wizard/general-step/general-step.less | 34 + .../wizard/general-step/general-step.ts | 381 + .../wizard/hierarchy-step/hierarchy-step.html | 40 + .../wizard/hierarchy-step/hierarchy-step.less | 125 + .../wizard/hierarchy-step/hierarchy-step.ts | 149 + .../view-models/wizard/icons-step/icons-step.html | 26 + .../view-models/wizard/icons-step/icons-step.less | 55 + .../view-models/wizard/icons-step/icons-step.ts | 150 + .../wizard/properties-step/properties-step.html | 57 + .../wizard/properties-step/properties-step.less | 55 + .../wizard/properties-step/properties-step.ts | 123 + .../property-form-view-model-tests.ts | 163 + .../property-form/property-form-view-model.ts | 250 + .../wizard/property-form/property-form.html | 133 + .../wizard/property-form/property-form.less | 7 + .../view-models/wizard/wizard-creation-base.html | 12 + .../view-models/wizard/wizard-creation-base.less | 60 + .../view-models/wizard/wizard-creation-base.ts | 399 + .../wizard/wizard-state/create-wizard.ts | 114 + .../view-models/wizard/wizard-state/edit-wizard.ts | 164 + .../wizard/wizard-state/import-wizard.ts | 64 + .../workspace/tabs/activity-log/activity-log.html | 85 + .../workspace/tabs/activity-log/activity-log.less | 83 + .../workspace/tabs/activity-log/activity-log.ts | 122 + .../tabs/attributes/attributes-view-model.ts | 107 + .../workspace/tabs/attributes/attributes-view.html | 52 + .../workspace/tabs/attributes/attributes.less | 54 + .../tabs/composition/composition-view-model.ts | 232 + .../tabs/composition/composition-view.html | 99 + .../workspace/tabs/composition/composition.less | 864 + .../tabs/artifacts/artifacts-view-model.ts | 255 + .../composition/tabs/artifacts/artifacts-view.html | 55 + .../tabs/composition/tabs/artifacts/artifacts.less | 172 + .../composition/tabs/details/details-view-model.ts | 132 + .../composition/tabs/details/details-view.html | 129 + .../tabs/composition/tabs/details/details.less | 68 + .../properties-view-model.ts | 228 + .../properties-and-attributes/properties-view.html | 81 + .../tabs/properties-and-attributes/properties.less | 16 + .../tabs/relations/relations-view-model.ts | 81 + .../composition/tabs/relations/relations-view.html | 57 + .../tabs/composition/tabs/relations/relations.less | 116 + .../composition/tabs/structure/structure-view.html | 13 + .../composition/tabs/structure/structure-view.ts | 34 + .../deployment-artifacts-view-model.ts | 253 + .../deployment-artifacts-view.html | 149 + .../deployment-artifacts/deployment-artifacts.less | 102 + .../tabs/deployment/deployment-view-model.ts | 127 + .../workspace/tabs/deployment/deployment-view.html | 10 + .../workspace/tabs/deployment/deployment.less | 33 + .../disribution-status-modal-view-model.ts | 67 + .../disribution-status-modal-view.html | 126 + .../disribution-status-modal.less | 33 + .../tabs/distribution/distribution-view-model.ts | 135 + .../tabs/distribution/distribution-view.html | 171 + .../workspace/tabs/distribution/distribution.less | 361 + .../workspace/tabs/general/general-view-model.ts | 379 + .../workspace/tabs/general/general-view.html | 307 + .../workspace/tabs/general/general.less | 64 + .../workspace/tabs/icons/icons-view-model.ts | 131 + .../workspace/tabs/icons/icons-view.html | 26 + .../view-models/workspace/tabs/icons/icons.less | 65 + .../information-artifacts-view-model.ts | 150 + .../information-artifacts-view.html | 57 + .../information-artifacts.less | 47 + .../view-models/workspace/tabs/inputs/inputs.less | 286 + .../resource-input/resource-inputs-view-model.ts | 145 + .../resource-input/resource-inputs-view.html | 136 + .../inputs/resource-input/resource-inputs.less | 9 + .../service-input/service-inputs-view-model.ts | 246 + .../inputs/service-input/service-inputs-view.html | 205 + .../tabs/inputs/service-input/service-inputs.less | 54 + .../management-workflow-view-model.ts | 128 + .../management-workflow-view.html | 3 + .../network-call-flow-view-model.ts | 80 + .../network-call-flow/network-call-flow-view.html | 3 + .../product-hierarchy-view-model.ts | 134 + .../product-hierarchy/product-hierarchy-view.html | 40 + .../tabs/product-hierarchy/product-hierarchy.less | 130 + .../tabs/properties/properties-view-model.ts | 114 + .../workspace/tabs/properties/properties-view.html | 62 + .../workspace/tabs/properties/properties.less | 115 + .../req-and-capabilities-view-model.ts | 165 + .../req-and-capabilities-view.html | 144 + .../req-and-capabilities/req-and-capabilities.less | 196 + .../tosca-artifacts/tosca-artifacts-view-model.ts | 87 + .../tabs/tosca-artifacts/tosca-artifacts-view.html | 45 + .../tabs/tosca-artifacts/tosca-artifacts.less | 74 + .../view-models/workspace/workspace-view-model.ts | 703 + .../view-models/workspace/workspace-view.html | 86 + .../scripts/view-models/workspace/workspace.less | 144 + catalog-ui/app/styles/animation.less | 51 + catalog-ui/app/styles/app.less | 122 + catalog-ui/app/styles/buttons.less | 274 + catalog-ui/app/styles/dark-header.less | 51 + catalog-ui/app/styles/fonts.less | 72 + .../styles/fonts/ClearviewATT/ClearviewATT-Bd.eot | Bin 0 -> 92160 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Bd.svg | 424 + .../styles/fonts/ClearviewATT/ClearviewATT-Bd.ttf | Bin 0 -> 93916 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Bd.woff | Bin 0 -> 42192 bytes .../fonts/ClearviewATT/ClearviewATT-BdIt.eot | Bin 0 -> 104184 bytes .../fonts/ClearviewATT/ClearviewATT-BdIt.svg | 425 + .../fonts/ClearviewATT/ClearviewATT-BdIt.ttf | Bin 0 -> 105932 bytes .../fonts/ClearviewATT/ClearviewATT-BdIt.woff | Bin 0 -> 46444 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Bk.eot | Bin 0 -> 86088 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Bk.svg | 425 + .../styles/fonts/ClearviewATT/ClearviewATT-Bk.ttf | Bin 0 -> 88696 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Bk.woff | Bin 0 -> 39280 bytes .../fonts/ClearviewATT/ClearviewATT-BkIt.eot | Bin 0 -> 104224 bytes .../fonts/ClearviewATT/ClearviewATT-BkIt.svg | 425 + .../fonts/ClearviewATT/ClearviewATT-BkIt.ttf | Bin 0 -> 105972 bytes .../fonts/ClearviewATT/ClearviewATT-BkIt.woff | Bin 0 -> 46676 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Lt.eot | Bin 0 -> 89640 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Lt.svg | 425 + .../styles/fonts/ClearviewATT/ClearviewATT-Lt.ttf | Bin 0 -> 92288 bytes .../styles/fonts/ClearviewATT/ClearviewATT-Lt.woff | Bin 0 -> 40332 bytes .../fonts/ClearviewATT/ClearviewATT-LtIt.eot | Bin 0 -> 108396 bytes .../fonts/ClearviewATT/ClearviewATT-LtIt.svg | 424 + .../fonts/ClearviewATT/ClearviewATT-LtIt.ttf | Bin 0 -> 110192 bytes .../fonts/ClearviewATT/ClearviewATT-LtIt.woff | Bin 0 -> 48120 bytes .../styles/fonts/OmnesATT/AT&T Variation ID.tab | 9 + .../fonts/OmnesATT/OmnesATTW02BoldItalic.eot | Bin 0 -> 31322 bytes .../fonts/OmnesATT/OmnesATTW02BoldItalic.svg | 3671 +++ .../fonts/OmnesATT/OmnesATTW02BoldItalic.ttf | Bin 0 -> 68660 bytes .../fonts/OmnesATT/OmnesATTW02BoldItalic.woff | Bin 0 -> 35986 bytes .../app/styles/fonts/OmnesATT/Omnes_ATTW02.eot | Bin 0 -> 30321 bytes .../app/styles/fonts/OmnesATT/Omnes_ATTW02.svg | 3694 +++ .../app/styles/fonts/OmnesATT/Omnes_ATTW02.ttf | Bin 0 -> 71692 bytes .../app/styles/fonts/OmnesATT/Omnes_ATTW02.woff | Bin 0 -> 35610 bytes .../app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.eot | Bin 0 -> 32077 bytes .../app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.svg | 4365 ++++ .../app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.ttf | Bin 0 -> 71564 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Bold.woff | Bin 0 -> 37149 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Italic.eot | Bin 0 -> 32079 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Italic.svg | 3799 +++ .../styles/fonts/OmnesATT/Omnes_ATTW02Italic.ttf | Bin 0 -> 76564 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Italic.woff | Bin 0 -> 37872 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Light.eot | Bin 0 -> 32072 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Light.svg | 3872 ++++ .../styles/fonts/OmnesATT/Omnes_ATTW02Light.ttf | Bin 0 -> 73968 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Light.woff | Bin 0 -> 37342 bytes .../fonts/OmnesATT/Omnes_ATTW02LightItalic.eot | Bin 0 -> 30983 bytes .../fonts/OmnesATT/Omnes_ATTW02LightItalic.svg | 3030 +++ .../fonts/OmnesATT/Omnes_ATTW02LightItalic.ttf | Bin 0 -> 70088 bytes .../fonts/OmnesATT/Omnes_ATTW02LightItalic.woff | Bin 0 -> 36261 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Medium.eot | Bin 0 -> 28695 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Medium.svg | 2473 ++ .../styles/fonts/OmnesATT/Omnes_ATTW02Medium.ttf | Bin 0 -> 65152 bytes .../styles/fonts/OmnesATT/Omnes_ATTW02Medium.woff | Bin 0 -> 33641 bytes .../fonts/OmnesATT/Omnes_ATTW02MediumItalic.eot | Bin 0 -> 33730 bytes .../fonts/OmnesATT/Omnes_ATTW02MediumItalic.svg | 3837 ++++ .../fonts/OmnesATT/Omnes_ATTW02MediumItalic.ttf | Bin 0 -> 77508 bytes .../fonts/OmnesATT/Omnes_ATTW02MediumItalic.woff | Bin 0 -> 39182 bytes .../app/styles/fonts/OmnesATT/demo-async.htm | 169 + catalog-ui/app/styles/fonts/OmnesATT/demo.htm | 155 + catalog-ui/app/styles/form-elements.less | 199 + catalog-ui/app/styles/global.less | 52 + catalog-ui/app/styles/images/anonymous.jpg | Bin 0 -> 1150 bytes catalog-ui/app/styles/images/att_logo_white.png | Bin 0 -> 2827 bytes .../images/relationship-icons/AttachesTo.svg | 37 + .../styles/images/relationship-icons/BindsTo.svg | 19 + .../images/relationship-icons/ConnectedTo.svg | 19 + .../styles/images/relationship-icons/DependsOn.svg | 34 + .../styles/images/relationship-icons/HostedOn.svg | 25 + .../styles/images/relationship-icons/LinksTo.svg | 22 + .../styles/images/relationship-icons/RoutesTo.svg | 19 + .../app/styles/images/relationship-icons/arrow.png | Bin 0 -> 1111 bytes .../app/styles/images/relationship-icons/arrow.svg | 11 + .../relationship-icons/arrow_connection_right.svg | 11 + .../styles/images/relationship-icons/attach.png | Bin 0 -> 1485 bytes .../styles/images/relationship-icons/binding.png | Bin 0 -> 1385 bytes .../styles/images/relationship-icons/conected.png | Bin 0 -> 1481 bytes .../styles/images/relationship-icons/conected.svg | 19 + .../images/relationship-icons/dependency.png | Bin 0 -> 1632 bytes .../app/styles/images/relationship-icons/host.png | Bin 0 -> 1836 bytes .../app/styles/images/relationship-icons/link.png | Bin 0 -> 1628 bytes .../images/relationship-icons/local_storage.png | Bin 0 -> 1485 bytes .../images/relationship-icons/local_storage.svg | 37 + .../app/styles/images/relationship-icons/rout.png | Bin 0 -> 1630 bytes .../images/resource-icons/Red_PLUS_HOVER.png | Bin 0 -> 1456 bytes .../Resource_Icons_NB_COLLABORATION-.png | Bin 0 -> 3898 bytes .../Resource_Icons_NB_COMPUTE-AS-SERVICE-.png | Bin 0 -> 3129 bytes .../Resource_Icons_NB_MESSAGING-.png | Bin 0 -> 2376 bytes .../resource-icons/Resource_Icons_NB_MOBILITY.png | Bin 0 -> 3396 bytes .../resource-icons/Resource_Icons_NB_NETWORK-.png | Bin 0 -> 4190 bytes .../Resource_Icons_NB_NETWORK-CLOUD-.png | Bin 0 -> 2908 bytes .../Resource_Icons_NB_NETWORK-L-1-3.png | Bin 0 -> 3239 bytes .../Resource_Icons_NB_NETWORK-L-4.png | Bin 0 -> 3104 bytes .../Resource_Icons_NB_NOTIFICATION-.png | Bin 0 -> 2818 bytes .../resource-icons/Resource_Icons_NB_ORPHAN.png | Bin 0 -> 3831 bytes .../Resource_Icons_NB_PLATFORM-AS-SERVICE-.png | Bin 0 -> 3728 bytes .../resource-icons/Resource_Icons_NB_SECURITY-.png | Bin 0 -> 3523 bytes .../resource-icons/Resource_Icons_NB_SETTING-.png | Bin 0 -> 4019 bytes .../resource-icons/Resource_Icons_NB_avater.png | Bin 0 -> 3818 bytes .../Resource_Icons_STORAGE-AS-SERVICE.png | Bin 0 -> 3106 bytes .../styles/images/resource-icons/alcatelLucent.png | Bin 0 -> 3301 bytes .../images/resource-icons/applicationServer.png | Bin 0 -> 2152 bytes .../app/styles/images/resource-icons/aricent.png | Bin 0 -> 2407 bytes .../app/styles/images/resource-icons/att.png | Bin 0 -> 3241 bytes .../styles/images/resource-icons/borderElement.png | Bin 0 -> 3744 bytes .../app/styles/images/resource-icons/broadsoft.png | Bin 0 -> 2725 bytes .../app/styles/images/resource-icons/brocade.png | Bin 0 -> 3601 bytes .../styles/images/resource-icons/call_controll.png | Bin 0 -> 3146 bytes .../images/resource-icons/canvasPlusIcon-red.png | Bin 0 -> 1434 bytes .../images/resource-icons/canvasPlusIcon.png | Bin 0 -> 1455 bytes .../app/styles/images/resource-icons/cisco.png | Bin 0 -> 2702 bytes .../styles/images/resource-icons/closeModule.png | Bin 0 -> 15427 bytes .../images/resource-icons/closeModuleHover.png | Bin 0 -> 14979 bytes .../app/styles/images/resource-icons/cloud.png | Bin 0 -> 3561 bytes .../app/styles/images/resource-icons/cloudep.png | Bin 0 -> 2944 bytes .../images/resource-icons/compute-uncertified.png | Bin 0 -> 2598 bytes .../app/styles/images/resource-icons/compute.png | Bin 0 -> 2212 bytes .../app/styles/images/resource-icons/connector.png | Bin 0 -> 2040 bytes catalog-ui/app/styles/images/resource-icons/cp.png | Bin 0 -> 1507 bytes .../app/styles/images/resource-icons/database.png | Bin 0 -> 2447 bytes .../images/resource-icons/dcae_analytics.png | Bin 0 -> 2501 bytes .../images/resource-icons/dcae_collector.png | Bin 0 -> 2582 bytes .../styles/images/resource-icons/dcae_database.png | Bin 0 -> 2447 bytes .../images/resource-icons/dcae_microservice.png | Bin 0 -> 2485 bytes .../styles/images/resource-icons/dcae_policy.png | Bin 0 -> 2492 bytes .../styles/images/resource-icons/dcae_source.png | Bin 0 -> 3451 bytes .../styles/images/resource-icons/dcae_utilty.png | Bin 0 -> 3840 bytes .../app/styles/images/resource-icons/default.png | Bin 0 -> 3831 bytes .../styles/images/resource-icons/defaulticon.png | Bin 0 -> 2132 bytes .../app/styles/images/resource-icons/ericsson.png | Bin 0 -> 3606 bytes .../app/styles/images/resource-icons/firewall.png | Bin 0 -> 3348 bytes .../app/styles/images/resource-icons/fortinet.png | Bin 0 -> 2016 bytes .../app/styles/images/resource-icons/gateway.png | Bin 0 -> 2647 bytes .../app/styles/images/resource-icons/juniper.png | Bin 0 -> 3505 bytes .../styles/images/resource-icons/loadBalancer.png | Bin 0 -> 2949 bytes .../styles/images/resource-icons/metaswitch.png | Bin 0 -> 3141 bytes .../app/styles/images/resource-icons/module.png | Bin 0 -> 1216 bytes .../app/styles/images/resource-icons/mysql.png | Bin 0 -> 3033 bytes .../app/styles/images/resource-icons/network.png | Bin 0 -> 4214 bytes .../styles/images/resource-icons/networkrules.png | Bin 0 -> 2920 bytes .../styles/images/resource-icons/nokia_siemens.png | Bin 0 -> 2615 bytes .../styles/images/resource-icons/objectStorage.png | Bin 0 -> 3031 bytes .../styles/images/resource-icons/openModule.png | Bin 0 -> 14990 bytes .../images/resource-icons/openModuleHover.png | Bin 0 -> 14989 bytes .../app/styles/images/resource-icons/oracle.png | Bin 0 -> 2432 bytes .../app/styles/images/resource-icons/ossep.png | Bin 0 -> 3768 bytes .../app/styles/images/resource-icons/personep.png | Bin 0 -> 3419 bytes .../app/styles/images/resource-icons/port.png | Bin 0 -> 2359 bytes .../styles/images/resource-icons/premisesep.png | Bin 0 -> 2822 bytes .../app/styles/images/resource-icons/router.png | Bin 0 -> 4031 bytes .../styles/images/resource-icons/securityrules.png | Bin 0 -> 2965 bytes .../images/resource-icons/selectedCPInstance.png | Bin 0 -> 1090 bytes .../images/resource-icons/selectedInstance.png | Bin 0 -> 1143 bytes .../images/resource-icons/selectedUcpeInstance.png | Bin 0 -> 3850 bytes .../images/resource-icons/selectedVLInstance.png | Bin 0 -> 1072 bytes .../app/styles/images/resource-icons/server.png | Bin 0 -> 2078 bytes .../app/styles/images/resource-icons/tropo.png | Bin 0 -> 3558 bytes .../app/styles/images/resource-icons/ucpe.png | Bin 0 -> 3983 bytes .../styles/images/resource-icons/uncertified.png | Bin 0 -> 1503 bytes .../app/styles/images/resource-icons/vfw.png | Bin 0 -> 3730 bytes catalog-ui/app/styles/images/resource-icons/vl.png | Bin 0 -> 3376741 bytes .../app/styles/images/resource-icons/vrouter.png | Bin 0 -> 3088 bytes .../app/styles/images/resource-icons/wanx.png | Bin 0 -> 3166 bytes .../styles/images/service-icons/call_controll.png | Bin 0 -> 3238 bytes .../styles/images/service-icons/collaboration.png | Bin 0 -> 3804 bytes .../styles/images/service-icons/collaboration1.png | Bin 0 -> 3194 bytes .../app/styles/images/service-icons/compute.png | Bin 0 -> 3201 bytes .../styles/images/service-icons/defaulticon.png | Bin 0 -> 2168 bytes .../app/styles/images/service-icons/messaging.png | Bin 0 -> 2458 bytes .../app/styles/images/service-icons/mobility.png | Bin 0 -> 3333 bytes .../styles/images/service-icons/network_l_1-3.png | Bin 0 -> 3030 bytes .../styles/images/service-icons/network_l_4.png | Bin 0 -> 2961 bytes .../styles/images/service-icons/notification.png | Bin 0 -> 2714 bytes .../app/styles/images/service-icons/platform.png | Bin 0 -> 3762 bytes .../app/styles/images/service-icons/storage.png | Bin 0 -> 3136 bytes .../styles/images/service-icons/uncertified.png | Bin 0 -> 1503 bytes .../styles/images/sprites/sprite-global-old.png | Bin 0 -> 84465 bytes .../app/styles/images/sprites/sprite-global.png | Bin 0 -> 71883 bytes .../styles/images/sprites/sprite-product-icons.png | Bin 0 -> 132122 bytes .../images/sprites/sprite-resource-icons.png | Bin 0 -> 469610 bytes .../images/sprites/sprite-services-icons.png | Bin 0 -> 127233 bytes .../app/styles/images/sprites/tlv-sprite.png | Bin 0 -> 14677 bytes catalog-ui/app/styles/images/tutorial/10.png | Bin 0 -> 6707 bytes catalog-ui/app/styles/images/tutorial/11.png | Bin 0 -> 7697 bytes catalog-ui/app/styles/images/tutorial/13.png | Bin 0 -> 11072 bytes catalog-ui/app/styles/images/tutorial/14.png | Bin 0 -> 2768 bytes catalog-ui/app/styles/images/tutorial/15.png | Bin 0 -> 8250 bytes catalog-ui/app/styles/images/tutorial/16.png | Bin 0 -> 11421 bytes catalog-ui/app/styles/images/tutorial/17.png | Bin 0 -> 12030 bytes catalog-ui/app/styles/images/tutorial/18.png | Bin 0 -> 10696 bytes catalog-ui/app/styles/images/tutorial/19.png | Bin 0 -> 7678 bytes catalog-ui/app/styles/images/tutorial/2.png | Bin 0 -> 5480 bytes catalog-ui/app/styles/images/tutorial/20.png | Bin 0 -> 8421 bytes catalog-ui/app/styles/images/tutorial/21.png | Bin 0 -> 11205 bytes catalog-ui/app/styles/images/tutorial/22.png | Bin 0 -> 9610 bytes catalog-ui/app/styles/images/tutorial/23.png | Bin 0 -> 9229 bytes catalog-ui/app/styles/images/tutorial/24.png | Bin 0 -> 7842 bytes catalog-ui/app/styles/images/tutorial/25.png | Bin 0 -> 7579 bytes catalog-ui/app/styles/images/tutorial/26.png | Bin 0 -> 8364 bytes catalog-ui/app/styles/images/tutorial/27.png | Bin 0 -> 10243 bytes catalog-ui/app/styles/images/tutorial/28.png | Bin 0 -> 6838 bytes catalog-ui/app/styles/images/tutorial/29.png | Bin 0 -> 9140 bytes catalog-ui/app/styles/images/tutorial/3.png | Bin 0 -> 6717 bytes catalog-ui/app/styles/images/tutorial/30.png | Bin 0 -> 8680 bytes catalog-ui/app/styles/images/tutorial/4.png | Bin 0 -> 3154 bytes catalog-ui/app/styles/images/tutorial/5.png | Bin 0 -> 3233 bytes catalog-ui/app/styles/images/tutorial/6.png | Bin 0 -> 6294 bytes catalog-ui/app/styles/images/tutorial/7.png | Bin 0 -> 6574 bytes catalog-ui/app/styles/images/tutorial/8.png | Bin 0 -> 8534 bytes catalog-ui/app/styles/images/welcome.png | Bin 0 -> 44721 bytes .../app/styles/images/welcome/SD&C_Welcome15.jpg | Bin 0 -> 3088201 bytes .../app/styles/images/welcome/SD&C_Welcome15_b.jpg | Bin 0 -> 3082618 bytes catalog-ui/app/styles/images/welcome/bg/001.jpg | Bin 0 -> 278335 bytes catalog-ui/app/styles/images/welcome/bg/002.jpg | Bin 0 -> 503913 bytes catalog-ui/app/styles/images/welcome/bg/002.png | Bin 0 -> 2804026 bytes catalog-ui/app/styles/images/welcome/bg/003.png | Bin 0 -> 1470296 bytes catalog-ui/app/styles/images/welcome/bg/004.png | Bin 0 -> 2906163 bytes catalog-ui/app/styles/images/welcome/bg/bg02.png | Bin 0 -> 141906 bytes catalog-ui/app/styles/images/welcome/bg/bg03.png | Bin 0 -> 148913 bytes .../app/styles/images/welcome/bg/connection02.png | Bin 0 -> 2735 bytes .../app/styles/images/welcome/bg/connection03.png | Bin 0 -> 7056 bytes .../app/styles/images/welcome/bg/connection04.png | Bin 0 -> 2712 bytes catalog-ui/app/styles/images/welcome/bg/global.png | Bin 0 -> 58238 bytes .../app/styles/images/welcome/bg/shape02.png | Bin 0 -> 163714 bytes .../app/styles/images/welcome/bg/shape03.png | Bin 0 -> 89805 bytes .../app/styles/images/welcome/bg/shape04.png | Bin 0 -> 127232 bytes .../app/styles/images/welcome/bg/shape05.png | Bin 0 -> 299086 bytes catalog-ui/app/styles/images/welcome/laptop.png | Bin 0 -> 83877 bytes catalog-ui/app/styles/images/welcome/logo_att.png | Bin 0 -> 19214 bytes catalog-ui/app/styles/images/welcome/sprite.png | Bin 0 -> 3386285 bytes catalog-ui/app/styles/images/welcome/ss-01.png | Bin 0 -> 3413794 bytes catalog-ui/app/styles/images/welcome/ss-02.png | Bin 0 -> 67191 bytes catalog-ui/app/styles/images/welcome/ss-03.png | Bin 0 -> 46870 bytes catalog-ui/app/styles/layout/header.less | 78 + catalog-ui/app/styles/layout/main.less | 124 + catalog-ui/app/styles/layout/sidebar.less | 163 + catalog-ui/app/styles/mixins.less | 217 + catalog-ui/app/styles/mixins_old.less | 558 + catalog-ui/app/styles/modal.less | 356 + catalog-ui/app/styles/scroller.less | 15 + catalog-ui/app/styles/sprite-old.less | 132 + catalog-ui/app/styles/sprite-product-icons.less | 71 + catalog-ui/app/styles/sprite-resource-icons.less | 258 + catalog-ui/app/styles/sprite-services-icons.less | 66 + catalog-ui/app/styles/sprite.html | 65 + catalog-ui/app/styles/sprite.less | 212 + catalog-ui/app/styles/table-flex.less | 178 + catalog-ui/app/styles/tlv-buttons.less | 234 + catalog-ui/app/styles/tlv-checkbox.less | 87 + catalog-ui/app/styles/tlv-loader.less | 164 + catalog-ui/app/styles/tlv-sprite.less | 138 + catalog-ui/app/styles/tooltips.less | 110 + catalog-ui/app/styles/variables-old.less | 77 + catalog-ui/app/styles/variables.less | 48 + catalog-ui/app/styles/welcome-sprite.less | 57 + catalog-ui/app/styles/welcome-style.less | 651 + catalog-ui/app/third-party/PunchOutRegistry.js | 98 + .../app/third-party/ng-infinite-scroll/.npmignore | 3 + .../app/third-party/ng-infinite-scroll/.travis.yml | 12 + .../ng-infinite-scroll/Gruntfile.coffee | 110 + .../app/third-party/ng-infinite-scroll/LICENSE | 22 + .../app/third-party/ng-infinite-scroll/README.md | 71 + .../app/third-party/ng-infinite-scroll/bower.json | 16 + .../ng-infinite-scroll/build/ng-infinite-scroll.js | 209 + .../build/ng-infinite-scroll.min.js | 22 + .../third-party/ng-infinite-scroll/package.json | 80 + .../ng-infinite-scroll/src/infinite-scroll.coffee | 209 + .../test/protractor-local.conf.js | 27 + .../test/protractor-shared.conf.js | 26 + .../test/protractor-travis.conf.js | 32 + .../test/spec/ng-infinite-scroll.spec.coffee | 221 + catalog-ui/bower dependecies | 29 + catalog-ui/bower.json | 42 + catalog-ui/build_catalog_ui.bat | 29 + catalog-ui/build_catalog_ui.sh | 84 + catalog-ui/configurations/MenuReadMe.txt | 60 + catalog-ui/configurations/dev.json | 430 + catalog-ui/configurations/menu.json | 576 + catalog-ui/configurations/mock.json | 192 + catalog-ui/configurations/prod.json | 432 + catalog-ui/docs/colors.jpg | Bin 0 -> 80399 bytes .../CytoscapeEdgeEditation.js | 554 + .../cytoscape.js-edge-editation/README.md | 58 + .../cytoscape.js-edge-editation/index.html | 169 + catalog-ui/package.json | 67 + catalog-ui/pom.xml | 231 + .../mock-data/artifact/artifact-types.json | 23 + .../server-mock/mock-data/category/category.json | 65 + .../server-mock/mock-data/element/element.json | 2915 +++ .../server-mock/mock-data/resource/properties.json | 35 + .../server-mock/mock-data/resource/resource.json | 153 + .../mock-data/resources/resourcesAbstract.json | 284 + .../mock-data/resources/resourcesNotAbstract.json | 510 + .../server-mock/mock-data/template/template.json | 37 + catalog-ui/server-mock/mock-data/user/user.json | 7 + catalog-ui/server-mock/mock-server.js | 140 + catalog-ui/server-mock/routes/property.js | 45 + catalog-ui/server-mock/routes/resource.js | 60 + catalog-ui/server-mock/routes/resources.js | 38 + catalog-ui/server-mock/routes/template.js | 45 + catalog-ui/server-mock/routes/user.js | 45 + catalog-ui/tests/karma.unit.conf.js | 149 + catalog-ui/tsd.json | 15 + catalog-ui/tslint.json | 58 + .../angular-ui-bootstrap/angular-ui-bootstrap.d.ts | 658 + .../angular-ui-router/angular-ui-router.d.ts | 207 + catalog-ui/typings/angularjs/angular-mocks.d.ts | 337 + catalog-ui/typings/angularjs/angular-resource.d.ts | 183 + catalog-ui/typings/angularjs/angular.d.ts | 1613 ++ catalog-ui/typings/angularjs/restangular.d.ts | 156 + .../typings/cytoscape/cytoscape-extension.js | 1 + .../typings/cytoscape/cytoscape-extension.js.map | 1 + .../typings/cytoscape/cytoscape-extension.ts | 40 + catalog-ui/typings/cytoscape/cytoscape.d.ts | 3095 +++ catalog-ui/typings/cytoscape/edge-editation.d.ts | 28 + catalog-ui/typings/d3/d3.d.ts | 3308 +++ catalog-ui/typings/jasmine/jasmine.d.ts | 515 + catalog-ui/typings/jquery/jquery.d.ts | 3181 +++ catalog-ui/typings/jsMd5/md5.d.ts | 55 + catalog-ui/typings/lodash/lodash.d.ts | 22949 +++++++++++++++++++ catalog-ui/typings/notifyjs/notifyjs.d.ts | 125 + catalog-ui/typings/tsd.d.ts | 21 + common-app-api/.gitignore | 2 + common-app-api/pom.xml | 209 + .../sdc/be/config/BeEcompErrorManager.java | 431 + .../be/config/CleanComponentsConfiguration.java | 46 + .../org/openecomp/sdc/be/config/Configuration.java | 1233 + .../sdc/be/config/ConfigurationManager.java | 154 + .../be/config/DistributionEngineConfiguration.java | 430 + .../sdc/be/config/ErrorConfiguration.java | 54 + .../org/openecomp/sdc/be/config/ErrorInfo.java | 102 + .../sdc/be/config/Neo4jErrorsConfiguration.java | 47 + .../DeploymentArtifactHeatConfiguration.java | 57 + .../sdc/be/monitoring/BeMonitoringService.java | 140 + .../sdc/common/api/ApplicationErrorCodesEnum.java | 37 + .../sdc/common/api/ArtifactGroupTypeEnum.java | 66 + .../openecomp/sdc/common/api/ArtifactTypeEnum.java | 81 + .../sdc/common/api/BasicConfiguration.java | 25 + .../sdc/common/api/ConfigurationListener.java | 50 + .../sdc/common/api/ConfigurationSource.java | 28 + .../org/openecomp/sdc/common/api/Constants.java | 126 + .../sdc/common/api/FileChangeCallback.java | 27 + .../openecomp/sdc/common/api/HealthCheckInfo.java | 76 + .../sdc/common/api/HealthCheckWrapper.java | 62 + .../org/openecomp/sdc/common/api/ResourceType.java | 25 + .../org/openecomp/sdc/common/api/ResponseInfo.java | 84 + .../sdc/common/api/ToscaNodeTypeInfo.java | 79 + .../sdc/common/api/ToscaNodeTypeInterface.java | 37 + .../sdc/common/api/UploadArtifactInfo.java | 147 + .../org/openecomp/sdc/common/api/UserRoleEnum.java | 41 + .../openecomp/sdc/common/api/YamlConstants.java | 29 + .../openecomp/sdc/common/api/YamlSuffixEnum.java | 60 + .../sdc/common/config/AbsEcompErrorManager.java | 121 + .../sdc/common/config/EcompClassification.java | 41 + .../sdc/common/config/EcompErrorCode.java | 155 + .../sdc/common/config/EcompErrorConfiguration.java | 161 + .../sdc/common/config/EcompErrorEnum.java | 484 + .../sdc/common/config/EcompErrorInfo.java | 78 + .../sdc/common/config/EcompErrorLogUtil.java | 199 + .../sdc/common/config/EcompErrorName.java | 41 + .../common/config/IEcompConfigurationManager.java | 25 + .../sdc/common/config/IEcompErrorManager.java | 27 + .../config/generation/GenerateEcompErrorsCsv.java | 242 + .../datastructure/AuditingFieldsKeysEnum.java | 103 + .../sdc/common/datastructure/CapList.java | 324 + .../sdc/common/datastructure/ESTimeBasedEvent.java | 125 + .../common/datastructure/FunctionalInterfaces.java | 282 + .../datastructure/MonitoringFieldsKeysEnum.java | 57 + .../sdc/common/datastructure/Wrapper.java | 52 + .../sdc/common/impl/ConfigFileChangeListener.java | 148 + .../sdc/common/impl/ExternalConfiguration.java | 106 + .../sdc/common/impl/FSConfigurationSource.java | 121 + .../sdc/common/impl/MutableHttpServletRequest.java | 73 + .../openecomp/sdc/common/kpi/api/ASDCKpiApi.java | 67 + .../sdc/common/listener/AppContextListener.java | 129 + .../sdc/common/monitoring/MonitoringEvent.java | 126 + .../monitoring/MonitoringMetricsFetcher.java | 212 + .../openecomp/sdc/common/rest/api/IRestClient.java | 103 + .../common/rest/api/RestClientServiceExeption.java | 78 + .../sdc/common/rest/api/RestConfigurationInfo.java | 107 + .../sdc/common/rest/api/RestResponse.java | 108 + .../common/rest/api/RestResponseAsByteArray.java | 133 + .../rest/impl/HttpRestClientServiceImpl.java | 436 + .../common/rest/impl/RestClientServiceFactory.java | 48 + .../impl/validator/RequestHeadersValidator.java | 95 + .../validator/RestRequestValidationException.java | 34 + .../sdc/common/servlets/BasicServlet.java | 30 + .../sdc/common/util/CapabilityTypeNameEnum.java | 46 + .../openecomp/sdc/common/util/GeneralUtility.java | 150 + .../org/openecomp/sdc/common/util/GsonFactory.java | 40 + .../org/openecomp/sdc/common/util/HtmlCleaner.java | 112 + .../org/openecomp/sdc/common/util/HttpUtil.java | 81 + .../org/openecomp/sdc/common/util/JsonUtils.java | 45 + .../common/util/MethodActivationStatusEnum.java | 25 + .../sdc/common/util/SerializationUtils.java | 87 + .../org/openecomp/sdc/common/util/StreamUtils.java | 136 + .../sdc/common/util/ThreadLocalsHolder.java | 63 + .../openecomp/sdc/common/util/ValidationUtils.java | 498 + .../sdc/common/util/YamlToObjectConverter.java | 275 + .../org/openecomp/sdc/common/util/ZipUtil.java | 178 + .../sdc/exception/AbstractSdncException.java | 116 + .../sdc/exception/AlreadyExistException.java | 41 + .../DeleteLastApplicationEnvironmentException.java | 34 + .../exception/DeleteReferencedObjectException.java | 35 + .../sdc/exception/FunctionalException.java | 41 + .../sdc/exception/IndexingServiceException.java | 39 + .../sdc/exception/InvalidArgumentException.java | 33 + .../openecomp/sdc/exception/NotFoundException.java | 35 + .../openecomp/sdc/exception/OkResponseInfo.java | 28 + .../openecomp/sdc/exception/PolicyException.java | 31 + .../openecomp/sdc/exception/ResponseFormat.java | 191 + .../openecomp/sdc/exception/ServiceException.java | 32 + .../sdc/exception/TechnicalException.java | 40 + .../sdc/exception/VersionConflictException.java | 33 + .../org/openecomp/sdc/fe/config/Configuration.java | 304 + .../sdc/fe/config/ConfigurationManager.java | 117 + .../org/openecomp/sdc/fe/config/Connection.java | 48 + .../sdc/fe/config/FeEcompErrorManager.java | 77 + .../sdc/fe/monitoring/FeMonitoringService.java | 140 + .../sdc/common/data_structure/CapListTest.java | 126 + .../openecomp/sdc/common/test/CommonUtilsTest.java | 549 + .../sdc/common/test/TestExternalConfiguration.java | 258 + .../org/openecomp/sdc/common/test/YamlTest.java | 61 + .../sdc/common/test/config/TestConfiguration.java | 149 + .../sdc/common/test/config/TestConnection.java | 48 + .../test/config/TestNotExistConfiguration.java | 47 + .../sdc/common/util/StreamUtilsTests.java | 143 + .../common/distribution-engine-configuration.yaml | 35 + .../config/common/test-configuration.yaml | 35 + common-app-api/src/test/resources/logback-test.xml | 13 + common-be/.gitignore | 1 + common-be/pom.xml | 116 + .../datatypes/category/CategoryDataDefinition.java | 130 + .../datatypes/category/GroupingDataDefinition.java | 112 + .../category/SubCategoryDataDefinition.java | 128 + .../ComponentMetadataDataDefinition.java | 429 + .../components/ResourceMetadataDataDefinition.java | 176 + .../components/ServiceMetadataDataDefinition.java | 87 + .../AdditionalInfoParameterDataDefinition.java | 89 + .../datatypes/elements/ArtifactDataDefinition.java | 587 + .../elements/AttributeDataDefinition.java | 186 + .../elements/CapabilityTypeDataDefinition.java | 128 + .../elements/ComponentInstanceDataDefinition.java | 187 + .../datatypes/elements/ConsumerDataDefinition.java | 204 + .../datatypes/elements/DataTypeDataDefinition.java | 119 + .../be/datatypes/elements/GroupDataDefinition.java | 142 + .../elements/GroupTypeDataDefinition.java | 163 + .../elements/HeatParameterDataDefinition.java | 162 + .../elements/InputsValueDataDefinition.java | 63 + .../elements/InterfaceDataDefinition.java | 109 + .../elements/OperationDataDefinition.java | 96 + .../elements/PolicyTypeDataDefinition.java | 163 + .../elements/ProductMetadataDataDefinition.java | 126 + .../datatypes/elements/PropertyDataDefinition.java | 195 + .../sdc/be/datatypes/elements/PropertyRule.java | 136 + .../elements/RelationshipTypeDataDefinition.java | 128 + .../be/datatypes/elements/SchemaDefinition.java | 139 + .../sdc/be/datatypes/enums/AssetTypeEnum.java | 53 + .../sdc/be/datatypes/enums/ComponentTypeEnum.java | 104 + .../sdc/be/datatypes/enums/FilterKeyEnum.java | 55 + .../sdc/be/datatypes/enums/GroupTypeEnum.java | 35 + .../sdc/be/datatypes/enums/NodeTypeEnum.java | 92 + .../sdc/be/datatypes/enums/OriginTypeEnum.java | 69 + .../sdc/be/datatypes/enums/ResourceTypeEnum.java | 49 + .../org/openecomp/sdc/be/utils/CommonBeUtils.java | 61 + .../java/org/openecomp/sdc/be/workers/Job.java | 29 + .../java/org/openecomp/sdc/be/workers/Main.java | 50 + .../java/org/openecomp/sdc/be/workers/Manager.java | 85 + .../java/org/openecomp/sdc/be/workers/Worker.java | 70 + .../openecomp/sdc/be/utils/CommonBeUtilsTest.java | 42 + distribution-ci/.gitignore | 1 + distribution-ci/etc/asdc-client.jks | Bin 0 -> 1177 bytes distribution-ci/etc/asdcclientstore.jks | Bin 0 -> 907 bytes distribution-ci/log4j.properties | 17 + distribution-ci/pom.xml | 64 + .../src/main/java/org/openecomp/test/BaseInit.java | 122 + .../main/java/org/openecomp/test/CallableTask.java | 57 + .../main/java/org/openecomp/test/ClientTest.java | 33 + .../src/main/java/org/openecomp/test/E2eFlows.java | 108 + .../org/openecomp/test/NotificationCallback.java | 19 + .../java/org/openecomp/test/SimpleCallback.java | 275 + .../org/openecomp/test/SimpleConfiguration.java | 149 + .../src/main/resources/ci/conf/log4j.properties | 34 + .../src/main/resources/ci/conf/sdc-packages.yaml | 10 + .../src/main/resources/ci/conf/sdc.yaml | 35 + .../src/main/resources/ci/conf/titan.properties | 5 + .../src/main/resources/ci/scripts/startTest.sh | 87 + .../ClientDownloadArtifact.java | 491 + pom.xml | 833 + sdc-os-chef/docker-compose.yml | 156 + sdc-os-chef/environments/Template.json | 75 + sdc-os-chef/pom.xml | 46 + sdc-os-chef/scripts/docker_clean.sh | 6 + sdc-os-chef/scripts/docker_health.sh | 22 + sdc-os-chef/scripts/docker_login.sh | 8 + sdc-os-chef/scripts/docker_run.sh | 128 + sdc-os-chef/scripts/docker_stats.sh | 36 + sdc-os-chef/scripts/docker_watchdog.sh | 43 + sdc-os-chef/scripts/restart_docker.sh | 97 + sdc-os-chef/sdc-backend/Dockerfile.template | 30 + .../cookbooks/sdc-catalog-be/attributes/default.rb | 1 + .../default/BE-ecomp-error-configuration.yaml | 383 + .../files/default/BE-error-configuration.yaml | 1694 ++ .../sdc-catalog-be/files/default/BE-logback.xml | 227 + .../sdc-catalog-be/files/default/consumers.py | 89 + .../cookbooks/sdc-catalog-be/files/default/user.py | 92 + .../recipes/BE_1_cleanup_jettydir.rb | 49 + .../sdc-catalog-be/recipes/BE_2_locate_wars.rb | 26 + .../recipes/BE_3_create_DMaaP_keys.rb | 34 + .../recipes/BE_4_setup_configuration.rb | 43 + .../recipes/BE_5_setup_elasticsearch.rb | 15 + .../recipes/BE_6_setup_portal_properties.rb | 17 + .../sdc-catalog-be/recipes/BE_7_logback.rb | 7 + .../sdc-catalog-be/recipes/BE_8_errors_config.rb | 14 + .../recipes/BE_9_import_Normatives.rb | 16 + .../templates/default/BE-configuration.yaml.erb | 459 + .../BE-distribution-engine-configuration.yaml.erb | 44 + .../templates/default/BE-elasticsearch.yml.erb | 11 + .../templates/default/BE-portal.properties.erb | 32 + .../templates/default/BE-titan.properties.erb | 24 + .../cookbooks/sdc-normatives/attributes/default.rb | 1 + .../files/default/check_Backend_Health.py | 51 + .../sdc-normatives/files/default/get-pip.py | 17760 ++++++++++++++ .../sdc-normatives/files/default/normatives.tar.gz | Bin 0 -> 49376 bytes .../sdc-normatives/recipes/check_Backend.rb | 19 + .../sdc-normatives/recipes/import_Normatives.rb | 16 + .../sdc-normatives/recipes/upgrade_Normatives.rb | 17 + sdc-os-chef/sdc-backend/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-backend/chef-solo/README.md | 37 + sdc-os-chef/sdc-backend/chef-solo/chefignore | 11 + .../sdc-backend/chef-solo/cookbooks/README.md | 54 + .../sdc-backend/chef-solo/data_bags/README.md | 63 + .../sdc-backend/chef-solo/environments/README.md | 5 + sdc-os-chef/sdc-backend/chef-solo/normatives.json | 4 + sdc-os-chef/sdc-backend/chef-solo/normatives.rb | 16 + sdc-os-chef/sdc-backend/chef-solo/roles/README.md | 16 + .../sdc-backend/chef-solo/roles/catalog-be.json | 24 + sdc-os-chef/sdc-backend/chef-solo/solo.json | 4 + sdc-os-chef/sdc-backend/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-backend/startup.sh | 40 + sdc-os-chef/sdc-cassandra/Dockerfile | 22 + .../recipes/01-configureCassandra.rb | 49 + .../cassandra-actions/recipes/02-createCsUser.rb | 8 + .../recipes/03-createDoxKeyspace.rb | 8 + .../cassandra-actions/recipes/04-schemaCreation.rb | 35 + .../default/cassandra-rackdc.properties.erb | 27 + .../templates/default/cassandra.yaml.erb | 824 + .../templates/default/configuration.yaml.erb | 459 + .../templates/default/create_cassandra_user.sh.erb | 57 + .../templates/default/create_dox_keyspace.sh.erb | 77 + .../templates/default/elasticsearch.yml.erb | 11 + sdc-os-chef/sdc-cassandra/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-cassandra/chef-solo/README.md | 37 + sdc-os-chef/sdc-cassandra/chef-solo/chefignore | 11 + .../sdc-cassandra/chef-solo/cookbooks/README.md | 54 + .../sdc-cassandra/chef-solo/data_bags/README.md | 63 + .../sdc-cassandra/chef-solo/environments/README.md | 5 + .../sdc-cassandra/chef-solo/roles/README.md | 16 + .../chef-solo/roles/cassandra-actions.json | 23 + sdc-os-chef/sdc-cassandra/chef-solo/solo.json | 6 + sdc-os-chef/sdc-cassandra/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-cassandra/startup.sh | 27 + sdc-os-chef/sdc-elasticsearch/Dockerfile | 21 + .../sdc-elasticsearch/attributes/default.rb | 1 + .../files/default/dashboard_BI-Dashboard.json | 13 + .../default/dashboard_Monitoring-Dashboared.json | 15 + .../sdc-elasticsearch/files/default/logging.yml | 23 + .../files/default/visualization_JVM-used-CPU.json | 10 + .../default/visualization_JVM-used-Memory.json | 10 + .../visualization_JVM-used-Threads-Num.json | 10 + ...ied-services-ampersand-resources-(per-day).json | 10 + ...ed-Resources-slash-Services-slash-Products.json | 10 + ...isualization_Show-all-distributed-services.json | 10 + .../files/default/visualization_host-used-CPU.json | 10 + .../visualization_host-used-Threads-Num.json | 10 + .../visualization_number-of-user-accesses.json | 10 + .../recipes/ES_1_setup_elasticsearch.rb | 16 + .../recipes/ES_2_setup_logging.rb | 6 + .../recipes/ES_3_create_audit_template.rb | 238 + .../recipes/ES_4_create_resources_template.rb | 37 + .../recipes/ES_5_create_monitoring_template.rb | 47 + .../ES_6_kibana_dashboard_virtualization.rb | 57 + .../templates/default/ES-elasticsearch.yml.erb | 16 + sdc-os-chef/sdc-elasticsearch/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-elasticsearch/chef-solo/README.md | 37 + sdc-os-chef/sdc-elasticsearch/chef-solo/chefignore | 11 + .../chef-solo/cookbooks/README.md | 54 + .../chef-solo/data_bags/README.md | 63 + .../chef-solo/environments/README.md | 5 + .../sdc-elasticsearch/chef-solo/roles/README.md | 16 + .../chef-solo/roles/elasticsearch.json | 19 + sdc-os-chef/sdc-elasticsearch/chef-solo/solo.json | 4 + sdc-os-chef/sdc-elasticsearch/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-elasticsearch/startup.sh | 19 + sdc-os-chef/sdc-frontend/Dockerfile.template | 26 + .../cookbooks/sdc-catalog-fe/attributes/default.rb | 2 + .../default/FE-ecomp-error-configuration.yaml | 48 + .../sdc-catalog-fe/files/default/FE-logback.xml | 227 + .../files/default/FE-rest-configuration.yaml | 11 + .../recipes/FE_1_cleanup_jettydir.rb | 49 + .../recipes/FE_2_setup_configuration.rb | 13 + .../sdc-catalog-fe/recipes/FE_3_errors_config.rb | 7 + .../sdc-catalog-fe/recipes/FE_4_logback.rb | 7 + .../recipes/FE_5_rest_configuration.rb | 7 + .../recipes/FE_6_create_jetty_modules.rb | 45 + .../templates/default/FE-configuration.yaml.erb | 79 + .../templates/default/FE-http-ini.erb | 32 + .../templates/default/FE-https-ini.erb | 15 + .../templates/default/FE-ssl-ini.erb | 83 + sdc-os-chef/sdc-frontend/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-frontend/chef-solo/README.md | 37 + sdc-os-chef/sdc-frontend/chef-solo/chefignore | 11 + .../sdc-frontend/chef-solo/cookbooks/README.md | 54 + .../sdc-frontend/chef-solo/data_bags/README.md | 63 + .../sdc-frontend/chef-solo/environments/README.md | 5 + sdc-os-chef/sdc-frontend/chef-solo/roles/README.md | 16 + .../sdc-frontend/chef-solo/roles/catalog-fe.json | 23 + sdc-os-chef/sdc-frontend/chef-solo/solo.json | 4 + sdc-os-chef/sdc-frontend/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-frontend/startup.sh | 12 + sdc-os-chef/sdc-kibana/Dockerfile | 18 + .../cookbooks/sdc-kibana/attributes/default.rb | 1 + .../cookbooks/sdc-kibana/recipes/setup_kibana.rb | 19 + .../sdc-kibana/templates/default/kibana.yml.erb | 74 + sdc-os-chef/sdc-kibana/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-kibana/chef-solo/README.md | 37 + sdc-os-chef/sdc-kibana/chef-solo/chefignore | 11 + .../sdc-kibana/chef-solo/cookbooks/README.md | 54 + .../sdc-kibana/chef-solo/data_bags/README.md | 63 + .../sdc-kibana/chef-solo/environments/README.md | 5 + sdc-os-chef/sdc-kibana/chef-solo/roles/README.md | 16 + sdc-os-chef/sdc-kibana/chef-solo/solo.json | 4 + sdc-os-chef/sdc-kibana/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-kibana/startup.sh | 7 + sdc-os-chef/sdc-sanity/Dockerfile | 20 + .../cookbooks/sdc-sanity/attributes/default.rb | 1 + .../cookbooks/sdc-sanity/recipes/setup_sanity.rb | 68 + .../templates/default/BE-titan.properties.erb | 24 + .../templates/default/sdc-sanity.yaml.erb | 82 + sdc-os-chef/sdc-sanity/chef-solo/LICENSE | 201 + sdc-os-chef/sdc-sanity/chef-solo/README.md | 37 + sdc-os-chef/sdc-sanity/chef-solo/chefignore | 11 + .../sdc-sanity/chef-solo/cookbooks/README.md | 54 + .../sdc-sanity/chef-solo/data_bags/README.md | 63 + .../sdc-sanity/chef-solo/environments/README.md | 5 + sdc-os-chef/sdc-sanity/chef-solo/roles/README.md | 16 + sdc-os-chef/sdc-sanity/chef-solo/solo.json | 4 + sdc-os-chef/sdc-sanity/chef-solo/solo.rb | 16 + sdc-os-chef/sdc-sanity/startup.sh | 17 + security-utils/.gitignore | 1 + security-utils/pom.xml | 22 + .../java/org/openecomp/sdc/security/Passwords.java | 163 + .../org/openecomp/sdc/security/PasswordTest.java | 49 + ui-ci-dev/.gitignore | 2 + ui-ci-dev/pom.xml | 255 + .../sdc/uici/scripts/CreateVfsFromOnboarding.java | 67 + .../sdc/uici/tests/datatypes/CanvasElement.java | 33 + .../sdc/uici/tests/datatypes/CanvasManager.java | 206 + .../sdc/uici/tests/datatypes/CleanTypeEnum.java | 28 + .../datatypes/CreateAndImportButtonsEnum.java | 7 + .../tests/datatypes/CreateAndUpdateStepsEnum.java | 25 + .../sdc/uici/tests/datatypes/DataTestIdEnum.java | 428 + .../sdc/uici/tests/datatypes/MenuOptionsEnum.java | 17 + .../sdc/uici/tests/datatypes/UserCredentials.java | 29 + .../sdc/uici/tests/execute/base/SetupCDTest.java | 408 + .../tests/execute/service/ServiceBasicTests.java | 147 + .../tests/execute/service/ServiceInputsTests.java | 124 + .../sdc/uici/tests/execute/vf/VfBasicTests.java | 234 + .../sdc/uici/tests/execute/vf/VfCanvasTests.java | 80 + .../uici/tests/execute/vf/VfDeploymentTests.java | 340 + .../uici/tests/execute/vf/VfOnboardingTests.java | 63 + .../sdc/uici/tests/execute/vfc/VfcBasicTests.java | 219 + .../openecomp/sdc/uici/tests/run/StartTest.java | 394 + .../sdc/uici/tests/utilities/ArtifactUIUtils.java | 70 + .../sdc/uici/tests/utilities/FileHandling.java | 30 + .../sdc/uici/tests/utilities/GeneralUIUtils.java | 346 + .../tests/utilities/MethodManipulationUtils.java | 15 + .../sdc/uici/tests/utilities/OnboardUtility.java | 477 + .../sdc/uici/tests/utilities/ResourceUIUtils.java | 299 + .../sdc/uici/tests/utilities/RestCDUtils.java | 167 + .../sdc/uici/tests/utilities/ServiceUIUtils.java | 147 + .../uici/tests/verificator/ServiceVerificator.java | 55 + .../uici/tests/verificator/VerificatorUtil.java | 27 + .../sdc/uici/tests/verificator/VfVerificator.java | 143 + ui-ci-dev/src/main/resources/Files/CP.yml | 65 + .../src/main/resources/Files/CP_LAN - Copy.yml | 13 + ui-ci-dev/src/main/resources/Files/CP_LAN.yml | 19 + ui-ci-dev/src/main/resources/Files/CP_WAN.yml | 19 + .../src/main/resources/Files/Heat-File 1.yaml | 791 + .../src/main/resources/Files/Heat-File 2.yaml | 791 + ui-ci-dev/src/main/resources/Files/Heat-File.yaml | 791 + .../main/resources/Files/InValid_tosca_File .yml | 34 + ui-ci-dev/src/main/resources/Files/JDM_vf.yml | 57 + ui-ci-dev/src/main/resources/Files/JDM_vfc.yml | 57 + .../src/main/resources/Files/Sample_CSAR.csar | Bin 0 -> 1094 bytes .../src/main/resources/Files/Sample_CSAR2.csar | Bin 0 -> 1085 bytes ui-ci-dev/src/main/resources/Files/UCPE_VFC.yml | 65 + ui-ci-dev/src/main/resources/Files/VF.yml | 17 + ui-ci-dev/src/main/resources/Files/VFC.yml | 77 + .../src/main/resources/Files/VFCWithAttributes.yml | 43 + ui-ci-dev/src/main/resources/Files/VL.yml | 17 + ui-ci-dev/src/main/resources/Files/Valid xml.xml | 4 + .../main/resources/Files/Valid_tosca_Mycompute.yml | 35 + .../resources/Files/Valid_tosca_ReplaceTest.yml | 35 + .../Files/hot-nimbus-oam-volumes_v0.3.env | 6 + .../main/resources/Files/hot-nimbus-oam_v0.6.env | 18 + .../main/resources/Files/hot-nimbus-oam_v0.6.yaml | 108 + .../main/resources/Files/hot-nimbus-pcm_v0.6.yaml | 80 + ui-ci-dev/src/main/resources/Files/myYang.xml | 8 + ui-ci-dev/src/main/resources/Files/mycompute.yml | 18 + .../main/resources/Files/service_with_inputs.csar | Bin 0 -> 35388 bytes ui-ci-dev/src/main/resources/Files/vADTRAN.zip | Bin 0 -> 2499 bytes ui-ci-dev/src/main/resources/Files/vCDN.zip | Bin 0 -> 4547 bytes ui-ci-dev/src/main/resources/Files/vFW_VF.yml | 58 + ui-ci-dev/src/main/resources/Files/vFW_VFC.yml | 58 + ui-ci-dev/src/main/resources/Files/vRouter_vfc.yml | 78 + .../main/resources/Files/valid HEAT_ENV files.env | 54 + .../src/main/resources/Files/validHEATfiles.yaml | 787 + ui-ci-dev/src/main/resources/Files/valid_vf.csar | Bin 0 -> 1316 bytes .../src/main/resources/Files/vf_with_groups.csar | Bin 0 -> 25253 bytes ui-ci-dev/src/main/resources/Files/yamlSample.yml | 5 + ui-ci-dev/src/main/resources/Files/yamlSample2.yml | 5 + .../src/main/resources/ci/conf/credentials.yaml | 48 + .../src/main/resources/ci/conf/log4j.properties | 34 + .../src/main/resources/ci/conf/sdc-packages.yaml | 2 + ui-ci-dev/src/main/resources/ci/conf/sdc.yaml | 80 + .../src/main/resources/ci/conf/titan.properties | 7 + .../src/main/resources/ci/scripts/startTest.sh | 123 + .../src/main/resources/ci/testSuites/fullTests.xml | 26 + .../src/main/resources/ci/testSuites/sanity.xml | 55 + ui-ci-dev/src/main/resources/images/gizmorambo.jpg | Bin 0 -> 16605 bytes ui-ci-dev/src/test/Completetheform.js | 3 + ui-ci-dev/tarball.xml | 66 + ui-ci/.gitignore | 3 + ui-ci/pom.xml | 260 + .../sdc/ci/tests/datatypes/ArtifactInfo.java | 85 + .../ci/tests/datatypes/BreadCrumbsButtonsEnum.java | 38 + .../sdc/ci/tests/datatypes/CanvasElement.java | 65 + .../sdc/ci/tests/datatypes/CanvasManager.java | 250 + .../tests/datatypes/CatalogFilterTitlesEnum.java | 37 + .../sdc/ci/tests/datatypes/CheckBoxStatusEnum.java | 50 + .../datatypes/CreateAndImportButtonsEnum.java | 27 + .../tests/datatypes/CreateAndUpdateStepsEnum.java | 45 + .../sdc/ci/tests/datatypes/DataTestIdEnum.java | 380 + .../ci/tests/datatypes/GeneralCanvasItemsEnum.java | 39 + .../sdc/ci/tests/datatypes/LifeCycleStateEnum.java | 46 + .../sdc/ci/tests/datatypes/MenuOptionsEnum.java | 45 + .../sdc/ci/tests/datatypes/PropertyInfo.java | 76 + .../datatypes/ResourceCategoriesNameEnum.java | 63 + .../tests/datatypes/ServiceCategoriesNameEnum.java | 39 + .../sdc/ci/tests/datatypes/TypesEnum.java | 43 + .../sdc/ci/tests/datatypes/UserCredentials.java | 57 + .../openecomp/sdc/ci/tests/datatypes/WorkMode.java | 25 + .../sdc/ci/tests/datatypes/environmentLocal | 10 + .../execute/adminworkspace/AdminUserManagment.java | 141 + .../CatalogLeftFilterPanelCheckBoxTest.java | 272 + .../execute/resourceui/CatalogSearchBoxTest.java | 130 + .../ChangeLifeCycleStatFromCatalogTest.java | 103 + .../execute/resourceui/ImportAssetInUITest.java | 480 + .../ci/tests/execute/resourceui/VFCanvasTest.java | 91 + .../sdc/ci/tests/execute/resourceui/VFUITest.java | 37 + .../sdc/ci/tests/execute/resourceui/VfTests.java | 33 + .../resourceui/WorkspaceCheckBoxFilterTest.java | 120 + .../sdc/ci/tests/execute/sanity/Import.java | 177 + .../sdc/ci/tests/execute/sanity/Onboard.java | 222 + .../openecomp/sdc/ci/tests/execute/sanity/Vf.java | 377 + .../ci/tests/execute/setup/OnboardCSVReport.java | 63 + .../tests/execute/setup/RemoteWebDriverTest.java | 45 + .../sdc/ci/tests/execute/setup/SetupCDTest.java | 538 + .../sdc/ci/tests/pages/ComponentLeftMenu.java | 25 + .../sdc/ci/tests/pages/CompositionPage.java | 56 + .../sdc/ci/tests/pages/DeploymentArtifactPage.java | 91 + .../sdc/ci/tests/pages/GeneralPageElements.java | 139 + .../sdc/ci/tests/pages/GovernorOperationPage.java | 46 + .../org/openecomp/sdc/ci/tests/pages/IconPage.java | 51 + .../ci/tests/pages/InformationalArtifactPage.java | 57 + .../sdc/ci/tests/pages/OpsOperationPage.java | 183 + .../sdc/ci/tests/pages/PropertiesPage.java | 61 + .../sdc/ci/tests/pages/PropertyPopup.java | 77 + .../sdc/ci/tests/pages/ResourceGeneralPage.java | 154 + .../sdc/ci/tests/pages/ResourceLeftMenu.java | 63 + .../sdc/ci/tests/pages/ServiceGeneralPage.java | 47 + .../sdc/ci/tests/pages/TesterOperationPage.java | 71 + .../sdc/ci/tests/pages/ToscaArtifactsPage.java | 35 + .../sdc/ci/tests/pages/UploadArtifactPopup.java | 76 + .../ci/tests/utilities/AdditionalConditions.java | 84 + .../tests/utilities/AdminWorkspaceUIUtilies.java | 71 + .../sdc/ci/tests/utilities/ArtifactUIUtils.java | 302 + .../sdc/ci/tests/utilities/AuditCDUtils.java | 67 + .../sdc/ci/tests/utilities/CanvasElement.java | 54 + .../sdc/ci/tests/utilities/CanvasManager.java | 181 + .../sdc/ci/tests/utilities/CaptureFailedTests.java | 54 + .../sdc/ci/tests/utilities/CatalogUIUtilitis.java | 148 + .../sdc/ci/tests/utilities/FileHandling.java | 88 + .../sdc/ci/tests/utilities/GeneralUIUtils.java | 1081 + .../sdc/ci/tests/utilities/ImportAssetUIUtils.java | 50 + .../sdc/ci/tests/utilities/OnboardingUtils.java | 457 + .../sdc/ci/tests/utilities/PropertiesUIUtils.java | 92 + .../sdc/ci/tests/utilities/ResourceUIUtils.java | 864 + .../sdc/ci/tests/utilities/RestCDUtils.java | 182 + .../sdc/ci/tests/utilities/ServiceUIUtils.java | 241 + .../ci/tests/verificator/ServiceVerificator.java | 60 + .../sdc/ci/tests/verificator/VfVerificator.java | 93 + ui-ci/src/main/resources/Downloads/CP_WAN.yml | 23 + .../resources/Downloads/Fortigate02_vFW_VFC.yml | 63 + ui-ci/src/main/resources/Files/CP.yml | 65 + .../src/main/resources/Files/CPWithAttributes.yml | 78 + ui-ci/src/main/resources/Files/CP_LAN - Copy.yml | 12 + ui-ci/src/main/resources/Files/CP_LAN.yml | 19 + ui-ci/src/main/resources/Files/CP_WAN.yml | 19 + .../src/main/resources/Files/DNSscaling12.8.16.zip | Bin 0 -> 2868 bytes ui-ci/src/main/resources/Files/Heat-File 1.yaml | 791 + ui-ci/src/main/resources/Files/Heat-File 2.yaml | 791 + ui-ci/src/main/resources/Files/Heat-File.yaml | 791 + .../main/resources/Files/InValid_tosca_File .yml | 34 + ui-ci/src/main/resources/Files/JDM_vf.yml | 57 + ui-ci/src/main/resources/Files/JDM_vfc.yml | 57 + ui-ci/src/main/resources/Files/Sample_CSAR.csar | Bin 0 -> 1085 bytes ui-ci/src/main/resources/Files/UCPE_VFC.yml | 65 + ui-ci/src/main/resources/Files/VF.yml | 17 + ui-ci/src/main/resources/Files/VFC.yml | 77 + ui-ci/src/main/resources/Files/VL.yml | 18 + ui-ci/src/main/resources/Files/Valid xml.xml | 4 + .../main/resources/Files/Valid_tosca_Mycompute.yml | 35 + .../resources/Files/Valid_tosca_ReplaceTest.yml | 35 + ui-ci/src/main/resources/Files/asc_heat 0 2.yaml | 787 + .../Files/hot-nimbus-oam-volumes_v0.3.env | 6 + .../main/resources/Files/hot-nimbus-oam_v0.6.env | 18 + .../main/resources/Files/hot-nimbus-oam_v0.6.yaml | 108 + .../main/resources/Files/hot-nimbus-pcm_v0.6.yaml | 80 + .../resources/Files/sample-xml-alldata-1-1.xml | 298 + ui-ci/src/main/resources/Files/vFW_8.12.16.zip | Bin 0 -> 3650 bytes ui-ci/src/main/resources/Files/vFW_VF.yml | 58 + ui-ci/src/main/resources/Files/vFW_VFC.yml | 58 + ui-ci/src/main/resources/Files/vLB12.8.16.zip | Bin 0 -> 3484 bytes ui-ci/src/main/resources/Files/vRouter_vfc.yml | 78 + .../main/resources/Files/valid HEAT_ENV files.env | 54 + ui-ci/src/main/resources/Files/validHEATfiles.yaml | 787 + ui-ci/src/main/resources/ci/conf/credentials.yaml | 48 + ui-ci/src/main/resources/ci/conf/log4j.properties | 34 + ui-ci/src/main/resources/ci/conf/sdc-packages.yaml | 2 + ui-ci/src/main/resources/ci/conf/sdc.yaml | 57 + ui-ci/src/main/resources/ci/conf/titan.properties | 7 + ui-ci/src/main/resources/ci/scripts/startTest.sh | 96 + ui-ci/src/main/resources/ci/testSuites/ui-ci.xml | 16 + ui-ci/src/main/resources/images/gizmorambo.jpg | Bin 0 -> 16605 bytes ui-ci/src/test/Completetheform.js | 23 + ui-ci/tarball.xml | 60 + webseal-simulator/README.txt | 18 + webseal-simulator/pom.xml | 126 + .../org/openecomp/sdc/webseal/simulator/Login.java | 131 + .../sdc/webseal/simulator/MethodEnum.java | 10 + .../simulator/MutableHttpServletRequest.java | 55 + .../openecomp/sdc/webseal/simulator/SdcProxy.java | 318 + .../org/openecomp/sdc/webseal/simulator/User.java | 64 + .../openecomp/sdc/webseal/simulator/conf/Conf.java | 67 + webseal-simulator/src/main/resources/webseal.conf | 64 + .../src/main/webapp/WEB-INF/jetty-web.xml | 8 + webseal-simulator/src/main/webapp/WEB-INF/web.xml | 32 + webseal-simulator/src/main/webapp/login.html | 18 + 3438 files changed, 556530 insertions(+) create mode 100644 .gitignore create mode 100644 .gitreview create mode 100644 .pydevproject create mode 100644 LICENSE.TXT create mode 100644 README.md create mode 100644 asdc-tests/.gitignore create mode 100644 asdc-tests/pom.xml create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentInstanceBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/SdcTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/Config.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/InvokedMethodListener.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/AssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentInstanceReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/GroupHeatMetaDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ImportReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ProductReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyHeatMetaDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceDetailedAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceInstanceAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceRespJavaObject.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceDetailedAssetStructure.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceReqDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceRespJavaObject.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/TypeHeatMetaDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ArtifactTypeEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AssocType.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditJsonKeysEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ComponentType.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ErrorInfo.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/EsIndexTypeIdToDelete.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ExceptionEnumType.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ImportTestTypesEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/LifeCycleStatesEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryResourceArtifactTypeEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryServiceArtifactTypeEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/NormativeTypesEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/PropertyTypeEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ResourceCategoryEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/RespJsonKeysEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceApiArtifactEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceCategoriesEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ToscaKeysEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/UserRoleEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedArtifactAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedAuthenticationAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedCategoryAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedDistDownloadAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedEcomConsumerAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedExternalAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGetUserListAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGroupingAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedProductAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedResourceAuditJavaObject.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedUserCRUDAudit.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderData.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderValue.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpHeaderEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpRequest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/MustHeaders.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/RestResponse.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/TODO/ImportCapabilityTypeCITest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ArtifactServletTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/CrudArt.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/DownloadComponentArt.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/PlaceHolderValidations.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateArtResponse.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsFromUI.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsTypes.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/attribute/ComponentInstanceAttributeTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CatalogDataApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesTests.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/ElementsApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/GroupingTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/SubCategoriesTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/CRUDExternalAPI.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarUpdate.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarValidateArtifacts.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ToscaGroupInsideVF.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/AuthanticationTests.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/DistributionDownloadArtifactTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/externalapi/DownloadArtifactsTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/BasicHttpAuthenticationTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/FeProxyTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/ManageEcompConsumerCredentials.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/UuidTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/CsarUtilsTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ExportToscaTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportCsarResourceTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportGenericResourceCITest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportNewResourceCITest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaCapabilitiesWithProperties.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaResourceTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportUpdateResourseCsarTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/inputs/InputsApiTests.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/lifecycle/LCSbaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ChangeServiceInstanceVersionTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckinTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckoutTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductComponentInstanceCRUDTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCreateWithValidationsTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCrudTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductGetFollowedTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductLifecycleTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductTestBase.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductToscaYamlGenerationTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductUndoCheckoutTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/AdditionalInformationServletTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentInstancePropertyTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentProperty.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/PropertyApisTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CheckGetResource.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ComponentRelationshipInVfTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CreateResourceApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetAllResourceVersions.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetResourceNotAbstractApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ResourceApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SampleDataProvider.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SimultaneousApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/UpdateResourceMetadataTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VFResourceInstanceNameCRUD.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ValidateExtendedVfData.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VfComponentInstanceCRUDTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ChangeServiceDistributionStatusApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/CreateServiceMetadataApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetAllServiceVersions.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetComponentAuditApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetServiceLatestVersionTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ReqCapOccurrencesTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ServiceComponentInstanceCRUDTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/UpdateServiceMetadataTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/ActivateDeActivateDeleteUser.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/CreateUserApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/GovernorWorkspaceApiTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/executeOnUGN/distributionClient/ClientConfiguration.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/ComplexResourceBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/DownloadArtifactBaseTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/SimpleOneRsrcOneServiceTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/rules/MyTestWatcher.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/ExtentReporterNG.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest2backup.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/CrudE2E.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/MultipleResourceUpdate.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaCapabilitiesNodeTemplatesDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaGroupsTopologyTemplateDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaImportsDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaInputsTopologyTemplateDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTemplatesTopologyTemplateDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTypesDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaPropertiesNodeTemplatesDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaRequirementsNodeTemplatesDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaTopologyTemplateDefinition.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/AddUserAuditMessageInfo.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserAuditJavaObject.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserHeaderData.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserResponseMessageEnum.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/WebSealUserDetails.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ArtifactUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/DbUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Decoder.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ReqCap.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ToscaParserUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Utils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils2.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/AtomicOperationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/Convertor.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/FileUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ImportUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ArtifactRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/AssetRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/BaseRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CatalogRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CategoryRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentInstanceRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ConsumerRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/EcompUserRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/GroupRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ImportRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/InputsRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/LifecycleRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ProductRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/PropertyRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResourceRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResponseParser.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/UserRestUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ArtifactValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/AuditValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/BaseValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CategoryValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CsarValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ErrorValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ProductValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ResourceValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ServiceValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/UserValidationUtils.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/webSealAccess/NeoJavaObject.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetAssetServlet.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetFilteredAssetServlet.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetSpecificAssetMetadataServlet.java create mode 100644 asdc-tests/src/main/java/org/openecomp/sdc/post/Install.java create mode 100644 asdc-tests/src/main/resources/ci/conf/log4j.properties create mode 100644 asdc-tests/src/main/resources/ci/conf/sdc-packages.yaml create mode 100644 asdc-tests/src/main/resources/ci/conf/sdc.yaml create mode 100644 asdc-tests/src/main/resources/ci/conf/testngLifeCycle.xml create mode 100644 asdc-tests/src/main/resources/ci/conf/titan.properties create mode 100644 asdc-tests/src/main/resources/ci/conf/truststore create mode 100644 asdc-tests/src/main/resources/ci/scripts/startTest.sh create mode 100644 asdc-tests/src/main/resources/ci/testSuites/artifacts.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/category.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/ciFull.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/externalApis.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/general.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/imports.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/product.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/property.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/resource.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/sanity.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/service.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/testngLifeCycle.xml create mode 100644 asdc-tests/src/main/resources/ci/testSuites/user.xml create mode 100644 asdc-tests/src/test/resources/CI/components/apache/apache-type.yml create mode 100644 asdc-tests/src/test/resources/CI/components/apache/images/apache.png create mode 100644 asdc-tests/src/test/resources/CI/components/apache/scripts/install_apache.sh create mode 100644 asdc-tests/src/test/resources/CI/components/apache/scripts/start_apache.sh create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/images/relational_db.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/normative-types-DBMS.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/images/volume.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/normative-types-blockStorage.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/compute/images/compute.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/compute/normative-types-compute.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/database/images/relational_db.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/database/normative-types-database.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/network/images/network.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/network/normative-types-network.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/images/objectstore.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/normative-types-objectStorage.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/root/images/root.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/root/normative-types-root.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/images/software.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/normative-types-softwareComponent.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/images/network.png create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/normative-types-webApplication.yml create mode 100644 asdc-tests/src/test/resources/CI/components/normativeTypes/webServer/normative-types-webServer.yml create mode 100644 asdc-tests/src/test/resources/CI/configuration.yaml create mode 100644 asdc-tests/src/test/resources/CI/csars/FCGI_with_inputs.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/LDSA1_with_inputs.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_a.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_b.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_a.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_add_update.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_delete_update.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_update.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/jsonPropertyTypeTest.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/mycompute.yml create mode 100644 asdc-tests/src/test/resources/CI/csars/mycompute2.yml create mode 100644 asdc-tests/src/test/resources/CI/csars/mycompute_failed.yml create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2G.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2GV001.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2GV001_a.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2GV006-remove-all-nested-artifacts.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2GV008-change-nested-oam-fileContent.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2G_a.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/orig2G_updated.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf_a.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf_b.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf_c.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf_d.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/valid_vf_f.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vf_relate_by_cap_name.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1_failed.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop_failed.csar create mode 100644 asdc-tests/src/test/resources/CI/csars/vmmc_relate_by_cap_name.csar create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/deleteResourcesLanWanDemo.sh create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/importResourcesLanWanDemo.sh create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.zip create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.json create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.yml create mode 100644 asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.zip create mode 100644 asdc-tests/src/test/resources/CI/error-configuration.yaml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml.old create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml.old create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml.old create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/compute/compute.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/compute/compute.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/compute/compute.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/deleteResourcesDemo.sh create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/importResourcesDemo.sh create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/root/root.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/root/root.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/root/root.zip create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.json create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.yml create mode 100644 asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.capabilities.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/capabilityTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/deleteNormative.sh create mode 100644 asdc-tests/src/test/resources/CI/importResource-MMSC/importNormative.sh create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/VCE_Brocade_Tosca.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/capabilityTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/importVceBrocade.sh create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.json create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/vce.brocade.capabilities.yaml create mode 100644 asdc-tests/src/test/resources/CI/importResource/DBMS/DBMS.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/blockStorage/blockStorage.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/capabilityTypes.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/capabilityTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/capabilityTypesCi.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/categoryTypes.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/categoryTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/compute/compute.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerApplication/containerApplication.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerRuntime/containerRuntime.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/database/database.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/deleteNormative.sh create mode 100644 asdc-tests/src/test/resources/CI/importResource/importNormative.sh create mode 100644 asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/loadBalancer/loadBalancer.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/network/network.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/normative-port/port.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/notmative-network/network.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/objectStorage/objectStorage.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/port/port.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/root/root.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/softwareComponent/softwareComponent.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/webApplication/webApplication.json create mode 100644 asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.yml create mode 100644 asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.zip create mode 100644 asdc-tests/src/test/resources/CI/importResource/webServer/webServer.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/VSPPackage.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_1.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_2.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/csars.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/fiveLinesAsBlock0.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion2.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion3.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion4.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion5.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile1.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile2.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile3.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile4.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile5.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/missingEntryDefintionPair.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/missingOneLineInToscaMeta.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf2.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThanOneMetaFile.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThenOneYamlFile.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/noCSARVersion.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/noCreatedByValue.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/noEntryDefinitionsValue.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/noNewLineAfterBLock0.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/noTOSCAMetaFileVersionValue.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlAndMetaFiles.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlFile.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/someValueAfterBlock0.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaFolderNotExists.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaFileNotExists.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaOutsideTheFolder.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/underscoreInsteadOfDash.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/validCsarVersion.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf.csar create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf_zip.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_category/empty_category.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/empty_contact.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/empty_desc.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/empty_icon.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/empty_payloadName.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/empty_resource_name.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/empty_tag.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/import _multiple_tags.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/importResource4test.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/importResource4testCP.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/importResource4testMissingNameSpace.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/importResource4testUnknown.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/importResource4testUpdateVendorNameAndCategory.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/importResource4testUpdateWithoutReqCap.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/importResource4testVF.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/importResource4testVFC.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/importResource4testVL.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_MissingDerivedFrom.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_WithoutRoot.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_category/missing_category.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/missing_contact.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/missing_derived_from.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/missing_desc.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/missing_icon.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/missing_payloadName.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/missing_resource_name.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/missing_tags.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/myCompute/myCompute.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/portInvalidDefaultValue.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userCompute/userCompute.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/userUpdateCompute.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/validateProporties_happyScenarios.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/validateProporties_typeBoolean_valueInit.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/validateProporties_typeBoolean_valueString.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/validateProporties_typeFloat_valueBoolean.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/validateProporties_typeFloat_valueString.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/validateProporties_typeInit_valueBoolean.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/validateProporties_typeInit_valueFloat.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/validateProporties_typeInit_valueString.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/validateProporties_typeList_valueUrlCredential.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/validateProporties_typeMap_valueUrlCredential.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/normative-types-new-validateProporties_typeString_valueString_special_chars.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/validateProporties_typeString_valueString_special_chars.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/normative-types-new-validateProporties_typeString_valueString_trimming.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/validateProporties_typeString_valueString_trimming.json create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.yml create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.zip create mode 100644 asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/validateProporties_typeTestDataType.json create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.yml create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.zip create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.yml create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.zip create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.yml create mode 100644 asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.zip create mode 100644 asdc-tests/src/test/resources/CI/other/mapping.json create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/addYangXmlArtifactToResource.xml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.zip create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat_net 0 2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatEnvfile.env create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatInvalidFormat.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heat_mini.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidJson.json create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYamlFormat.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYangXml.xml create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/jsonArtifact.json create mode 100644 asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/other.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/bluePrintSampleArtifact.xml create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/docSampleArtifact.docx create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.emf create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.xml create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/eventSampleArtifact.xml create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/jsonSampleArtifact.json create mode 100644 asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/toscaSampleArtifact.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/addHeatArtifactToServiceAndSertify/asc_heat 0 2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/downloadResourceArtifactSuccess/org.openstack.Rally.zip create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactListNoContentTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataNoContentTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getResourceArtifactPayloadNoContentTest/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/install_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/start_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/install_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/start_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/install_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/start_mysql2.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDefault.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDesc.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingType.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithValidParams.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_1.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/heatEnv/yuli.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/BindingAsset.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap_DerivedFromMyCompute1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPWithAttributes.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_2.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_2.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromCPWithOwnReq.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromWebApplication_HasNoReqType.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentCapFromRoot.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqAndCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute2.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqFromCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/FatherHasNoReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure01.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure02.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure03.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure04.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure05.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure06.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure07.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure08.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure09.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure10.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure11.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure12.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure13.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure14.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure15.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure16.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure01.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure02.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure03.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure04.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure05.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure06.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure07.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure08.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure09.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure10.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure11.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure12.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure13.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure14.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure15.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure16.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MyFatherCompute_NoReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameCapAsCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute_DerivedFromMyCompute1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap11.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap1UNBOUNDED.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromMyCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromWebAppDerivedReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importAttributeSuccessFlow.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importCapabilityNameExistsOnParent.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateCapability.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateRequirements.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyBadDefault.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyGoodDefault.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertySuccessFlow.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importMapPropertySuccessFlow.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent_DerivedFromMyCompute1.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInCapDefinition.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInReqDefinition.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildCompute_NoReqCap.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildWebApp_DerivedFromContainer.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myCompute.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeDerivedFromNotExists.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectDefenitionVersionValue.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectNameSpaceFormat.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeNoDefenitionVersion.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeOccurencySuccess.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeParssingFalure.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeReqNameExistsOnDerived.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeVF.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithNodeTypesTwice.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithTopologyTemplate.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myFatherWebApp_derviedFromDocker.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myLinkVL.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myPortCP.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/noContent.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure01.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure02.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure03.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure04.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure05.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure06.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure07.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure08.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure09.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure10.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure11.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure31.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure32.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure33.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure34.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure35.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure36.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure37.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure38.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure39.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure40.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure41.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq11.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq12.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/testCsarAPI/topology.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/testCsarAPI/topologyTemplate.txt create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool10_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool11_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool12_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool1_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool2_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool3_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool4_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool5_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool6_true.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool7_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool8_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool9_false.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number1.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/uploadComponent/images/mysql.png create mode 100644 asdc-tests/src/test/resources/CI/tests/uploadComponent/mysql.yml create mode 100644 asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/install_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/start_mysql.sh create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/artifact_unsupported.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool1.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number1.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number2.yaml create mode 100644 asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_string1.yaml create mode 100644 asdc-tests/src/test/resources/config.json create mode 100644 asdc-tests/src/test/resources/logback-test.xml create mode 100644 asdc-tests/tarball.xml create mode 100644 asdc-tests/testng.xml create mode 100644 asdc-tests/testngLifeCycle.xml create mode 100644 asdctool/.gitignore create mode 100644 asdctool/.pydevproject create mode 100644 asdctool/pom.xml create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/Utils.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/DataMigration.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/EsToCassandraDataMigrationConfig.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLConverter.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/PopulateComponentCache.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/ProductLogic.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/RestUtils.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/UpdatePropertyOnVertex.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AddGroupUuid.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AllowMultipleHeats.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AppConfig.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/DerivedFromAlignment.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/GroupsAlignment.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationCategory.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationSubCategory.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/VfcNamingAlignment.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1607/CsarMigration.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/TitanFixUtils.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/ToscaArtifactsAlignment.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/DataSchemaMenu.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/EsToCassandraDataMigrationMenu.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/ExportImportMenu.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/RemoveUtils.java create mode 100644 asdctool/src/main/java/org/openecomp/sdc/asdctool/main/UpdateIsVnfMenu.java create mode 100644 asdctool/src/main/resources/application-context.xml create mode 100644 asdctool/src/main/resources/config/categoryMigration.yaml create mode 100644 asdctool/src/main/resources/config/configuration.yaml create mode 100644 asdctool/src/main/resources/config/elasticsearch.yml create mode 100644 asdctool/src/main/resources/config/error-configuration.yaml create mode 100644 asdctool/src/main/resources/config/logback.xml create mode 100644 asdctool/src/main/resources/config/titan.properties create mode 100644 asdctool/src/main/resources/es-resources/README.txt create mode 100644 asdctool/src/main/resources/es-resources/auditMappings.txt create mode 100644 asdctool/src/main/resources/es-resources/audit_migration_1602.py create mode 100644 asdctool/src/main/resources/es-resources/config_properties.py create mode 100644 asdctool/src/main/resources/es-resources/file_utils.py create mode 100644 asdctool/src/main/resources/es-resources/get-pip.py create mode 100644 asdctool/src/main/resources/es-resources/index_ops.py create mode 100644 asdctool/src/main/resources/es-resources/types/auditinggetuebclusterevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/distributiondeployevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/distributiondownloadevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/distributionengineevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/distributionnotificationevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/distributionstatusevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/resourceadminevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/useraccessevent.txt create mode 100644 asdctool/src/main/resources/es-resources/types/useradminevent.txt create mode 100644 asdctool/src/main/resources/scripts/baseOperation.sh create mode 100644 asdctool/src/main/resources/scripts/cleanCsar.sh create mode 100644 asdctool/src/main/resources/scripts/dataMigration.sh create mode 100644 asdctool/src/main/resources/scripts/dataMigration1607.sh create mode 100644 asdctool/src/main/resources/scripts/dataMigration1610.sh create mode 100644 asdctool/src/main/resources/scripts/deleteAllProducts.sh create mode 100644 asdctool/src/main/resources/scripts/derivedFromAlignment.sh create mode 100644 asdctool/src/main/resources/scripts/esToCassandraMigration.sh create mode 100644 asdctool/src/main/resources/scripts/esToCassandraMigrationExportOnly.sh create mode 100644 asdctool/src/main/resources/scripts/esToCassandraMigrationImportOnly.sh create mode 100644 asdctool/src/main/resources/scripts/exportGraph.sh create mode 100644 asdctool/src/main/resources/scripts/exportGraphAsGraphMl.sh create mode 100644 asdctool/src/main/resources/scripts/exportUsers.sh create mode 100644 asdctool/src/main/resources/scripts/fix_icons.sh create mode 100644 asdctool/src/main/resources/scripts/fix_issue.sh create mode 100644 asdctool/src/main/resources/scripts/groupsAlignment.sh create mode 100644 asdctool/src/main/resources/scripts/importGraph.sh create mode 100644 asdctool/src/main/resources/scripts/populateComponentCache.sh create mode 100644 asdctool/src/main/resources/scripts/python/duplicates.py create mode 100644 asdctool/src/main/resources/scripts/python/duplicatesAndRemove.py create mode 100644 asdctool/src/main/resources/scripts/python/graphSize.py create mode 100644 asdctool/src/main/resources/scripts/python/user/exportUsers.py create mode 100644 asdctool/src/main/resources/scripts/python/user/importUsers.py create mode 100644 asdctool/src/main/resources/scripts/schemaCreation.sh create mode 100644 asdctool/src/main/resources/scripts/updateIsVnf.sh create mode 100644 asdctool/src/main/resources/scripts/vfcNameAlignment.sh create mode 100644 asdctool/tarball.xml create mode 100644 catalog-be/.gitignore create mode 100644 catalog-be/.pydevproject create mode 100644 catalog-be/README.txt create mode 100644 catalog-be/normatives.xml create mode 100644 catalog-be/pom.xml create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/auditing/api/IAuditingManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatConstants.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatUtil.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/AsdcComponentsCleanerTask.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/ComponentsCleanBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ArtifactInfoImpl.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaErrorResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DeConfigurationStatus.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngine.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineClusterHealth.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineInitTask.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEnginePollingTask.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionNotificationSender.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotification.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotificationEnum.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IArtifactInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IDistributionEngine.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/INotificationData.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IResourceArtifactInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IServiceArtifactInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/JsonContainerResourceInstance.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationDataImpl.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationExecutorService.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/PublishNotificationRunnable.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ResourceArtifactInfoImpl.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceArtifactInfoImpl.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceDistributionArtifactsBuilder.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/SubscriberTypeEnum.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/TestQueue.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/UebHealthCheckCall.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/VfModuleArtifactPayload.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AdditionalInformationBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CompositionBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ConsumerBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CsarValidationUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupTypeImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/HealthCheckBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/IDeploymentArtifactTypeConfigGetter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InformationDeployedArtifactsBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceLifecycleTypeImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/MonitoringBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyTypeImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductComponentInstanceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementsBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResponseFormatManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceComponentInstanceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/VFComponentInstanceBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationRequestTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckinTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifeCycleTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoBase.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoWithAction.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/StartCertificationTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/UndoCheckoutTransition.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/CategoryTypeEnum.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/HighestFilterEnum.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ArtifactUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/NodeTypeConvertUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/CambriaOperationStatus.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/RegistrationRequest.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/ServerListResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicRegistrationResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicUnregistrationResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/EcompIntImpl.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompRoleConverter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompUserConverter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetMetadataConverter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ArtifactMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/AssetMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/IAssetMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductAssetMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductCategoryGroupMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetDetailedMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceInstanceMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetDetailedMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/filters/BasicAuthenticationFilter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeServletFilter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/filters/ComponentsAvailabilityFilter.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/impl/DownloadArtifactLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServletUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/impl/WebAppContextWrapper.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessList.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactDefinitionInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTemplateInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTypesInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/CreateAndAssotiateInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatus.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupDefinitionInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupTemplateInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/MergedArtifactInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceVersionInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ServicesWrapper.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ServletJsonResponse.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInfo.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInterface.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/listen/BEAppContextListener.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/monitoring/EsGateway.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigMgrServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CsarBuildServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceArtifactDownloadServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ToscaDaoServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/switchover/detector/SwitchoverDetector.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ArtifactTypes.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CSARTool.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabiltyRequirementConvertor.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaError.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/EntrySchema.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/IToscaMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/SubstitutionMapping.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaCapability.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaGroupTemplate.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeType.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaRequirement.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateCapability.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateRequirement.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/VfModuleToscaMetadata.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/user/IUserBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/user/Role.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminAction.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminValidator.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/be/user/UserBusinessLogic.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ICommitHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBAction.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBType.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ITransactionSdnc.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/RollbackHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/TransactionUtils.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESAction.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESRollbackHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanCommitHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanRollbackHandler.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/CommitManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/RollbackManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionManager.java create mode 100644 catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionSdncImpl.java create mode 100644 catalog-be/src/main/resources/application-context.xml create mode 100644 catalog-be/src/main/resources/config/configuration.yaml create mode 100644 catalog-be/src/main/resources/config/distribution-engine-configuration.yaml create mode 100644 catalog-be/src/main/resources/config/ecomp-error-configuration.yaml create mode 100644 catalog-be/src/main/resources/config/error-configuration.yaml create mode 100644 catalog-be/src/main/resources/config/logback.xml create mode 100644 catalog-be/src/main/resources/config/neo4j-errors-configuration.yaml create mode 100644 catalog-be/src/main/resources/config/titan.properties create mode 100644 catalog-be/src/main/resources/elasticsearch.yml create mode 100644 catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/categories/categoryTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/categories/categoryTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/data-types/dataTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/data-types/dataTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/group-types/groupTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/group-types/groupTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.zip create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.json create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.yml create mode 100644 catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.zip create mode 100644 catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/database/database.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/database/database.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/database/database.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/network/network.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/network/network.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/network/network.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/port/port.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/port/port.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/port/port.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/root/root.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/root/root.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/root/root.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.zip create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.json create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.yml create mode 100644 catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.zip create mode 100644 catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.yml create mode 100644 catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.zip create mode 100644 catalog-be/src/main/resources/import/tosca/users/importUsers.yaml create mode 100644 catalog-be/src/main/resources/jetty-ssl.xml create mode 100644 catalog-be/src/main/resources/keystore/README.txt create mode 100644 catalog-be/src/main/resources/keystore/catalogbe.jks create mode 100644 catalog-be/src/main/resources/keystore/catalogbe.jks.pwd create mode 100644 catalog-be/src/main/resources/portal.properties create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importCategoryTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importCommon.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importDataTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importGroupTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importHeatTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNodeType.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNormativeCapabilities.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNormativeElements.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNormativeInterfaceLifecycleTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importNormativeTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importPolicyTypes.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/importUsersFromYaml.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersion.py create mode 100644 catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersionAll.py create mode 100644 catalog-be/src/main/resources/swagger/css/print.css create mode 100644 catalog-be/src/main/resources/swagger/css/reset.css create mode 100644 catalog-be/src/main/resources/swagger/css/screen.css create mode 100644 catalog-be/src/main/resources/swagger/css/typography.css create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.eot create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.svg create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.ttf create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff2 create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.eot create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.svg create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.ttf create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff create mode 100644 catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff2 create mode 100644 catalog-be/src/main/resources/swagger/images/explorer_icons.png create mode 100644 catalog-be/src/main/resources/swagger/images/favicon-16x16.png create mode 100644 catalog-be/src/main/resources/swagger/images/favicon-32x32.png create mode 100644 catalog-be/src/main/resources/swagger/images/favicon.ico create mode 100644 catalog-be/src/main/resources/swagger/images/logo_small.png create mode 100644 catalog-be/src/main/resources/swagger/images/pet_store_api.png create mode 100644 catalog-be/src/main/resources/swagger/images/throbber.gif create mode 100644 catalog-be/src/main/resources/swagger/images/wordnik_api.png create mode 100644 catalog-be/src/main/resources/swagger/index.html create mode 100644 catalog-be/src/main/resources/swagger/lib/backbone-min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/handlebars-2.0.0.js create mode 100644 catalog-be/src/main/resources/swagger/lib/highlight.7.3.pack.js create mode 100644 catalog-be/src/main/resources/swagger/lib/jquery-1.8.0.min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/jquery.ba-bbq.min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/jquery.slideto.min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/jquery.wiggle.min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/marked.js create mode 100644 catalog-be/src/main/resources/swagger/lib/swagger-oauth.js create mode 100644 catalog-be/src/main/resources/swagger/lib/underscore-min.js create mode 100644 catalog-be/src/main/resources/swagger/lib/underscore-min.map create mode 100644 catalog-be/src/main/resources/swagger/o2c.html create mode 100644 catalog-be/src/main/resources/swagger/swagger-ui.js create mode 100644 catalog-be/src/main/resources/swagger/swagger-ui.min.js create mode 100644 catalog-be/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 catalog-be/src/main/webapp/WEB-INF/jetty-web.xml create mode 100644 catalog-be/src/main/webapp/WEB-INF/web.xml create mode 100644 catalog-be/src/main/webapp/index.html create mode 100644 catalog-be/src/main/webapp/index.jsp create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/AuditingMockManager.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/ElementOperationMock.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/ErrorConfigurationTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/TestExternalConfiguration.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/ZipUtil.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/AuditingManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/BaseConfDependentTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/ComponentBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/HealthCheckBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/PropertyBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceImportManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/ResourceTestUtils.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/ServiceBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineConfigTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineHealthCheckTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineInitTaskTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ArtifactBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CategoriesImportManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CompositionBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/CsarValidationUtilsTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ImportUtilsTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/InterfaceLifecycleTypeImportManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/impl/ResourceInstanceBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransitionTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CertificationRequestTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckinTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/LifecycleTestBase.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/components/lifecycle/UndoCheckoutTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogicTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/distribution/servlet/DistributionServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/ecomp/GenerateEcompErrorFileTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/AbstractValidationsServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ApplicationConfig.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/ResourceUploadServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/TypesUploadServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/servlets/UserAdminServletTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/be/user/UserAdminManagerTest.java create mode 100644 catalog-be/src/test/java/org/openecomp/sdc/common/transaction/mngr/SdncTransactionTest.java create mode 100644 catalog-be/src/test/resources/config/catalog-be/configuration.yaml create mode 100644 catalog-be/src/test/resources/config/catalog-be/distribution-engine-configuration.yaml create mode 100644 catalog-be/src/test/resources/config/catalog-be/ecomp-error-configuration.yaml create mode 100644 catalog-be/src/test/resources/config/catalog-be/error-configuration.yaml create mode 100644 catalog-be/src/test/resources/config/catalog-be/neo4j-errors-configuration.yaml create mode 100644 catalog-be/src/test/resources/config/catalog-be/users-configuration.yaml create mode 100644 catalog-be/src/test/resources/config/configuration1.yaml create mode 100644 catalog-be/src/test/resources/config/elasticsearch.yml create mode 100644 catalog-be/src/test/resources/config/elasticsearch.yml.bak create mode 100644 catalog-be/src/test/resources/config/mysql-type-empty-nodes.zip create mode 100644 catalog-be/src/test/resources/config/mysql-type-no-nodes.zip create mode 100644 catalog-be/src/test/resources/config/mysql-type-no-version.zip create mode 100644 catalog-be/src/test/resources/config/mysql-type-only-yaml.zip create mode 100644 catalog-be/src/test/resources/config/mysql-type-with-scripts.zip create mode 100644 catalog-be/src/test/resources/config/mysql-type.yml create mode 100644 catalog-be/src/test/resources/config/mysql-type.zip create mode 100644 catalog-be/src/test/resources/config/normative-types-root.zip create mode 100644 catalog-be/src/test/resources/config/sample.yaml create mode 100644 catalog-be/src/test/resources/config/sampleNoProtocol.yaml create mode 100644 catalog-be/src/test/resources/elasticsearch.yml create mode 100644 catalog-be/src/test/resources/logback-test.xml create mode 100644 catalog-be/src/test/resources/mock_vf.csar create mode 100644 catalog-be/src/test/resources/normativeTypes/importToscaProperties.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/importToscaWithAttribute.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-all-map-test.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-DBMS.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-Root.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-blockStorage.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-compute.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-database.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-port.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-softwareComponent.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-new-webServer.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/normative-types-string-list-test.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_duplicateNode.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_empty.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_inputs.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_nodeEmpty.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_nodeVF.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_notValidNode.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_notValidRelationNode.yml create mode 100644 catalog-be/src/test/resources/normativeTypes/topology_template_sample.yml create mode 100644 catalog-be/src/test/resources/types/capabilityTypes.yml create mode 100644 catalog-be/src/test/resources/types/capabilityTypes.zip create mode 100644 catalog-be/src/test/resources/types/categoryTypes.yml create mode 100644 catalog-be/src/test/resources/types/categoryTypes.zip create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeDeriveFromIntegerWithProperty.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeDerivedFromRootNoProperties.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeDuplicateProperty.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeForGroup.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdatePropertyRemoved_part1.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdatePropertyRemoved_part2.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentDerivedDataType_part1.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentDerivedDataType_part2.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentEntryType_part1.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentEntryType_part2.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentPropertyType_part1.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithDifferentPropertyType_part2.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithExistingPropertyNameInAncestor_part1.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeUpdateWithExistingPropertyNameInAncestor_part2.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypeWithPropertyTypeThisDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/dataTypes.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/derived3levelDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/derivedDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/derivedDataTypeNoProperties.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/derivedInvalidDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/emptyDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/emptyDataTypeNoPropertiesTag.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/exitingPropertyAtAncestor.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/invalidDataType.yml create mode 100644 catalog-be/src/test/resources/types/datatypes/oneDataType.yml create mode 100644 catalog-be/src/test/resources/types/interfaceLifecycleTypes.yml create mode 100644 catalog-be/src/test/resources/types/interfaceLifecycleTypes.zip create mode 100644 catalog-be/src/test/resources/valid_vf.csar create mode 100644 catalog-be/tarball.xml create mode 100644 catalog-dao/.gitignore create mode 100644 catalog-dao/pom.xml create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/Account.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ActionStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/BasicDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ESGenericIdDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ESGenericSearchDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IBasicDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ICatalogDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IElementDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IEsHealthCheckDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IGenericIdDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IGenericSearchDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IPropertyDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IResourceDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/IUsersDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/api/ResourceUploadStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/ArtifactCassandraDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/AuditAccessor.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/AuditCassandraDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/CassandraClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/CassandraDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/CassandraOperationStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/ComponentCacheAccessor.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/ComponentCassandraDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/ITableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/SdcSchemaBuilder.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/Table.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/ArtifactTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/AuthEventTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/CategoryEventTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/ComponentCacheTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/ConsumerEventTableDefinition.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/DistribDeployEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/DistribDownloadEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/DistribEngineEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/DistribNotifEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/DistribStatusEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/ExternalApiEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/GetCatHierEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/GetUebClusterEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/GetUsersListEventTableDesc.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/ResAdminEventTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/UserAccessEventTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/cassandra/schema/tables/UserAdminEventTableDescription.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/es/ElasticSearchClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/GraphElementFactory.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/ActionEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/AdditionalInformationEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphEdge.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphElement.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphElementTypeEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphNode.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/GraphRelation.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/graph/datatype/RelationEndPoint.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/AuditingDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/ESCatalogDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/ESTimeBasedDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/EsHealthCheckDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/MonitoringDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/Neo4jElementDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/Neo4jPropertyDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/Neo4jResourceDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/impl/Neo4jUsersDAO.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/model/FacetedSearchFacet.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/model/FacetedSearchResult.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/model/FetchContext.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/model/GetMultipleDataResult.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/BatchBuilder.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTemplates.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/CypherTranslator.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgeLabels.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphEdgePropertiesDictionary.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphNeighbourTable.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/GraphPropertiesDictionary.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jEdge.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jGraphBatchBuilder.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/Neo4jOperationStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/NodeRelation.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/MatchFilter.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveByRelationFilter.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/RecursiveFilter.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/neo4j/filters/UpdateFilter.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/rest/HttpRestClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/rest/RestConfigurationInfo.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/QueryType.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGenericDao.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanGraphClient.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/titan/TitanOperationStatus.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/CollectionUtils.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/Constants.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/DaoUtils.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/ElasticSearchUtil.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/Exceptions.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/ImageQuality.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/ImageResizeUtil.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/JsonUtil.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapEntry.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/MapUtil.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/TypeMap.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/dao/utils/UserStatusEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/api/ArtifactDataEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/api/IResourceUploader.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/AdditionalInfoParameterData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ArtifactData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/AttributeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/AttributeValueData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/CapabilityData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/CapabilityInstData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/CapabilityTypeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/CategoryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ComponentCacheData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ComponentInstanceData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ComponentMetadataData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ConsumerData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/DataTypeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ESArtifactData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/EntryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/GraphNodeLock.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/GroupData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/GroupTypeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/HeatParameterData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/HeatParameterValueData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/InputValueData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/InputsData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/InterfaceData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/OperationData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/PolicyTypeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ProductMetadataData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/PropertyData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/PropertyValueData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipInstData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RelationshipTypeData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RequirementData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/RequirementImplData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ResourceCategoryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ResourceMetadataData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ServiceArtifactsDataCollection.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ServiceCategoryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/ServiceMetadataData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/TagData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/UniqueIdData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/UserData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/UserFunctionalMenuData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditRecordFactory.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingActionEnum.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingGenericEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingGetUebClusterEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuditingTypesConstants.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/AuthEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/CategoryEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/ConsumerEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/DistributionDeployEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/DistributionDownloadEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/DistributionEngineEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/DistributionNotificationEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/DistributionStatusEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/ExternalApiEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/GetCategoryHierarchyEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/GetUsersListEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/ResourceAdminEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/UserAccessEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/auditing/UserAdminEvent.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/CategoryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/GroupingData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/data/category/SubCategoryData.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/exception/DeleteDeployedException.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/exception/InitializationException.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/exception/ResourceDAOException.java create mode 100644 catalog-dao/src/main/java/org/openecomp/sdc/be/resources/impl/ResourceUploader.java create mode 100644 catalog-dao/src/test/java/org/openecomp/sdc/be/resources/ArtifactDaoTest.java create mode 100644 catalog-dao/src/test/java/org/openecomp/sdc/be/resources/AuditingDaoTest.java create mode 100644 catalog-dao/src/test/java/org/openecomp/sdc/be/resources/CassandraTest.java create mode 100644 catalog-dao/src/test/java/org/openecomp/sdc/be/resources/ESUsersDAOTest.java create mode 100644 catalog-dao/src/test/java/org/openecomp/sdc/be/resources/TitanGenericDaoTest.java create mode 100644 catalog-dao/src/test/resources/application-context-test.xml create mode 100644 catalog-dao/src/test/resources/cassandra.yaml create mode 100644 catalog-dao/src/test/resources/config/catalog-dao/configuration.yaml create mode 100644 catalog-dao/src/test/resources/config/catalog-dao/ecomp-error-configuration.yaml create mode 100644 catalog-dao/src/test/resources/elasticsearch.yml create mode 100644 catalog-dao/src/test/resources/images/apache.png create mode 100644 catalog-dao/src/test/resources/log4j.properties create mode 100644 catalog-dao/src/test/resources/logback-test.xml create mode 100644 catalog-fe/.gitignore create mode 100644 catalog-fe/pom.xml create mode 100644 catalog-fe/readMe.txt create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/Constants.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/client/BackendClient.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/Audit.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/CrudOperation.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/HttpRequestInfo.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/impl/ImportMetadata.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/FEAppContextListener.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/listen/MyObjectMapperProvider.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigMgrServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/ConfigServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeHealthCheckServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/FeProxyServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/HealthCheckService.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/KibanaServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/PortalServlet.java create mode 100644 catalog-fe/src/main/java/org/openecomp/sdc/fe/servlets/SSLProxyServlet.java create mode 100644 catalog-fe/src/main/resources/application-context.xml create mode 100644 catalog-fe/src/main/resources/config/configuration.yaml create mode 100644 catalog-fe/src/main/resources/config/ecomp-error-configuration.yaml create mode 100644 catalog-fe/src/main/resources/config/logback.xml create mode 100644 catalog-fe/src/main/resources/config/rest-configuration-info.yaml create mode 100644 catalog-fe/src/main/resources/jetty-ipaccess.xml create mode 100644 catalog-fe/src/main/resources/portal.properties create mode 100644 catalog-fe/src/main/resources/scripts/install.sh create mode 100644 catalog-fe/src/main/resources/scripts/installJettyBase.sh create mode 100644 catalog-fe/src/main/resources/scripts/jvm.properties create mode 100644 catalog-fe/src/main/resources/scripts/startJetty.sh create mode 100644 catalog-fe/src/main/resources/scripts/updateSslParams.sh create mode 100644 catalog-fe/src/main/webapp/META-INF/MANIFEST.MF create mode 100644 catalog-fe/src/main/webapp/WEB-INF/jetty-web.xml create mode 100644 catalog-fe/src/main/webapp/WEB-INF/web.xml create mode 100644 catalog-fe/src/test/SpecRunner.html create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/MIT.LICENSE create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/SpecRunner.html create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/boot.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/console.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/jasmine-html.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/jasmine.css create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/jasmine.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/lib/jasmine-2.0.0/jasmine_favicon.png create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/spec/PlayerSpec.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/spec/SpecHelper.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/src/Player.js create mode 100644 catalog-fe/src/test/jasmine-standalone-2.0.0/src/Song.js create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/ApplicationConfig.java create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/ContentDisposiotionDelegator.java create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/Main.java create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/TestExternalConfiguration.java create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/servlets/FeProxyServletTest.java create mode 100644 catalog-fe/src/test/java/org/openecomp/sdc/servlets/PortalServletTest.java create mode 100644 catalog-fe/src/test/resources/CI/ReadMe.txt create mode 100644 catalog-fe/src/test/resources/CI/originalResources/apache-type.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/apache.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/compute.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/loadbalancer.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/network.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/objectstore.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/relational_db.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/root.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/router.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/software.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/images/volume.png create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-DBMS.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-blockStorage.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-compute.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-database.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-network.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-objectStorage.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-root.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-softwareComponent.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-webApplication.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/normative-types-webServer.yml create mode 100644 catalog-fe/src/test/resources/CI/originalResources/scripts/apache_start_detection.groovy create mode 100644 catalog-fe/src/test/resources/CI/originalResources/scripts/install_apache.sh create mode 100644 catalog-fe/src/test/resources/CI/originalResources/scripts/start_apache.sh create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/command create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/results create mode 100644 catalog-fe/src/test/resources/CI/tests/01_NormativeTypeCI-root/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/command create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/results create mode 100644 catalog-fe/src/test/resources/CI/tests/02_NormativeTypeCI-compute/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/command create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/results create mode 100644 catalog-fe/src/test/resources/CI/tests/03_NormativeTypeCI-blockStorage/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/command create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/results create mode 100644 catalog-fe/src/test/resources/CI/tests/04_NormativeTypeCI-objectStorage/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/command create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/results create mode 100644 catalog-fe/src/test/resources/CI/tests/05_NormativeTypeCI-softwareComponent/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/command create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/results create mode 100644 catalog-fe/src/test/resources/CI/tests/06_NormativeTypeCI-webServer/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/command create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/results create mode 100644 catalog-fe/src/test/resources/CI/tests/07_NormativeTypeCI-webApplication/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/command create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/results create mode 100644 catalog-fe/src/test/resources/CI/tests/08_NormativeTypeCI-DBMS/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/command create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/results create mode 100644 catalog-fe/src/test/resources/CI/tests/09_NormativeTypeCI-database/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/command create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/results create mode 100644 catalog-fe/src/test/resources/CI/tests/10_NormativeTypeCI-network/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/command create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/results create mode 100644 catalog-fe/src/test/resources/CI/tests/11_AlienApacheType/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/command create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/results create mode 100644 catalog-fe/src/test/resources/CI/tests/12_DatabaseType-GetArtifacts/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/command create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/results create mode 100644 catalog-fe/src/test/resources/CI/tests/13_ApacheType-GetMetadata/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/command create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/results create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/results.json create mode 100644 catalog-fe/src/test/resources/CI/tests/14_ApacheType-GetArtifacts/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/body.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/command create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/commandTrial create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/contentMD5.txt create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/headers create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/results create mode 100644 catalog-fe/src/test/resources/CI/tests/15_ApacheType-DownloadArtifact/toExec create mode 100644 catalog-fe/src/test/resources/CI/tests/env/env.sh create mode 100644 catalog-fe/src/test/resources/CI/tests/runTests.sh create mode 100644 catalog-fe/src/test/resources/config/catalog-fe/configuration.yaml create mode 100644 catalog-fe/src/test/resources/config/catalog-fe/rest-configuration-info.yaml create mode 100644 catalog-fe/src/test/resources/config/configuration1.yaml create mode 100644 catalog-fe/src/test/resources/config/sample.yaml create mode 100644 catalog-fe/src/test/resources/config/sampleNoProtocol.yaml create mode 100644 catalog-fe/src/test/resources/logback-test.xml create mode 100644 catalog-fe/src/test/spec/codeSpec.js create mode 100644 catalog-fe/src/test/testScripts/filesContents.js create mode 100644 catalog-fe/src/test/testScripts/jasmine-fixture.js create mode 100644 catalog-fe/tarball.xml create mode 100644 catalog-model/.gitignore create mode 100644 catalog-model/pom.xml create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInfoParameterInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/AdditionalInformationDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactType.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ArtifactUiDownloadData.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/AttributeDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/CapReqDef.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabilityTypeDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/CapabiltyInstance.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Category.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Component.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstInputsMap.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstance.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceAttribute.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceInput.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentInstanceProperty.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentMetadataDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ComponentParametersView.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ConsumerDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/DataTypeDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionStatusEnum.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/DistributionTransitionEnum.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/FunctionalMenuInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/GetInputValueInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupProperty.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/GroupTypeDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/HeatParameterDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/IComplexDefaultValue.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/IComponentInstanceConnectedElement.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/IOperationParameter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ImplementationArtifact.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/InputDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/InterfaceDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/LifeCycleTransitionEnum.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/LifecycleStateEnum.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Operation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ParsedToscaYamlInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Point.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/PolicyTypeDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Product.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ProductMetadataDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyScope.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/PropertyValueDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RelationshipImpl.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementAndRelationshipPair.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementCapabilityRelDef.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementImplDef.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/RequirementInstance.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Resource.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceInstanceHeatParameter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ResourceMetadataDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Schema.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Service.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/ServiceMetadataDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/Tag.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/TargetCapabilityRelDef.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadCapInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadComponentInstanceInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadPropInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadReqInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/UploadResourceInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/User.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationCache.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ApplicationDataTypeCache.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/ComponentCache.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/DaoInfo.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/CheckAndUpdateJob.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/DeleteJob.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/Job.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/OverrideJob.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/jobs/StoreJob.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/CacheWorker.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/IWorker.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/cache/workers/SyncWorker.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/category/CategoryDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/category/GroupingDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/category/SubCategoryDefinition.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/heat/HeatParameterType.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAdditionalInformationOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IArtifactOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IAttributeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICacheMangerOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityInstanceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ICapabilityTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentInstanceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IComponentOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IConsumerOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IDataTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IElementOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGraphLockOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IGroupTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IHeatParametersOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInputsOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IInterfaceLifecycleOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/ILifecycleOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPolicyTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IProductOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IPropertyOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IRequirementOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IResourceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IServiceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/IUserAdminOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/api/StorageOperationStatus.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AbstractOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AllOperationsUtil.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/AttributeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CacheMangerOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityInstanceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ConsumerOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/CsarOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/DaoStatusConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ElementOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GraphLockOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/GroupTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InputsOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/InterfaceLifecycleOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/Neo4jStatusConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/OnboardingClient.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ProductOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UniqueIdBuilder.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperation.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/ComponentValidationUtils.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/operations/utils/GraphDeleteUtil.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaPropertyType.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/ToscaType.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/VersionUtil.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractComparablePropertyConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractPropertyConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/AbstractStringPropertyConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintType.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ConstraintUtil.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/EqualConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterOrEqualConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/GreaterThanConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/InRangeConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LengthConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessOrEqualConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/LessThanConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MaxLengthConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/MinLengthConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/PatternConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/ValidValuesConstraint.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintFunctionalException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintRequiredParameterException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintTechnicalException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintValueDoNotMatchPropertyTypeException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/ConstraintViolationException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/FunctionalException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/InvalidPropertyConstraintImplementationException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/constraints/exception/TechnicalException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/BooleanConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/DefaultConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/FloatConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatBooleanConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatCommaDelimitedListConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatJsonConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatNumberConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/HeatStringConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/IntegerConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/JsonConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ListConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/LowerCaseConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/MapConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/PropertyValueConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/StringConvertor.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaBooleanConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaFloatConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaJsonValueConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaListValueConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaMapValueConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaStringConvertor.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueBaseConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/converters/ToscaValueDefaultConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/BooleanValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/DataTypeValidatorConverter.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/FloatValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatBooleanValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatCommaDelimitedListValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatNumberValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/HeatStringValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/JsonValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/KeyValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ListValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/MapValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/PropertyTypeValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/StringValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/validators/ToscaBooleanValidator.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ApplicationVersionException.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/ComparableVersion.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/model/tosca/version/Version.java create mode 100644 catalog-model/src/main/java/org/openecomp/sdc/be/unittests/utils/FactoryUtils.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/ModelTestBase.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/JsonObjectTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/AdditionalInformationOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ArtifactOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/CapabilityTypeOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationSpringTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentInstanceOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ComponentOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ElementOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/HeatParametersOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/InterfaceOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/LifecycleOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PolicyTypeOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/PropertyOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/RequirementOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceInstanceOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ResourceOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/ServiceOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/UserAdminOperationTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/DataTypeValidatorTest.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/OperationTestsUtil.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/PrintGraph.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/operations/impl/util/ResourceCreationUtils.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/serialize/TestResourceSerialization.java create mode 100644 catalog-model/src/test/java/org/openecomp/sdc/be/model/tosca/validators/IntegerValidatorTest.java create mode 100644 catalog-model/src/test/resources/application-context-test.xml create mode 100644 catalog-model/src/test/resources/config/ecomp-error-configuration.yaml create mode 100644 catalog-model/src/test/resources/logback-test.xml create mode 100644 catalog-ui/Gruntfile.js create mode 100644 catalog-ui/SETTING-ENVIRONMENT.md create mode 100644 catalog-ui/SETTING-MOCK-SERVER.md create mode 100644 catalog-ui/app/_favicon.png create mode 100644 catalog-ui/app/index.html create mode 100644 catalog-ui/app/languages/en_US_OS.json create mode 100644 catalog-ui/app/scripts/app.ts create mode 100644 catalog-ui/app/scripts/directives/clicked-outside/clicked-outside-directive.ts create mode 100644 catalog-ui/app/scripts/directives/custom-validation/custom-validation.ts create mode 100644 catalog-ui/app/scripts/directives/download-artifact/download-artifact.ts create mode 100644 catalog-ui/app/scripts/directives/ecomp-header/ecomp-header.html create mode 100644 catalog-ui/app/scripts/directives/ecomp-header/ecomp-header.less create mode 100644 catalog-ui/app/scripts/directives/ecomp-header/ecomp-header.ts create mode 100644 catalog-ui/app/scripts/directives/edit-name-popover/edit-module-name-popover.html create mode 100644 catalog-ui/app/scripts/directives/edit-name-popover/edit-name-popover-directive.ts create mode 100644 catalog-ui/app/scripts/directives/edit-name-popover/edit-name-popover-view.html create mode 100644 catalog-ui/app/scripts/directives/edit-name-popover/edit-name-popover.less create mode 100644 catalog-ui/app/scripts/directives/elements/checkbox/checkbox.html create mode 100644 catalog-ui/app/scripts/directives/elements/checkbox/checkbox.less create mode 100644 catalog-ui/app/scripts/directives/elements/checkbox/checkbox.ts create mode 100644 catalog-ui/app/scripts/directives/elements/radiobutton/radiobutton.html create mode 100644 catalog-ui/app/scripts/directives/elements/radiobutton/radiobutton.less create mode 100644 catalog-ui/app/scripts/directives/elements/radiobutton/radiobutton.ts create mode 100644 catalog-ui/app/scripts/directives/ellipsis/ellipsis-directive.html create mode 100644 catalog-ui/app/scripts/directives/ellipsis/ellipsis-directive.less create mode 100644 catalog-ui/app/scripts/directives/ellipsis/ellipsis-directive.ts create mode 100644 catalog-ui/app/scripts/directives/events/on-last-repeat/on-last-repeat.ts create mode 100644 catalog-ui/app/scripts/directives/file-opener/file-opener.html create mode 100644 catalog-ui/app/scripts/directives/file-opener/file-opener.ts create mode 100644 catalog-ui/app/scripts/directives/file-type/file-type.ts create mode 100644 catalog-ui/app/scripts/directives/file-upload/file-upload.html create mode 100644 catalog-ui/app/scripts/directives/file-upload/file-upload.less create mode 100644 catalog-ui/app/scripts/directives/file-upload/file-upload.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/common/common-graph-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/common/style/component-instances-nodes-style.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/common/style/module-node-style.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.directive.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.html create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/composition-graph.less create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-general-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-links-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/composition-graph-nodes-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/composition-graph/utils/match-capability-requierment-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/deployment-graph/deployment-graph.directive.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/deployment-graph/deployment-graph.html create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/deployment-graph/deployment-graph.less create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/deployment-graph/deployment-utils/deployment-graph-general-utils.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/image-creator/image-creator.service.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/palette/interfaces/i-dragdrop-event.d.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/palette/palette.directive.ts create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/palette/palette.html create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/palette/palette.less create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/relation-menu/relation-menu.html create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/relation-menu/relation-menu.less create mode 100644 catalog-ui/app/scripts/directives/graphs-v2/relation-menu/relation-menu.ts create mode 100644 catalog-ui/app/scripts/directives/info-tooltip/info-tooltip.html create mode 100644 catalog-ui/app/scripts/directives/info-tooltip/info-tooltip.less create mode 100644 catalog-ui/app/scripts/directives/info-tooltip/info-tooltip.ts create mode 100644 catalog-ui/app/scripts/directives/invalid-characters/invalid-characters.ts create mode 100644 catalog-ui/app/scripts/directives/layout/top-nav/top-nav.html create mode 100644 catalog-ui/app/scripts/directives/layout/top-nav/top-nav.less create mode 100644 catalog-ui/app/scripts/directives/layout/top-nav/top-nav.ts create mode 100644 catalog-ui/app/scripts/directives/layout/top-progress/top-progress.html create mode 100644 catalog-ui/app/scripts/directives/layout/top-progress/top-progress.less create mode 100644 catalog-ui/app/scripts/directives/layout/top-progress/top-progress.ts create mode 100644 catalog-ui/app/scripts/directives/loader/loader-directive.html create mode 100644 catalog-ui/app/scripts/directives/loader/loader-directive.less create mode 100644 catalog-ui/app/scripts/directives/loader/loader-directive.ts create mode 100644 catalog-ui/app/scripts/directives/modal/sdc-modal.html create mode 100644 catalog-ui/app/scripts/directives/modal/sdc-modal.less create mode 100644 catalog-ui/app/scripts/directives/modal/sdc-modal.ts create mode 100644 catalog-ui/app/scripts/directives/page-scroller/page-scroller.html create mode 100644 catalog-ui/app/scripts/directives/page-scroller/page-scroller.less create mode 100644 catalog-ui/app/scripts/directives/page-scroller/page-scroller.ts create mode 100644 catalog-ui/app/scripts/directives/perfect-scrollbar/angular-perfect-scrollbar.ts create mode 100644 catalog-ui/app/scripts/directives/print-graph-screen/print-graph-screen.ts create mode 100644 catalog-ui/app/scripts/directives/property-types/data-type-fields-structure/data-type-fields-structure.html create mode 100644 catalog-ui/app/scripts/directives/property-types/data-type-fields-structure/data-type-fields-structure.less create mode 100644 catalog-ui/app/scripts/directives/property-types/data-type-fields-structure/data-type-fields-structure.ts create mode 100644 catalog-ui/app/scripts/directives/property-types/type-list/type-list-directive.html create mode 100644 catalog-ui/app/scripts/directives/property-types/type-list/type-list-directive.less create mode 100644 catalog-ui/app/scripts/directives/property-types/type-list/type-list-directive.ts create mode 100644 catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.html create mode 100644 catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.less create mode 100644 catalog-ui/app/scripts/directives/property-types/type-map/type-map-directive.ts create mode 100644 catalog-ui/app/scripts/directives/punch-out/punch-out.ts create mode 100644 catalog-ui/app/scripts/directives/sdc-tabs/sdc-single-tab/sdc-single-tab-directive.ts create mode 100644 catalog-ui/app/scripts/directives/sdc-tabs/sdc-single-tab/sdc-single-tab.less create mode 100644 catalog-ui/app/scripts/directives/sdc-tabs/sdc-tabs-directive-view.html create mode 100644 catalog-ui/app/scripts/directives/sdc-tabs/sdc-tabs-directive.ts create mode 100644 catalog-ui/app/scripts/directives/sdc-tabs/sdc-tabs.less create mode 100644 catalog-ui/app/scripts/directives/structure-tree/structure-tree-directive.html create mode 100644 catalog-ui/app/scripts/directives/structure-tree/structure-tree-directive.less create mode 100644 catalog-ui/app/scripts/directives/structure-tree/structure-tree-directive.ts create mode 100644 catalog-ui/app/scripts/directives/tag/tag-directive.html create mode 100644 catalog-ui/app/scripts/directives/tag/tag-directive.less create mode 100644 catalog-ui/app/scripts/directives/tag/tag-directive.ts create mode 100644 catalog-ui/app/scripts/directives/tutorial/image-template.html create mode 100644 catalog-ui/app/scripts/directives/tutorial/text-template.html create mode 100644 catalog-ui/app/scripts/directives/tutorial/tutorial-directive.html create mode 100644 catalog-ui/app/scripts/directives/tutorial/tutorial-directive.less create mode 100644 catalog-ui/app/scripts/directives/tutorial/tutorial-directive.ts create mode 100644 catalog-ui/app/scripts/directives/user-header-details/user-header-details-directive.html create mode 100644 catalog-ui/app/scripts/directives/user-header-details/user-header-details-directive.less create mode 100644 catalog-ui/app/scripts/directives/user-header-details/user-header-details-directive.ts create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collaps-menu-box.ts create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.html create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.less create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.html create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.less create mode 100644 catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.ts create mode 100644 catalog-ui/app/scripts/directives/utils/page-selector/page-selector.html create mode 100644 catalog-ui/app/scripts/directives/utils/page-selector/page-selector.less create mode 100644 catalog-ui/app/scripts/directives/utils/page-selector/page-selector.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc-keyboard-events/sdc-keyboard-events.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.html create mode 100644 catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.less create mode 100644 catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.html create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-message.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.less create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.ts create mode 100644 catalog-ui/app/scripts/directives/utils/sdc_messages/sdc_messages.html create mode 100644 catalog-ui/app/scripts/directives/utils/smart-tooltip/smart-tooltip.ts create mode 100644 catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.html create mode 100644 catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.less create mode 100644 catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.ts create mode 100644 catalog-ui/app/scripts/filters/_category-name-filter.ts create mode 100644 catalog-ui/app/scripts/filters/capitalize-filter.ts create mode 100644 catalog-ui/app/scripts/filters/catalog-status-filter.ts create mode 100644 catalog-ui/app/scripts/filters/category-icon-filter.ts create mode 100644 catalog-ui/app/scripts/filters/category-type-filter.ts create mode 100644 catalog-ui/app/scripts/filters/clear-whitespaces-filter.ts create mode 100644 catalog-ui/app/scripts/filters/entity-filter.ts create mode 100644 catalog-ui/app/scripts/filters/graph-resource-name-filter.ts create mode 100644 catalog-ui/app/scripts/filters/product-category-name-filter.ts create mode 100644 catalog-ui/app/scripts/filters/product-subcategory-name-filter.ts create mode 100644 catalog-ui/app/scripts/filters/relation-name-fllter.ts create mode 100644 catalog-ui/app/scripts/filters/resource-name-filter.ts create mode 100644 catalog-ui/app/scripts/filters/resource-type-filter.ts create mode 100644 catalog-ui/app/scripts/filters/string-to-date-filter.ts create mode 100644 catalog-ui/app/scripts/filters/tests-id-filter.ts create mode 100644 catalog-ui/app/scripts/filters/trim-filter.ts create mode 100644 catalog-ui/app/scripts/filters/truncate-filter.ts create mode 100644 catalog-ui/app/scripts/filters/underscoreless-filter.ts create mode 100644 catalog-ui/app/scripts/models/activity.ts create mode 100644 catalog-ui/app/scripts/models/additional-information.ts create mode 100644 catalog-ui/app/scripts/models/app-config.ts create mode 100644 catalog-ui/app/scripts/models/artifacts.ts create mode 100644 catalog-ui/app/scripts/models/aschema-property.ts create mode 100644 catalog-ui/app/scripts/models/attributes.ts create mode 100644 catalog-ui/app/scripts/models/capability.ts create mode 100644 catalog-ui/app/scripts/models/category.ts create mode 100644 catalog-ui/app/scripts/models/comments.ts create mode 100644 catalog-ui/app/scripts/models/components/component.ts create mode 100644 catalog-ui/app/scripts/models/components/displayComponent.ts create mode 100644 catalog-ui/app/scripts/models/components/product.ts create mode 100644 catalog-ui/app/scripts/models/components/resource.ts create mode 100644 catalog-ui/app/scripts/models/components/service.ts create mode 100644 catalog-ui/app/scripts/models/componentsInstances/componentInstance.ts create mode 100644 catalog-ui/app/scripts/models/componentsInstances/productInstance.ts create mode 100644 catalog-ui/app/scripts/models/componentsInstances/resourceInstance.ts create mode 100644 catalog-ui/app/scripts/models/componentsInstances/serviceInstance.ts create mode 100644 catalog-ui/app/scripts/models/csar-component.ts create mode 100644 catalog-ui/app/scripts/models/data-type-properties.ts create mode 100644 catalog-ui/app/scripts/models/data-types-map.ts create mode 100644 catalog-ui/app/scripts/models/data-types.ts create mode 100644 catalog-ui/app/scripts/models/distribution.ts create mode 100644 catalog-ui/app/scripts/models/file-download.ts create mode 100644 catalog-ui/app/scripts/models/graph/d2-node.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/common-base-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/common-ci-link-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-link-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-simple-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-ucpe-host-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-ucpe-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-vl-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/composition-graph-links/composition-ci-vl-ucpe-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/links-factory.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/module-graph-links/module-ci-link-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/graph-links/module-graph-links/module-ci-vl-link.ts create mode 100644 catalog-ui/app/scripts/models/graph/graphTooltip.ts create mode 100644 catalog-ui/app/scripts/models/graph/link-menu.ts create mode 100644 catalog-ui/app/scripts/models/graph/match-relation.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/base-common-node.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/common-ci-node-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-cp.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-service.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe-cp.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-ucpe.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-vf.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-vfc.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/composition-graph-nodes/composition-ci-node-vl.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/modules-graph-nodes/module-node-base.ts create mode 100644 catalog-ui/app/scripts/models/graph/nodes/nodes-factory.ts create mode 100644 catalog-ui/app/scripts/models/graph/point.ts create mode 100644 catalog-ui/app/scripts/models/graph/relationMenuObjects.ts create mode 100644 catalog-ui/app/scripts/models/graph/relationship.ts create mode 100644 catalog-ui/app/scripts/models/inputs.ts create mode 100644 catalog-ui/app/scripts/models/instance-inputs-properties-map.ts create mode 100644 catalog-ui/app/scripts/models/instances-inputs-map.ts create mode 100644 catalog-ui/app/scripts/models/left-panel.ts create mode 100644 catalog-ui/app/scripts/models/member.ts create mode 100644 catalog-ui/app/scripts/models/modules/base-module.ts create mode 100644 catalog-ui/app/scripts/models/properties.ts create mode 100644 catalog-ui/app/scripts/models/requirement.ts create mode 100644 catalog-ui/app/scripts/models/schema-attribute.ts create mode 100644 catalog-ui/app/scripts/models/tab.ts create mode 100644 catalog-ui/app/scripts/models/tooltip-data.ts create mode 100644 catalog-ui/app/scripts/models/user.ts create mode 100644 catalog-ui/app/scripts/models/validate.ts create mode 100644 catalog-ui/app/scripts/modules/directive-module.ts create mode 100644 catalog-ui/app/scripts/modules/filters.ts create mode 100644 catalog-ui/app/scripts/modules/service-module.ts create mode 100644 catalog-ui/app/scripts/modules/utils.ts create mode 100644 catalog-ui/app/scripts/modules/view-model-module.ts create mode 100644 catalog-ui/app/scripts/services/activity-log-service.ts create mode 100644 catalog-ui/app/scripts/services/angular-js-bridge-service.ts create mode 100644 catalog-ui/app/scripts/services/available-icons-service.ts create mode 100644 catalog-ui/app/scripts/services/cache-service.ts create mode 100644 catalog-ui/app/scripts/services/category-resource-service.ts create mode 100644 catalog-ui/app/scripts/services/components/component-service.ts create mode 100644 catalog-ui/app/scripts/services/components/product-service.ts create mode 100644 catalog-ui/app/scripts/services/components/resource-service.ts create mode 100644 catalog-ui/app/scripts/services/components/service-service.ts create mode 100644 catalog-ui/app/scripts/services/components/utils/composition-left-palette-service.ts create mode 100644 catalog-ui/app/scripts/services/configuration-ui-service.ts create mode 100644 catalog-ui/app/scripts/services/cookie-service.ts create mode 100644 catalog-ui/app/scripts/services/data-types-service.ts create mode 100644 catalog-ui/app/scripts/services/ecomp-service.ts create mode 100644 catalog-ui/app/scripts/services/entity-service.ts create mode 100644 catalog-ui/app/scripts/services/event-listener-service.ts create mode 100644 catalog-ui/app/scripts/services/header-interceptor.ts create mode 100644 catalog-ui/app/scripts/services/http-error-interceptor.ts create mode 100644 catalog-ui/app/scripts/services/loader-service.ts create mode 100644 catalog-ui/app/scripts/services/onboarding-service.ts create mode 100644 catalog-ui/app/scripts/services/progress-service.ts create mode 100644 catalog-ui/app/scripts/services/relation-icons-service.ts create mode 100644 catalog-ui/app/scripts/services/sdc-version-service.ts create mode 100644 catalog-ui/app/scripts/services/sharing-service.ts create mode 100644 catalog-ui/app/scripts/services/url-tobase64-service.ts create mode 100644 catalog-ui/app/scripts/services/user-resource-service.ts create mode 100644 catalog-ui/app/scripts/utils/artifacts-utils.ts create mode 100644 catalog-ui/app/scripts/utils/change-lifecycle-state-handler.ts create mode 100644 catalog-ui/app/scripts/utils/common-utils.ts create mode 100644 catalog-ui/app/scripts/utils/component-factory.ts create mode 100644 catalog-ui/app/scripts/utils/component-instance-factory.ts create mode 100644 catalog-ui/app/scripts/utils/constants.ts create mode 100644 catalog-ui/app/scripts/utils/dictionary/dictionary.ts create mode 100644 catalog-ui/app/scripts/utils/file-utils.ts create mode 100644 catalog-ui/app/scripts/utils/functions.ts create mode 100644 catalog-ui/app/scripts/utils/menu-handler.ts create mode 100644 catalog-ui/app/scripts/utils/modals-handler.ts create mode 100644 catalog-ui/app/scripts/utils/prototypes.ts create mode 100644 catalog-ui/app/scripts/utils/validation-utils.ts create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/add-category-modal/add-category-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/add-category-modal/add-category-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/add-category-modal/add-category-modal-view.less create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/admin-dashboard-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/admin-dashboard-view.html create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/admin-dashboard.less create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/category-management/category-management-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/category-management/category-management-view.html create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/category-management/category-management.less create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/ecomp/ecomp-view.html create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/user-management/user-management-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/user-management/user-management-view.html create mode 100644 catalog-ui/app/scripts/view-models/admin-dashboard/user-management/user-management.less create mode 100644 catalog-ui/app/scripts/view-models/catalog/catalog-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/catalog/catalog-view-tests.ts create mode 100644 catalog-ui/app/scripts/view-models/catalog/catalog-view.html create mode 100644 catalog-ui/app/scripts/view-models/catalog/catalog.less create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/activity-log/activity-log-view.html create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/activity-log/activity-log-view.less create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/component-viewer-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/component-viewer.html create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/component-viewer.less create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/properties/product-properties-view.html create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/properties/properties-view.less create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/properties/resource-properties-view.html create mode 100644 catalog-ui/app/scripts/view-models/component-viewer/properties/service-properties-view.html create mode 100644 catalog-ui/app/scripts/view-models/dashboard/cover/dashboard-cover-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/dashboard/cover/dashboard-cover-view.html create mode 100644 catalog-ui/app/scripts/view-models/dashboard/dashboard-view-model-tests.ts create mode 100644 catalog-ui/app/scripts/view-models/dashboard/dashboard-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/dashboard/dashboard-view.html create mode 100644 catalog-ui/app/scripts/view-models/dashboard/dashboard.less create mode 100644 catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form-view.html create mode 100644 catalog-ui/app/scripts/view-models/forms/artifact-form/artifact-form.less create mode 100644 catalog-ui/app/scripts/view-models/forms/attribute-form/attribute-form-view.html create mode 100644 catalog-ui/app/scripts/view-models/forms/attribute-form/attribute-from-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/forms/env-parameters-form/env-parameters-form.html create mode 100644 catalog-ui/app/scripts/view-models/forms/env-parameters-form/env-parameters-form.less create mode 100644 catalog-ui/app/scripts/view-models/forms/env-parameters-form/env-parameters-form.ts create mode 100644 catalog-ui/app/scripts/view-models/forms/property-form/property-form-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/forms/property-form/property-form-view.html create mode 100644 catalog-ui/app/scripts/view-models/forms/property-form/property-form.less create mode 100644 catalog-ui/app/scripts/view-models/forms/resource-instance-name-form/resource-instance-name-model.ts create mode 100644 catalog-ui/app/scripts/view-models/forms/resource-instance-name-form/resource-instance-name-view.html create mode 100644 catalog-ui/app/scripts/view-models/forms/resource-instance-name-form/resource-instance-name.less create mode 100644 catalog-ui/app/scripts/view-models/modals/confirmation-modal/confirmation-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/confirmation-modal/confirmation-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/confirmation-modal/confirmation-modal.less create mode 100644 catalog-ui/app/scripts/view-models/modals/email-modal/email-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/email-modal/email-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/email-modal/email-modal.less create mode 100644 catalog-ui/app/scripts/view-models/modals/error-modal/error-403-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/error-modal/error-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/error-modal/error.less create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-base-modal-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-client-modal/client-message-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-client-modal/client-message-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-client-modal/client-message-modal.less create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-server-modal/server-message-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-server-modal/server-message-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/message-modal/message-server-modal/server-message-modal.less create mode 100644 catalog-ui/app/scripts/view-models/modals/onboarding-modal/onboarding-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/modals/onboarding-modal/onboarding-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/modals/onboarding-modal/onboarding-modal.less create mode 100644 catalog-ui/app/scripts/view-models/onboard-vendor/onboard-vendor-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/onboard-vendor/onboard-vendor-view.html create mode 100644 catalog-ui/app/scripts/view-models/onboard-vendor/onboard-vendor.less create mode 100644 catalog-ui/app/scripts/view-models/preloading/preloading-view.html create mode 100644 catalog-ui/app/scripts/view-models/preloading/preloading-view.less create mode 100644 catalog-ui/app/scripts/view-models/preloading/preloading-view.ts create mode 100644 catalog-ui/app/scripts/view-models/support/support-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/support/support-view.html create mode 100644 catalog-ui/app/scripts/view-models/support/support.less create mode 100644 catalog-ui/app/scripts/view-models/tabs/general-tab.less create mode 100644 catalog-ui/app/scripts/view-models/tabs/hierarchy/hierarchy-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/tabs/hierarchy/hierarchy-view.html create mode 100644 catalog-ui/app/scripts/view-models/tabs/hierarchy/hierarchy.less create mode 100644 catalog-ui/app/scripts/view-models/tutorial-end/tutorial-end.html create mode 100644 catalog-ui/app/scripts/view-models/tutorial-end/tutorial-end.less create mode 100644 catalog-ui/app/scripts/view-models/tutorial-end/tutorial-end.ts create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide0.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide1.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide2.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide3.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide4.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide5.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/slide6.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/welcome-steps-controller.ts create mode 100644 catalog-ui/app/scripts/view-models/welcome/welcome-view.html create mode 100644 catalog-ui/app/scripts/view-models/welcome/welcome-view.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/ReadMe.txt create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-deployment-step/artifact-deployment-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-form-step/artifact-form-step-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-form-step/artifact-form-step-view.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-form-step/artifact-form-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-information-step/artifact-information-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-information-step/artifact-information-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/artifact-information-step/artifact-information-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/general-step/general-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/general-step/general-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/general-step/general-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/hierarchy-step/hierarchy-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/hierarchy-step/hierarchy-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/hierarchy-step/hierarchy-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/icons-step/icons-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/icons-step/icons-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/icons-step/icons-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/properties-step/properties-step.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/properties-step/properties-step.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/properties-step/properties-step.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/property-form/property-form-view-model-tests.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/property-form/property-form-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/property-form/property-form.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/property-form/property-form.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-creation-base.html create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-creation-base.less create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-creation-base.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-state/create-wizard.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-state/edit-wizard.ts create mode 100644 catalog-ui/app/scripts/view-models/wizard/wizard-state/import-wizard.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/activity-log/activity-log.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/activity-log/activity-log.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/activity-log/activity-log.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/attributes/attributes-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/attributes/attributes-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/attributes/attributes.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/composition-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/composition-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/composition.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/artifacts/artifacts-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/artifacts/artifacts.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/details/details-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/details/details-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/details/details.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/properties-and-attributes/properties.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/relations/relations-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/relations/relations-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/relations/relations.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/structure/structure-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/composition/tabs/structure/structure-view.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment-artifacts/deployment-artifacts.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment/deployment-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment/deployment-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/deployment/deployment.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/disribution-status-modal/disribution-status-modal.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/distribution-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/distribution-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/distribution/distribution.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/general/general-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/general/general-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/general/general.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/icons/icons-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/icons/icons-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/icons/icons.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/information-artifacts/information-artifacts-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/information-artifacts/information-artifacts-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/information-artifacts/information-artifacts.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/inputs.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/resource-input/resource-inputs.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/inputs/service-input/service-inputs.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/management-workflow/management-workflow-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/management-workflow/management-workflow-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/network-call-flow/network-call-flow-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/network-call-flow/network-call-flow-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/product-hierarchy/product-hierarchy-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/product-hierarchy/product-hierarchy-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/product-hierarchy/product-hierarchy.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/properties/properties-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/properties/properties-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/properties/properties.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/req-and-capabilities/req-and-capabilities.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/tabs/tosca-artifacts/tosca-artifacts.less create mode 100644 catalog-ui/app/scripts/view-models/workspace/workspace-view-model.ts create mode 100644 catalog-ui/app/scripts/view-models/workspace/workspace-view.html create mode 100644 catalog-ui/app/scripts/view-models/workspace/workspace.less create mode 100644 catalog-ui/app/styles/animation.less create mode 100644 catalog-ui/app/styles/app.less create mode 100644 catalog-ui/app/styles/buttons.less create mode 100644 catalog-ui/app/styles/dark-header.less create mode 100644 catalog-ui/app/styles/fonts.less create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bd.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bd.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bd.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bd.woff create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BdIt.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BdIt.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BdIt.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BdIt.woff create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bk.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bk.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bk.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Bk.woff create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BkIt.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BkIt.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BkIt.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-BkIt.woff create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Lt.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Lt.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Lt.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-Lt.woff create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-LtIt.eot create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-LtIt.svg create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-LtIt.ttf create mode 100644 catalog-ui/app/styles/fonts/ClearviewATT/ClearviewATT-LtIt.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/AT&T Variation ID.tab create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/OmnesATTW02BoldItalic.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/OmnesATTW02BoldItalic.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/OmnesATTW02BoldItalic.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/OmnesATTW02BoldItalic.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Bold.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Italic.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Italic.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Italic.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Italic.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Light.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Light.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Light.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Light.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02LightItalic.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02LightItalic.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02LightItalic.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02LightItalic.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Medium.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Medium.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Medium.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02Medium.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02MediumItalic.eot create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02MediumItalic.svg create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02MediumItalic.ttf create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/Omnes_ATTW02MediumItalic.woff create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/demo-async.htm create mode 100644 catalog-ui/app/styles/fonts/OmnesATT/demo.htm create mode 100644 catalog-ui/app/styles/form-elements.less create mode 100644 catalog-ui/app/styles/global.less create mode 100644 catalog-ui/app/styles/images/anonymous.jpg create mode 100644 catalog-ui/app/styles/images/att_logo_white.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/AttachesTo.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/BindsTo.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/ConnectedTo.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/DependsOn.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/HostedOn.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/LinksTo.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/RoutesTo.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/arrow.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/arrow.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/arrow_connection_right.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/attach.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/binding.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/conected.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/conected.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/dependency.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/host.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/link.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/local_storage.png create mode 100644 catalog-ui/app/styles/images/relationship-icons/local_storage.svg create mode 100644 catalog-ui/app/styles/images/relationship-icons/rout.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Red_PLUS_HOVER.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_COLLABORATION-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_COMPUTE-AS-SERVICE-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_MESSAGING-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_MOBILITY.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_NETWORK-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_NETWORK-CLOUD-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_NETWORK-L-1-3.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_NETWORK-L-4.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_NOTIFICATION-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_ORPHAN.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_PLATFORM-AS-SERVICE-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_SECURITY-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_SETTING-.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_NB_avater.png create mode 100644 catalog-ui/app/styles/images/resource-icons/Resource_Icons_STORAGE-AS-SERVICE.png create mode 100644 catalog-ui/app/styles/images/resource-icons/alcatelLucent.png create mode 100644 catalog-ui/app/styles/images/resource-icons/applicationServer.png create mode 100644 catalog-ui/app/styles/images/resource-icons/aricent.png create mode 100644 catalog-ui/app/styles/images/resource-icons/att.png create mode 100644 catalog-ui/app/styles/images/resource-icons/borderElement.png create mode 100644 catalog-ui/app/styles/images/resource-icons/broadsoft.png create mode 100644 catalog-ui/app/styles/images/resource-icons/brocade.png create mode 100644 catalog-ui/app/styles/images/resource-icons/call_controll.png create mode 100644 catalog-ui/app/styles/images/resource-icons/canvasPlusIcon-red.png create mode 100644 catalog-ui/app/styles/images/resource-icons/canvasPlusIcon.png create mode 100644 catalog-ui/app/styles/images/resource-icons/cisco.png create mode 100644 catalog-ui/app/styles/images/resource-icons/closeModule.png create mode 100644 catalog-ui/app/styles/images/resource-icons/closeModuleHover.png create mode 100644 catalog-ui/app/styles/images/resource-icons/cloud.png create mode 100644 catalog-ui/app/styles/images/resource-icons/cloudep.png create mode 100644 catalog-ui/app/styles/images/resource-icons/compute-uncertified.png create mode 100644 catalog-ui/app/styles/images/resource-icons/compute.png create mode 100644 catalog-ui/app/styles/images/resource-icons/connector.png create mode 100644 catalog-ui/app/styles/images/resource-icons/cp.png create mode 100644 catalog-ui/app/styles/images/resource-icons/database.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_analytics.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_collector.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_database.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_microservice.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_policy.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_source.png create mode 100644 catalog-ui/app/styles/images/resource-icons/dcae_utilty.png create mode 100644 catalog-ui/app/styles/images/resource-icons/default.png create mode 100644 catalog-ui/app/styles/images/resource-icons/defaulticon.png create mode 100644 catalog-ui/app/styles/images/resource-icons/ericsson.png create mode 100644 catalog-ui/app/styles/images/resource-icons/firewall.png create mode 100644 catalog-ui/app/styles/images/resource-icons/fortinet.png create mode 100644 catalog-ui/app/styles/images/resource-icons/gateway.png create mode 100644 catalog-ui/app/styles/images/resource-icons/juniper.png create mode 100644 catalog-ui/app/styles/images/resource-icons/loadBalancer.png create mode 100644 catalog-ui/app/styles/images/resource-icons/metaswitch.png create mode 100644 catalog-ui/app/styles/images/resource-icons/module.png create mode 100644 catalog-ui/app/styles/images/resource-icons/mysql.png create mode 100644 catalog-ui/app/styles/images/resource-icons/network.png create mode 100644 catalog-ui/app/styles/images/resource-icons/networkrules.png create mode 100644 catalog-ui/app/styles/images/resource-icons/nokia_siemens.png create mode 100644 catalog-ui/app/styles/images/resource-icons/objectStorage.png create mode 100644 catalog-ui/app/styles/images/resource-icons/openModule.png create mode 100644 catalog-ui/app/styles/images/resource-icons/openModuleHover.png create mode 100644 catalog-ui/app/styles/images/resource-icons/oracle.png create mode 100644 catalog-ui/app/styles/images/resource-icons/ossep.png create mode 100644 catalog-ui/app/styles/images/resource-icons/personep.png create mode 100644 catalog-ui/app/styles/images/resource-icons/port.png create mode 100644 catalog-ui/app/styles/images/resource-icons/premisesep.png create mode 100644 catalog-ui/app/styles/images/resource-icons/router.png create mode 100644 catalog-ui/app/styles/images/resource-icons/securityrules.png create mode 100644 catalog-ui/app/styles/images/resource-icons/selectedCPInstance.png create mode 100644 catalog-ui/app/styles/images/resource-icons/selectedInstance.png create mode 100644 catalog-ui/app/styles/images/resource-icons/selectedUcpeInstance.png create mode 100644 catalog-ui/app/styles/images/resource-icons/selectedVLInstance.png create mode 100644 catalog-ui/app/styles/images/resource-icons/server.png create mode 100644 catalog-ui/app/styles/images/resource-icons/tropo.png create mode 100644 catalog-ui/app/styles/images/resource-icons/ucpe.png create mode 100644 catalog-ui/app/styles/images/resource-icons/uncertified.png create mode 100644 catalog-ui/app/styles/images/resource-icons/vfw.png create mode 100644 catalog-ui/app/styles/images/resource-icons/vl.png create mode 100644 catalog-ui/app/styles/images/resource-icons/vrouter.png create mode 100644 catalog-ui/app/styles/images/resource-icons/wanx.png create mode 100644 catalog-ui/app/styles/images/service-icons/call_controll.png create mode 100644 catalog-ui/app/styles/images/service-icons/collaboration.png create mode 100644 catalog-ui/app/styles/images/service-icons/collaboration1.png create mode 100644 catalog-ui/app/styles/images/service-icons/compute.png create mode 100644 catalog-ui/app/styles/images/service-icons/defaulticon.png create mode 100644 catalog-ui/app/styles/images/service-icons/messaging.png create mode 100644 catalog-ui/app/styles/images/service-icons/mobility.png create mode 100644 catalog-ui/app/styles/images/service-icons/network_l_1-3.png create mode 100644 catalog-ui/app/styles/images/service-icons/network_l_4.png create mode 100644 catalog-ui/app/styles/images/service-icons/notification.png create mode 100644 catalog-ui/app/styles/images/service-icons/platform.png create mode 100644 catalog-ui/app/styles/images/service-icons/storage.png create mode 100644 catalog-ui/app/styles/images/service-icons/uncertified.png create mode 100644 catalog-ui/app/styles/images/sprites/sprite-global-old.png create mode 100644 catalog-ui/app/styles/images/sprites/sprite-global.png create mode 100644 catalog-ui/app/styles/images/sprites/sprite-product-icons.png create mode 100644 catalog-ui/app/styles/images/sprites/sprite-resource-icons.png create mode 100644 catalog-ui/app/styles/images/sprites/sprite-services-icons.png create mode 100644 catalog-ui/app/styles/images/sprites/tlv-sprite.png create mode 100644 catalog-ui/app/styles/images/tutorial/10.png create mode 100644 catalog-ui/app/styles/images/tutorial/11.png create mode 100644 catalog-ui/app/styles/images/tutorial/13.png create mode 100644 catalog-ui/app/styles/images/tutorial/14.png create mode 100644 catalog-ui/app/styles/images/tutorial/15.png create mode 100644 catalog-ui/app/styles/images/tutorial/16.png create mode 100644 catalog-ui/app/styles/images/tutorial/17.png create mode 100644 catalog-ui/app/styles/images/tutorial/18.png create mode 100644 catalog-ui/app/styles/images/tutorial/19.png create mode 100644 catalog-ui/app/styles/images/tutorial/2.png create mode 100644 catalog-ui/app/styles/images/tutorial/20.png create mode 100644 catalog-ui/app/styles/images/tutorial/21.png create mode 100644 catalog-ui/app/styles/images/tutorial/22.png create mode 100644 catalog-ui/app/styles/images/tutorial/23.png create mode 100644 catalog-ui/app/styles/images/tutorial/24.png create mode 100644 catalog-ui/app/styles/images/tutorial/25.png create mode 100644 catalog-ui/app/styles/images/tutorial/26.png create mode 100644 catalog-ui/app/styles/images/tutorial/27.png create mode 100644 catalog-ui/app/styles/images/tutorial/28.png create mode 100644 catalog-ui/app/styles/images/tutorial/29.png create mode 100644 catalog-ui/app/styles/images/tutorial/3.png create mode 100644 catalog-ui/app/styles/images/tutorial/30.png create mode 100644 catalog-ui/app/styles/images/tutorial/4.png create mode 100644 catalog-ui/app/styles/images/tutorial/5.png create mode 100644 catalog-ui/app/styles/images/tutorial/6.png create mode 100644 catalog-ui/app/styles/images/tutorial/7.png create mode 100644 catalog-ui/app/styles/images/tutorial/8.png create mode 100644 catalog-ui/app/styles/images/welcome.png create mode 100644 catalog-ui/app/styles/images/welcome/SD&C_Welcome15.jpg create mode 100644 catalog-ui/app/styles/images/welcome/SD&C_Welcome15_b.jpg create mode 100644 catalog-ui/app/styles/images/welcome/bg/001.jpg create mode 100644 catalog-ui/app/styles/images/welcome/bg/002.jpg create mode 100644 catalog-ui/app/styles/images/welcome/bg/002.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/003.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/004.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/bg02.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/bg03.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/connection02.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/connection03.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/connection04.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/global.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/shape02.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/shape03.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/shape04.png create mode 100644 catalog-ui/app/styles/images/welcome/bg/shape05.png create mode 100644 catalog-ui/app/styles/images/welcome/laptop.png create mode 100644 catalog-ui/app/styles/images/welcome/logo_att.png create mode 100644 catalog-ui/app/styles/images/welcome/sprite.png create mode 100644 catalog-ui/app/styles/images/welcome/ss-01.png create mode 100644 catalog-ui/app/styles/images/welcome/ss-02.png create mode 100644 catalog-ui/app/styles/images/welcome/ss-03.png create mode 100644 catalog-ui/app/styles/layout/header.less create mode 100644 catalog-ui/app/styles/layout/main.less create mode 100644 catalog-ui/app/styles/layout/sidebar.less create mode 100644 catalog-ui/app/styles/mixins.less create mode 100644 catalog-ui/app/styles/mixins_old.less create mode 100644 catalog-ui/app/styles/modal.less create mode 100644 catalog-ui/app/styles/scroller.less create mode 100644 catalog-ui/app/styles/sprite-old.less create mode 100644 catalog-ui/app/styles/sprite-product-icons.less create mode 100644 catalog-ui/app/styles/sprite-resource-icons.less create mode 100644 catalog-ui/app/styles/sprite-services-icons.less create mode 100644 catalog-ui/app/styles/sprite.html create mode 100644 catalog-ui/app/styles/sprite.less create mode 100644 catalog-ui/app/styles/table-flex.less create mode 100644 catalog-ui/app/styles/tlv-buttons.less create mode 100644 catalog-ui/app/styles/tlv-checkbox.less create mode 100644 catalog-ui/app/styles/tlv-loader.less create mode 100644 catalog-ui/app/styles/tlv-sprite.less create mode 100644 catalog-ui/app/styles/tooltips.less create mode 100644 catalog-ui/app/styles/variables-old.less create mode 100644 catalog-ui/app/styles/variables.less create mode 100644 catalog-ui/app/styles/welcome-sprite.less create mode 100644 catalog-ui/app/styles/welcome-style.less create mode 100644 catalog-ui/app/third-party/PunchOutRegistry.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/.npmignore create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/.travis.yml create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/Gruntfile.coffee create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/LICENSE create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/README.md create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/bower.json create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/build/ng-infinite-scroll.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/build/ng-infinite-scroll.min.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/package.json create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/src/infinite-scroll.coffee create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/test/protractor-local.conf.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/test/protractor-shared.conf.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/test/protractor-travis.conf.js create mode 100644 catalog-ui/app/third-party/ng-infinite-scroll/test/spec/ng-infinite-scroll.spec.coffee create mode 100644 catalog-ui/bower dependecies create mode 100644 catalog-ui/bower.json create mode 100644 catalog-ui/build_catalog_ui.bat create mode 100644 catalog-ui/build_catalog_ui.sh create mode 100644 catalog-ui/configurations/MenuReadMe.txt create mode 100644 catalog-ui/configurations/dev.json create mode 100644 catalog-ui/configurations/menu.json create mode 100644 catalog-ui/configurations/mock.json create mode 100644 catalog-ui/configurations/prod.json create mode 100644 catalog-ui/docs/colors.jpg create mode 100644 catalog-ui/non_bower_components/cytoscape.js-edge-editation/CytoscapeEdgeEditation.js create mode 100644 catalog-ui/non_bower_components/cytoscape.js-edge-editation/README.md create mode 100644 catalog-ui/non_bower_components/cytoscape.js-edge-editation/index.html create mode 100644 catalog-ui/package.json create mode 100644 catalog-ui/pom.xml create mode 100644 catalog-ui/server-mock/mock-data/artifact/artifact-types.json create mode 100644 catalog-ui/server-mock/mock-data/category/category.json create mode 100644 catalog-ui/server-mock/mock-data/element/element.json create mode 100644 catalog-ui/server-mock/mock-data/resource/properties.json create mode 100644 catalog-ui/server-mock/mock-data/resource/resource.json create mode 100644 catalog-ui/server-mock/mock-data/resources/resourcesAbstract.json create mode 100644 catalog-ui/server-mock/mock-data/resources/resourcesNotAbstract.json create mode 100644 catalog-ui/server-mock/mock-data/template/template.json create mode 100644 catalog-ui/server-mock/mock-data/user/user.json create mode 100644 catalog-ui/server-mock/mock-server.js create mode 100644 catalog-ui/server-mock/routes/property.js create mode 100644 catalog-ui/server-mock/routes/resource.js create mode 100644 catalog-ui/server-mock/routes/resources.js create mode 100644 catalog-ui/server-mock/routes/template.js create mode 100644 catalog-ui/server-mock/routes/user.js create mode 100644 catalog-ui/tests/karma.unit.conf.js create mode 100644 catalog-ui/tsd.json create mode 100644 catalog-ui/tslint.json create mode 100644 catalog-ui/typings/angular-ui-bootstrap/angular-ui-bootstrap.d.ts create mode 100644 catalog-ui/typings/angular-ui-router/angular-ui-router.d.ts create mode 100644 catalog-ui/typings/angularjs/angular-mocks.d.ts create mode 100644 catalog-ui/typings/angularjs/angular-resource.d.ts create mode 100644 catalog-ui/typings/angularjs/angular.d.ts create mode 100644 catalog-ui/typings/angularjs/restangular.d.ts create mode 100644 catalog-ui/typings/cytoscape/cytoscape-extension.js create mode 100644 catalog-ui/typings/cytoscape/cytoscape-extension.js.map create mode 100644 catalog-ui/typings/cytoscape/cytoscape-extension.ts create mode 100644 catalog-ui/typings/cytoscape/cytoscape.d.ts create mode 100644 catalog-ui/typings/cytoscape/edge-editation.d.ts create mode 100644 catalog-ui/typings/d3/d3.d.ts create mode 100644 catalog-ui/typings/jasmine/jasmine.d.ts create mode 100644 catalog-ui/typings/jquery/jquery.d.ts create mode 100644 catalog-ui/typings/jsMd5/md5.d.ts create mode 100644 catalog-ui/typings/lodash/lodash.d.ts create mode 100644 catalog-ui/typings/notifyjs/notifyjs.d.ts create mode 100644 catalog-ui/typings/tsd.d.ts create mode 100644 common-app-api/.gitignore create mode 100644 common-app-api/pom.xml create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/BeEcompErrorManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/CleanComponentsConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/Configuration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/ConfigurationManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/DistributionEngineConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/ErrorConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/ErrorInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/Neo4jErrorsConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/config/validation/DeploymentArtifactHeatConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/be/monitoring/BeMonitoringService.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ApplicationErrorCodesEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ArtifactGroupTypeEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ArtifactTypeEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/BasicConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ConfigurationListener.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ConfigurationSource.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/Constants.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/FileChangeCallback.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/HealthCheckInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/HealthCheckWrapper.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ResourceType.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ResponseInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ToscaNodeTypeInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/ToscaNodeTypeInterface.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/UploadArtifactInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/UserRoleEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/YamlConstants.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/api/YamlSuffixEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/AbsEcompErrorManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompClassification.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorCode.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorLogUtil.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/EcompErrorName.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/IEcompConfigurationManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/IEcompErrorManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/config/generation/GenerateEcompErrorsCsv.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/AuditingFieldsKeysEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/CapList.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/ESTimeBasedEvent.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/FunctionalInterfaces.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/MonitoringFieldsKeysEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/datastructure/Wrapper.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/impl/ConfigFileChangeListener.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/impl/ExternalConfiguration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/impl/FSConfigurationSource.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/impl/MutableHttpServletRequest.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/kpi/api/ASDCKpiApi.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/listener/AppContextListener.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/monitoring/MonitoringEvent.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/monitoring/MonitoringMetricsFetcher.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/api/IRestClient.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/api/RestClientServiceExeption.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/api/RestConfigurationInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/api/RestResponse.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/api/RestResponseAsByteArray.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/impl/HttpRestClientServiceImpl.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/impl/RestClientServiceFactory.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/impl/validator/RequestHeadersValidator.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/rest/impl/validator/RestRequestValidationException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/servlets/BasicServlet.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/CapabilityTypeNameEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/GeneralUtility.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/GsonFactory.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/HtmlCleaner.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/HttpUtil.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/JsonUtils.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/MethodActivationStatusEnum.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/SerializationUtils.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/StreamUtils.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/ThreadLocalsHolder.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/ValidationUtils.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/YamlToObjectConverter.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/common/util/ZipUtil.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/AbstractSdncException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/AlreadyExistException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/DeleteLastApplicationEnvironmentException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/DeleteReferencedObjectException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/FunctionalException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/IndexingServiceException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/InvalidArgumentException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/NotFoundException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/OkResponseInfo.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/PolicyException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/ResponseFormat.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/ServiceException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/TechnicalException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/exception/VersionConflictException.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/fe/config/Configuration.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/fe/config/ConfigurationManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/fe/config/Connection.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/fe/config/FeEcompErrorManager.java create mode 100644 common-app-api/src/main/java/org/openecomp/sdc/fe/monitoring/FeMonitoringService.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/data_structure/CapListTest.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/CommonUtilsTest.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/TestExternalConfiguration.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/YamlTest.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/config/TestConfiguration.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/config/TestConnection.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/test/config/TestNotExistConfiguration.java create mode 100644 common-app-api/src/test/java/org/openecomp/sdc/common/util/StreamUtilsTests.java create mode 100644 common-app-api/src/test/resources/config/common/distribution-engine-configuration.yaml create mode 100644 common-app-api/src/test/resources/config/common/test-configuration.yaml create mode 100644 common-app-api/src/test/resources/logback-test.xml create mode 100644 common-be/.gitignore create mode 100644 common-be/pom.xml create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/CategoryDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/GroupingDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/category/SubCategoryDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ComponentMetadataDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ResourceMetadataDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/components/ServiceMetadataDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AdditionalInfoParameterDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ArtifactDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/AttributeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/CapabilityTypeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ComponentInstanceDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ConsumerDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/DataTypeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GroupDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/GroupTypeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/HeatParameterDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InputsValueDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/InterfaceDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/OperationDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PolicyTypeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/ProductMetadataDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/PropertyRule.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/RelationshipTypeDataDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/elements/SchemaDefinition.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/AssetTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ComponentTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/FilterKeyEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/GroupTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/NodeTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/OriginTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/datatypes/enums/ResourceTypeEnum.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/utils/CommonBeUtils.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/workers/Job.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/workers/Main.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/workers/Manager.java create mode 100644 common-be/src/main/java/org/openecomp/sdc/be/workers/Worker.java create mode 100644 common-be/src/test/java/org/openecomp/sdc/be/utils/CommonBeUtilsTest.java create mode 100644 distribution-ci/.gitignore create mode 100644 distribution-ci/etc/asdc-client.jks create mode 100644 distribution-ci/etc/asdcclientstore.jks create mode 100644 distribution-ci/log4j.properties create mode 100644 distribution-ci/pom.xml create mode 100644 distribution-ci/src/main/java/org/openecomp/test/BaseInit.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/CallableTask.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/ClientTest.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/E2eFlows.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/NotificationCallback.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/SimpleCallback.java create mode 100644 distribution-ci/src/main/java/org/openecomp/test/SimpleConfiguration.java create mode 100644 distribution-ci/src/main/resources/ci/conf/log4j.properties create mode 100644 distribution-ci/src/main/resources/ci/conf/sdc-packages.yaml create mode 100644 distribution-ci/src/main/resources/ci/conf/sdc.yaml create mode 100644 distribution-ci/src/main/resources/ci/conf/titan.properties create mode 100644 distribution-ci/src/main/resources/ci/scripts/startTest.sh create mode 100644 distribution-ci/src/test/java/org/openecomp/sdc/ci/tests/execute/downloadArtifactUGN/ClientDownloadArtifact.java create mode 100644 pom.xml create mode 100644 sdc-os-chef/docker-compose.yml create mode 100644 sdc-os-chef/environments/Template.json create mode 100644 sdc-os-chef/pom.xml create mode 100644 sdc-os-chef/scripts/docker_clean.sh create mode 100644 sdc-os-chef/scripts/docker_health.sh create mode 100644 sdc-os-chef/scripts/docker_login.sh create mode 100644 sdc-os-chef/scripts/docker_run.sh create mode 100644 sdc-os-chef/scripts/docker_stats.sh create mode 100644 sdc-os-chef/scripts/docker_watchdog.sh create mode 100644 sdc-os-chef/scripts/restart_docker.sh create mode 100644 sdc-os-chef/sdc-backend/Dockerfile.template create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/attributes/default.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/BE-ecomp-error-configuration.yaml create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/BE-error-configuration.yaml create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/BE-logback.xml create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/consumers.py create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/files/default/user.py create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_1_cleanup_jettydir.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_2_locate_wars.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_3_create_DMaaP_keys.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_4_setup_configuration.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_5_setup_elasticsearch.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_6_setup_portal_properties.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_7_logback.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_8_errors_config.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/recipes/BE_9_import_Normatives.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-configuration.yaml.erb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-distribution-engine-configuration.yaml.erb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-elasticsearch.yml.erb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-portal.properties.erb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-catalog-be/templates/default/BE-titan.properties.erb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/attributes/default.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/files/default/check_Backend_Health.py create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/files/default/get-pip.py create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/files/default/normatives.tar.gz create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/recipes/check_Backend.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/recipes/import_Normatives.rb create mode 100644 sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/recipes/upgrade_Normatives.rb create mode 100644 sdc-os-chef/sdc-backend/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-backend/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-backend/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-backend/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-backend/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-backend/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-backend/chef-solo/normatives.json create mode 100644 sdc-os-chef/sdc-backend/chef-solo/normatives.rb create mode 100644 sdc-os-chef/sdc-backend/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-backend/chef-solo/roles/catalog-be.json create mode 100644 sdc-os-chef/sdc-backend/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-backend/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-backend/startup.sh create mode 100644 sdc-os-chef/sdc-cassandra/Dockerfile create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/recipes/01-configureCassandra.rb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/recipes/02-createCsUser.rb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/recipes/03-createDoxKeyspace.rb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/recipes/04-schemaCreation.rb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/cassandra-rackdc.properties.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/cassandra.yaml.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/configuration.yaml.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/create_cassandra_user.sh.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/create_dox_keyspace.sh.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/templates/default/elasticsearch.yml.erb create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/roles/cassandra-actions.json create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-cassandra/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-cassandra/startup.sh create mode 100644 sdc-os-chef/sdc-elasticsearch/Dockerfile create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/attributes/default.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/dashboard_BI-Dashboard.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/dashboard_Monitoring-Dashboared.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/logging.yml create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_JVM-used-CPU.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_JVM-used-Memory.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_JVM-used-Threads-Num.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_Show-all-certified-services-ampersand-resources-(per-day).json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_Show-all-created-Resources-slash-Services-slash-Products.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_Show-all-distributed-services.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_host-used-CPU.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_host-used-Threads-Num.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/files/default/visualization_number-of-user-accesses.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_1_setup_elasticsearch.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_2_setup_logging.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_3_create_audit_template.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_4_create_resources_template.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_5_create_monitoring_template.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/recipes/ES_6_kibana_dashboard_virtualization.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-repo/cookbooks/sdc-elasticsearch/templates/default/ES-elasticsearch.yml.erb create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/roles/elasticsearch.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-elasticsearch/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-elasticsearch/startup.sh create mode 100644 sdc-os-chef/sdc-frontend/Dockerfile.template create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/attributes/default.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/files/default/FE-ecomp-error-configuration.yaml create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/files/default/FE-logback.xml create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/files/default/FE-rest-configuration.yaml create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_1_cleanup_jettydir.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_2_setup_configuration.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_3_errors_config.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_4_logback.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_5_rest_configuration.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/recipes/FE_6_create_jetty_modules.rb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-configuration.yaml.erb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-http-ini.erb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-https-ini.erb create mode 100644 sdc-os-chef/sdc-frontend/chef-repo/cookbooks/sdc-catalog-fe/templates/default/FE-ssl-ini.erb create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/roles/catalog-fe.json create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-frontend/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-frontend/startup.sh create mode 100644 sdc-os-chef/sdc-kibana/Dockerfile create mode 100644 sdc-os-chef/sdc-kibana/chef-repo/cookbooks/sdc-kibana/attributes/default.rb create mode 100644 sdc-os-chef/sdc-kibana/chef-repo/cookbooks/sdc-kibana/recipes/setup_kibana.rb create mode 100644 sdc-os-chef/sdc-kibana/chef-repo/cookbooks/sdc-kibana/templates/default/kibana.yml.erb create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-kibana/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-kibana/startup.sh create mode 100644 sdc-os-chef/sdc-sanity/Dockerfile create mode 100644 sdc-os-chef/sdc-sanity/chef-repo/cookbooks/sdc-sanity/attributes/default.rb create mode 100644 sdc-os-chef/sdc-sanity/chef-repo/cookbooks/sdc-sanity/recipes/setup_sanity.rb create mode 100644 sdc-os-chef/sdc-sanity/chef-repo/cookbooks/sdc-sanity/templates/default/BE-titan.properties.erb create mode 100644 sdc-os-chef/sdc-sanity/chef-repo/cookbooks/sdc-sanity/templates/default/sdc-sanity.yaml.erb create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/LICENSE create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/README.md create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/chefignore create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/cookbooks/README.md create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/data_bags/README.md create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/environments/README.md create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/roles/README.md create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/solo.json create mode 100644 sdc-os-chef/sdc-sanity/chef-solo/solo.rb create mode 100644 sdc-os-chef/sdc-sanity/startup.sh create mode 100644 security-utils/.gitignore create mode 100644 security-utils/pom.xml create mode 100644 security-utils/src/main/java/org/openecomp/sdc/security/Passwords.java create mode 100644 security-utils/src/test/java/org/openecomp/sdc/security/PasswordTest.java create mode 100644 ui-ci-dev/.gitignore create mode 100644 ui-ci-dev/pom.xml create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/scripts/CreateVfsFromOnboarding.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/CanvasElement.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/CanvasManager.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/CleanTypeEnum.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/CreateAndImportButtonsEnum.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/CreateAndUpdateStepsEnum.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/DataTestIdEnum.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/MenuOptionsEnum.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/datatypes/UserCredentials.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/base/SetupCDTest.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/service/ServiceBasicTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/service/ServiceInputsTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/vf/VfBasicTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/vf/VfCanvasTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/vf/VfDeploymentTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/vf/VfOnboardingTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/execute/vfc/VfcBasicTests.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/run/StartTest.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/ArtifactUIUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/FileHandling.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/GeneralUIUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/MethodManipulationUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/OnboardUtility.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/ResourceUIUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/RestCDUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/utilities/ServiceUIUtils.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/verificator/ServiceVerificator.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/verificator/VerificatorUtil.java create mode 100644 ui-ci-dev/src/main/java/org/openecomp/sdc/uici/tests/verificator/VfVerificator.java create mode 100644 ui-ci-dev/src/main/resources/Files/CP.yml create mode 100644 ui-ci-dev/src/main/resources/Files/CP_LAN - Copy.yml create mode 100644 ui-ci-dev/src/main/resources/Files/CP_LAN.yml create mode 100644 ui-ci-dev/src/main/resources/Files/CP_WAN.yml create mode 100644 ui-ci-dev/src/main/resources/Files/Heat-File 1.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/Heat-File 2.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/Heat-File.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/InValid_tosca_File .yml create mode 100644 ui-ci-dev/src/main/resources/Files/JDM_vf.yml create mode 100644 ui-ci-dev/src/main/resources/Files/JDM_vfc.yml create mode 100644 ui-ci-dev/src/main/resources/Files/Sample_CSAR.csar create mode 100644 ui-ci-dev/src/main/resources/Files/Sample_CSAR2.csar create mode 100644 ui-ci-dev/src/main/resources/Files/UCPE_VFC.yml create mode 100644 ui-ci-dev/src/main/resources/Files/VF.yml create mode 100644 ui-ci-dev/src/main/resources/Files/VFC.yml create mode 100644 ui-ci-dev/src/main/resources/Files/VFCWithAttributes.yml create mode 100644 ui-ci-dev/src/main/resources/Files/VL.yml create mode 100644 ui-ci-dev/src/main/resources/Files/Valid xml.xml create mode 100644 ui-ci-dev/src/main/resources/Files/Valid_tosca_Mycompute.yml create mode 100644 ui-ci-dev/src/main/resources/Files/Valid_tosca_ReplaceTest.yml create mode 100644 ui-ci-dev/src/main/resources/Files/hot-nimbus-oam-volumes_v0.3.env create mode 100644 ui-ci-dev/src/main/resources/Files/hot-nimbus-oam_v0.6.env create mode 100644 ui-ci-dev/src/main/resources/Files/hot-nimbus-oam_v0.6.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/hot-nimbus-pcm_v0.6.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/myYang.xml create mode 100644 ui-ci-dev/src/main/resources/Files/mycompute.yml create mode 100644 ui-ci-dev/src/main/resources/Files/service_with_inputs.csar create mode 100644 ui-ci-dev/src/main/resources/Files/vADTRAN.zip create mode 100644 ui-ci-dev/src/main/resources/Files/vCDN.zip create mode 100644 ui-ci-dev/src/main/resources/Files/vFW_VF.yml create mode 100644 ui-ci-dev/src/main/resources/Files/vFW_VFC.yml create mode 100644 ui-ci-dev/src/main/resources/Files/vRouter_vfc.yml create mode 100644 ui-ci-dev/src/main/resources/Files/valid HEAT_ENV files.env create mode 100644 ui-ci-dev/src/main/resources/Files/validHEATfiles.yaml create mode 100644 ui-ci-dev/src/main/resources/Files/valid_vf.csar create mode 100644 ui-ci-dev/src/main/resources/Files/vf_with_groups.csar create mode 100644 ui-ci-dev/src/main/resources/Files/yamlSample.yml create mode 100644 ui-ci-dev/src/main/resources/Files/yamlSample2.yml create mode 100644 ui-ci-dev/src/main/resources/ci/conf/credentials.yaml create mode 100644 ui-ci-dev/src/main/resources/ci/conf/log4j.properties create mode 100644 ui-ci-dev/src/main/resources/ci/conf/sdc-packages.yaml create mode 100644 ui-ci-dev/src/main/resources/ci/conf/sdc.yaml create mode 100644 ui-ci-dev/src/main/resources/ci/conf/titan.properties create mode 100644 ui-ci-dev/src/main/resources/ci/scripts/startTest.sh create mode 100644 ui-ci-dev/src/main/resources/ci/testSuites/fullTests.xml create mode 100644 ui-ci-dev/src/main/resources/ci/testSuites/sanity.xml create mode 100644 ui-ci-dev/src/main/resources/images/gizmorambo.jpg create mode 100644 ui-ci-dev/src/test/Completetheform.js create mode 100644 ui-ci-dev/tarball.xml create mode 100644 ui-ci/.gitignore create mode 100644 ui-ci/pom.xml create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactInfo.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/BreadCrumbsButtonsEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CanvasElement.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CanvasManager.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CatalogFilterTitlesEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CheckBoxStatusEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CreateAndImportButtonsEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/CreateAndUpdateStepsEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/DataTestIdEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/GeneralCanvasItemsEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/LifeCycleStateEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/MenuOptionsEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyInfo.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceCategoriesNameEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceCategoriesNameEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/TypesEnum.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/UserCredentials.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/WorkMode.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/datatypes/environmentLocal create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/adminworkspace/AdminUserManagment.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/CatalogLeftFilterPanelCheckBoxTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/CatalogSearchBoxTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/ChangeLifeCycleStatFromCatalogTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/ImportAssetInUITest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/VFCanvasTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/VFUITest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/VfTests.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/resourceui/WorkspaceCheckBoxFilterTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/Import.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/Onboard.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/sanity/Vf.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/setup/OnboardCSVReport.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/setup/RemoteWebDriverTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/execute/setup/SetupCDTest.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ComponentLeftMenu.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/CompositionPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/DeploymentArtifactPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/GeneralPageElements.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/GovernorOperationPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/IconPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/InformationalArtifactPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/OpsOperationPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/PropertiesPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/PropertyPopup.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceGeneralPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ResourceLeftMenu.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ServiceGeneralPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/TesterOperationPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/ToscaArtifactsPage.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/pages/UploadArtifactPopup.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/AdditionalConditions.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/AdminWorkspaceUIUtilies.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/ArtifactUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/AuditCDUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/CanvasElement.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/CanvasManager.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/CaptureFailedTests.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/CatalogUIUtilitis.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/FileHandling.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/GeneralUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/ImportAssetUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/OnboardingUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/PropertiesUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/ResourceUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/RestCDUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/utilities/ServiceUIUtils.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/verificator/ServiceVerificator.java create mode 100644 ui-ci/src/main/java/org/openecomp/sdc/ci/tests/verificator/VfVerificator.java create mode 100644 ui-ci/src/main/resources/Downloads/CP_WAN.yml create mode 100644 ui-ci/src/main/resources/Downloads/Fortigate02_vFW_VFC.yml create mode 100644 ui-ci/src/main/resources/Files/CP.yml create mode 100644 ui-ci/src/main/resources/Files/CPWithAttributes.yml create mode 100644 ui-ci/src/main/resources/Files/CP_LAN - Copy.yml create mode 100644 ui-ci/src/main/resources/Files/CP_LAN.yml create mode 100644 ui-ci/src/main/resources/Files/CP_WAN.yml create mode 100644 ui-ci/src/main/resources/Files/DNSscaling12.8.16.zip create mode 100644 ui-ci/src/main/resources/Files/Heat-File 1.yaml create mode 100644 ui-ci/src/main/resources/Files/Heat-File 2.yaml create mode 100644 ui-ci/src/main/resources/Files/Heat-File.yaml create mode 100644 ui-ci/src/main/resources/Files/InValid_tosca_File .yml create mode 100644 ui-ci/src/main/resources/Files/JDM_vf.yml create mode 100644 ui-ci/src/main/resources/Files/JDM_vfc.yml create mode 100644 ui-ci/src/main/resources/Files/Sample_CSAR.csar create mode 100644 ui-ci/src/main/resources/Files/UCPE_VFC.yml create mode 100644 ui-ci/src/main/resources/Files/VF.yml create mode 100644 ui-ci/src/main/resources/Files/VFC.yml create mode 100644 ui-ci/src/main/resources/Files/VL.yml create mode 100644 ui-ci/src/main/resources/Files/Valid xml.xml create mode 100644 ui-ci/src/main/resources/Files/Valid_tosca_Mycompute.yml create mode 100644 ui-ci/src/main/resources/Files/Valid_tosca_ReplaceTest.yml create mode 100644 ui-ci/src/main/resources/Files/asc_heat 0 2.yaml create mode 100644 ui-ci/src/main/resources/Files/hot-nimbus-oam-volumes_v0.3.env create mode 100644 ui-ci/src/main/resources/Files/hot-nimbus-oam_v0.6.env create mode 100644 ui-ci/src/main/resources/Files/hot-nimbus-oam_v0.6.yaml create mode 100644 ui-ci/src/main/resources/Files/hot-nimbus-pcm_v0.6.yaml create mode 100644 ui-ci/src/main/resources/Files/sample-xml-alldata-1-1.xml create mode 100644 ui-ci/src/main/resources/Files/vFW_8.12.16.zip create mode 100644 ui-ci/src/main/resources/Files/vFW_VF.yml create mode 100644 ui-ci/src/main/resources/Files/vFW_VFC.yml create mode 100644 ui-ci/src/main/resources/Files/vLB12.8.16.zip create mode 100644 ui-ci/src/main/resources/Files/vRouter_vfc.yml create mode 100644 ui-ci/src/main/resources/Files/valid HEAT_ENV files.env create mode 100644 ui-ci/src/main/resources/Files/validHEATfiles.yaml create mode 100644 ui-ci/src/main/resources/ci/conf/credentials.yaml create mode 100644 ui-ci/src/main/resources/ci/conf/log4j.properties create mode 100644 ui-ci/src/main/resources/ci/conf/sdc-packages.yaml create mode 100644 ui-ci/src/main/resources/ci/conf/sdc.yaml create mode 100644 ui-ci/src/main/resources/ci/conf/titan.properties create mode 100644 ui-ci/src/main/resources/ci/scripts/startTest.sh create mode 100644 ui-ci/src/main/resources/ci/testSuites/ui-ci.xml create mode 100644 ui-ci/src/main/resources/images/gizmorambo.jpg create mode 100644 ui-ci/src/test/Completetheform.js create mode 100644 ui-ci/tarball.xml create mode 100644 webseal-simulator/README.txt create mode 100644 webseal-simulator/pom.xml create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/Login.java create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/MethodEnum.java create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/MutableHttpServletRequest.java create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/SdcProxy.java create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/User.java create mode 100644 webseal-simulator/src/main/java/org/openecomp/sdc/webseal/simulator/conf/Conf.java create mode 100644 webseal-simulator/src/main/resources/webseal.conf create mode 100644 webseal-simulator/src/main/webapp/WEB-INF/jetty-web.xml create mode 100644 webseal-simulator/src/main/webapp/WEB-INF/web.xml create mode 100644 webseal-simulator/src/main/webapp/login.html diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..da39ab03ca --- /dev/null +++ b/.gitignore @@ -0,0 +1,99 @@ +# Eclipse +.classpath +.project +.settings/ + +# Maven +log/ +target/ + +# Package Files # +*.jar +*.war +*.ear + +# Other +*.class +*.orig +catalog-ui/.* +catalog-ui/app/scripts/tsconfig.json +catalog-ui/app/scripts/references.ts +catalog-ui/app/scripts/**/*.js +catalog-ui/app/scripts/**/*.js.map + +# catalog-ui +catalog-ui/app/**/*.css +catalog-ui/.editorconfig +catalog-ui/.jshintrc +catalog-ui/.yo-rc.json +catalog-ui/app/robots.txt +catalog-ui/node_modules/ +catalog-ui/bower_components/ +catalog-ui/app/tsconfig.json + + +catalog-be/.checkstyle +catalog-be/bin/ +catalog-be/src/main/java/META-INF/MANIFEST.MF +catalog-builders/src/test/java/com/att/tlv/sdc/be/builders/tosca/t1 +a4c/ +catalog-ui/*.tmp.txt +catalog-dao/bin/ +catalog-ui/dist +catalog-builders/bin/ +common-app-api/bin/ +data/compute.png +data/loadbalancer.png +data/mysql.png +data/network.png +data/normative-types-blockStorage.yml +data/normative-types-compute.yml +data/normative-types-database.yml +data/normative-types-DBMS.yml +data/normative-types-network.yml +data/normative-types-objectStorage.yml +data/normative-types-root.yml +data/normative-types-softwareComponent.yml +data/normative-types-webApplication.yml +data/normative-types-webServer.yml +data/objectstore.png +data/relational_db.png +data/root.png +data/router.png +data/software.png +data/volume.png +catalog-ui/app/dist/* +catalog-fe/src/main/webapp/* +catalog-fe/bin +!catalog-fe/src/main/webapp/WEB-INF/ +!catalog-fe/src/main/webapp/META-INF/ +ui-ci/.tern-project +catalog-be/data/* +ci/src/main/java/com/att/tlv/sdc/ci/tests/execute/ShayPracticeTests.java +ci/src/main/java/com/att/tlv/sdc/ci/tests/execute/ShayPracticeTests.java +.metadata/* +.metadata/* +.idea/* +*.iml +catalog-ui/npm-debug.log +sdnc-tests/logs/wordnik.log +distribution-ci/logs/* +vagrant-asdc-all-in-one/ +catalog-ui/tests/Coverage/* +catalog-ui/Chrome* +catalog-ui/PhantomJS_1.9.8_(Windows_7_0.0.0)/* + +.metadata/ +bin/ +Vagrantfile +sdnc-tests/test-output/* +sdnc-tests-new-frame-work/test-output/* +ui-ci/test-output/* + + +sdnc-tests-new-frame-work/test-output/** +asdc-tests/test-output/** + +asdc-chef/cookbooks/Deploy-SDandC/attributes/version.rb +asdc-tests/ExtentReport/ASDC_CI_Extent_Report.html + diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000000..921054bdf2 --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=gerrit.openecomp.org +port=29418 +project=sdc.git \ No newline at end of file diff --git a/.pydevproject b/.pydevproject new file mode 100644 index 0000000000..40e9f40a0a --- /dev/null +++ b/.pydevproject @@ -0,0 +1,5 @@ + + +Default +python 2.7 + diff --git a/LICENSE.TXT b/LICENSE.TXT new file mode 100644 index 0000000000..649de64348 --- /dev/null +++ b/LICENSE.TXT @@ -0,0 +1,24 @@ +/* +* ============LICENSE_START========================================== +* =================================================================== +* Copyright © 2017 AT&T Intellectual Property. +* Copyright © 2017 Amdocs +* 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============================================ +* +* ECOMP and OpenECOMP are trademarks +* and service marks of AT&T Intellectual Property. +* +*/ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000000..297457a339 --- /dev/null +++ b/README.md @@ -0,0 +1,165 @@ +# OpenECOMP SDC + +--- +--- + + +# Introduction + +OpenECOMP SDC is delivered with 5 Docker containers: +1. sdc-FE - frontend SDC application running on jetty server +2. sdc-BE - backend SDC application running on jetty server +3. sdc-kbn - hosting kibana application +4. sdc-cs - hosting cassandra +5. sdc-es - hosting elastic search + +All containers runs on the same machine and can be started by runnin the command: +/data/scripts/docker_run.sh -e -r -p +Example: /data/scripts/docker_run.sh -e OS-ETE-DFW -p 51220 + + +# Compiling SDC + +SDC is built from several projects, while "sdc-main" contains the main pom.xml for all project: +- catalog-be - backend code +- catalog-fe - frontend java code (servlet, proxy) +- catalog-dao - database layer +- catalog-model - data model of the application +- catalog-ui - front end code (javascript, html, css) +- common-app-api - common code for frontend and backend +- common-be - utilities, datatypes and enums +- security-utils - handle encryption/decryption of passwords + +SDC projects can be compiled easily using maven command: `mvn clean install`. +In order to build all projects, enter to sdc-main project and run the command: `mvn clean install`. +By default unit test will run when compiling + +** igor ** +Docker containers are build with the following profile +`-P docker -Ddocker.buildArg.chef_repo_branch_name=bugfix/external_adress -Ddocker.buildArg.chef_repo_git_username=git -Ddocker.buildArg.chef_repo_address=23.253.149.175/SDC -Ddocker.buildArg.chef_repo_git_name=chef-repo` + + +# Getting the containers + +***to be changed for rrelease*** OpenECOMP SDC containers are stored on the Rackspace Nexus Docker Registry + +The following Docker images are the actual deployment images used for running SDC + +| Name | Tag | Description | +|---------|-----------|-------------------------------------------------------------------------------------------------------------------------------| +| sdc-FE | 1610.2.16 | Contains Jetty + OpenJDK + SDC frontend code + **3rd party jars** | +| sdc-BE | 1610.2.16 | Contains Jetty + OpenJDK + SDC backend code + **3rd party jars** | +| sdc-kbn | 1610.2.16 | Contains nodeJs + Kibana application | +| sdc-cs | 1610.2.16 | OpenJDK + Contains cassandra application | +| sdc-es | 1610.2.16 | Elastic search application | + + +*********************** Israel ************************ +# Starting SDC +There are several ways to start OpenECOMP SDC: +TBD - Israel + +# Accessing SDC +SDC UI can be accessed from: + +### Ecomp portal +Login to ecomp portal URL with user that has permission for SDC application. +Define in your hosts file the following: + sdc.api.simpledemo.openecomp.org + portal.api.simpledemo.openecomp.org +Open browser and navigate to: http://portal.api.simpledemo.openecomp.org:8989/ECOMPPORTAL/login.htm + +### Webseal simulator +This options is for developers to run locally SDC +1. Build web simulator WAR file: run `mvn clean install` on project "webseal simulator". This will generate war file (WSSimulator.war) in the target folder. +2. Copy the war to: /home/vagrant/webseal-simulator/webapps +3. Add users to simulator: open configuration file - /home/vagrant/webseal-simulator/config/webseal.conf and add new user to the user list. + Note: You need to define the user in the SDC as well. +4. Restart the simulator: + Stop the simulator: stopWebsealSimulator.sh + Start the simulator: startWebsealSimulator.sh +5. Enter to UI: http://:8285/sdc1/login + +### SDC import normatives from CLI +SDC needs to work with predefined basic normatives, in order to update the database with the normatives need to: +1. From catalog-be project copy: + src\main\resources\import\tosca -> to :catalog-be/import/tosca + src\main\resources\scripts\import\tosca ->to :catalog-be/scripts/import/tosca +2. cd catalog-be/scripts/import/tosca +3. Run: python importNormativeAll.py +4. Wait until all normatives are loaded to the database + + +### SDC APIs +TBD + +##### Main API endpoints in the first open source release + +- ***to be completed*** APIHandler health checks +TBD + +# Configuration of SDC +TBD + +Here are the main parameters you could change: +TBD + +The credentials are defined in 2 places: +TBD + +# Logging +TBD + +### Jetty +TBD + +### Debuging +TBD + +# Testing SDC Functionalities +TBD + +### Frontend Local Env - onboarding + +Steps: +------ +Install nodejs & gulp +1. download nodejs from here: https://nodejs.org/en/ (take the "current" version with latest features) & install it. +2. install gulp by running the following command: npm install --global gulp-cli + +Install DOX-UI a: +----------------- +1. pull for latest changes +2. go to folder dox-sequence-diagram-ui +3. run npm install +4. wait for it... +5. go to folder dox-ui +6. run npm install +7. create a copy of devConfig.defaults.json file and name it devConfig.json (we already configured git to ignore it so it will not be pushed) +8. in that file, populate the fields of the IP addresses of your BE machine you'd like to connect (pay attention, it is a JSON file): For example http://: +9. after everything was successful, run gulp +10. after server was up, your favorite UI will wait for you at: http://localhost:9000/sdc1/proxy-designer1#/onboardVendor + +Troubleshooting: +---------------- +| Problem | Why is this happening | Solution | +-------------------------------------------------------------------------------------------------------------------------------------------------------- +| npm cannot reach destination | onboarding proxy | When within onboarding network, you should set onboarding proxy to NPM as the following: | +| | | npm config set proxy http://genproxy:8080 | +| | | npm config set https-proxy http://genproxy:8080 | +| | | | +| git protocol is blocked | onboarding network | When within onboarding network, you should set globally that when git | +| and cannot connect | rules for protocols | protocol is used, then it will be replaced with "https" | +| | | git config --global url."https://".insteadOf git:// | +-------------------------------------------------------------------------------------------------------------------------------------------------------- + +# Getting Help + +*** to be completed on rrelease *** + +SDC@lists.openecomp.org + +SDC Javadoc and Maven site + +*** to be completed on rrelease *** + diff --git a/asdc-tests/.gitignore b/asdc-tests/.gitignore new file mode 100644 index 0000000000..9b563712b6 --- /dev/null +++ b/asdc-tests/.gitignore @@ -0,0 +1,4 @@ +/target +/build/ +/bin/ +/target/ diff --git a/asdc-tests/pom.xml b/asdc-tests/pom.xml new file mode 100644 index 0000000000..ce346ae901 --- /dev/null +++ b/asdc-tests/pom.xml @@ -0,0 +1,367 @@ + + + 4.0.0 + + asdc-tests + + + org.openecomp.sdc + sdc-main + 1.0.0-SNAPSHOT + + + + + + com.google.guava + guava + compile + + + + junit + junit + 4.12 + compile + + + + org.testng + testng + 6.9.10 + compile + + + + com.relevantcodes + extentreports + 2.41.0 + compile + + + + org.mockito + mockito-all + 1.10.19 + compile + + + + com.typesafe + config + 1.0.2 + compile + + + + log4j + log4j + 1.2.17 + compile + + + + com.jcraft.jsch + com.springsource.com.jcraft.jsch + 0.1.41 + compile + + + + org.openecomp.sdc + common-app-api + ${common-app-api.version} + compile + + + + org.openecomp.sdc.be + common-be + ${common-be.version} + compile + + + + + org.openecomp.sdc.be + catalog-model + ${catalog-model.version} + compile + + + + + org.openecomp.sdc.be + catalog-dao + ${catalog-dao.version} + compile + + + + org.functionaljava + functionaljava + compile + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra.driver.version} + compile + + + + + + + org.slf4j + slf4j-api + compile + + + + ch.qos.logback + logback-classic + compile + + + + ch.qos.logback + logback-core + compile + + + + com.googlecode.json-simple + json-simple + compile + + + + + + org.apache.commons + commons-jci-core + compile + + + + commons-codec + commons-codec + compile + + + + + + com.google.code.gson + gson + compile + + + + + org.yaml + snakeyaml + compile + + + + + org.apache.httpcomponents + httpclient + compile + + + + org.apache.httpcomponents + httpmime + compile + + + + commons-io + commons-io + 2.5 + compile + + + + commons-logging + commons-logging + compile + + + + + org.apache.httpcomponents + httpcore + compile + + + + + com.thinkaurelius.titan + titan-core + ${titan.version} + compile + + + slf4j-log4j12 + org.slf4j + + + + + + com.thinkaurelius.titan + titan-cassandra + ${titan.version} + compile + + + slf4j-log4j12 + org.slf4j + + + + + + org.codehaus.jackson + jackson-mapper-asl + 1.9.2 + compile + + + + com.fasterxml.jackson.core + jackson-databind + 2.3.1 + compile + + + + com.fasterxml.jackson.core + jackson-core + 2.3.1 + compile + + + + org.openecomp.sdc + sdc-distribution-client + 1.0.0-SNAPSHOT + compile + + + + org.openecomp.ecompsdkos + ecompFW + ${ecomp.version} + compile + + + slf4j-log4j12 + org.slf4j + + + + + + org.json + json + 20090211 + + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.5 + + + create.jar.with.dependencies + package + + single + + + + + org.openecomp.sdc.ci.tests.run.StartTest + + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.6 + + + + ${project.artifactId} + false + ${project.basedir}/tarball.xml + + assemble-file + package + + single + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + + copy-asdc-tests + install + + copy-resources + + + ${project.parent.basedir}/sdc-os-chef/sdc-sanity/chef-repo/cookbooks/sdc-sanity/files/default + + + ./target + + asdc-tests.tar + + + + + + + + + + + + diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentBaseTest.java new file mode 100644 index 0000000000..370c195f53 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentBaseTest.java @@ -0,0 +1,348 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.api; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.thinkaurelius.titan.core.TitanGraphQuery; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.cassandra.CassandraUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.ITestResult; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.AfterSuite; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.BeforeSuite; + +import com.relevantcodes.extentreports.ExtentReports; +import com.relevantcodes.extentreports.ExtentTest; +import com.relevantcodes.extentreports.LogStatus; +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import ch.qos.logback.classic.Level; +import ch.qos.logback.classic.LoggerContext; + +public abstract class ComponentBaseTest { + + private static Logger logger = LoggerFactory.getLogger(ComponentBaseTest.class.getName()); + + // public ComponentBaseTest(TestName testName, String className) { + // super(testName, className); + // } + + protected static ExtentReports extentReport; + protected static ExtentTest extendTest; + public static final String REPORT_FOLDER = "./ExtentReport/"; + private static final String REPORT_FILE_NAME = "ASDC_CI_Extent_Report.html"; + protected static TitanGraph titanGraph; + private static Config myconfig; + public static Config config; + + public static enum ComponentOperationEnum { + CREATE_COMPONENT, UPDATE_COMPONENT, GET_COMPONENT, DELETE_COMPONENT, CHANGE_STATE_CHECKIN, CHANGE_STATE_CHECKOUT, CHANGE_STATE_UNDO_CHECKOUT + }; + + public ComponentBaseTest(TestName name, String name2) { + // TODO Auto-generated constructor stub + LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); + lc.getLogger("com.thinkaurelius").setLevel(Level.INFO); + lc.getLogger("com.datastax").setLevel(Level.INFO); + lc.getLogger("io.netty").setLevel(Level.INFO); + lc.getLogger("c.d").setLevel(Level.INFO); + } + + @BeforeSuite(alwaysRun = true) + public static void openTitan() throws FileNotFoundException { + + File dir = new File(REPORT_FOLDER); + try { + FileUtils.deleteDirectory(dir); + } catch (IOException e) { + } + extentReport = new ExtentReports(REPORT_FOLDER + REPORT_FILE_NAME); + + myconfig = Utils.getConfig(); + config = Utils.getConfig(); + logger.trace(config.toString()); + String titanConfigFilePath = myconfig.getTitanPropertiesFile(); + System.out.println("titan configuration path:\n"+titanConfigFilePath); + titanGraph = TitanFactory.open(titanConfigFilePath); + System.out.println("is open:\n"+titanGraph.isOpen()); + assertNotNull(titanGraph); + } + + @AfterSuite(alwaysRun = true) + public static void shutdownTitan() { + if (titanGraph.isOpen()) { + titanGraph.close(); + } + CassandraUtils.close(); + } + + @BeforeMethod(alwaysRun = true) + public void beforeState(java.lang.reflect.Method method) throws Exception { + + cleanComponents(); + CassandraUtils.truncateAllKeyspaces(); + extendTest = extentReport.startTest(method.getName()); + extendTest.log(LogStatus.INFO, "Test started"); + + } + + @AfterMethod(alwaysRun = true) + public void afterState(ITestResult result) throws Exception { + cleanComponents(); + CassandraUtils.truncateAllKeyspaces(); + + if (result.isSuccess()) { + extendTest.log(LogStatus.PASS, "Test Result : Success"); + } else { + extendTest.log(LogStatus.ERROR, "ERROR - The following exepction occured"); + extendTest.log(LogStatus.ERROR, result.getThrowable()); + extendTest.log(LogStatus.FAIL, "Failure"); + } + + extentReport.endTest(extendTest); + extentReport.flush(); + + } + + public void verifyErrorCode(RestResponse response, String action, int expectedCode) { + assertNotNull("check response object is not null after " + action, response); + assertNotNull("check error code exists in response after " + action, response.getErrorCode()); + assertEquals("Check response code after + action" + action, expectedCode, response.getErrorCode().intValue()); + } + + private void cleanComponents() throws Exception { + + // Components to delete + List vfResourcesToDelete = new ArrayList(); + List nonVfResourcesToDelete = new ArrayList(); + List servicesToDelete = new ArrayList(); + List productsToDelete = new ArrayList(); + + // Categories to delete + List> productGroupingsToDelete = new ArrayList<>(); + List> productSubsToDelete = new ArrayList<>(); + List> resourceSubsToDelete = new ArrayList<>(); + List productCategoriesToDelete = new ArrayList<>(); + List resourceCategoriesToDelete = new ArrayList(); + List serviceCategoriesToDelete = new ArrayList(); + + List resourcesNotToDelete = config.getResourcesNotToDelete(); + List resourceCategoriesNotToDelete = config.getResourceCategoriesNotToDelete(); + List serviceCategoriesNotToDelete = config.getServiceCategoriesNotToDelete(); + TitanGraphQuery query = titanGraph.query(); + query = query.has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()); + Iterable vertices=query.vertices(); +// Iterable vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex vertex = iter.next(); + Boolean isAbstract = vertex.value(GraphPropertiesDictionary.IS_ABSTRACT.getProperty()); + // if (!isAbstract) { + String name = vertex.value(GraphPropertiesDictionary.NAME.getProperty()); + String version = vertex.value(GraphPropertiesDictionary.VERSION.getProperty()); + + if ((resourcesNotToDelete != null && !resourcesNotToDelete.contains(name)) || (version != null && !version.equals("1.0"))) { + String id = vertex.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String resourceType = vertex.value(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty()); + // if (name.startsWith("ci")) { + if (resourceType.equals(ResourceTypeEnum.VF.name())) { + vfResourcesToDelete.add(id); + } else { + nonVfResourcesToDelete.add(id); + } + // } + } else if ((resourcesNotToDelete != null && !resourcesNotToDelete.contains(name)) || (version != null && version.equals("1.0"))) { + if ((boolean) vertex.value(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty()) == false) { + vertex.property(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + } + } + // } + } + } + vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex vertex = iter.next(); + String id = vertex.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String name = vertex.value(GraphPropertiesDictionary.NAME.getProperty()); + // if (name.startsWith("ci")){ + servicesToDelete.add(id); + // } + } + } + + vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Product.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex vertex = iter.next(); + String id = vertex.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String name = vertex.value(GraphPropertiesDictionary.NAME.getProperty()); + //if (name.startsWith("ci")) { + productsToDelete.add(id); + //} + } + } + + // Getting categories + + vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.ResourceNewCategory.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex category = iter.next(); + String name = category.value(GraphPropertiesDictionary.NAME.getProperty()); + if (!resourceCategoriesNotToDelete.contains(name)) { + String catId = category.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + resourceCategoriesToDelete.add(catId); + Iterator subs = category.vertices(Direction.OUT, GraphEdgeLabels.SUB_CATEGORY.getProperty()); + while (subs.hasNext()) { + Vertex sub = subs.next(); + String subCatId = sub.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + resourceSubsToDelete.add(new ImmutablePair(catId, subCatId)); + } + } + } + } + + vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.ServiceNewCategory.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex category = iter.next(); + String name = category.value(GraphPropertiesDictionary.NAME.getProperty()); + if (!serviceCategoriesNotToDelete.contains(name)) { + String id = category.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + serviceCategoriesToDelete.add(id); + } + } + } + + vertices = titanGraph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.ProductCategory.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex category = iter.next(); + String catId = category.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + productCategoriesToDelete.add(catId); + Iterator subs = category.vertices(Direction.OUT, GraphEdgeLabels.SUB_CATEGORY.getProperty()); + while (subs.hasNext()) { + Vertex sub = subs.next(); + String subCatId = sub.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + productSubsToDelete.add(new ImmutablePair(catId, subCatId)); + Iterator groupings = sub.vertices(Direction.OUT, GraphEdgeLabels.GROUPING.getProperty()); + while (groupings.hasNext()) { + Vertex grouping = groupings.next(); + String groupId = grouping.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + productGroupingsToDelete.add(new ImmutableTriple(catId, subCatId, groupId)); + } + } + + } + } + + titanGraph.tx().commit(); + + String adminId = UserRoleEnum.ADMIN.getUserId(); + String productStrategistId = UserRoleEnum.PRODUCT_STRATEGIST1.getUserId(); + + // Component delete + for (String id : productsToDelete) { + RestResponse deleteProduct = ProductRestUtils.deleteProduct(id, productStrategistId); + + } + for (String id : servicesToDelete) { + RestResponse deleteServiceById = ServiceRestUtils.deleteServiceById(id, adminId); + + } + for (String id : vfResourcesToDelete) { + RestResponse deleteResource = ResourceRestUtils.deleteResource(id, adminId); + + } + + for (String id : nonVfResourcesToDelete) { + RestResponse deleteResource = ResourceRestUtils.deleteResource(id, adminId); + + } + + // Categories delete - product + String componentType = BaseRestUtils.PRODUCT_COMPONENT_TYPE; + for (ImmutableTriple triple : productGroupingsToDelete) { + CategoryRestUtils.deleteGrouping(triple.getRight(), triple.getMiddle(), triple.getLeft(), productStrategistId, componentType); + } + for (ImmutablePair pair : productSubsToDelete) { + CategoryRestUtils.deleteSubCategory(pair.getRight(), pair.getLeft(), productStrategistId, componentType); + } + for (String id : productCategoriesToDelete) { + CategoryRestUtils.deleteCategory(id, productStrategistId, componentType); + } + + // Categories delete - resource + componentType = BaseRestUtils.RESOURCE_COMPONENT_TYPE; + for (ImmutablePair pair : resourceSubsToDelete) { + CategoryRestUtils.deleteSubCategory(pair.getRight(), pair.getLeft(), adminId, componentType); + } + for (String id : resourceCategoriesToDelete) { + CategoryRestUtils.deleteCategory(id, adminId, componentType); + } + // Categories delete - resource + componentType = BaseRestUtils.SERVICE_COMPONENT_TYPE; + for (String id : serviceCategoriesToDelete) { + CategoryRestUtils.deleteCategory(id, adminId, componentType); + } + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentInstanceBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentInstanceBaseTest.java new file mode 100644 index 0000000000..2b0a35d472 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/ComponentInstanceBaseTest.java @@ -0,0 +1,763 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.api; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.Assert; + +public class ComponentInstanceBaseTest extends ComponentBaseTest { + public static final String acceptHeaderData = "application/json"; + // Req/cap of container component + protected Map> expectedContainerCapabilities; + protected Map> expectedContainerRequirements; + protected Map>> removedRequirements; + protected Map>, Map>>> expectedContInstReqCap; + + protected User sdncPsDetails1; + protected User sdncPsDetails2; + protected User sdncPmDetails1; + protected User sdncPmDetails2; + protected User sdncDesignerDetails; + protected User sdncAdminDetails; + protected User sdncTesterDetails; + protected ResourceReqDetails resourceDetailsVFC_01; + protected ResourceReqDetails resourceDetailsVFC_02; + protected ResourceReqDetails resourceDetailsVF_01; + protected ResourceReqDetails resourceDetailsVF_02; + protected ResourceReqDetails resourceDetailsCP_01; + protected ResourceReqDetails resourceDetailsCP_02; + protected ResourceReqDetails resourceDetailsVL_01; + protected ResourceReqDetails resourceDetailsVL_02; + protected ServiceReqDetails serviceDetails_01; + protected ServiceReqDetails serviceDetails_02; + protected ServiceReqDetails serviceDetails_03; + protected ProductReqDetails productDetails_01; + protected ProductReqDetails productDetails_02; + + public void init() { + // Req/caps of inner componentInstances + expectedContainerCapabilities = new LinkedHashMap>(); + expectedContainerRequirements = new LinkedHashMap>(); + removedRequirements = new HashMap<>(); + expectedContInstReqCap = new HashMap<>(); + + sdncPsDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + sdncPsDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST2); + sdncPmDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + sdncPmDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER2); + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncTesterDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + resourceDetailsVFC_01 = ElementFactory.getDefaultResourceByType("ciVFC100", NormativeTypesEnum.SOFTWARE_COMPONENT, ResourceCategoryEnum.GENERIC_DATABASE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VFC.toString()); // resourceType = VFC + resourceDetailsVFC_02 = ElementFactory.getDefaultResourceByType("ciVFC200", NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VFC.toString()); + resourceDetailsVF_01 = ElementFactory.getDefaultResourceByType("ciVF100", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VF.toString()); + resourceDetailsVF_02 = ElementFactory.getDefaultResourceByType("ciVF200", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VF.toString()); + resourceDetailsCP_01 = ElementFactory.getDefaultResourceByType("ciCP100", NormativeTypesEnum.PORT, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), ResourceTypeEnum.CP.toString()); + resourceDetailsCP_02 = ElementFactory.getDefaultResourceByType("ciCP200", NormativeTypesEnum.PORT, ResourceCategoryEnum.GENERIC_DATABASE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.CP.toString()); + resourceDetailsVL_01 = ElementFactory.getDefaultResourceByType("ciVL100", NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VL.toString()); + resourceDetailsVL_02 = ElementFactory.getDefaultResourceByType("ciVL200", NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VL.toString()); + serviceDetails_01 = ElementFactory.getDefaultService("ciNewtestservice1", ServiceCategoriesEnum.MOBILITY, sdncDesignerDetails.getUserId()); + serviceDetails_02 = ElementFactory.getDefaultService("ciNewtestservice2", ServiceCategoriesEnum.MOBILITY, sdncDesignerDetails.getUserId()); + serviceDetails_03 = ElementFactory.getDefaultService("ciNewtestservice3", ServiceCategoriesEnum.MOBILITY, sdncDesignerDetails.getUserId()); + productDetails_01 = ElementFactory.getDefaultProduct("ciProduct01"); + productDetails_02 = ElementFactory.getDefaultProduct("ciProduct02"); + } + + public ComponentInstanceBaseTest(TestName testName, String className) { + super(testName, className); + } + + public void verifyVFReqCap(String componentId) throws Exception { + RestResponse restResponse = ResourceRestUtils.getResource(componentId); + Resource resource = ResponseParser.parseToObject(restResponse.getResponse(), Resource.class); + verifyReqCap(resource); + } + + public void verifyServiceReqCap(String componentId) throws Exception { + RestResponse restResponse = ServiceRestUtils.getService(componentId, sdncDesignerDetails); + Service service = ResponseParser.parseToObject(restResponse.getResponse(), Service.class); + verifyReqCap(service); + } + + public void verifyProductReqCap(String componentId) throws Exception { + RestResponse restResponse = ProductRestUtils.getProduct(componentId, sdncPsDetails1.getUserId()); + Product product = ResponseParser.parseToObject(restResponse.getResponse(), Product.class); + verifyReqCap(product); + } + + public void verifyReqCap(Component actualComponent) { + verifyContainerReqCap(actualComponent); + verifyCompInstReqCap(actualComponent); + } + + public RestResponse changeServiceInstanceVersion(String componentUniqueId, String serviceInstanceToReplaceUniqueId, String serviceUniqueId, User sdncModifierDetails, ComponentTypeEnum componentType, boolean isHighestLevel) throws Exception { + RestResponse changeResourceInstanceVersion = ProductRestUtils.changeServiceInstanceVersion(componentUniqueId, serviceInstanceToReplaceUniqueId, serviceUniqueId, sdncModifierDetails, componentType); + if (changeResourceInstanceVersion.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS) && isHighestLevel) { + /* + * // Add RI Capabilities and Requirements to expected MAP --> expectedVfCapabilities and expectedVfRequirements + * + * ComponentInstance componentInstance = ResponseParser.parseToObjectUsingMapper( changeResourceInstanceVersion.getResponse(), ComponentInstance.class); addCompInstReqCapToExpected(componentInstance, componentType); + */ + } + return changeResourceInstanceVersion; + } + + protected void updateExpectedReqCapAfterChangeLifecycleState(String oldContainerUniqueIdToReplace, String newContainerUniqueId) { + + // Update of container req/cap + + Set compInstKeysToChange = new HashSet<>(); + + for (String expKey : expectedContainerCapabilities.keySet()) { + List expCapList = expectedContainerCapabilities.get(expKey); + for (CapabilityDefinition cap : expCapList) { + String ownerId = cap.getOwnerId(); + + if (ownerId.contains(oldContainerUniqueIdToReplace)) { + compInstKeysToChange.add(ownerId); + cap.setOwnerId(cap.getOwnerId().replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + } + } + } + + for (String expKey : expectedContainerRequirements.keySet()) { + List expCapList = expectedContainerRequirements.get(expKey); + for (RequirementDefinition cap : expCapList) { + String ownerId = cap.getOwnerId(); + if (ownerId.contains(oldContainerUniqueIdToReplace)) { + compInstKeysToChange.add(ownerId); + cap.setOwnerId(cap.getOwnerId().replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + } + } + } + + // Update of internal comp instances req/cap + for (String oldKey : compInstKeysToChange) { + ImmutablePair>, Map>> immutablePair = expectedContInstReqCap.get(oldKey); + if (immutablePair != null) { + expectedContInstReqCap.remove(oldKey); + String newKey = oldKey.replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId); + expectedContInstReqCap.put(newKey, immutablePair); + } + } + + // Update of removed req + for (String oldKey : compInstKeysToChange) { + Map> map = removedRequirements.get(oldKey); + if (map != null) { + removedRequirements.remove(oldKey); + String newKey = oldKey.replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId); + Collection> values = map.values(); + if (values != null) { + for (List list : values) { + for (RequirementDefinition reqDef : list) { + reqDef.setOwnerId(reqDef.getOwnerId().replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + } + } + } + removedRequirements.put(newKey, map); + } + } + } + + private void verifyCompInstReqCap(Component actualComponent) { + List componentInstances = actualComponent.getComponentInstances(); + if (componentInstances != null) { + assertEquals(expectedContInstReqCap.size(), componentInstances.size()); + for (ComponentInstance compInst : componentInstances) { + String uniqueId = compInst.getUniqueId(); + // System.out.println("Verifying req/cap of component instance + // "+ uniqueId); + Map> actualCompInstReq = compInst.getRequirements(); + if (actualCompInstReq == null) { + actualCompInstReq = new HashMap<>(); + } + Map> actualCompInstCap = compInst.getCapabilities(); + if (actualCompInstCap == null) { + actualCompInstCap = new HashMap<>(); + } + ImmutablePair>, Map>> expReqCap = expectedContInstReqCap.get(uniqueId); + assertNotNull(expReqCap); + // System.out.println("expected instance requirements: + // "+expReqCap.right); + // System.out.println("expected instance capabilities: + // "+expReqCap.left); + // System.out.println("actual instance requirements: + // "+actualCompInstReq); + // System.out.println("actual instance capabilities: + // "+actualCompInstCap); + + // REQ comparison + compareReqCapMaps(expReqCap.right, actualCompInstReq); + + // CAP comparison + compareReqCapMaps(expReqCap.left, actualCompInstCap); + } + + } else { + assertTrue(expectedContInstReqCap.isEmpty()); + } + } + + private void verifyContainerReqCap(Component actualComponent) { + Map> actualContainerRequirements = actualComponent.getRequirements(); + if (actualContainerRequirements == null) { + actualContainerRequirements = new HashMap<>(); + } + Map> actualContainerCapabilities = actualComponent.getCapabilities(); + if (actualContainerCapabilities == null) { + actualContainerCapabilities = new HashMap<>(); + } + // System.out.println("Verifying req/cap of container component "+ + // actualComponent.getUniqueId()); + // System.out.println("expected container requirements: + // "+expectedContainerRequirements); + // System.out.println("expected container capabilities: + // "+expectedContainerCapabilities); + // System.out.println("actual container requirements: + // "+actualContainerRequirements); + // System.out.println("actual container capabilities: + // "+actualContainerCapabilities); + + // REQ comparison + compareReqCapMaps(expectedContainerRequirements, actualContainerRequirements); + + // CAP comparison + compareReqCapMaps(expectedContainerCapabilities, actualContainerCapabilities); + } + + private void compareReqCapMaps(Map> expectedMap, Map> actualMap) { + assertEquals(expectedMap.size(), actualMap.size()); + for (String expKey : expectedMap.keySet()) { + List expCapList = expectedMap.get(expKey); + List actCapList = actualMap.get(expKey); + assertEquals(expCapList.size(), actCapList.size()); + assertEquals(new HashSet<>(expCapList), new HashSet<>(actCapList)); + } + } + + public void addCompInstReqCapToExpected(ComponentInstance componentInstance, ComponentTypeEnum containerComponentType) throws Exception { + String uniqueId = componentInstance.getUniqueId(); + String name = componentInstance.getName(); + String originComponentId = componentInstance.getComponentUid(); + RestResponse getResponse = null; + ComponentTypeEnum compInstType = getCompInstTypeByContainerType(containerComponentType); + Component component = null; + if (compInstType == ComponentTypeEnum.RESOURCE) { + getResponse = ResourceRestUtils.getResource(sdncDesignerDetails, originComponentId); + ResourceRestUtils.checkSuccess(getResponse); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Resource.class); + } else if (compInstType == ComponentTypeEnum.SERVICE) { + getResponse = ServiceRestUtils.getService(originComponentId, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getResponse); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Service.class); + } else { + Assert.fail("Unsupported type - " + containerComponentType); + } + + Map> resourceRequirements = component.getRequirements(); + if (resourceRequirements == null) { + resourceRequirements = new HashMap<>(); + } + Function>, List> requirementDefinitionMapper = e -> new ArrayList<>(e.getValue().stream().map(item -> new RequirementDefinition(item)).collect(Collectors.toList())); + Map> reqCopy = resourceRequirements.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), requirementDefinitionMapper)); + + Map> resourceCapabilities = component.getCapabilities(); + if (resourceCapabilities == null) { + resourceCapabilities = new HashMap<>(); + } + + Function>, List> capabilityDefinitionMapper = e -> new ArrayList<>(e.getValue().stream().map(item -> new CapabilityDefinition(item)).collect(Collectors.toList())); + Map> capCopy = resourceCapabilities.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), capabilityDefinitionMapper)); + + setupContainerExpectedReqCap(uniqueId, name, resourceRequirements, resourceCapabilities); + if (component.getComponentType().equals(ComponentTypeEnum.RESOURCE) && ((Resource) component).getResourceType() != ResourceTypeEnum.VF) { + setupConstInstExpectedReqCap(uniqueId, name, reqCopy, capCopy); + } + + // adding entry for expected componentInstance + ImmutablePair>, Map>> compInstReqCapPair = new ImmutablePair>, Map>>(capCopy, reqCopy); + expectedContInstReqCap.put(uniqueId, compInstReqCapPair); + } + + private void setupContainerExpectedReqCap(String uniqueId, String name, Map> componentRequirements, Map> componentCapabilities) { + for (Entry> resReq : componentRequirements.entrySet()) { + List reqListToAdd = resReq.getValue(); + for (RequirementDefinition requirementDefinition : reqListToAdd) { + requirementDefinition.setOwnerId(uniqueId); + requirementDefinition.setOwnerName(name); + } + List expectedReqList = expectedContainerRequirements.get(resReq.getKey()); + if (expectedReqList == null) { + expectedReqList = reqListToAdd; + } else { + expectedReqList.addAll(reqListToAdd); + } + expectedContainerRequirements.put(resReq.getKey(), expectedReqList); + } + + for (Entry> resCap : componentCapabilities.entrySet()) { + List capListToAdd = resCap.getValue(); + for (CapabilityDefinition capDefinition : capListToAdd) { + capDefinition.setOwnerId(uniqueId); + capDefinition.setOwnerName(name); + } + List expectedCapList = expectedContainerCapabilities.get(resCap.getKey()); + if (expectedCapList == null) { + expectedCapList = capListToAdd; + } else { + expectedCapList.addAll(capListToAdd); + } + expectedContainerCapabilities.put(resCap.getKey(), expectedCapList); + } + } + + private void setupConstInstExpectedReqCap(String uniqueId, String name, Map> componentRequirements, Map> componentCapabilities) { + for (Entry> resReq : componentRequirements.entrySet()) { + List reqListToAdd = resReq.getValue(); + for (RequirementDefinition requirementDefinition : reqListToAdd) { + requirementDefinition.setOwnerId(uniqueId); + requirementDefinition.setOwnerName(name); + } + } + + for (Entry> resCap : componentCapabilities.entrySet()) { + List capListToAdd = resCap.getValue(); + for (CapabilityDefinition capDefinition : capListToAdd) { + capDefinition.setOwnerId(uniqueId); + capDefinition.setOwnerName(name); + } + } + } + + private ComponentTypeEnum getCompInstTypeByContainerType(ComponentTypeEnum componentType) { + switch (componentType) { + case RESOURCE: + return ComponentTypeEnum.RESOURCE; + case SERVICE: + return ComponentTypeEnum.RESOURCE; + case PRODUCT: + return ComponentTypeEnum.SERVICE; + default: + break; + } + return null; + } + + public void deleteCompInstReqCapFromExpected(String componentInstanceId) { + List entriesRequirementsToRemove = new ArrayList<>(); + List entriesCapabilitiesToRemove = new ArrayList<>(); + for (Entry> reqEntry : expectedContainerRequirements.entrySet()) { + List reqList = reqEntry.getValue(); + List reqListToDelete = new ArrayList<>(); + for (RequirementDefinition requirementDefinition : reqList) { + if (requirementDefinition.getOwnerId().equals(componentInstanceId)) { + reqListToDelete.add(requirementDefinition); + } + } + reqList.removeAll(reqListToDelete); + if (reqList.isEmpty()) { + entriesRequirementsToRemove.add(reqEntry.getKey()); + } + } + + for (String ekey : entriesRequirementsToRemove) { + expectedContainerRequirements.remove(ekey); + } + + for (Entry> capEntry : expectedContainerCapabilities.entrySet()) { + List capList = capEntry.getValue(); + List capListToDelete = new ArrayList<>(); + for (CapabilityDefinition capabilityDefinition : capList) { + if (capabilityDefinition.getOwnerId().equals(componentInstanceId)) { + capListToDelete.add(capabilityDefinition); + } + } + capList.removeAll(capListToDelete); + if (capList.isEmpty()) { + entriesCapabilitiesToRemove.add(capEntry.getKey()); + } + } + for (String ekey : entriesCapabilitiesToRemove) { + expectedContainerCapabilities.remove(ekey); + } + + expectedContInstReqCap.remove(componentInstanceId); + + } + + // Automatically updates the expected req/cap of the container + protected RestResponse createAtomicInstanceForVF(ResourceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.RESOURCE, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse createAtomicInstanceForService(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse createVFInstance(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse createServiceInstance(ProductReqDetails containerDetails, ServiceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.PRODUCT, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse deleteAtomicInstanceForVF(String compInstUniqueId, ResourceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.RESOURCE, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse deleteAtomicInstanceForService(String compInstUniqueId, ServiceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + // Automatically updates the expected req/cap of the container + protected RestResponse deleteVFInstance(String compInstUniqueId, ServiceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, true); + + } + + // Automatically updates the expected req/cap of the container + protected RestResponse deleteServiceInstance(String compInstUniqueId, ProductReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.PRODUCT, true); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse createAtomicInstanceForVFDuringSetup(ResourceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.RESOURCE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse createAtomicInstanceForServiceDuringSetup(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse createVFInstanceDuringSetup(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse createServiceInstanceDuringSetup(ProductReqDetails containerDetails, ServiceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.PRODUCT, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse deleteAtomicInstanceForVFDuringSetup(String compInstUniqueId, ResourceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.RESOURCE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse deleteAtomicInstanceForServiceDuringSetup(String compInstUniqueId, ServiceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse deleteVFInstanceDuringSetup(String compInstUniqueId, ServiceReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, false); + + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + protected RestResponse deleteServiceInstanceDuringSetup(String compInstUniqueId, ProductReqDetails containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.PRODUCT, false); + } + + protected Component getComponentAndValidateRIs(ComponentReqDetails componentDetails, int numberOfRIs, int numberOfRelations) throws IOException, Exception { + + RestResponse getResponse = null; + Component component = null; + if (componentDetails instanceof ResourceReqDetails) { + getResponse = ResourceRestUtils.getResource(sdncAdminDetails, componentDetails.getUniqueId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Resource.class); + } else if (componentDetails instanceof ServiceReqDetails) { + getResponse = ServiceRestUtils.getService((ServiceReqDetails) componentDetails, sdncAdminDetails); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Service.class); + } else if (componentDetails instanceof ProductReqDetails) { + getResponse = ProductRestUtils.getProduct(componentDetails.getUniqueId(), sdncAdminDetails.getUserId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Product.class); + } else { + Assert.fail("Unsupported type of componentDetails - " + componentDetails.getClass().getSimpleName()); + } + ResourceRestUtils.checkSuccess(getResponse); + int numberOfActualRIs = component.getComponentInstances() != null ? component.getComponentInstances().size() : 0; + int numberOfActualRelations = component.getComponentInstancesRelations() != null ? component.getComponentInstancesRelations().size() : 0; + assertEquals("Check number of RIs meet the expected number", numberOfRIs, numberOfActualRIs); + assertEquals("Check number of RI relations meet the expected number", numberOfRelations, numberOfActualRelations); + verifyReqCap(component); + + return component; + } + + protected void getComponentAndValidateRIsAfterChangeLifecycleState(String oldComponentUniqueIdToReplace, ComponentReqDetails componentDetails, int numOfRIs, int numOfRelations) throws IOException, Exception { + updateExpectedReqCapAfterChangeLifecycleState(oldComponentUniqueIdToReplace, componentDetails.getUniqueId()); + getComponentAndValidateRIs(componentDetails, numOfRIs, numOfRelations); + } + + private RestResponse createComponentInstance(ComponentReqDetails containerDetails, ComponentReqDetails compInstOriginDetails, User modifier, ComponentTypeEnum containerComponentTypeEnum, boolean isHighestLevel) throws IOException, Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getComponentResourceInstance(compInstOriginDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, modifier, containerDetails.getUniqueId(), containerComponentTypeEnum); + if (createResourceInstanceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_CREATED) && isHighestLevel) { + // Add RI Capabilities and Requirements to expected MAP --> + // expectedVfCapabilities and expectedVfRequirements + ComponentInstance componentInstance = ResponseParser.parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, containerComponentTypeEnum); + } + return createResourceInstanceResponse; + } + + private RestResponse deleteComponentInstance(String compInstUniqueId, ComponentReqDetails containerDetails, User modifier, ComponentTypeEnum componentTypeEnum, boolean isHighestLevel) throws Exception { + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(modifier, containerDetails.getUniqueId(), compInstUniqueId, componentTypeEnum); + if (deleteResourceInstanceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_DELETE) && isHighestLevel) { + deleteCompInstReqCapFromExpected(compInstUniqueId); + } + return deleteResourceInstanceResponse; + } + + // Create Atomic resource ( VFC/CP/VL) + protected void createAtomicResource(ResourceReqDetails resourceDetails) throws Exception { + RestResponse createResourceResponse = ResourceRestUtils.createResource(resourceDetails, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceResponse); + + } + + protected void createVF(ResourceReqDetails resourceDetails) throws Exception { + createVF(resourceDetails, sdncDesignerDetails); + + } + + protected void createVF(ResourceReqDetails resourceDetails, User sdncModifier) throws Exception { + RestResponse createVfResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifier); + ResourceRestUtils.checkCreateResponse(createVfResponse); + } + + protected void createService(ServiceReqDetails serviceDetails) throws Exception { + createService(serviceDetails, sdncDesignerDetails); + } + + protected void createService(ServiceReqDetails serviceDetails, User sdncModifier) throws Exception { + RestResponse createServiceResponse = ServiceRestUtils.createService(serviceDetails, sdncModifier); + ResourceRestUtils.checkCreateResponse(createServiceResponse); + } + + protected void createProduct(ProductReqDetails productDetails) throws Exception { + createProduct(productDetails, sdncPmDetails1); + } + + protected void createProduct(ProductReqDetails productDetails, User sdncModifier) throws Exception { + RestResponse createProductResponse = ProductRestUtils.createProduct(productDetails, sdncModifier); + ResourceRestUtils.checkCreateResponse(createProductResponse); + } + + protected RestResponse associateComponentInstancesForService(RequirementCapabilityRelDef requirementDef, ComponentReqDetails containerDetails, User user) throws IOException { + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, user, containerDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + deleteAssociatedFromExpected(requirementDef); + + return associateInstances; + } + + private void deleteAssociatedFromExpected(RequirementCapabilityRelDef requirementDef) { + // removing from requirements + RequirementAndRelationshipPair relationship = requirementDef.getRelationships().get(0); + String type = relationship.getRelationship().getType(); + String fromId = requirementDef.getFromNode(); + List reqList = expectedContainerRequirements.get(type); + List capList = expectedContainerCapabilities.get(type); + RequirementDefinition toDelete = null; + if (reqList != null) { + for (RequirementDefinition reqDef : reqList) { + if (reqDef.getOwnerId().equals(fromId)) { + toDelete = reqDef; + } + } + if (toDelete != null) { + reqList.remove(toDelete); + if (reqList.isEmpty()) { + expectedContainerRequirements.remove(type); + } + String ownerId = toDelete.getOwnerId(); + Map> map = removedRequirements.get(ownerId); + if (map == null) { + map = new HashMap<>(); + removedRequirements.put(ownerId, map); + } + List list = map.get(type); + if (list == null) { + list = new ArrayList<>(); + map.put(type, list); + } + list.add(toDelete); + } + } + + for (CapabilityDefinition capabilityDefinition : capList) { + if (capabilityDefinition.getType().equals(type)) { + int minOccurrences = Integer.parseInt(capabilityDefinition.getMinOccurrences()) - 1; + if (minOccurrences < 0) + minOccurrences = 0; + String minOccurrencesString = Integer.toString(minOccurrences); + capabilityDefinition.setMinOccurrences(minOccurrencesString); + if (!capabilityDefinition.getMaxOccurrences().equals("UNBOUNDED")) { + int maxOccurrences = Integer.parseInt(capabilityDefinition.getMaxOccurrences()) - 1; + if (maxOccurrences < 0) + maxOccurrences = 0; + String maxOccurrencesString = Integer.toString(maxOccurrences); + capabilityDefinition.setMaxOccurrences(maxOccurrencesString); + } + } + } + expectedContainerCapabilities.put(type, capList); + } + + protected void dissociateComponentInstancesForService(RequirementCapabilityRelDef requirementDef, ComponentReqDetails containerDetails, User user) throws IOException { + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, user, containerDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(dissociateInstances); + addDissociatedToExpected(requirementDef); + } + + protected void fulfillCpRequirement(ComponentReqDetails component, String cpCompInstId, String cpReqFulfillerCompInstId, String cpReqFulfillerOwnerId, User user, ComponentTypeEnum containerCompType) throws IOException { + // Fulfilling cp's "binding" requirement - US626240 + String requirementName = "binding"; + String capType = "tosca.capabilities.network.Bindable"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(user, component); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef reqCapRelation = ElementFactory.getReqCapRelation(cpCompInstId, cpReqFulfillerCompInstId, cpCompInstId, cpReqFulfillerOwnerId, capType, requirementName, capList, reqList); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(reqCapRelation, user, component.getUniqueId(), containerCompType); + ResourceRestUtils.checkSuccess(associateInstances); + } + + protected void consumeVlCapability(ComponentReqDetails component, String vlCapConsumerCompInstId, String vlCompInstId, String vlCapConsumerOwnerId, User user, ComponentTypeEnum containerCompType) throws IOException { + // Consuming vl's "link" capability - US626240 + String requirementName = "link"; + String capType = "tosca.capabilities.network.Linkable"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(user, component); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef reqCapRelation = ElementFactory.getReqCapRelation(vlCapConsumerCompInstId, vlCompInstId, vlCapConsumerOwnerId, vlCompInstId, capType, requirementName, capList, reqList); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(reqCapRelation, user, component.getUniqueId(), containerCompType); + ResourceRestUtils.checkSuccess(associateInstances); + } + + private void addDissociatedToExpected(RequirementCapabilityRelDef requirementDef) { + // adding to requirements + RequirementAndRelationshipPair relationship = requirementDef.getRelationships().get(0); + String type = relationship.getRelationship().getType(); + String fromId = requirementDef.getFromNode(); + Map> map = removedRequirements.get(fromId); + if (map != null) { + List list = map.get(type); + if (list != null && !list.isEmpty()) { + List reqList = expectedContainerRequirements.get(type); + if (reqList == null) { + reqList = new ArrayList<>(); + expectedContainerRequirements.put(type, reqList); + } + reqList.add(list.remove(0)); + } + } + + List capList = expectedContainerCapabilities.get(type); + + for (CapabilityDefinition capabilityDefinition : capList) { + if (capabilityDefinition.getType().equals(type)) { + int minOccurrences = Integer.parseInt(capabilityDefinition.getMinOccurrences()) + 1; + String minOccurrencesString = Integer.toString(minOccurrences); + capabilityDefinition.setMinOccurrences(minOccurrencesString); + if (!capabilityDefinition.getMaxOccurrences().equals("UNBOUNDED")) { + int maxOccurrences = Integer.parseInt(capabilityDefinition.getMaxOccurrences()) + 1; + String maxOccurrencesString = Integer.toString(maxOccurrences); + capabilityDefinition.setMaxOccurrences(maxOccurrencesString); + } + } + } + expectedContainerCapabilities.put(type, capList); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/SdcTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/SdcTest.java new file mode 100644 index 0000000000..ebad749097 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/SdcTest.java @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.api; + +import static org.junit.Assert.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.List; + +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.junit.rules.TestWatcher; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.rules.MyTestWatcher; +import org.openecomp.sdc.ci.tests.run.StartTest; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public abstract class SdcTest { + + public static StringBuilder doc = new StringBuilder(); + public static String file = null; + public static Config config = null; + // protected Gson gson = new Gson(); + protected Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + protected TestName testName = null; + protected Logger logger = null; + + protected static boolean displayException = false; + + public SdcTest(TestName testName, String className) { + super(); + + StartTest.enableLogger(); + + this.testName = testName; + this.logger = LoggerFactory.getLogger(className); + + String displayEx = System.getProperty("displayException"); + if (displayEx != null && Boolean.valueOf(displayEx).booleanValue()) { + displayException = true; + } + + } + + @Rule + public TestWatcher tw = new MyTestWatcher(this); + + @BeforeClass + public static void beforeClass() { + doc = new StringBuilder(); + doc.append( + ""); + + doc.append(""); + doc.append( + ""); + + doc.append(""); + + doc.append(""); + doc.append(""); + + doc.append(""); + + doc.append(""); + doc.append(""); + doc.append(""); + doc.append(""); + + if (displayException) { + doc.append(""); + } + doc.append(""); + } + + @AfterClass + public static void afterClass() { + doc.append("
").append("Test Name").append("").append("Status").append("").append("Message").append("").append("Exception").append("
"); + FileUtils.writeToFile( + Config.instance().getOutputFolder() + File.separator + file + StartTest.timeOfTest + ".html", + doc.toString()); + + } + + @Before + public void beforeTest() throws FileNotFoundException { + file = FileUtils.getFileName(this.getClass().getName()); + config = Utils.getConfig(); + assertTrue(config != null); + + // logger.info("Start running test " + testName.getMethodName()); + } + + @After + public void afterTest() throws FileNotFoundException { + + // logger.info("Finish running test " + testName.getMethodName()); + } + + public void addTestSummary(String testName, boolean isSuccess) { + addTestSummary(testName, isSuccess, null); + } + + public void addTestSummary(String testName, boolean isSuccess, Throwable exception) { + + String message = exception == null ? "" : exception.getMessage(); + + String result = (isSuccess) ? "success" : "fail"; + doc.append(""); + doc.append(""); + doc.append(""); + doc.append(""); + + if (displayException) { + // doc.append(""); + doc.append(""); + } + + doc.append(""); + + if (isSuccess) { + logger.debug("Test {} succeeded.", testName); + } else { + logger.error("Test {} failed with error: {}", testName, message); + } + } + + private String convertExceptionToString(Throwable exception) { + + if (exception == null) { + return ""; + } + + StringWriter sw = new StringWriter(); + exception.printStackTrace(new PrintWriter(sw)); + String exceptionAsString = sw.toString(); + + return exceptionAsString; + } + + public Logger getLogger() { + return logger; + } + + protected boolean ignoreDueToBug(String bug) { + + List bugs = config.getBugs(); + + if (bugs != null && bugs.size() > 0) { + for (String bugNumber : bugs) { + if (bugNumber.startsWith(bug)) { + return true; + } + } + } + + return false; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java new file mode 100644 index 0000000000..5aceb4fae3 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/api/Urls.java @@ -0,0 +1,348 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.api; + +public interface Urls { + + final String UPLOAD_ZIP_URL = "http://%s:%s/sdc1/rest/v1/catalog/resources"; + final String GET_IMAGE_DATA_FROM_ES = "http://%s:%s/resources/imagedata/_search?q=resourceName:%s&pretty=true&size=1000"; + final String GET_SCRIPT_DATA_FROM_ES = "http://%s:%s/resources/artifactdata/_search?q=resourceName:%s&pretty=true&size=1000"; + final String GET_ID_LIST_BY_INDEX_FROM_ES = "http://%s:%s/%s/%s/_search?fields=_id&size=1000"; + + final String ES_URL = "http://%s:%s"; + final String GET_SERVICE_CSAR_API1 = "http://%s:%s/sdc2/rest/services/%s/%s"; + final String GET_SERVICE_CSAR_API2 = "http://%s:%s/sdc2/rest/services/%s/%s/csar"; + + final String GET_SERVICE_CSAR_FE_PROXY_API1 = "http://%s:%s/sdc1/portal/rest/services/%s/%s"; + final String GET_CSAR_USING_SIMULATOR = "http://%s:%s/onboardingci/onbrest/onboarding-api/v1.0/vendor-software-products/packages/%s"; + final String COPY_CSAR_USING_SIMULATOR = "http://%s:%s/onboardingci/onbrest/onboarding-api/v1.0/vendor-software-products/packages/%s/%s"; + + final String GET_HEALTH_CHECK_VIA_PROXY = "http://%s:%s/sdc1/rest/healthCheck"; + + // Get back-end config http://172.20.43.132:8080/sdc2/rest/configmgr/get + final String GET_CONFIG_MANAGER = "http://%s:%s/sdc2/rest/configmgr/get"; + + // Get latest version of all non-abstract resources + final String GET_RESOURCE_lATEST_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/resources/latestversion/notabstract"; + + final String GET_SERVICE_lATEST_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/services/latestversion/notabstract"; + + // Get resource artifact list: + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/resources/alien.nodes.Apache/2.0.0-SNAPSHOT/artifacts + final String GET_RESOURCE_ARTIFACTS_LIST = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/artifacts"; + + // get resource artifact metadata (creation, MD5, etc): + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/resources/alien.nodes.Apache/2.0.0-SNAPSHOT/artifacts/install_apache.sh/metadata + final String GET_RESOURCE_ARTIFACT_METADATA = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/artifacts/%s/metadata"; + + // resource artifact payload: + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/resources/alien.nodes.Apache/2.0.0-SNAPSHOT/artifacts/install_apache.sh + final String GET_RESOURCE_ARTIFACT_PAYLOAD = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/artifacts/%s"; + + final String GET_RESOURCE_ARTIFACT_PAYLOAD_FE_PROXY = "http://%s:%s/sdc1/portal/rest/v1/catalog/resources/%s/%s/artifacts/%s"; + + // Get service list: http://172.20.43.124:8080/sdc2/rest/v1/catalog/services + final String GET_SERVICE_LIST = "http://%s:%s/sdc2/rest/v1/catalog/services"; + + // Get service versions: + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/services/MyService + final String GET_SERVICE_VERSIONS = "http://%s:%s/sdc2/rest/v1/catalog/services/%s"; + + // Get service artifact list: + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/services/alien.nodes.Apache/0.0.1/artifacts + final String GET_SERVICE_ARTIFACTS_LIST = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/%s/artifacts"; + + // get service artifact metadata (creation, MD5, etc): + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/services/alien.nodes.Apache/0.0.1/artifacts/install_apache.sh/metadata + final String GET_SERVICE_METADATA = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/%s/artifacts/%s/metadata"; + + // service artifact payload: + // http://172.20.43.124:8080/sdc2/rest/v1/catalog/services/alien.nodes.Apache/0.0.1/artifacts/install_apache.sh + final String GET_SERVICE_ARTIFACT_PAYLOAD = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/artifacts/%s"; + + final String GET_SEARCH_DATA_FROM_ES = "http://%s:%s/%s"; + + // ****************************************************USER + // URLs******************************************************** + final String GET_USER = "http://%s:%s/sdc2/rest/v1/user/%s"; + + final String GET_USER_ROLE = "http://%s:%s/sdc2/rest/v1/user/%s/role"; + + final String CREATE_USER = "http://%s:%s/sdc2/rest/v1/user"; + + final String UPDATE_USER = "http://%s:%s/sdc2/rest/v1/user/%s"; + + final String UPDATE_USER_ROLE = "http://%s:%s/sdc2/rest/v1/user/%s/role"; + + final String DELETE_USER = "http://%s:%s/sdc2/rest/v1/user/%s"; + + final String GET_ALL_ADMIN_USERS = "http://%s:%s/sdc2/rest/v1/user/admins"; + + final String AUTHORIZE_USER = "http://%s:%s/sdc2/rest/v1/user/authorize"; + + final String GET_ALL_TAGS = "http://%s:%s/sdc2/rest/v1/tags"; + + final String AUTH_USER = "http://%s:%s/sdc2/rest/v1/user/authorize"; + + final String GET_ALL_NOT_ABSTRACT_RESOURCES = "http://%s:%s/sdc2/rest/v1/catalog/resources/certified/notabstract"; + + final String GET_ALL_ABSTRACT_RESOURCES = "http://%s:%s/sdc2/rest/v1/catalog/resources/certified/abstract"; + + final String QUERY_NEO4J = "http://%s:%s/db/data/transaction"; + final String CHANGE_IN_NEO4J = "http://%s:%s/db/data/transaction/commit"; + + final String GET_ALL_ADMINS = "http://%s:%s/sdc2/rest/v1/user/admins"; + + final String GET_USERS_BY_ROLES = "http://%s:%s/sdc2/rest/v1/user/users?roles=%s"; + + final String GET_ALL_USERS = "http://%s:%s/sdc2/rest/v1/user/users?roles/"; + + // *****************************************ECOMP User + // URL's***************************************************** + final String ECOMP_PUSH_USER = "http://%s:%s/api/user"; + + final String ECOMP_EDIT_USER = "http://%s:%s/api/user/%s"; + + final String ECOMP_GET_USER = "http://%s:%s/api/user/%s"; + + final String ECOMP_GET_ALL_USERS = "http://%s:%s/api/users"; + + final String ECOMP_GET_ALL_AVAILABLE_ROLES = "http://%s:%s/api/roles"; + + final String ECOMP_PUSH_USER_ROLES = "http://%s:%s/api/user/%s/roles"; + + final String ECOMP_GET_USER_ROLES = "http://%s:%s/api/user/%s/roles"; + + // *****************************************Elements************************************************************* + final String GET_TAGS_LIST = "http://%s:%s/sdc2/rest/v1/tags"; + + final String GET_PROPERTY_SCOPES_LIST = "http://%s:%s/sdc2/rest/v1/propertyScopes"; + + final String GET_CONFIGURATION = "http://%s:%s/sdc2/rest/v1/configuration/ui"; + + final String GET_ALL_ARTIFACTS = "http://%s:%s/sdc2/rest/v1/artifactTypes"; + + final String GET_FOLLWED_LIST = "http://%s:%s/sdc2/rest/v1/followed"; + + final String GET_CATALOG_DATA = "http://%s:%s/sdc2/rest/v1/screen"; + + // *****************************************Resources + // ********************************************************************** + final String GET_LIST_CERTIFIED_RESOURCE_TEMPLATES = "http://%s:%s/sdc2/rest/v1/resoourceTemplates"; + + final String CREATE_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources"; + final String UPDATE_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s"; + + final String IMPORT_RESOURCE_NORMATIVE = "http://%s:%s/sdc2/rest/v1/catalog/upload/multipart"; + + final String IMPORT_USER_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/upload/user-resource"; + + final String IMPORT_CAPABILITY_TYPE = "http://%s:%s/sdc2/rest/v1/catalog/uploadType/capability"; + final String IMPORT_CATEGORIES = "http://%s:%s/sdc2/rest/v1/catalog/uploadType/categories"; + final String IMPORT_GROUP_TYPE = "http://%s:%s/sdc2/rest/v1/catalog/uploadType/grouptypes"; + + // last %s is resourceId, resourceId = resourceName.resourceVersion + final String GET_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s"; + final String GET_RESOURCE_BY_NAME_AND_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/resources/resourceName/%s/resourceVersion/%s"; + final String GET_RESOURCE_BY_CSAR_UUID = "http://%s:%s/sdc2/rest/v1/catalog/resources/csar/%s"; + final String GET_COMPONENT_REQUIRMENTS_CAPABILITIES = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/requirmentsCapabilities"; + + final String DELETE_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s"; + final String DELETE_RESOURCE_BY_NAME_AND_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s"; + final String DELETE_SERVICE_BY_NAME_AND_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/%s"; + + final String DELETE_MARKED_RESOURCES = "http://%s:%s/sdc2/rest/v1/inactiveComponents/resource"; + final String DELETE_MARKED_SERVICES = "http://%s:%s/sdc2/rest/v1/inactiveComponents/service"; + + final String GET_FOLLOWED_RESOURCES = "http://%s:%s/sdc2/rest/v1/followed/resources/%s"; + final String CHANGE_RESOURCE_LIFECYCLE_STATE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/lifecycleState/%s"; + final String CHANGE_SERVICE_LIFECYCLE_STATE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/lifecycleState/%s"; + final String CHANGE_PRODUCT_LIFECYCLE_STATE = "http://%s:%s/sdc2/rest/v1/catalog/products/%s/lifecycleState/%s"; + final String CHANGE_COMPONENT_LIFECYCLE_STATE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/lifecycleState/%s"; + + final String CREATE_PROPERTY = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/properties"; + + final String UPDATE_RESOURCE_METADATA = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/metadata"; + + // ***********************************External API's + // (AssetData)**************************************** + + final String POST_EXTERNAL_API_UPLOAD_ARTIFACT_OF_ASSET = "http://%s:%s/asdc/v1/catalog/%s/%s/artifacts"; + + final String GET_DOWNLOAD_RESOURCE_ARTIFACT_OF_ASSET = "http://%s:%s/asdc/v1/catalog/resources/%s/artifacts/%s"; + final String GET_DOWNLOAD_SERVICE_ARTIFACT_OF_ASSET = "http://%s:%s/asdc/v1/catalog/services/%s/artifacts/%s"; + + final String GET_DOWNLOAD_RESOURCE_ARTIFACT_OF_COMPONENT_INSTANCE = "http://%s:%s/asdc/v1/catalog/resources/%s/resourceInstances/%s/artifacts/%s"; + final String GET_DOWNLOAD_SERVICE_ARTIFACT_OF_COMPONENT_INSTANCE = "http://%s:%s/asdc/v1/catalog/services/%s/resourceInstances/%s/artifacts/%s"; + + final String GET_ASSET_LIST = "http://%s:%s/asdc/v1/catalog/%s"; + final String GET_FILTERED_ASSET_LIST = "http://%s:%s/asdc/v1/catalog/%s?%s"; + final String GET_TOSCA_MODEL = "http://%s:%s/asdc/v1/catalog/%s/%s/toscaModel"; + // https://{serverRoot}/asdc/v1/catalog/{assetType}/{uuid}/metadata, where + // assetType in {resources, services} + final String GET_ASSET_METADATA = "http://%s:%s/asdc/v1/catalog/%s/%s/metadata"; + final String POST_AUTHORIZATION = "http://%s:%s/sdc2/rest/v1/consumers"; + final String GET_DOWNLOAD_SERVICE_RI_ARTIFACT = "http://%s:%s/asdc/v1/catalog/services/%s/resourceInstances/%s/artifacts/%s"; + final String GET_DOWNLOAD_SERVICE_ARTIFACT = "http://%s:%s/asdc/v1/catalog/services/%s/artifacts/%s"; + + // ***************************************************************************************************** + + final String ADD_ARTIFACT_TO_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/artifacts"; + final String UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/artifacts/%s"; + final String ADD_ARTIFACT_TO_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/artifacts"; + final String UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/artifacts/%s"; + + final String UPLOAD_DELETE_ARTIFACT_OF_COMPONENT = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/artifacts"; + final String UPDATE_ARTIFACT_OF_COMPONENT = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/artifacts/%s"; + final String UPLOAD_HEAT_ENV_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s/artifacts/%s"; + // ***************************************************************************************************** + final String UPLOAD_ARTIFACT_BY_INTERFACE_TO_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/%s/artifacts/"; + final String UPDATE_OR_DELETE_ARTIFACT_BY_INTERFACE_TO_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/%s/artifacts/%s"; + + final String UPLOAD_ARTIFACT_BY_INTERFACE_TO_COMPONENT = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/%s/artifacts/"; + final String UPDATE_OR_DELETE_ARTIFACT_BY_INTERFACE_TO_COMPONENT = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/%s/%s/artifacts/%s"; + + // ***************************************************************************************************** + // "/sdc2/v1/services//<0.1>/artifacts/aaa.hh" + final String DISTRIB_DOWNLOAD_SERVICE_ARTIFACT = "/sdc2/rest/v1/catalog/services/%s/%s/artifacts/%s"; + // "/sdc2/v1/services//<0.1>/resources/{resourceName}/{resourceVersion}/artifacts/_aaa.hh" + final String DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT = "/sdc2/rest/v1/catalog/services/%s/%s/resources/%s/%s/artifacts/%s"; + final String DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL = "/asdc/v1/catalog/services/%s/%s/artifacts/%s"; + final String DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL = "/asdc/v1/catalog/services/%s/%s/resources/%s/%s/artifacts/%s"; + final String DOWNLOAD_SERVICE_ARTIFACT_FULL_URL = "http://%s:%s%s"; + final String DOWNLOAD_RESOURCE_ARTIFACT_FULL_URL = "http://%s:%s%s"; + // ********************************************************************************** + final String UI_DOWNLOAD_RESOURCE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/artifacts/%s"; + final String UI_DOWNLOAD_SERVICE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/artifacts/%s"; + + // ********************************************************************************************************** + final String UPDATE_PROPERTY = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/properties/%s"; + + final String DELETE_PROPERTY = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/properties/%s"; + + final String GET_PROPERTY = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/properties/%s"; + + // ***************************************************************************************************** + + final String VALIDATE_RESOURCE_NAME = "http://%s:%s/sdc2/rest/v1/catalog/resources/validate-name/%s"; + + final String CREATE_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services"; + final String DELETE_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s"; + final String GET_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s"; + final String GET_SERVICE_BY_NAME_AND_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/services/serviceName/%s/serviceVersion/%s"; + + final String GET_SERVICES_REQUIRMENTS_CAPABILITIES = "http://%s:%s/sdc2/rest/v1/catalog/requirmentsCapabilities/services/%s"; + + final String CREATE_COMPONENT_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance"; + final String DELETE_COMPONENT_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s"; + final String UPDATE_COMPONENT_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s"; + final String GET_COMPONENT_INSTANCES = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/componentInstances"; + // Tal New API + final String UPDATE_MULTIPLE_COMPONENT_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/multipleComponentInstance"; + + final String CHANGE__RESOURCE_INSTANCE_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s/changeVersion"; + + final String CREATE_AND_ASSOCIATE_RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/createAndAssociate"; + final String ASSOCIATE__RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/associate"; + final String DISSOCIATE__RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/dissociate"; + + final String DISTRIBUTION_INIT = "http://%s:%s/init"; + final String DISTRIBUTION_INIT_RESET = "http://%s:%s/initReset"; + final String APPROVE_DISTRIBUTION = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/distribution-state/approve"; + final String REJECT_DISTRIBUTION = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/distribution-state/reject"; + final String DISTRIBUTION_DOWNLOAD_ARTIFACT = "http://%s:%s/download"; + final String ACTIVATE_DISTRIBUTION = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/distribution/%s/activate"; + + final String DEPLOY_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/distribution/%s/markDeployed"; + final String UPDATE_SERVICE_METADATA = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/metadata"; + + // Andrey changed name from ADD_PROPERTY_TO_RESOURCE_INSTANCE to + // UPDATE_PROPERTY_TO_RESOURCE_INSTANCE + final String UPDATE_PROPERTY_TO_RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s/property"; + final String DELETE_PROPERTY_FROM_RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/%s/property/%s"; + final String UPDATE_RESOURCE_INSTANCE_HEAT_ENV_PARAMS = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/%s/artifacts/%s/heatParams"; + + // Actions on artifact in resource instance + final String ADD_RESOURCE_INSTANCE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/%s/artifacts"; + final String UPDATE_RESOURCE_INSTANCE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/%s/artifacts/%s"; + final String DELETE_RESOURCE_INSTANCE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstance/%s/artifacts/%s"; + + // Attributes On Resource instance + public static final String UPDATE_ATTRIBUTE_ON_RESOURCE_INSTANCE = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/resourceInstance/%s/attribute"; + + // ("/services/{serviceId}/resourceInstances/{resourceInstanceId}/artifacts/{artifactId}") + final String DOWNLOAD_COMPONENT_INSTANCE_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/resourceInstances/%s/artifacts/%s"; + + // -------------------------------service api + // artifact----------------------------------------------------- + final String UPDATE_DELETE_SERVICE_API_ARTIFACT = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/artifacts/api/%s"; + + final String CREATE_ADDITIONAL_INFORMATION_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/additionalinfo"; + final String UPDATE_ADDITIONAL_INFORMATION_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/additionalinfo/%s"; + final String DELETE_ADDITIONAL_INFORMATION_RESOURCE = UPDATE_ADDITIONAL_INFORMATION_RESOURCE; + final String GET_ADDITIONAL_INFORMATION_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/additionalinfo/%s"; + final String GET_ALL_ADDITIONAL_INFORMATION_RESOURCE = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/additionalinfo"; + + final String CREATE_ADDITIONAL_INFORMATION_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/additionalinfo"; + final String UPDATE_ADDITIONAL_INFORMATION_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/additionalinfo/%s"; + final String DELETE_ADDITIONAL_INFORMATION_SERVICE = UPDATE_ADDITIONAL_INFORMATION_SERVICE; + final String GET_ADDITIONAL_INFORMATION_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/additionalinfo/%s"; + final String GET_ALL_ADDITIONAL_INFORMATION_SERVICE = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/additionalinfo"; + + final String GET_COMPONENT_AUDIT_RECORDS = "http://%s:%s/sdc2/rest/v1/catalog/audit-records/%s/%s"; + + // CONSUMER + final String CREATE_CONSUMER = "http://%s:%s/sdc2/rest/v1/consumers"; + final String GET_CONSUMER = "http://%s:%s/sdc2/rest/v1/consumers/%s"; + final String DELETE_CONSUMER = "http://%s:%s/sdc2/rest/v1/consumers/%s"; + + // Categories + final String CREATE_CATEGORY = "http://%s:%s/sdc2/rest/v1/category/%s"; + final String GET_ALL_CATEGORIES = "http://%s:%s/sdc2/rest/v1/categories/%s"; + final String GET_ALL_CATEGORIES_FE = "http://%s:%s/sdc1/feProxy/rest/v1/categories/%s"; + final String DELETE_CATEGORY = "http://%s:%s/sdc2/rest/v1/category/%s/%s"; + final String CREATE_SUB_CATEGORY = "http://%s:%s/sdc2/rest/v1/category/%s/%s/subCategory"; + final String DELETE_SUB_CATEGORY = "http://%s:%s/sdc2/rest/v1/category/%s/%s/subCategory/%s"; + final String CREATE_GROUPING = "http://%s:%s/sdc2/rest/v1/category/%s/%s/subCategory/%s/grouping"; + final String DELETE_GROUPING = "http://%s:%s/sdc2/rest/v1/category/%s/%s/subCategory/%s/grouping/%s"; + + // product + final String CREATE_PRODUCT = "http://%s:%s/sdc2/rest/v1/catalog/products"; + final String DELETE_PRODUCT = "http://%s:%s/sdc2/rest/v1/catalog/products/%s"; + // last %s is resourceId, productId + final String GET_PRODUCT = "http://%s:%s/sdc2/rest/v1/catalog/products/%s"; + final String UPDATE_PRODUCT = "http://%s:%s/sdc2/rest/v1/catalog/products/%s/metadata"; + final String GET_PRODUCT_BY_NAME_AND_VERSION = "http://%s:%s/sdc2/rest/v1/catalog/products/productName/%s/productVersion/%s"; + + // groups + final String GET_GROUP_BY_ID = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/groups/%s"; + + // modules + final String GET_MODULE_BY_ID = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/groups/%s"; + + // inputs + final String ADD_INPUTS = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/create/inputs"; //{componentType}/{componentId}/create/inputs + final String DELETE_INPUT_BY_ID = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/delete/%s/input"; //{componentType}/{componentId}/delete/{inputId}/input + final String GET_COMPONENT_INPUTS = "http://%s:%s/sdc2/rest/v1/catalog/services/%s/inputs"; //services/{componentId}/inputs + final String GET_COMPONENT_INSTANCE_INPUTS = "http://%s:%s/sdc2/rest/v1/catalog/%s/%s/componentInstances/%s/%s/inputs"; //{componentType}/{componentId}/componentInstances/{instanceId}/{originComonentUid}/inputs + final String GET_INPUTS_FOR_COMPONENT_INPUT = "http://%s:%s/sdc2/rest/v1/catalog/resources/%s/groups/%s"; //{componentType}/{componentId}/inputs/{inputId}/inputs + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/Config.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/Config.java new file mode 100644 index 0000000000..ce025715fd --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/Config.java @@ -0,0 +1,584 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.config; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; + +import org.yaml.snakeyaml.Yaml; + +public class Config { + + private static String WINDOWS_CONFIG_FILE = "src/main/resources/ci/conf/sdc.yaml"; + + String catalogBeHost; + String esHost; + String esPort; + String neoHost; + String neoPort; + String disributionClientHost; + String disributionClientPort; + + String errorConfigurationFile; + String resourceConfigDir; + String componentsConfigDir; + String importResourceConfigDir; + String importResourceTestsConfigDir; + String importTypesConfigDir; + String testSuites; + + String catalogFeHost; + String catalogFePort; + String catalogBePort; + String catalogBeTlsPort; + + String neoDBusername; + String neoDBpassword; + + String titanPropertiesFile; + List packages; + List bugs; + List resourcesNotToDelete; + List resourceCategoriesNotToDelete; + List serviceCategoriesNotToDelete; + Boolean stopOnClassFailure = false; + + private String outputFolder; + private String reportName; + private String url; + private String remoteTestingMachineIP; + private String remoteTestingMachinePort; + private boolean remoteTesting; + + private String cassandraHost; + private String cassandraAuditKeySpace; + private String cassandraArtifactKeySpace; + private Boolean cassandraAuthenticate; + private String cassandraUsername; + private String cassandraPassword; + private Boolean cassandraSsl; + private String cassandraTruststorePath; + private String cassandraTruststorePassword; + + private static Config configIt = null; + + private static Yaml yaml = new Yaml(); + + private Config() { + super(); + } + + public static class TestPackages { + + List packages; + List bugs; + + public List getPackages() { + return packages; + } + + public void setPackages(List packages) { + this.packages = packages; + } + + public List getBugs() { + return bugs; + } + + public void setBugs(List bugs) { + this.bugs = bugs; + } + + @Override + public String toString() { + return "TestPackages [packages=" + packages + ", bugs=" + bugs + "]"; + } + + } + + public synchronized static Config instance() { + if (configIt == null) { + try { + configIt = init(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + return configIt; + } + + private static Config init() throws IOException { + + Config config = null; + + String configFile = System.getProperty("config.resource"); + if (configFile == null) { + if (System.getProperty("os.name").contains("Windows")) { + configFile = WINDOWS_CONFIG_FILE; + } else { + throw new RuntimeException("Please Add Jvm Argument config.resource"); + } + } + + File file = new File(configFile); + if (false == file.exists()) { + throw new RuntimeException("The config file " + configFile + " cannot be found."); + } + + InputStream in = null; + try { + + in = Files.newInputStream(Paths.get(configFile)); + + config = yaml.loadAs(in, Config.class); + + setPackagesAndBugs(configFile, config); + + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + return config; + } + + private static void setPackagesAndBugs(String path, Config config) throws IOException { + + int separator = Math.max(path.lastIndexOf("\\"), path.lastIndexOf("/")); + String dirPath = path.substring(0, separator + 1); + String packagesFile = dirPath + File.separator + "sdc-packages.yaml"; + File file = new File(packagesFile); + if (false == file.exists()) { + throw new RuntimeException("The config file " + packagesFile + " cannot be found."); + } + + TestPackages testPackages = null; + InputStream in = null; + try { + + in = Files.newInputStream(Paths.get(packagesFile)); + + testPackages = yaml.loadAs(in, TestPackages.class); + + List bugs = testPackages.getBugs(); + List packages = testPackages.getPackages(); + + config.setBugs(bugs); + config.setPackages(packages); + + } finally { + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } + + } + + // public Config(String catalogBeHost, String esHost, String esPort, String + // resourceConfigDir, String componentsConfigDir, String catalogFeHost, + // String catalogFePort, String catalogBePort) { + // super(); + // this.catalogBeHost = catalogBeHost; + // this.esHost = esHost; + // this.esPort = esPort; + // this.resourceConfigDir = resourceConfigDir; + // this.componentsConfigDir = componentsConfigDir; + // this.catalogFeHost = catalogFeHost; + // this.catalogFePort = catalogFePort; + // this.catalogBePort = catalogBePort; + // } + + String configurationFile; + + public String getConfigurationFile() { + return configurationFile; + } + + public void setConfigurationFile(String configurationFile) { + this.configurationFile = configurationFile; + } + + public String getCatalogBePort() { + return catalogBePort; + } + + public String getDisributionClientHost() { + return disributionClientHost; + } + + public void setDisributionClientHost(String disributionClientHost) { + this.disributionClientHost = disributionClientHost; + } + + public String getDisributionClientPort() { + return disributionClientPort; + } + + public void setDisributionClientPort(String disributionClientPort) { + this.disributionClientPort = disributionClientPort; + } + + public void setCatalogBePort(String catalogBePort) { + this.catalogBePort = catalogBePort; + } + + public String getCatalogFeHost() { + return catalogFeHost; + } + + public void setCatalogFeHost(String catalogFeHost) { + this.catalogFeHost = catalogFeHost; + } + + public String getCatalogFePort() { + return catalogFePort; + } + + public void setCatalogFePort(String catalogFePort) { + this.catalogFePort = catalogFePort; + } + + public String getCatalogBeHost() { + return catalogBeHost; + } + + public void setCatalogBeHost(String catalogBeHost) { + this.catalogBeHost = catalogBeHost; + } + + public String getEsHost() { + return esHost; + } + + public void setEsHost(String esHost) { + this.esHost = esHost; + } + + public String getEsPort() { + return esPort; + } + + public void setEsPort(String esPort) { + this.esPort = esPort; + } + + public String getResourceConfigDir() { + return resourceConfigDir; + } + + public void setResourceConfigDir(String resourceConfigDir) { + this.resourceConfigDir = resourceConfigDir; + } + + public String getComponentsConfigDir() { + return componentsConfigDir; + } + + public void setComponentsConfigDir(String componentsConfigDir) { + this.componentsConfigDir = componentsConfigDir; + } + + public String getOutputFolder() { + return outputFolder; + } + + public void setOutputFolder(String outputFolder) { + this.outputFolder = outputFolder; + } + + public String getReportName() { + return reportName; + } + + public void setReportName(String reportName) { + this.reportName = reportName; + } + + public String getNeoPort() { + return neoPort; + } + + public void setNeoPort(String neoPort) { + this.neoPort = neoPort; + } + + public String getNeoHost() { + return neoHost; + } + + public void setNeoHost(String neoHost) { + this.neoHost = neoHost; + } + + public String getNeoDBpassword() { + return neoDBpassword; + } + + public String getNeoDBusername() { + return neoDBusername; + } + + public void setNeoDBusername(String neoDBusername) { + this.neoDBusername = neoDBusername; + } + + public void setNeoDBpassword(String neoDBpassword) { + this.neoDBpassword = neoDBpassword; + } + + public String getTitanPropertiesFile() { + return titanPropertiesFile; + } + + public void setTitanPropertiesFile(String titanPropertiesFile) { + this.titanPropertiesFile = titanPropertiesFile; + } + + public List getPackages() { + return packages; + } + + public void setPackages(List packages) { + this.packages = packages; + } + + public List getBugs() { + return bugs; + } + + public void setBugs(List bugs) { + this.bugs = bugs; + } + + public Boolean isStopOnClassFailure() { + return stopOnClassFailure; + } + + public void setStopOnClassFailure(Boolean stopOnClassFailure) { + this.stopOnClassFailure = stopOnClassFailure; + } + + public String getImportResourceConfigDir() { + return importResourceConfigDir; + } + + public void setImportResourceConfigDir(String importResourceConfigDir) { + this.importResourceConfigDir = importResourceConfigDir; + } + + public String getImportResourceTestsConfigDir() { + return importResourceTestsConfigDir; + } + + public void setImportResourceTestsConfigDir(String importResourceTestsConfigDir) { + this.importResourceTestsConfigDir = importResourceTestsConfigDir; + } + + public String getErrorConfigurationFile() { + return errorConfigurationFile; + } + + public void setErrorConfigurationFile(String errorConfigurationFile) { + this.errorConfigurationFile = errorConfigurationFile; + } + + public String getCatalogBeTlsPort() { + return catalogBeTlsPort; + } + + public void setCatalogBeTlsPort(String catalogBeTlsPort) { + this.catalogBeTlsPort = catalogBeTlsPort; + } + + public List getResourcesNotToDelete() { + return resourcesNotToDelete; + } + + public void setResourcesNotToDelete(List resourcesNotToDelete) { + this.resourcesNotToDelete = resourcesNotToDelete; + } + + public List getResourceCategoriesNotToDelete() { + return resourceCategoriesNotToDelete; + } + + public void setResourceCategoriesNotToDelete(List resourceCategoriesNotToDelete) { + this.resourceCategoriesNotToDelete = resourceCategoriesNotToDelete; + } + + public List getServiceCategoriesNotToDelete() { + return serviceCategoriesNotToDelete; + } + + public void setServiceCategoriesNotToDelete(List serviceCategoriesNotToDelete) { + this.serviceCategoriesNotToDelete = serviceCategoriesNotToDelete; + } + + public String getImportTypesConfigDir() { + return importTypesConfigDir; + } + + public void setImportTypesConfigDir(String importTypesConfigDir) { + this.importTypesConfigDir = importTypesConfigDir; + } + + public String getCassandraHost() { + return cassandraHost; + } + + public void setCassandraHost(String cassandraHost) { + this.cassandraHost = cassandraHost; + } + + public String getCassandraAuditKeySpace() { + return cassandraAuditKeySpace; + } + + public void setCassandraAuditKeySpace(String cassandraAuditKeySpace) { + this.cassandraAuditKeySpace = cassandraAuditKeySpace; + } + + public String getCassandraArtifactKeySpace() { + return cassandraArtifactKeySpace; + } + + public void setCassandraArtifactKeySpace(String cassandraArtifactKeySpace) { + this.cassandraArtifactKeySpace = cassandraArtifactKeySpace; + } + + @Override + public String toString() { + return "Config [catalogBeHost=" + catalogBeHost + ", esHost=" + esHost + ", esPort=" + esPort + ", neoHost=" + + neoHost + ", neoPort=" + neoPort + ", disributionClientHost=" + disributionClientHost + + ", disributionClientPort=" + disributionClientPort + ", errorConfigurationFile=" + + errorConfigurationFile + ", resourceConfigDir=" + resourceConfigDir + ", componentsConfigDir=" + + componentsConfigDir + ", importResourceConfigDir=" + importResourceConfigDir + + ", importResourceTestsConfigDir=" + importResourceTestsConfigDir + ", importTypesConfigDir=" + + importTypesConfigDir + ", catalogFeHost=" + catalogFeHost + ", catalogFePort=" + catalogFePort + + ", catalogBePort=" + catalogBePort + ", catalogBeTlsPort=" + catalogBeTlsPort + ", neoDBusername=" + + neoDBusername + ", neoDBpassword=" + neoDBpassword + ", titanPropertiesFile=" + titanPropertiesFile + + ", packages=" + packages + ", bugs=" + bugs + ", resourcesNotToDelete=" + resourcesNotToDelete + + ", resourceCategoriesNotToDelete=" + resourceCategoriesNotToDelete + ", serviceCategoriesNotToDelete=" + + serviceCategoriesNotToDelete + ", stopOnClassFailure=" + stopOnClassFailure + ", outputFolder=" + + outputFolder + ", reportName=" + reportName + ", configurationFile=" + configurationFile + "]"; + } + + public boolean isRemoteTesting() { + return remoteTesting; + } + + public void setRemoteTesting(boolean remoteTesting) { + this.remoteTesting = remoteTesting; + } + + public String getUrl() { + try { + return url; + } catch (Exception e) { + return null; + } + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRemoteTestingMachineIP() { + return remoteTestingMachineIP; + } + + public void setRemoteTestingMachineIP(String remoteTestingMachineIP) { + this.remoteTestingMachineIP = remoteTestingMachineIP; + } + + public String getRemoteTestingMachinePort() { + return remoteTestingMachinePort; + } + + public void setRemoteTestingMachinePort(String remoteTestingMachinePort) { + this.remoteTestingMachinePort = remoteTestingMachinePort; + } + + public Boolean getCassandraAuthenticate() { + return cassandraAuthenticate; + } + + public void setCassandraAuthenticate(Boolean cassandraAuthenticate) { + this.cassandraAuthenticate = cassandraAuthenticate; + } + + public String getCassandraUsername() { + return cassandraUsername; + } + + public void setCassandraUsername(String cassandraUsername) { + this.cassandraUsername = cassandraUsername; + } + + public String getCassandraPassword() { + return cassandraPassword; + } + + public void setCassandraPassword(String cassandraPassword) { + this.cassandraPassword = cassandraPassword; + } + + public Boolean getCassandraSsl() { + return cassandraSsl; + } + + public void setCassandraSsl(Boolean cassandraSsl) { + this.cassandraSsl = cassandraSsl; + } + + public String getCassandraTruststorePath() { + return cassandraTruststorePath; + } + + public void setCassandraTruststorePath(String cassandraTruststorePath) { + this.cassandraTruststorePath = cassandraTruststorePath; + } + + public String getCassandraTruststorePassword() { + return cassandraTruststorePassword; + } + + public void setCassandraTruststorePassword(String cassandraTruststorePassword) { + this.cassandraTruststorePassword = cassandraTruststorePassword; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/InvokedMethodListener.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/InvokedMethodListener.java new file mode 100644 index 0000000000..fbc493ffd6 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/config/InvokedMethodListener.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.config; + +import java.util.HashMap; +import java.util.Map; + +import org.testng.IInvokedMethod; +import org.testng.IInvokedMethodListener; +import org.testng.ITestResult; +import org.testng.SkipException; +import org.testng.internal.TestResult; + +public class InvokedMethodListener implements IInvokedMethodListener { + + static Map methodFailCount = new HashMap(); + + @Override + + public void beforeInvocation(IInvokedMethod method, ITestResult testResult) { + + if (methodFailCount.get(method.getTestMethod().getMethodName()) != null + && methodFailCount.get(method.getTestMethod().getMethodName()) > 1) + throw new SkipException("Skipped due to failure count > 1"); + ; + + } + + @Override + + public void afterInvocation(IInvokedMethod method, ITestResult testResult) { + + if (testResult.getStatus() == TestResult.FAILURE) { + if (methodFailCount.get(method.getTestMethod().getMethodName()) == null) + methodFailCount.put(method.getTestMethod().getMethodName(), 1); + else { + methodFailCount.put(method.getTestMethod().getMethodName(), + methodFailCount.get(method.getTestMethod().getMethodName()) + 1); + } + + } + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactAssetStructure.java new file mode 100644 index 0000000000..41936e2c30 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactAssetStructure.java @@ -0,0 +1,135 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +public class ArtifactAssetStructure { + + String artifactName; + String artifactType; + String artifactURL; + String artifactDescription; + int artifactTimeout;// optional + String artifactChecksum; + String artifactUUID; + String artifactVersion; + String generatedFromUUID;// optional + + public ArtifactAssetStructure(String artifactName, String artifactType, String artifactURL, + String artifactDescription, int artifactTimeout, String artifactChecksum, String artifactUUID, + String artifactVersion, String generatedFromUUID) { + super(); + this.artifactName = artifactName; + this.artifactType = artifactType; + this.artifactURL = artifactURL; + this.artifactDescription = artifactDescription; + this.artifactTimeout = artifactTimeout; + this.artifactChecksum = artifactChecksum; + this.artifactUUID = artifactUUID; + this.artifactVersion = artifactVersion; + this.generatedFromUUID = generatedFromUUID; + } + + public ArtifactAssetStructure() { + super(); + // TODO Auto-generated constructor stub + } + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public String getArtifactType() { + return artifactType; + } + + public void setArtifactType(String artifactType) { + this.artifactType = artifactType; + } + + public String getArtifactURL() { + return artifactURL; + } + + public void setArtifactURL(String artifactURL) { + this.artifactURL = artifactURL; + } + + public String getArtifactDescription() { + return artifactDescription; + } + + public void setArtifactDescription(String artifactDescription) { + this.artifactDescription = artifactDescription; + } + + public int getArtifactTimeout() { + return artifactTimeout; + } + + public void setArtifactTimeout(int artifactTimeout) { + this.artifactTimeout = artifactTimeout; + } + + public String getArtifactChecksum() { + return artifactChecksum; + } + + public void setArtifactChecksum(String artifactChecksum) { + this.artifactChecksum = artifactChecksum; + } + + public String getArtifactUUID() { + return artifactUUID; + } + + public void setArtifactUUID(String artifactUUID) { + this.artifactUUID = artifactUUID; + } + + public String getArtifactVersion() { + return artifactVersion; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public String getGeneratedFromUUID() { + return generatedFromUUID; + } + + public void setGeneratedFromUUID(String generatedFromUUID) { + this.generatedFromUUID = generatedFromUUID; + } + + @Override + public String toString() { + return "ArtifactAssetStructure [artifactName=" + artifactName + ", artifactType=" + artifactType + + ", artifactURL=" + artifactURL + ", artifactDescription=" + artifactDescription + ", artifactTimeout=" + + artifactTimeout + ", artifactChecksum=" + artifactChecksum + ", artifactUUID=" + artifactUUID + + ", artifactVersion=" + artifactVersion + ", generatedFromUUID=" + generatedFromUUID + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactReqDetails.java new file mode 100644 index 0000000000..28606af14d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ArtifactReqDetails.java @@ -0,0 +1,226 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +import org.openecomp.sdc.be.model.HeatParameterDefinition; + +public class ArtifactReqDetails { + + public ArtifactReqDetails() { + + } + + public ArtifactReqDetails(String artifactName, String artifactType, String artifactDescription, String payloadData, + String artifactLable) { + super(); + this.artifactName = artifactName; + this.artifactType = artifactType; + this.description = artifactDescription; + this.payloadData = payloadData; + this.artifactLabel = artifactLable; + } + + public ArtifactReqDetails(String artifactLable, ArtifactReqDetails a) { + super(); + this.artifactName = a.getArtifactName(); + this.artifactType = a.getArtifactType(); + this.description = a.getArtifactType(); + this.payloadData = a.getPayload(); + this.artifactLabel = artifactLable; + } + + private String uniqueId; + private String artifactName; + private String artifactType; + private String description; + private String payloadData; + private String artifactLabel; + private String apiUrl; + private String artifactGroupType; + private Integer timeout; + private String userIdLastUpdater; + private String creatorFullName; + private String updaterFullName; + private String artifactChecksum; + private String artifactDisplayName; + private List heatParameters; + + private boolean mandatory; + private boolean serviceApi; + + public boolean isServiceApi() { + return serviceApi; + } + + public void setServiceApi(boolean serviceApi) { + this.serviceApi = serviceApi; + } + + public String getArtifactLabel() { + return artifactLabel; + } + + public void setArtifactLabel(String artifactLabel) { + this.artifactLabel = artifactLabel; + } + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public String getArtifactType() { + return artifactType; + } + + public void setArtifactType(String artifactType) { + this.artifactType = artifactType; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPayload() { + return payloadData; + } + + public void setPayload(String payload) { + this.payloadData = payload; + } + + public void setPayloadData(String payloadData) { + this.payloadData = payloadData; + } + + public String getArtifactGroupType() { + return artifactGroupType; + } + + public void setArtifactGroupType(String artifactGroupType) { + this.artifactGroupType = artifactGroupType; + } + + public Integer getTimeout() { + return timeout; + } + + public void setTimeout(Integer timeout) { + this.timeout = timeout; + } + + public boolean isMandatory() { + return mandatory; + } + + public void setMandatory(boolean mandatory) { + this.mandatory = mandatory; + } + + public String getUrl() { + return apiUrl; + } + + public void setUrl(String url) { + this.apiUrl = url; + } + + @Override + public String toString() { + if (!apiUrl.isEmpty()) { + return "ArtifactReqDetails [artifactName=" + artifactName + ", artifactType=" + artifactType + + ", description=" + description + ", payloadData=" + payloadData + ", artifactLabel=" + + artifactLabel + ", mandatory=" + mandatory + ", url=" + apiUrl + "]"; + } + + return "ArtifactReqDetails [artifactName=" + artifactName + ", artifactType=" + artifactType + ", description=" + + description + ", payloadData=" + payloadData + ", artifactLabel=" + artifactLabel + + ", artifactUniqueId=" + uniqueId + ", mandatory=" + mandatory + ", serviceApi=" + serviceApi + "]"; + + } + + public String getArtifactDisplayName() { + + return artifactDisplayName; + } + + public void setArtifactDisplayName(String artifactDisplayName) { + this.artifactDisplayName = artifactDisplayName; + } + + public String getUserIdLastUpdater() { + return userIdLastUpdater; + } + + public void setUserIdLastUpdater(String userIdLastUpdater) { + this.userIdLastUpdater = userIdLastUpdater; + } + + public String getCreatorFullName() { + return creatorFullName; + } + + public void setCreatorFullName(String creatorFullName) { + this.creatorFullName = creatorFullName; + } + + public String getUpdaterFullName() { + return updaterFullName; + } + + public void setUpdaterFullName(String updaterFullName) { + this.updaterFullName = updaterFullName; + } + + public String getArtifactChecksum() { + return artifactChecksum; + } + + public void setArtifactChecksum(String artifactChecksum) { + this.artifactChecksum = artifactChecksum; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String artifactUniqueId) { + this.uniqueId = artifactUniqueId; + } + + public List getHeatParameters() { + return heatParameters; + } + + public void setHeatParameters(List heatParameters) { + this.heatParameters = heatParameters; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/AssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/AssetStructure.java new file mode 100644 index 0000000000..8820b05772 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/AssetStructure.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +public class AssetStructure { + + private String uuid; + private String invariantUUID; + private String name; + private String version; + private String toscaModelURL; + private String category; + private String lifecycleState; + private String lastUpdaterUserId; + + public AssetStructure() { + super(); + } + + public AssetStructure(String uuid, String invariantUUID, String name, String version, String toscaModelURL, + String category, String lifecycleState, String lastUpdaterUserId) { + super(); + this.uuid = uuid; + this.invariantUUID = invariantUUID; + this.name = name; + this.version = version; + this.toscaModelURL = toscaModelURL; + this.category = category; + this.lifecycleState = lifecycleState; + this.lastUpdaterUserId = lastUpdaterUserId; + } + + @Override + public String toString() { + return "AssetStructure [uuid=" + uuid + ", invariantUUID=" + invariantUUID + ", name=" + name + ", version=" + + version + ", toscaModelURL=" + toscaModelURL + ", category=" + category + ", lifecycleState=" + + lifecycleState + ", lastUpdaterUserId=" + lastUpdaterUserId + "]"; + } + + public String getUuid() { + return uuid; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getInvariantUUID() { + return invariantUUID; + } + + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getToscaModelURL() { + return toscaModelURL; + } + + public void setToscaModelURL(String toscaModelURL) { + this.toscaModelURL = toscaModelURL; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentInstanceReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentInstanceReqDetails.java new file mode 100644 index 0000000000..549700f384 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentInstanceReqDetails.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import org.openecomp.sdc.be.model.ComponentInstance; + +public class ComponentInstanceReqDetails { + + String componentUid; + String description; + String posX; + String posY; + String name; + String uniqueId; + + public ComponentInstanceReqDetails() { + super(); + // TODO Auto-generated constructor stub + } + + public ComponentInstanceReqDetails(ComponentInstance componentInstance) { + super(); + this.setUniqueId(componentInstance.getUniqueId()); + this.description = componentInstance.getDescription(); + this.posX = componentInstance.getPosX(); + this.posY = componentInstance.getPosY(); + // this.name = "myResourceInstance"; + this.name = componentInstance.getName(); + } + + public ComponentInstanceReqDetails(String resourceUid, String description, String posX, String posY, String name) { + super(); + this.componentUid = resourceUid; + this.description = description; + this.posX = posX; + this.posY = posY; + // this.name = "myResourceInstance"; + this.name = name; + } + + public ComponentInstanceReqDetails(String resourceUid, String description, String posX, String posY) { + super(); + this.componentUid = resourceUid; + this.description = description; + this.posX = posX; + this.posY = posY; + } + + public String getComponentUid() { + return componentUid; + } + + public void setComponentUid(String resourceUid) { + this.componentUid = resourceUid; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getPosX() { + return posX; + } + + public void setPosX(String posX) { + this.posX = posX; + } + + public String getPosY() { + return posY; + } + + public void setPosY(String posY) { + this.posY = posY; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + @Override + public String toString() { + return "ResourceInstanceReqDetails [resourceUid=" + componentUid + ", description=" + description + ", posX=" + + posX + ", posY=" + posY + ", name=" + name + ", uniqueId=" + uniqueId + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentReqDetails.java new file mode 100644 index 0000000000..8546732414 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ComponentReqDetails.java @@ -0,0 +1,272 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; + +public abstract class ComponentReqDetails { + + protected String name; + protected String description; + protected List tags = new ArrayList<>(); + protected String contactId; + protected String icon; + protected String uniqueId; + protected String creatorUserId; + protected String creatorFullName; + protected String lastUpdaterUserId; + protected String lastUpdaterFullName; + protected Long creationDate; + protected Long lastUpdateDate; + protected LifecycleStateEnum lifecycleState; + protected String version; + protected String UUID; + protected List categories; + protected String projectCode; + protected String csarUUID; + protected String csarVersion; + protected String importedToscaChecksum; + protected String invariantUUID; + + public String getCsarVersion() { + return csarVersion; + } + + public void setCsarVersion(String csarVersion) { + this.csarVersion = csarVersion; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + tags.add(name); + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + // public String getCategory() { + // return category; + // } + // + public String getContactId() { + return contactId; + } + + public void setContactId(String contactId) { + this.contactId = contactId; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public void setCreatorUserId(String creatorUserId) { + this.creatorUserId = creatorUserId; + } + + public void setCreatorFullName(String creatorFullName) { + this.creatorFullName = creatorFullName; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public void setCreationDate(Long creationDate) { + this.creationDate = creationDate; + } + + public void setLastUpdateDate(Long lastUpdateDate) { + this.lastUpdateDate = lastUpdateDate; + } + + public void setLifecycleState(LifecycleStateEnum lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public void setUUID(String uUID) { + this.UUID = uUID; + } + + public String getCreatorUserId() { + return creatorUserId; + } + + public String getCreatorFullName() { + return creatorFullName; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public Long getCreationDate() { + return creationDate; + } + + public Long getLastUpdateDate() { + return lastUpdateDate; + } + + public LifecycleStateEnum getLifecycleState() { + return lifecycleState; + } + + public String getUUID() { + return UUID; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public void removeAllCategories() { + this.categories = new ArrayList<>(); + } + + public void addCategoryChain(String category, String subCategory) { + if (category != null || subCategory != null) { + if (categories == null) { + categories = new ArrayList<>(); + } + CategoryDefinition selectedCategory = null; + for (CategoryDefinition categoryDef : categories) { + if (categoryDef.getName().equals(category)) { + selectedCategory = categoryDef; + } + } + if (selectedCategory == null) { + selectedCategory = new CategoryDefinition(); + selectedCategory.setName(category); + categories.add(selectedCategory); + } + if (subCategory != null) { + List subcategories = selectedCategory.getSubcategories(); + if (subcategories == null) { + subcategories = new ArrayList<>(); + selectedCategory.setSubcategories(subcategories); + } + SubCategoryDefinition selectedSubcategory = null; + for (SubCategoryDefinition subcategory : subcategories) { + if (subcategory.getName().equals(subCategory)) { + selectedSubcategory = subcategory; + } + } + if (selectedSubcategory == null) { + selectedSubcategory = new SubCategoryDefinition(); + selectedSubcategory.setName(subCategory); + subcategories.add(selectedSubcategory); + } + } + } + } + + public void addCategory(String category) { + addCategoryChain(category, null); + } + + public String getProjectCode() { + return projectCode; + } + + public void setProjectCode(String projectCode) { + this.projectCode = projectCode; + } + + public String getCsarUUID() { + return csarUUID; + } + + public void setCsarUUID(String csarUUID) { + this.csarUUID = csarUUID; + } + + public String getImportedToscaChecksum() { + return importedToscaChecksum; + } + + public void setImportedToscaChecksum(String importedToscaChecksum) { + this.importedToscaChecksum = importedToscaChecksum; + } + + public String getInvariantUUID() { + return invariantUUID; + } + + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/GroupHeatMetaDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/GroupHeatMetaDefinition.java new file mode 100644 index 0000000000..690f63955d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/GroupHeatMetaDefinition.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.ArrayList; +import java.util.List; + +public class GroupHeatMetaDefinition { + + int group = 0; + List artifactList = new ArrayList(); + PropertyHeatMetaDefinition propertyHeatMetaDefinition; + + public PropertyHeatMetaDefinition getPropertyHeatMetaDefinition() { + return propertyHeatMetaDefinition; + } + + public void setPropertyHeatMetaDefinition(PropertyHeatMetaDefinition propertyHeatMetaDefinition) { + this.propertyHeatMetaDefinition = propertyHeatMetaDefinition; + } + + public GroupHeatMetaDefinition() { + super(); + } + + public int getGroup() { + return group; + } + + public void setGroup(int group) { + this.group = group; + } + + public List getArtifactList() { + return artifactList; + } + + public void setArtifactList(List artifactList) { + this.artifactList = artifactList; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ImportReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ImportReqDetails.java new file mode 100644 index 0000000000..0089eec5a7 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ImportReqDetails.java @@ -0,0 +1,332 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.yaml.snakeyaml.Yaml; + +public class ImportReqDetails extends ResourceReqDetails { + + private String payloadName; + private String payloadData; + + private Map requirements; + private Map capabilities; + + private List derivedList; + private String derivedFromField; + + public ImportReqDetails(String resourceName, String description, List tags, List derivedFrom, + String vendorName, String vendorRelease, String contactId, String icon) { + super(resourceName, description, tags, null, derivedFrom, vendorName, vendorRelease, contactId, icon); + } + + public String getPayloadName() { + return payloadName; + } + + public void setPayloadName(String payloadName) { + this.payloadName = payloadName; + } + + public String getPayloadData() { + return payloadData; + } + + public void setPayloadData(String payloadData) { + this.payloadData = payloadData; + } + + @Override + public String toString() { + return "ImportReqDetails [payloadName=" + payloadName + ", payloadData=" + payloadData + "]"; + } + + public void setReqirementsAndCapabilities(String path, String fileName, User user, String derivedFromSource) + throws Exception { + setRequirements(path, fileName, user, derivedFromSource); + setCapabilities(path, fileName, user, derivedFromSource); + } + + public List getDerivedList() { + return derivedList; + } + + public void setDerivedList(List derivedList) { + this.derivedList = derivedList; + } + + public String getDerivedFromField() { + return derivedFromField; + } + + public void setDerivedFromField(String derivedFromField) { + this.derivedFromField = derivedFromField; + } + + public Map getRequirements() { + return requirements; + } + + public void setRequirements(String path, String fileName, User user, String derivedFromSource) throws Exception { + Map requirementsFromFile = getRequirementsMapFromFile(path + File.separator + fileName, + toscaResourceName, "requirements"); + Map requirements = organizeRequirementsMap(requirementsFromFile); + getDerivedReqCap(user, requirements, "requirements", derivedFromSource); + this.requirements = requirements; + } + + private void getDerivedReqCap(User user, Map reqCapMap, String field, String derivedFromResource) + throws IOException, JSONException { + + if (derivedFromResource == null) { + derivedFromResource = "Root"; + } + + RestResponse rest = getResourceSource(user, derivedFromResource); + Map parsedFieldFromResponseAsMap = ResponseParser.getJsonValueAsMap(rest, field); + Iterator iterator = parsedFieldFromResponseAsMap.keySet().iterator(); + Map convertListToMap = null; + while (iterator.hasNext()) { + String type = iterator.next(); + List lst = (List) parsedFieldFromResponseAsMap.get(type); + convertListToMap = convertListToMap(lst); + + if (field.equals("capabilities")) { + convertListToMap.replace("capabilitySources", derivedList); + lst = new ArrayList(Arrays.asList(convertListToMap)); + } + + Object existingValue = reqCapMap.get(type); + if (existingValue != null) { + Map convertedExistingValue = convertListToMap((List) existingValue); + if (convertedExistingValue.get("name").toString().toLowerCase() + .equals(convertListToMap.get("name").toString().toLowerCase())) { + lst = new ArrayList(Arrays.asList(convertedExistingValue)); + } else { + lst.add(convertedExistingValue); + } + } + + reqCapMap.put(type, lst); + } + } + + private RestResponse getResourceSource(User user, String source) throws IOException, JSONException { + org.codehaus.jettison.json.JSONObject getResourceJSONObject = null; + RestResponse rest = ResourceRestUtils.getResourceByNameAndVersion(user.getUserId(), source, "1.0"); + if (rest.getErrorCode().intValue() == 200) { + JSONArray jArray = new JSONArray(rest.getResponse()); + for (int i = 0; i < jArray.length(); i++) { + getResourceJSONObject = jArray.getJSONObject(i); + String resourceType = getResourceJSONObject.get("resourceType").toString(); + if (!resourceType.equals("VF")) { + rest.setResponse(getResourceJSONObject.toString()); + } + } + } + return rest; + } + + public Map getCapabilities() { + return capabilities; + } + + public void setCapabilities(String path, String fileName, User user, String derivedFromSource) throws Exception { + Map capabilitiesFromFile = getCapabilitiesMapFromFile(path + File.separator + fileName, + toscaResourceName, "capabilities"); + Map capabilities = organizeCapabilitiesMap(capabilitiesFromFile); + getDerivedReqCap(user, capabilities, "capabilities", derivedFromSource); + this.capabilities = capabilities; + } + + private Map organizeCapabilitiesMap(Map capabilitiesFromFile) { + Iterator iterator = capabilitiesFromFile.keySet().iterator(); + Map capMap = new HashMap(); + while (iterator.hasNext()) { + List valueList = new ArrayList(); + String next = iterator.next(); + Map valuesMap = (Map) capabilitiesFromFile.get(next); + String key = valuesMap.remove("type").toString(); + valuesMap.put("name", next); + valuesMap.put("capabilitySources", derivedList); + valuesMap.put("type", key); + + if (!valuesMap.containsKey("occurrences")) { + valuesMap.put("minOccurrences", "1"); + valuesMap.put("maxOccurrences", "UNBOUNDED"); + } + + Object tempValue = capMap.get(key); + if (tempValue == null) { + valueList.add(valuesMap); + } else { + Map convertValue = convertListToMap((List) tempValue); + valueList = new ArrayList(Arrays.asList(convertValue, valuesMap)); + } + capMap.put(key, valueList); + } + return capMap; + } + + private Map getCapabilitiesMapFromFile(String fileName, String toscaResourceName, + String fieldToTest) throws Exception { + Map resourceToscaMap = getToscaResourceFromFile(fileName, toscaResourceName); + Object capMap = resourceToscaMap.get(fieldToTest); + if (capMap == null) { + return new HashMap(); + } + return (Map) capMap; + } + + private Map organizeRequirementsMap(Map requirementsFromFile) { + Map reqMap = new HashMap(); + List valueList = new ArrayList(); + Iterator iterator = requirementsFromFile.keySet().iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + Map valuesMap = (Map) requirementsFromFile.get(key); + valuesMap.put("name", key); + String capability = valuesMap.get("capability").toString(); + + List occurencesList = (List) valuesMap.remove("occurrences"); + if (occurencesList != null) { + valuesMap.put("minOccurrences", occurencesList.get(0).toString()); + valuesMap.put("maxOccurrences", occurencesList.get(1).toString()); + } + + valueList.add(valuesMap); + reqMap.put(capability, valueList); + } + + return reqMap; + } + + private Map getRequirementsMapFromFile(String fileName, String toscaResourceName, + String fieldToTest) throws Exception { + Map resourceToscaMap = getToscaResourceFromFile(fileName, toscaResourceName); + List reqListFromFile = (List) resourceToscaMap.get(fieldToTest); + if (reqListFromFile == null) { + return new HashMap(); + } + Map testedMapFromFile = convertListToMap(reqListFromFile); + return testedMapFromFile; + } + + private Map getToscaResourceFromFile(String fullFileName, String toscaResourceName) + throws Exception { + Map nodesTypesMap = getNodesTypesMapFromFile(fullFileName); + Map resourceToscaMap = (Map) nodesTypesMap.get(toscaResourceName); + + derivedFromField = resourceToscaMap.get("derived_from").toString(); + + return resourceToscaMap; + } + + private Map getNodesTypesMapFromFile(String fullFileName) throws FileNotFoundException { + Yaml yaml = new Yaml(); + File file = new File(fullFileName); + InputStream inputStream = new FileInputStream(file); + Map mapFromFile = (Map) yaml.load(inputStream); + Map nodesTypesMap = (Map) mapFromFile.get("node_types"); + return nodesTypesMap; + } + + private Map convertListToMap(List testedListFromFile) { + Map testedMapFromFile = new HashMap(); + for (int i = 0; i < testedListFromFile.size(); i++) { + Object req = testedListFromFile.get(i); + ObjectMapper m = new ObjectMapper(); + Map mappedObject = m.convertValue(req, Map.class); + testedMapFromFile.putAll(mappedObject); + } + return testedMapFromFile; + } + + public void compareRequirementsOrCapabilities(Map exepectedReq, Map actualReq) { + Iterator iterator = exepectedReq.keySet().iterator(); + while (iterator.hasNext()) { + String key = iterator.next(); + List expectedValues = (List) exepectedReq.get(key); + List actualValues = (List) actualReq.get(key); + assertNotNull(actualValues); + + List> expectedMapsList = convertListToMapList(expectedValues); + List> actualMapsList = convertListToMapList(actualValues); + assertEquals(expectedMapsList.size(), actualMapsList.size()); + + for (int i = 0; i < expectedMapsList.size(); i++) { + Map expectedMap = expectedMapsList.get(i); + Map actualdMap = actualMapsList.get(i); + if (expectedMap.get("name").equals(actualdMap.get("name"))) { + Iterator iterator2 = expectedMap.keySet().iterator(); + while (iterator2.hasNext()) { + String innerKey = iterator2.next(); + assertTrue( + "check " + innerKey + " in " + key + ":\nexpected: " + + expectedMap.get(innerKey).toString() + "\nactual: " + + actualdMap.get(innerKey).toString(), + expectedMap.get(innerKey).equals(actualdMap.get(innerKey))); + + } + + } + } + } + } + + private List> convertListToMapList(List testedListFromFile) { + List> listOfMaps = new ArrayList>(); + for (int i = 0; i < testedListFromFile.size(); i++) { + Object req = testedListFromFile.get(i); + ObjectMapper m = new ObjectMapper(); + Map mappedObject = m.convertValue(req, Map.class); + mappedObject.remove("uniqueId"); + Map testedMapFromFile = new HashMap(); + testedMapFromFile.putAll(mappedObject); + listOfMaps.add(testedMapFromFile); + } + return listOfMaps; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ProductReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ProductReqDetails.java new file mode 100644 index 0000000000..f2484e274d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ProductReqDetails.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.model.category.CategoryDefinition; + +public class ProductReqDetails extends ComponentReqDetails { + + private String fullName; + private List contacts; + private String isActive; + + public ProductReqDetails(String name, List category) { + this.categories = category; + this.name = name; + } + + public ProductReqDetails(String name) { + this.name = name; + } + + public void addCategory(CategoryDefinition category) { + if (categories == null) { + categories = new ArrayList<>(); + } + categories.add(category); + } + + public void addContact(String contactUserId) { + if (contacts == null) { + contacts = new ArrayList<>(); + } + contacts.add(contactUserId); + } + + public List getContacts() { + return contacts; + } + + public void setContacts(List contacts) { + this.contacts = contacts; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + public String getFullName() { + return fullName; + } + + public void setFullName(String fullName) { + this.fullName = fullName; + } + + public String getActive() { + return isActive; + } + + public void setActive(String isActive) { + this.isActive = isActive; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyHeatMetaDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyHeatMetaDefinition.java new file mode 100644 index 0000000000..6271e1f59d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyHeatMetaDefinition.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +public class PropertyHeatMetaDefinition { + + String name; + boolean value; + + public PropertyHeatMetaDefinition() { + super(); + } + + public String getName() { + return name; + } + + public boolean isValue() { + return value; + } + + public void setValue(boolean value) { + this.value = value; + } + + public void setName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "PropertyHeatMetaDefinition [name=" + name + ", value=" + value + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyReqDetails.java new file mode 100644 index 0000000000..208e4aa3ea --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/PropertyReqDetails.java @@ -0,0 +1,145 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; + +public class PropertyReqDetails { + String name; + String type; + Boolean required = false; + String defaultValue; + String description; + String propertyRangeMin; + String propertyRangeMax; + Boolean isPassword = false; + SchemaDefinition schema; + + public PropertyReqDetails() { + super(); + } + + public PropertyReqDetails(String propertyName, String propertyType, Boolean propertyRequired, + String propertyDefaultValue, String propertyDescription, String propertyRangeMin, String propertyRangeMax, + Boolean propertyPassword) { + super(); + this.name = propertyName; + this.type = propertyType; + this.required = propertyRequired; + this.defaultValue = propertyDefaultValue; + this.description = propertyDescription; + this.propertyRangeMin = propertyRangeMin; + this.propertyRangeMax = propertyRangeMax; + this.isPassword = propertyPassword; + } + + public PropertyReqDetails(String propertyName, String propertyType, String propertyDefaultValue, + String propertyDescription, SchemaDefinition schema) { + super(); + this.name = propertyName; + this.type = propertyType; + this.defaultValue = propertyDefaultValue; + this.description = propertyDescription; + this.schema = schema; + } + + public SchemaDefinition getSchema() { + return schema; + } + + public void setSchema(SchemaDefinition schema) { + this.schema = schema; + } + + public String getName() { + return name; + } + + public void setName(String propertyName) { + this.name = propertyName; + } + + public String getPropertyType() { + return type; + } + + public void setPropertyType(String propertyType) { + this.type = propertyType; + } + + public Boolean getPropertyRequired() { + return required; + } + + public void setPropertyRequired(Boolean propertyRequired) { + this.required = propertyRequired; + } + + public String getPropertyDefaultValue() { + return defaultValue; + } + + public void setPropertyDefaultValue(String propertyDefaultValue) { + this.defaultValue = propertyDefaultValue; + } + + public String getPropertyDescription() { + return description; + } + + public void setPropertyDescription(String propertyDescription) { + this.description = propertyDescription; + } + + public String getPropertyRangeMin() { + return propertyRangeMin; + } + + public void setPropertyRangeMin(String propertyRangeMin) { + this.propertyRangeMin = propertyRangeMin; + } + + public String getPropertyRangeMax() { + return propertyRangeMax; + } + + public void setPropertyRangeMax(String propertyRangeMax) { + this.propertyRangeMax = propertyRangeMax; + } + + public Boolean getPropertyPassword() { + return isPassword; + } + + public void setPropertyPassword(Boolean propertyPassword) { + this.isPassword = propertyPassword; + } + + public String propertyToJsonString() { + String jsonString; + jsonString = "{\"" + this.getName() + "\":{" + "\"type\":\"" + this.getPropertyType() + "\"," + "\"required\":" + + this.getPropertyRequired() + "," + "\"defaultValue\":\"" + this.getPropertyDefaultValue() + "\"," + + "\"description\":\"" + this.getPropertyDescription() + "\"," + "\"constraints\":[{\"inRange\":[\"" + + this.getPropertyRangeMin() + "\",\"" + this.getPropertyRangeMax() + "\"]}]," + "\"isPassword\":" + + this.getPropertyPassword() + "}}"; + return jsonString; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceAssetStructure.java new file mode 100644 index 0000000000..d429d05a51 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceAssetStructure.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +public class ResourceAssetStructure extends AssetStructure { + + private String subCategory; + private String resourceType; + + public ResourceAssetStructure() { + super(); + } + + public ResourceAssetStructure(String uuid, String invariantUUID, String name, String version, String toscaModelURL, + String category, String lifecycleState, String lastUpdaterUserId) { + super(uuid, invariantUUID, name, version, toscaModelURL, category, lifecycleState, lastUpdaterUserId); + } + + @Override + public String toString() { + return "ResourceAssetStructure [subCategory=" + subCategory + ", resourceType=" + resourceType + "]"; + } + + public String getSubCategory() { + return subCategory; + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceDetailedAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceDetailedAssetStructure.java new file mode 100644 index 0000000000..737343f24c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceDetailedAssetStructure.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +public class ResourceDetailedAssetStructure extends ResourceAssetStructure { + + private String lastUpdaterFullName; + private String toscaResourceName; + private List resources; + private List artifacts; + + public ResourceDetailedAssetStructure() { + super(); + } + + public ResourceDetailedAssetStructure(String lastUpdaterFullName, String toscaResourceName, + List resources, List artifacts) { + super(); + this.lastUpdaterFullName = lastUpdaterFullName; + this.toscaResourceName = toscaResourceName; + this.resources = resources; + this.artifacts = artifacts; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public String getToscaResourceName() { + return toscaResourceName; + } + + public void setToscaResourceName(String toscaResourceName) { + this.toscaResourceName = toscaResourceName; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + @Override + public String toString() { + return "ResourceDetailedAssetStructure [lastUpdaterFullName=" + lastUpdaterFullName + ", toscaResourceName=" + + toscaResourceName + ", resources=" + resources + ", artifacts=" + artifacts + ", toString()=" + + super.toString() + ", getSubCategory()=" + getSubCategory() + ", getResourceType()=" + + getResourceType() + ", getUuid()=" + getUuid() + ", getInvariantUUID()=" + getInvariantUUID() + + ", getName()=" + getName() + ", getVersion()=" + getVersion() + ", getToscaModelURL()=" + + getToscaModelURL() + ", getCategory()=" + getCategory() + ", getLifecycleState()=" + + getLifecycleState() + ", getLastUpdaterUserId()=" + getLastUpdaterUserId() + ", getClass()=" + + getClass() + ", hashCode()=" + hashCode() + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceInstanceAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceInstanceAssetStructure.java new file mode 100644 index 0000000000..6a69120a05 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceInstanceAssetStructure.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +public class ResourceInstanceAssetStructure { + + String resourceInstanceName; + String resourceName; + String resourceInvariantUUID; + String resourceVersion; + String resoucreType; + String resourceUUID; + List artifacts; + + public ResourceInstanceAssetStructure() { + super(); + } + + public ResourceInstanceAssetStructure(String resourceInstanceName, String resourceName, + String resourceInvariantUUID, String resourceVersion, String resoucreType, String resourceUUID, + List artifacts) { + super(); + this.resourceInstanceName = resourceInstanceName; + this.resourceName = resourceName; + this.resourceInvariantUUID = resourceInvariantUUID; + this.resourceVersion = resourceVersion; + this.resoucreType = resoucreType; + this.resourceUUID = resourceUUID; + this.artifacts = artifacts; + } + + public String getResourceInstanceName() { + return resourceInstanceName; + } + + public void setResourceInstanceName(String resourceInstanceName) { + this.resourceInstanceName = resourceInstanceName; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceInvariantUUID() { + return resourceInvariantUUID; + } + + public void setResourceInvariantUUID(String resourceInvariantUUID) { + this.resourceInvariantUUID = resourceInvariantUUID; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public String getResoucreType() { + return resoucreType; + } + + public void setResoucreType(String resoucreType) { + this.resoucreType = resoucreType; + } + + public String getResourceUUID() { + return resourceUUID; + } + + public void setResourceUUID(String resourceUUID) { + this.resourceUUID = resourceUUID; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + @Override + public String toString() { + return "ResourceInstanceAssetStructure [resourceInstanceName=" + resourceInstanceName + ", resourceName=" + + resourceName + ", resourceInvariantUUID=" + resourceInvariantUUID + ", resourceVersion=" + + resourceVersion + ", resoucreType=" + resoucreType + ", resourceUUID=" + resourceUUID + ", artifacts=" + + artifacts + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceReqDetails.java new file mode 100644 index 0000000000..8456e5b35b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceReqDetails.java @@ -0,0 +1,220 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; + +public class ResourceReqDetails extends ComponentReqDetails { + List derivedFrom; + String vendorName; + String vendorRelease; + + // Unsettable/unupdatable fields + + Boolean isAbstract; + Boolean isHighestVersion; + String cost; + String licenseType; + String toscaResourceName; + + private String resourceType = ResourceTypeEnum.VFC.toString(); // Default + // value + + public ResourceReqDetails() { + super(); + } + + public ResourceReqDetails(Resource resource) { + super(); + this.resourceType = resource.getResourceType().toString(); + this.name = resource.getName(); + this.description = resource.getDescription(); + this.tags = resource.getTags(); + // this.category = resource.getCategories(); + this.derivedFrom = resource.getDerivedFrom(); + this.vendorName = resource.getVendorName(); + this.vendorRelease = resource.getVendorRelease(); + this.contactId = resource.getContactId(); + this.icon = resource.getIcon(); + this.toscaResourceName = resource.getToscaResourceName(); + this.uniqueId = resource.getUniqueId(); + this.creatorUserId = resource.getCreatorUserId(); + this.creatorFullName = resource.getCreatorFullName(); + this.lastUpdaterUserId = resource.getLastUpdaterUserId(); + this.lastUpdaterFullName = resource.getLastUpdaterFullName(); + this.lifecycleState = resource.getLifecycleState(); + this.version = resource.getVersion(); + this.UUID = resource.getUUID(); + this.categories = resource.getCategories(); + this.importedToscaChecksum = resource.getImportedToscaChecksum(); + + } + + public ResourceReqDetails(String resourceName, String description, List tags, String category, + List derivedFrom, String vendorName, String vendorRelease, String contactId, String icon) { + this(resourceName, description, tags, category, derivedFrom, vendorName, vendorRelease, contactId, icon, + ResourceTypeEnum.VFC.toString()); + } + + // new + public ResourceReqDetails(String resourceName, String description, List tags, String category, + List derivedFrom, String vendorName, String vendorRelease, String contactId, String icon, + String resourceType) { + super(); + this.resourceType = resourceType; + this.name = resourceName; + this.description = description; + this.tags = tags; + // this.category = category; + this.derivedFrom = derivedFrom; + this.vendorName = vendorName; + this.vendorRelease = vendorRelease; + this.contactId = contactId; + this.icon = icon; + if (category != null) { + String[] arr = category.split("/"); + if (arr.length == 2) { + addCategoryChain(arr[0], arr[1]); + } + } + this.toscaResourceName = resourceName; + } + + public ResourceReqDetails(ResourceReqDetails originalResource, String version) { + super(); + this.name = originalResource.getName(); + this.description = originalResource.getDescription(); + this.tags = originalResource.getTags(); + // this.category = originalResource.getCategory(); + this.derivedFrom = originalResource.getDerivedFrom(); + this.vendorName = originalResource.getVendorName(); + this.vendorRelease = originalResource.getVendorRelease(); + this.contactId = originalResource.getContactId(); + this.icon = originalResource.getIcon(); + this.version = version; + this.uniqueId = originalResource.getUniqueId(); + this.categories = originalResource.getCategories(); + this.toscaResourceName = originalResource.getToscaResourceName(); + this.resourceType = originalResource.getResourceType(); + } + + public ResourceReqDetails(String resourceName, List derivedFrom, String vendorName, String vendorRelease, + String resourceVersion, Boolean isAbstract, Boolean isHighestVersion, String cost, String licenseType, + String resourceType) { + super(); + this.name = resourceName; + this.derivedFrom = derivedFrom; + this.vendorName = vendorName; + this.vendorRelease = vendorRelease; + this.version = resourceVersion; + this.isAbstract = isAbstract; + this.isHighestVersion = isHighestVersion; + this.cost = cost; + this.licenseType = licenseType; + this.resourceType = resourceType; + this.toscaResourceName = resourceName; + } + + public String getToscaResourceName() { + return toscaResourceName; + } + + public void setToscaResourceName(String toscaResourceName) { + this.toscaResourceName = toscaResourceName; + } + + public List getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(List derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public String getVendorName() { + return vendorName; + } + + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + } + + public String getVendorRelease() { + return vendorRelease; + } + + public void setVendorRelease(String vendorRelease) { + this.vendorRelease = vendorRelease; + } + + public String getCost() { + return cost; + } + + public void setCost(String cost) { + this.cost = cost; + } + + public String getLicenseType() { + return licenseType; + } + + public void setLicenseType(String licenseType) { + this.licenseType = licenseType; + } + + // Unupdatable fields - to check that they are not updated + public void setIsAbstract(Boolean isAbstract) { + this.isAbstract = isAbstract; + } + + public void setIsHighestVersion(Boolean isHighestVersion) { + this.isHighestVersion = isHighestVersion; + } + + public Boolean getIsAbstract() { + return isAbstract; + } + + public Boolean getIsHighestVersion() { + return isHighestVersion; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + @Override + public String toString() { + return "ResourceReqDetails [name=" + name + ", derivedFrom=" + derivedFrom + ", vendorName=" + vendorName + + ", vendorRelease=" + vendorRelease + ", version=" + version + ", isAbstract=" + isAbstract + + ", isHighestVersion=" + isHighestVersion + ", cost=" + cost + ", licenseType=" + licenseType + + ", resourceType=" + resourceType + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceRespJavaObject.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceRespJavaObject.java new file mode 100644 index 0000000000..eb473ab39f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ResourceRespJavaObject.java @@ -0,0 +1,337 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +import org.openecomp.sdc.be.model.category.CategoryDefinition; + +public class ResourceRespJavaObject { + String uniqueId; + String name; + String version; + String creatorUserId; + String creatorFullName; + String lastUpdaterUserId; + String lastUpdaterFullName; + String description; + String icon; + List tags; + String isHighestVersion; + String creationDate; + String lastUpdateDate; + // String category; + String lifecycleState; + List derivedFrom; + String vendorName; + String vendorRelease; + String contactId; + String abstractt; + String highestVersion; + List artifacts; + List interfaces; + String uuid; + String cost; + String licenseType; + String resourceType; + List categories; + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public ResourceRespJavaObject(String uniqueId, String resourceName, String resourceVersion, String creatorUserId, + String creatorFullName, String lastUpdaterUserId, String lastUpdaterFullName, String description, + String icon, List tags, String isHighestVersion, String creationDate, String lastUpdateDate, + String category, String lifecycleState, List derivedFrom, String vendorName, String vendorRelease, + String contactId, String abstractt, String highestVersion, List artifacts, List interfaces, + String uuid, String cost, String licenseType, String resourceType) { + super(); + this.uniqueId = uniqueId; + this.name = resourceName; + this.version = resourceVersion; + this.creatorUserId = creatorUserId; + this.creatorFullName = creatorFullName; + this.lastUpdaterUserId = lastUpdaterUserId; + this.lastUpdaterFullName = lastUpdaterFullName; + this.description = description; + this.icon = icon; + this.tags = tags; + this.isHighestVersion = isHighestVersion; + this.creationDate = creationDate; + this.lastUpdateDate = lastUpdateDate; + // this.category = category; + this.lifecycleState = lifecycleState; + this.derivedFrom = derivedFrom; + this.vendorName = vendorName; + this.vendorRelease = vendorRelease; + this.contactId = contactId; + this.abstractt = abstractt; + this.highestVersion = highestVersion; + this.artifacts = artifacts; + this.interfaces = interfaces; + this.uuid = uuid; + this.cost = cost; + this.licenseType = licenseType; + this.resourceType = resourceType; + } + + public void setUuid(String uuid) { + this.uuid = uuid; + } + + public String getCost() { + return cost; + } + + public void setCost(String cost) { + this.cost = cost; + } + + public String getLicenseType() { + return licenseType; + } + + public void setLicenseType(String licenseType) { + this.licenseType = licenseType; + } + + public String getUuid() { + return uuid; + } + + public String setUuid() { + return uuid; + } + + public List getInterfaces() { + return interfaces; + } + + public void setInterfaces(List interfaces) { + this.interfaces = interfaces; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + public ResourceRespJavaObject() { + super(); + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getName() { + return name; + } + + public void setName(String resourceName) { + this.name = resourceName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String resourceVersion) { + this.version = resourceVersion; + } + + public String getCreatorUserId() { + return creatorUserId; + } + + public void setCreatorUserId(String creatorUserId) { + this.creatorUserId = creatorUserId; + } + + public String getCreatorFullName() { + return creatorFullName; + } + + public void setCreatorFullName(String creatorFullName) { + this.creatorFullName = creatorFullName; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public List getTags() { + return tags; + } + + public void setTags(List tags) { + this.tags = tags; + } + + public String getIsHighestVersion() { + return isHighestVersion; + } + + public void setIsHighestVersion(String isHighestVersion) { + this.isHighestVersion = isHighestVersion; + } + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + + public String getLastUpdateDate() { + return lastUpdateDate; + } + + public void setLastUpdateDate(String lastUpdateDate) { + this.lastUpdateDate = lastUpdateDate; + } + + // public String getCategory() { + // return category; + // } + // public void setCategory(String category) { + // this.category = category; + // } + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public List getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(List derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public String getVendorName() { + return vendorName; + } + + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + } + + public String getVendorRelease() { + return vendorRelease; + } + + public void setVendorRelease(String vendorRelease) { + this.vendorRelease = vendorRelease; + } + + public String getContactId() { + return contactId; + } + + public void setContactId(String contactId) { + this.contactId = contactId; + } + + public String getAbstractt() { + return abstractt; + } + + public void setAbstractt(String abstractt) { + this.abstractt = abstractt; + } + + public String getHighestVersion() { + return highestVersion; + } + + public void setHighestVersion(String highestVersion) { + this.highestVersion = highestVersion; + } + + public List getCategories() { + return categories; + } + + public void setCategories(List categories) { + this.categories = categories; + } + + @Override + public String toString() { + return "ResourceRespJavaObject [uniqueId=" + uniqueId + ", resourceName=" + name + ", resourceVersion=" + + version + ", creatorUserId=" + creatorUserId + ", creatorFullName=" + creatorFullName + + ", lastUpdaterUserId=" + lastUpdaterUserId + ", lastUpdaterFullName=" + lastUpdaterFullName + + ", description=" + description + ", icon=" + icon + ", tags=" + tags + ", isHighestVersion=" + + isHighestVersion + ", creationDate=" + creationDate + ", lastUpdateDate=" + lastUpdateDate + + ", lifecycleState=" + lifecycleState + ", derivedFrom=" + derivedFrom + ", vendorName=" + vendorName + + ", vendorRelease=" + vendorRelease + ", contactId=" + contactId + ", abstractt=" + abstractt + + ", highestVersion=" + highestVersion + ", artifacts=" + artifacts + ", interfaces=" + interfaces + + ", uuid=" + uuid + ", cost=" + cost + ", licenseType=" + licenseType + ", resourceType=" + + resourceType + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceAssetStructure.java new file mode 100644 index 0000000000..015d228acf --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceAssetStructure.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +public class ServiceAssetStructure extends AssetStructure { + + private String distributionStatus; + + public ServiceAssetStructure() { + super(); + } + + public ServiceAssetStructure(String uuid, String invariantUUID, String name, String version, String toscaModelURL, + String category, String lifecycleState, String lastUpdaterUserId) { + super(uuid, invariantUUID, name, version, toscaModelURL, category, lifecycleState, lastUpdaterUserId); + } + + @Override + public String toString() { + return "ServiceAssetStructure [distributionStatus=" + distributionStatus + "]"; + } + + public String getDistributionStatus() { + return distributionStatus; + } + + public void setDistributionStatus(String distributionStatus) { + this.distributionStatus = distributionStatus; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceDetailedAssetStructure.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceDetailedAssetStructure.java new file mode 100644 index 0000000000..cc283a3169 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceDetailedAssetStructure.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +public class ServiceDetailedAssetStructure extends ServiceAssetStructure { + + String lastUpdaterFullName; + List resources; + List artifacts; + + public ServiceDetailedAssetStructure() { + super(); + } + + public ServiceDetailedAssetStructure(String uuid, String invariantUUID, String name, String version, + String toscaModelURL, String category, String lifecycleState, String lastUpdaterUserId) { + super(uuid, invariantUUID, name, version, toscaModelURL, category, lifecycleState, lastUpdaterUserId); + } + + public ServiceDetailedAssetStructure(String lastUpdaterFullName, List resources, + List artifacts) { + super(); + this.lastUpdaterFullName = lastUpdaterFullName; + this.resources = resources; + this.artifacts = artifacts; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + @Override + public String toString() { + return "ServiceDetailedAssetStructure [lastUpdaterFullName=" + lastUpdaterFullName + ", resources=" + resources + + ", artifacts=" + artifacts + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceReqDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceReqDetails.java new file mode 100644 index 0000000000..e33183ca94 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceReqDetails.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.ArrayList; + +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.category.CategoryDefinition; + +public class ServiceReqDetails extends ComponentReqDetails { + + public ServiceReqDetails(String serviceName, String category, ArrayList tags, String description, + String contactId, String icon) { + this.name = serviceName; + // this.category = category; + this.tags = tags; + this.description = description; + this.contactId = contactId; + this.icon = icon; + projectCode = "12345"; + CategoryDefinition categoryDefinition = new CategoryDefinition(); + categoryDefinition.setName(category); + categories = new ArrayList<>(); + categories.add(categoryDefinition); + + } + + public ServiceReqDetails(Service service) { + this.contactId = service.getContactId(); + this.categories = service.getCategories(); + this.creatorUserId = service.getCreatorUserId(); + this.creatorFullName = service.getCreatorFullName(); + this.description = service.getDescription(); + this.icon = service.getIcon(); + this.name = service.getName(); + this.projectCode = service.getProjectCode(); + this.tags = service.getTags(); + this.uniqueId = service.getUniqueId(); + this.UUID = service.getUUID(); + this.version = service.getVersion(); + + } + + public ServiceReqDetails() { + contactId = "aa1234"; + projectCode = "12345"; + } + + public ServiceReqDetails(ServiceReqDetails a, String newServiceName) { + a.setName(newServiceName); + } + + @Override + public String toString() { + return "ServiceDetails [name=" + name + ", category=" + getCategory() + ", tags=" + tags + ", description=" + + description + ", contactId=" + contactId + ", icon=" + icon + "]"; + } + + public ServiceReqDetails(ServiceReqDetails aService) { + this(aService.getName(), aService.getCategory(), (ArrayList) aService.getTags(), + aService.getDescription(), aService.getContactId(), aService.getIcon()); + uniqueId = aService.getUniqueId(); + version = aService.getVersion(); + } + + public String getCategory() { + if (categories != null && categories.size() >= 1) { + return categories.get(0).getName(); + } + return null; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceRespJavaObject.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceRespJavaObject.java new file mode 100644 index 0000000000..4aeb0ce589 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/ServiceRespJavaObject.java @@ -0,0 +1,267 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.ArrayList; + +public class ServiceRespJavaObject { + + String category; + String creatorUserId; + String creatorFullName; + String lastUpdaterUserId; + String lastUpdaterFullName; + String serviceName; + String version; + String creationDate; + String icon; + String name; + String description; + ArrayList tags; + String uniqueId; + String lastUpdateDate; + String contactId; + String vendorName; + String vendorRelease; + String lifecycleState; + String highestVersion; + ArrayList artifacts; + ArrayList ResourceInstances; + ArrayList ResourceInstancesRelations; + + public ServiceRespJavaObject() { + super(); + // TODO Auto-generated constructor stub + } + + public ServiceRespJavaObject(String category, String creatorUserId, String creatorFullName, + String lastUpdaterUserId, String lastUpdaterFullName, String serviceName, String version, + String creationDate, String icon, String name, String description, ArrayList tags, String uniqueId, + String lastUpdateDate, String contactId, String vendorName, String vendorRelease, String lifecycleState, + String highestVersion, ArrayList artifacts, ArrayList resourceInstances, + ArrayList resourceInstancesRelations) { + super(); + this.category = category; + this.creatorUserId = creatorUserId; + this.creatorFullName = creatorFullName; + this.lastUpdaterUserId = lastUpdaterUserId; + this.lastUpdaterFullName = lastUpdaterFullName; + this.serviceName = serviceName; + this.version = version; + this.creationDate = creationDate; + this.icon = icon; + this.name = name; + this.description = description; + this.tags = tags; + this.uniqueId = uniqueId; + this.lastUpdateDate = lastUpdateDate; + this.contactId = contactId; + this.vendorName = vendorName; + this.vendorRelease = vendorRelease; + this.lifecycleState = lifecycleState; + this.highestVersion = highestVersion; + this.artifacts = artifacts; + ResourceInstances = resourceInstances; + ResourceInstancesRelations = resourceInstancesRelations; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getCreatorUserId() { + return creatorUserId; + } + + public void setCreatorUserId(String creatorUserId) { + this.creatorUserId = creatorUserId; + } + + public String getCreatorFullName() { + return creatorFullName; + } + + public void setCreatorFullName(String creatorFullName) { + this.creatorFullName = creatorFullName; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public String getCreationDate() { + return creationDate; + } + + public void setCreationDate(String creationDate) { + this.creationDate = creationDate; + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ArrayList getTags() { + return tags; + } + + public void setTags(ArrayList tags) { + this.tags = tags; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getLastUpdateDate() { + return lastUpdateDate; + } + + public void setLastUpdateDate(String lastUpdateDate) { + this.lastUpdateDate = lastUpdateDate; + } + + public String getContactId() { + return contactId; + } + + public void setContactId(String contactId) { + this.contactId = contactId; + } + + public String getVendorName() { + return vendorName; + } + + public void setVendorName(String vendorName) { + this.vendorName = vendorName; + } + + public String getVendorRelease() { + return vendorRelease; + } + + public void setVendorRelease(String vendorRelease) { + this.vendorRelease = vendorRelease; + } + + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public String getHighestVersion() { + return highestVersion; + } + + public void setHighestVersion(String highest) { + this.highestVersion = highest; + } + + public ArrayList getArtifacts() { + return artifacts; + } + + public void setArtifacts(ArrayList artifacts) { + this.artifacts = artifacts; + } + + public ArrayList getResourceInstances() { + return ResourceInstances; + } + + public void setResourceInstances(ArrayList resourceInstances) { + ResourceInstances = resourceInstances; + } + + public ArrayList getResourceInstancesRelations() { + return ResourceInstancesRelations; + } + + public void setResourceInstancesRelations(ArrayList resourceInstancesRelations) { + ResourceInstancesRelations = resourceInstancesRelations; + } + + @Override + public String toString() { + return "ServiceRespJavaObject [category=" + category + ", creatorUserId=" + creatorUserId + ", creatorFullName=" + + creatorFullName + ", lastUpdaterUserId=" + lastUpdaterUserId + ", lastUpdaterFullName=" + + lastUpdaterFullName + ", serviceName=" + serviceName + ", version=" + version + ", creationDate=" + + creationDate + ", icon=" + icon + ", name=" + name + ", description=" + description + ", tags=" + tags + + ", uniqueId=" + uniqueId + ", lastUpdateDate=" + lastUpdateDate + ", contactId=" + contactId + + ", vendorName=" + vendorName + ", vendorRelease=" + vendorRelease + ", lifecycleState=" + + lifecycleState + ", lifecycleState=" + lifecycleState + ", artifacts=" + artifacts + + ", ResourceInstances=" + ResourceInstances + ", ResourceInstancesRelations=" + + ResourceInstancesRelations + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/TypeHeatMetaDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/TypeHeatMetaDefinition.java new file mode 100644 index 0000000000..d0f029242f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/TypeHeatMetaDefinition.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes; + +import java.util.List; + +public class TypeHeatMetaDefinition { + + String typeName; + + List groupHeatMetaDefinition; + + public TypeHeatMetaDefinition() { + super(); + } + + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public List getGroupHeatMetaDefinition() { + return groupHeatMetaDefinition; + } + + public void setGroupHeatMetaDefinition(List groupHeatMetaDefinition) { + this.groupHeatMetaDefinition = groupHeatMetaDefinition; + } + + @Override + public String toString() { + return "TypeHeatMetaDefinition [typeName=" + typeName + ", groupHeatMetaDefinition=" + groupHeatMetaDefinition + + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ArtifactTypeEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ArtifactTypeEnum.java new file mode 100644 index 0000000000..1e6b06a6c8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ArtifactTypeEnum.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +import java.util.ArrayList; +import java.util.List; + +/** + * Enum That Represents possible Artifacts Types. + * + */ +public enum ArtifactTypeEnum { + CHEF("CHEF"), PUPPET("PUPPET"), YANG("YANG"), SHELL_SCRIPT("SHELL_SCRIPT"), ICON("ICON"), UNKNOWN("UNKNOWN"), HEAT("HEAT"), DG_XML("DG_XML"), MURANO_PKG("MURANO_PKG"), + HEAT_ENV("HEAT_ENV"), YANG_XML("YANG_XML"), HEAT_VOL("HEAT_VOL"), HEAT_NET("HEAT_NET"), OTHER("OTHER"), WORKFLOW("WORKFLOW"), NETWORK_CALL_FLOW("NETWORK_CALL_FLOW"), + TOSCA_TEMPLATE("TOSCA_TEMPLATE"), TOSCA_CSAR("TOSCA_CSAR"), VNF_CATALOG("VNF_CATALOG"), VF_LICENSE("VF_LICENSE"), VENDOR_LICENSE("VENDOR_LICENSE"), + MODEL_INVENTORY_PROFILE("MODEL_INVENTORY_PROFILE"), MODEL_QUERY_SPEC("MODEL_QUERY_SPEC"), APPC_CONFIG("APPC_CONFIG"), HEAT_NESTED("HEAT_NESTED"), + HEAT_ARTIFACT("HEAT_ARTIFACT"), VF_MODULES_METADATA("VF_MODULES_METADATA"), + // DCAE Artifacts + DCAE_TOSCA("DCAE_TOSCA"), DCAE_JSON("DCAE_JSON"), DCAE_POLICY("DCAE_POLICY"), DCAE_DOC("DCAE_DOC"), DCAE_EVENT("DCAE_EVENT"), DCAE_INVENTORY_TOSCA("DCAE_INVENTORY_TOSCA"), + DCAE_INVENTORY_JSON("DCAE_INVENTORY_JSON"), DCAE_INVENTORY_POLICY("DCAE_INVENTORY_POLICY"), DCAE_INVENTORY_DOC("DCAE_INVENTORY_DOC"), + DCAE_INVENTORY_BLUEPRINT("DCAE_INVENTORY_BLUEPRINT"), DCAE_INVENTORY_EVENT("DCAE_INVENTORY_EVENT"), + // AAI Artifacts + AAI_SERVICE_MODEL("AAI_SERVICE_MODEL"), AAI_VF_MODEL("AAI_VF_MODEL"), AAI_VF_MODULE_MODEL("AAI_VF_MODULE_MODEL"), AAI_VF_INSTANCE_MODEL("AAI_VF_INSTANCE_MODEL") + ; + + ArtifactTypeEnum(String type) { + this.type = type; + } + + private String type; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public static ArtifactTypeEnum findType(final String type) { + for (ArtifactTypeEnum ate : ArtifactTypeEnum.values()) { + // According to Pavel/Ella + if (ate.getType().equalsIgnoreCase(type)) { + return ate; + } + } + return null; + } + + public static List getAllTypes() { + List types = new ArrayList(); + for (ArtifactTypeEnum ate : ArtifactTypeEnum.values()) { + types.add(ate.getType()); + } + return types; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AssocType.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AssocType.java new file mode 100644 index 0000000000..b0da1f987d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AssocType.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum AssocType { + + BINDABLE("tosca.capabilities.network.Bindable"), + HOSTEDON("tosca.relationships.HostedOn"), + LINKABLE("tosca.capabilities.network.Linkable"), + CONTAINER("tosca.capabilities.Container"), + NODE("tosca.capabilities.Node"); + + private String assocType; + + private AssocType(String assocType) { + this.assocType = assocType; + + } + + public String getAssocType() { + return assocType; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditEnum.java new file mode 100644 index 0000000000..a73cff9373 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditEnum.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum AuditEnum { + + ACTION("ACTION"), + RESOURCE_NAME("RESOURCE_NAME"), + RESOURCE_TYPE("RESOURCE_TYPE"), + PREV_VERSION("PREV_VERSION"), + CURR_VERSION("CURR_VERSION"), + MODIFIER("MODIFIER"), + PREV_STATE("PREV_STATE"), + CURR_STATE("CURR_STATE"), + STATUS("STATUS-Type"), + DESC("DESC"), + URL("URL"), + USER("USER"), + AUTH_STATUS("AUTH_STATUS"), + REALM("REALM"); + + String value; + + private AuditEnum(String value) { + this.value = value; + } + + public String getValue() { + + return value.toLowerCase(); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditJsonKeysEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditJsonKeysEnum.java new file mode 100644 index 0000000000..c1b9fd4747 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/AuditJsonKeysEnum.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum AuditJsonKeysEnum { + + ACTION("ACTION"), RESOURCE_NAME("RESOURCE_NAME"), RESOURCE_TYPE("RESOURCE_TYPE"), PREV_VERSION("PREV_VERSION"), CURR_VERSION("CURR_VERSION"), PREV_STATE("PREV_STATE"), CURR_STATE("CURR_STATE"), + DPREV_STATUS("DPREV_STATUS"), DCURR_STATUS("DCURR_STATUS"), STATUS("STATUS"), DESCRIPTION("DESCRIPTION"), ARTIFACT_DATA("ARTIFACT_DATA"), CONSUMER_ID("CONSUMER_ID"), RESOURCE_URL("RESOURCE_URL"), + COMMENT("COMMENT"), DID("DID"), TOPIC_NAME("TOPIC_NAME"), TOSCA_NODE_TYPE("TOSCA_NODE_TYPE"), CURR_ARTIFACT_UUID("CURR_ARTIFACT_UUID"), PREV_ARTIFACT_UUID("PREV_ARTIFACT_UUID"), DETAILS("DETAILS"), + MODIFIER("MODIFIER"), SERVICE_INSTANCE_ID("SERVICE_INSTANCE_ID"); + + private String auditJsonKeyName; + + private AuditJsonKeysEnum(String auditJsonKeyName) { + this.auditJsonKeyName = auditJsonKeyName; + } + + public String getAuditJsonKeyName() { + return auditJsonKeyName.toLowerCase(); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ComponentType.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ComponentType.java new file mode 100644 index 0000000000..3d242e8c52 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ComponentType.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ComponentType { + + RESOURCE("Resource"), SERVICE("Service"), ARTIFACT("Artifact"); + + String value; + + private ComponentType(String value) { + this.value = value; + } + + public String getValue() { + + return value; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ErrorInfo.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ErrorInfo.java new file mode 100644 index 0000000000..c2a28a1edf --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ErrorInfo.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public class ErrorInfo { + + private Integer code; + private String message; + private String messageId; + + public ErrorInfo() { + super(); + // TODO Auto-generated constructor stub + } + + public ErrorInfo(Integer code, String message, String messageId) { + super(); + this.code = code; + this.message = message; + this.messageId = messageId; + } + + public ErrorInfo(Integer code, String message) { + super(); + this.code = code; + this.message = message; + } + + public Integer getCode() { + return code; + } + + public void setCode(Integer code) { + this.code = code; + } + + public String getMessage() { + return message; + } + + public String getMessageAndReplaceVariables(Object... variables) { + String formatReadyString = message.replaceAll("%[\\d]+", "%s"); + formatReadyString = String.format(formatReadyString, variables); + return formatReadyString; + } + + public String getAuditDesc(Object... variables) { + String messageAndReplaceVariables = getMessageAndReplaceVariables(variables); + String res; + if (messageId != null) { + res = messageId + ": " + messageAndReplaceVariables; + } else { + res = messageAndReplaceVariables; + } + return res; + } + + public void setMessage(String message) { + this.message = message; + } + + public String getMessageId() { + return messageId; + } + + public void setMessageId(String messageId) { + this.messageId = messageId; + } + + @Override + public String toString() { + return "ErrorInfo [code=" + code + ", message=" + message + ", messageId=" + messageId + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/EsIndexTypeIdToDelete.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/EsIndexTypeIdToDelete.java new file mode 100644 index 0000000000..6bfbd8af7d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/EsIndexTypeIdToDelete.java @@ -0,0 +1,64 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public class EsIndexTypeIdToDelete { + + String index; + String type; + String id; + + public EsIndexTypeIdToDelete() { + super(); + } + + public EsIndexTypeIdToDelete(String index, String type, String id) { + super(); + this.index = index; + this.type = type; + this.id = id; + } + + public String getIndex() { + return index; + } + + public void setIndex(String index) { + this.index = index; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ExceptionEnumType.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ExceptionEnumType.java new file mode 100644 index 0000000000..59d1dec453 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ExceptionEnumType.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ExceptionEnumType { + + SERVICE_EXCEPTION("serviceException"), POLICY_EXCPTION("policyException"); + + String value; + + private ExceptionEnumType(String value) { + this.value = value; + } + + public String getValue() { + return value; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ImportTestTypesEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ImportTestTypesEnum.java new file mode 100644 index 0000000000..21901e4635 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ImportTestTypesEnum.java @@ -0,0 +1,95 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +import java.util.Arrays; +import java.util.List; + +import org.openecomp.sdc.be.dao.api.ActionStatus; + +public enum ImportTestTypesEnum { + + MISSING_CONTACT("tosca.nodes.missing_contact", "missing_contact", ActionStatus.COMPONENT_MISSING_CONTACT, Arrays.asList("Resource"), true), + MISSING_RESOURCE_NAME("tosca.nodes.missing_resource_name", "missing_resource_name", ActionStatus.MISSING_COMPONENT_NAME, Arrays.asList("Resource"), true), + MISSING_DESC("tosca.nodes.missing_desc", "missing_desc", ActionStatus.COMPONENT_MISSING_DESCRIPTION, Arrays.asList("Resource"), true), + MISSING_ICON("tosca.nodes.missing_icon", "missing_icon", ActionStatus.COMPONENT_MISSING_ICON, Arrays.asList("Resource"), true), + MISSING_TAGS("tosca.nodes.missing_tags", "missing_tags", ActionStatus.COMPONENT_MISSING_TAGS, null, true), + MISSING_CATEGORY("tosca.nodes.missing_category", "missing_category", ActionStatus.COMPONENT_MISSING_CATEGORY, Arrays.asList("Resource"), true), + // MISSING_PAYLOADNAME("tosca.nodes.missing_payloadName", + // "missing_payloadName", ActionStatus.INVALID_TOSCA_FILE_EXTENSION, null, + // true), + + EMPTY_RESOURCE_NAME("tosca.nodes.empty_resource_name", "missing_resource_name"/* "empty_resource_name" */, ActionStatus.MISSING_COMPONENT_NAME, Arrays.asList("Resource"), false), + EMPTY_CONTACT("tosca.nodes.empty_contact", "missing_contact"/* "empty_contact" */, ActionStatus.COMPONENT_MISSING_CONTACT, Arrays.asList("Resource"), false), + EMPTY_CATEGORY("tosca.nodes.empty_category", "missing_category"/* "empty_category" */, ActionStatus.COMPONENT_MISSING_CATEGORY, Arrays.asList("Resource"), false), + EMPTY_DESC("tosca.nodes.empty_desc", "missing_desc"/* "empty_desc" */, ActionStatus.COMPONENT_MISSING_DESCRIPTION, Arrays.asList("Resource"), false), + EMPTY_ICON("tosca.nodes.empty_icon", "missing_icon"/* "empty_icon" */, ActionStatus.COMPONENT_MISSING_ICON, Arrays.asList("Resource"), false), + EMPTY_PAYLOADNAME("tosca.nodes.empty_payloadName", "missing_payloadName"/* "empty_payloadName" */, ActionStatus.INVALID_TOSCA_FILE_EXTENSION, null, false), + EMPTY_TAG("tosca.nodes.empty_tag", "empty_tag", ActionStatus.INVALID_FIELD_FORMAT, Arrays.asList("Resource", "tag"), false), + VALIDATE_PROPORTIES_1("tosca.nodes.validateProporties_typeBoolean_valueInit", "validateProporties_typeBoolean_valueInit", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "boolean", "123456"), false), + VALIDATE_PROPORTIES_2("tosca.nodes.validateProporties_typeBoolean_valueString", "validateProporties_typeBoolean_valueString", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "boolean", "abcd"), false), + VALIDATE_PROPORTIES_3("tosca.nodes.validateProporties_typeFloat_valueBoolean", "validateProporties_typeFloat_valueBoolean", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "float", "true"), false), + VALIDATE_PROPORTIES_4("tosca.nodes.validateProporties_typeFloat_valueString", "validateProporties_typeFloat_valueString", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "float", "abcd"), false), + VALIDATE_PROPORTIES_5("tosca.nodes.validateProporties_typeInit_valueBoolean", "validateProporties_typeInit_valueBoolean", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "integer", "true"), false), + VALIDATE_PROPORTIES_6("tosca.nodes.validateProporties_typeInit_valueFloat", "validateProporties_typeInit_valueFloat", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "integer", "0.123"), false), + VALIDATE_PROPORTIES_7("tosca.nodes.validateProporties_typeInit_valueString", "validateProporties_typeInit_valueString", ActionStatus.INVALID_DEFAULT_VALUE, Arrays.asList("validation_test", "integer", "abcd"), false); + // VALIDATE_PROPORTIES_8("tosca.nodes.validateProporties_happyScenarios","validateProporties_happyScenarios", ActionStatus.OK, null, false); + + private String normativeName; + private String folderName; + private ActionStatus actionStatus; + private Boolean validateAudit; + private List errorParams; + private Boolean validateYaml; + + // private enum ActionStatus; + + private ImportTestTypesEnum(String resourceName, String folderName, ActionStatus actionStatus, + List errorParams, Boolean validateAudit) { + this.normativeName = resourceName; + this.folderName = folderName; + this.actionStatus = actionStatus; + this.errorParams = errorParams; + this.validateAudit = validateAudit; + + } + + public String getNormativeName() { + return normativeName; + } + + public String getFolderName() { + return folderName; + } + + public ActionStatus getActionStatus() { + return actionStatus; + } + + public Boolean getvalidateAudit() { + return validateAudit; + } + + public List getErrorParams() { + return errorParams; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/LifeCycleStatesEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/LifeCycleStatesEnum.java new file mode 100644 index 0000000000..7c330a3d10 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/LifeCycleStatesEnum.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum LifeCycleStatesEnum { + + CHECKOUT("checkout", "NOT_CERTIFIED_CHECKOUT"), + CHECKIN("checkin", "NOT_CERTIFIED_CHECKIN"), + CERTIFICATIONREQUEST("certificationRequest", "READY_FOR_CERTIFICATION"), + UNDOCHECKOUT("undoCheckout", ""), + CANCELCERTIFICATION("cancelCertification", ""), + STARTCERTIFICATION("startCertification", "CERTIFICATION_IN_PROGRESS"), + FAILCERTIFICATION("failCertification", ""), + CERTIFY("certify", "CERTIFIED"); + + private String state; + private String componentState; + + private LifeCycleStatesEnum(String state, String componentState) { + this.state = state; + this.componentState = componentState; + + } + + public String getState() { + return state; + } + + public String getComponentState() { + return componentState; + } + + public static LifeCycleStatesEnum findByCompState(String compState) { + + for (LifeCycleStatesEnum lifeCycleStatesEnum : LifeCycleStatesEnum.values()) { + if (lifeCycleStatesEnum.getComponentState().equals(compState)) { + return lifeCycleStatesEnum; + } + } + + return null; + + } + + public static LifeCycleStatesEnum findByState(String state) { + + for (LifeCycleStatesEnum lifeCycleStatesEnum : LifeCycleStatesEnum.values()) { + if (lifeCycleStatesEnum.name().equals(state)) { + return lifeCycleStatesEnum; + } + } + + return null; + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryResourceArtifactTypeEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryResourceArtifactTypeEnum.java new file mode 100644 index 0000000000..7769d19802 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryResourceArtifactTypeEnum.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; + +public enum MandatoryResourceArtifactTypeEnum { + + TEST_SCRIPTS(null, "testscripts"), + FEATURES(null, "features"), + CAPACITY(null, "capacity"), + VENDOR_TEST_RESULT(null,"vendortestresult"), + CLOUD_QUESTIONNAIRE(null, "cloudquestionnaire"); + + String artifactName; + String logicalName; + + private MandatoryResourceArtifactTypeEnum(String artifactName, String logicalName) { + this.artifactName = artifactName; + this.logicalName = logicalName; + } + + public String getArtifactName() { + return artifactName; + } + + public String getLogicalName() { + return logicalName; + } + + public ArtifactGroupTypeEnum getGroupType() { + return ArtifactGroupTypeEnum.INFORMATIONAL; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryServiceArtifactTypeEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryServiceArtifactTypeEnum.java new file mode 100644 index 0000000000..b73d5a8fee --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/MandatoryServiceArtifactTypeEnum.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum MandatoryServiceArtifactTypeEnum { + + MESSAGE_FLOWS(null, "messageflows".toLowerCase(), "Message Flows"), + INSTANT_FLOWS(null, "instantiationflows".toLowerCase(), "Management Flows"), + SERVICE_ART_PLAN(null, "serviceartifactplan".toLowerCase(), "Service Artifact Plan"), + SUM_OF_ELEMENTS(null, "summaryofimpactstoecompelements".toLowerCase(), "Summary of impacts to ECOMP elements,OSSs, BSSs"), + CONTROL_LOOP_FUN(null, "controlloopfunctions".toLowerCase(), "Control Loop Functions"), + DIMENSIONNING_INFO(null, "dimensioninginfo".toLowerCase(), "Dimensioning Info"), + AFFINITY_RULES(null, "affinityrules".toLowerCase(), "Affinity Rules"), + OPERATIONAL_POLICIES(null, "operationalpolicies".toLowerCase(), "Operational Policies"), + SERVICE_SPECIFIC_POLICIES(null, "servicespecificpolicies".toLowerCase(), "Service-specific Policies"), + ENGINEERING_RULES(null, "engineeringrules".toLowerCase(), "Engineering Rules (ERD)"), + DISTRIB_INSTRUCTIONS(null, "distributioninstructions".toLowerCase(), "Distribution Instructions"), + DEPLOYMENT_VOTING_REC(null, "deploymentvotingrecord".toLowerCase(), "Deployment Voting Record"), + CERTIFICATION_TEST_RESULT(null, "certificationtestresults".toLowerCase(), "TD Certification Test Results"); + // SERVICE_QUESTIONNAIRE(null, "serviceQuestionnaire".toLowerCase()); + + String artifactName; + String logicalName; + String artifactDisplayName; + + private MandatoryServiceArtifactTypeEnum(String artifactName, String logicalName, String artifactDisplayName) { + this.artifactName = artifactName; + this.logicalName = logicalName; + this.artifactDisplayName = artifactDisplayName; + } + + public String getArtifactName() { + return artifactName; + } + + public String getLogicalName() { + return logicalName; + } + + public String getArtifactDisplayName() { + return artifactDisplayName; + } + + public void setArtifactDisplayName(String artifactDisplayName) { + this.artifactDisplayName = artifactDisplayName; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/NormativeTypesEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/NormativeTypesEnum.java new file mode 100644 index 0000000000..f1cfcf0c98 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/NormativeTypesEnum.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum NormativeTypesEnum { + ROOT("tosca.nodes.Root", "root"), + COMPUTE("tosca.nodes.Compute", "compute"), + BLOCK_STORAGE("tosca.nodes.BlockStorage", "blockStorage"), + CONTAINER_APPLICATION("tosca.nodes.Container.Application", "containerApplication"), + CONTAINER_RUNTIME("tosca.nodes.Container.Runtime", "containerRuntime"), + DATABASE("tosca.nodes.Database", "database"), + DBMS("tosca.nodes.DBMS", "DBMS"), + LOAD_BALANCER("tosca.nodes.LoadBalancer", "loadBalancer"), + OBJECT_STORAGE("tosca.nodes.ObjectStorage", "objectStorage"), + NETWORK("tosca.nodes.network.Network", "network"), + PORT("tosca.nodes.network.Port", "port"), + SOFTWARE_COMPONENT("tosca.nodes.SoftwareComponent", "softwareComponent"), + WEB_APPLICATION("tosca.nodes.webapplication", "webApplication"), + WEB_SERVER("tosca.nodes.WebServer", "webServer"); + + public String normativeName; + private String folderName; + + private NormativeTypesEnum(String resourceName, String folderName) { + this.normativeName = resourceName; + this.folderName = folderName; + } + + public String getNormativeName() { + return normativeName; + } + + public String getFolderName() { + return folderName; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/PropertyTypeEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/PropertyTypeEnum.java new file mode 100644 index 0000000000..5dac326c70 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/PropertyTypeEnum.java @@ -0,0 +1,105 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; + +public enum PropertyTypeEnum { + INTEGER("defaultIntegerPropName1", "integer", "125", "default integer type property description", null), + STRING("defaultStringPropName1", "string", "string", "default string type property description", null), + BOOLEAN("defaultBooleanPropName1", "boolean", "true", "default boolean type property description", null), + STRING_LIST("defaultStringListPropName", "list", "[a,b]", "outer description", getDefaultStringSchema(ToscaPropertyType.STRING.getType())), + INTEGER_LIST("defaultIntegerListPropName", "list", "[1,2]", "outer description", getDefaultStringSchema(ToscaPropertyType.INTEGER.getType())), + BOOLEAN_LIST("defaultBooleanListPropName", "list", "[true,false]", "outer description", getDefaultStringSchema(ToscaPropertyType.BOOLEAN.getType())), + FLOAT_LIST("defaultFloatMapPropName", "list", "[1.0,2.0]", "outer description", getDefaultStringSchema(ToscaPropertyType.FLOAT.getType())), + STRING_MAP("defaultStringMapPropName", "map", "{\"key1\":val1 , \"key2\":val2}", "outer description", getDefaultStringSchema(ToscaPropertyType.STRING.getType())), + INTEGER_MAP("defaultIntegerMapPropName", "map", "{\"key1\":123 , \"key2\":-456}", "outer description", getDefaultStringSchema(ToscaPropertyType.INTEGER.getType())), + BOOLEAN_MAP("defaultBooleanMapPropName", "map", "{\"key1\":true , \"key2\":false}", "outer description", getDefaultStringSchema(ToscaPropertyType.BOOLEAN.getType())), + FLOAT_MAP("defaultFloatMapPropName", "map", "{\"key1\":0.2123 , \"key2\":43.545f}", "outer description", getDefaultStringSchema(ToscaPropertyType.FLOAT.getType())); + + private String name; + private String type; + private String value; + private String description; + private SchemaDefinition schemaDefinition; + + private PropertyTypeEnum(String name, String type, String value, String description, + SchemaDefinition schemaDefinition) { + this.name = name; + this.type = type; + this.value = value; + this.description = description; + this.schemaDefinition = schemaDefinition; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public SchemaDefinition getSchemaDefinition() { + return schemaDefinition; + } + + public void setSchemaDefinition(SchemaDefinition schemaDefinition) { + this.schemaDefinition = schemaDefinition; + } + + private static SchemaDefinition getDefaultStringSchema(String innerType) { + SchemaDefinition schema = new SchemaDefinition(); + String description = "inner description"; + PropertyDefinition property = new PropertyDefinition(); + property.setType(innerType); + property.setDescription(description); + schema.setProperty(property); + return schema; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ResourceCategoryEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ResourceCategoryEnum.java new file mode 100644 index 0000000000..3ece77b8ec --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ResourceCategoryEnum.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ResourceCategoryEnum { + + NETWORK_L2_3_ROUTERS("Network L2-3", "Router"), NETWORK_L2_3_GETEWAY("Network L2-3","Gateway"), NETWORK_L2_3_WAN_CONNECTORS("Network L2-3", "WAN Connectors"), NETWORK_L2_3_LAN_CONNECTORS("Network L2-3", "LAN Connectors"), + NETWORK_L2_3_INFRASTRUCTURE("Network L2-3", "Infrastructure"), NETWORK_L4("Network L4+", "Common Network Resources"), APPLICATION_L4_BORDER("Application L4+", "Border Element"), + APPLICATION_L4_APP_SERVER("Application L4+", "Application Server"), APPLICATION_L4_WEB_SERVERS("Application L4+", "Web Server"), APPLICATION_L4_CALL_CONTROL("Application L4+","Call Control"), + APPLICATION_L4_MEDIA_SERVER("Application L4+", "Media Servers"), APPLICATION_L4_LOAD_BALANCER("Application L4+", "Load Balancer"), APPLICATION_L4_DATABASE("Application L4+","Database"), + APPLICATION_L4_FIREWALL("Application L4+", "Firewall"), GENERIC_INFRASTRUCTURE("Generic", "Infrastructure"), GENERIC_ABSTRACT("Generic", "Abstract"), GENERIC_NETWORK_ELEMENTS("Generic","Network Elements"), + GENERIC_DATABASE("Generic", "Database"), NETWORK_CONNECTIVITY_CON_POINT("Network Connectivity", "Connection Points"), NETWORK_CONNECTIVITY_VIRTUAL_LINK("Network Connectivity","Virtual Links"); + + private String category; + private String subCategory; + + ResourceCategoryEnum(String category, String subCategory) { + this.category = category; + this.subCategory = subCategory; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSubCategory() { + return subCategory; + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/RespJsonKeysEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/RespJsonKeysEnum.java new file mode 100644 index 0000000000..4350cba105 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/RespJsonKeysEnum.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum RespJsonKeysEnum { + + IS_ABSTRACT("abstract"), + UNIQUE_ID("uniqueId"), + RESOURCE_NAME("name"), + RESOURCE_VERSION("version"), + TAGS("tags"), + LIFE_CYCLE_STATE("lifecycleState"), + DERIVED_FROM("derivedFrom"), + RESOURCE_DESC("description"), + VENDOR_NAME("vendorName"), + VENDOR_RELEASE("vendorRelease"), + CONTACT_ID("contactId"), + ICON("icon"), + HIGHEST_VERSION("highestVersion"), + CREATOR_USER_ID("creatorUserId"), + CREATOR_FULL_NAME("creatorFullName"), + LAST_UPDATER_ATT_UID("lastUpdaterUserId"), + LAST_UPDATER_FULL_NAME("lastUpdaterFullName"), + ARTIFACTS("artifacts"), + DESCRIPTION("description"), + UUID("uuid"), + COST("cost"), + LICENSE_TYPE("licenseType"), + RESOURCE_TYPE("resourceType"), + CATEGORIES("categories"); + + private String respJsonKeyName; + + private RespJsonKeysEnum(String respJsonKeyName) { + this.respJsonKeyName = respJsonKeyName; + } + + public String getRespJsonKeyName() { + return respJsonKeyName; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceApiArtifactEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceApiArtifactEnum.java new file mode 100644 index 0000000000..675e1d7502 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceApiArtifactEnum.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ServiceApiArtifactEnum { + CONFIGURATION("Configuration".toLowerCase()), + INSTANTIATION("Instantiation".toLowerCase()), + MONITORING("Monitoring".toLowerCase()), + REPORTING("Reporting".toLowerCase()), + LOGGING("Logging".toLowerCase()), + TESTING("Testing".toLowerCase()); + + String logicalName; + + private ServiceApiArtifactEnum(String logicalName) { + this.logicalName = logicalName; + } + + public String getLogicalName() { + return logicalName; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceCategoriesEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceCategoriesEnum.java new file mode 100644 index 0000000000..61d4e487e2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ServiceCategoriesEnum.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ServiceCategoriesEnum { + + VOIP("VoIP Call Control"), MOBILITY("Mobility"), NETWORK_L4("Network L4+"), NETWORK_L3("Network L1-3"); + String value; + + private ServiceCategoriesEnum(String value) { + this.value = value; + } + + public String getValue() { + + return value; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ToscaKeysEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ToscaKeysEnum.java new file mode 100644 index 0000000000..f8479e912c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/ToscaKeysEnum.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum ToscaKeysEnum { + + TOSCA_DEFINITION_VERSION("tosca_definitions_version"), + METADATA("metadata"), IMPORTS("imports"), + NODE_TYPES("node_types"), + TOPOLOGY_TEMPLATE("topology_template"); + + private String toscaKey; + + public String getToscaKey() { + return toscaKey; + } + + private ToscaKeysEnum(String toscaKey) { + this.toscaKey = toscaKey; + } + + public static ToscaKeysEnum findToscaKey(final String toscaKey) { + for (ToscaKeysEnum toscaKeyEnum : ToscaKeysEnum.values()) { + if (toscaKeyEnum.getToscaKey().equalsIgnoreCase(toscaKey)) { + return toscaKeyEnum; + } + } + return null; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/UserRoleEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/UserRoleEnum.java new file mode 100644 index 0000000000..399779fefe --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/enums/UserRoleEnum.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.enums; + +public enum UserRoleEnum { + + ADMIN("jh0003","Jimmy", "Hendrix"), DESIGNER("cs0008","Carlos", "Santana"), DESIGNER2("me0009","Melissa", "Etheridge"), TESTER("jm0007","Joni", "Mitchell"),ADMIN4("km2000","Kot", "May"), GOVERNOR("gv0001","David", "Shadmi"), + OPS("op0001","Steve", "Regev"),PRODUCT_STRATEGIST1("ps0001","Eden", "Rozin"),PRODUCT_STRATEGIST2("ps0002","Ella", "Kvetny"),PRODUCT_STRATEGIST3("ps0003","Geva", "Alon"), PRODUCT_MANAGER1("pm0001","Teddy", "Isashar"), + PRODUCT_MANAGER2("pm0002","Sarah", "Bettens"); + + private String userId; + private String firstName; + private String lastName; + private String userName; + private UserRoleEnum(String userId, String userName) { + this.userId = userId; + this.userName = userName; + } + + private UserRoleEnum(String userId, String firstName, String lastName) { + this.userId = userId; + this.firstName =firstName; + this.lastName = lastName; + this.userName = firstName+" " + lastName; + } + public String getUserId() { + return userId; + } + public void setUserId(String userId) { + this.userId = userId; + } + public String getUserName() { + return userName; + } + public void setUserName(String userName) { + this.userName = userName; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + +} + + diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedArtifactAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedArtifactAudit.java new file mode 100644 index 0000000000..344f353348 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedArtifactAudit.java @@ -0,0 +1,166 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedArtifactAudit { + + private String action; + private String resourceName; + private String resourceType; + private String prevVersion; + private String currVersion; + private String modifier; + private String prevState; + private String currState; + private String prevArtifactUuid; + private String currArtifactUuid; + private String artifactData; + private String status; + private String desc; + + public ExpectedArtifactAudit(String action, String resourceName, String resourceType, String prevVersion, + String currVersion, String modifier, String prevState, String currState, String prevArtifactUuid, + String currArtifactUuid, String artifactData, String status, String desc) { + super(); + this.action = action; + this.resourceName = resourceName; + this.resourceType = resourceType; + this.prevVersion = prevVersion; + this.currVersion = currVersion; + this.modifier = modifier; + this.prevState = prevState; + this.currState = currState; + this.prevArtifactUuid = prevArtifactUuid; + this.currArtifactUuid = currArtifactUuid; + this.artifactData = artifactData; + this.status = status; + this.desc = desc; + } + + public ExpectedArtifactAudit() { + super(); + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getPrevVersion() { + return prevVersion; + } + + public void setPrevVersion(String prevVersion) { + this.prevVersion = prevVersion; + } + + public String getCurrVersion() { + return currVersion; + } + + public void setCurrVersion(String currVersion) { + this.currVersion = currVersion; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getPrevState() { + return prevState; + } + + public void setPrevState(String prevState) { + this.prevState = prevState; + } + + public String getCurrState() { + return currState; + } + + public void setCurrState(String currState) { + this.currState = currState; + } + + public String getPrevArtifactUuid() { + return prevArtifactUuid; + } + + public void setPrevArtifactUuid(String prevArtifactUuid) { + this.prevArtifactUuid = prevArtifactUuid; + } + + public String getCurrArtifactUuid() { + return currArtifactUuid; + } + + public void setCurrArtifactUuid(String currArtifactUuid) { + this.currArtifactUuid = currArtifactUuid; + } + + public String getArtifactData() { + return artifactData; + } + + public void setArtifactData(String artifactData) { + this.artifactData = artifactData; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedAuthenticationAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedAuthenticationAudit.java new file mode 100644 index 0000000000..0d6a5f3b3c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedAuthenticationAudit.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedAuthenticationAudit { + + private String url; + private String realm; + private String user; + private String action; + private String authStatus; + + public ExpectedAuthenticationAudit(String url, String user, String action, String authStatus) { + super(); + this.url = url; + this.user = user; + this.action = action; + this.authStatus = authStatus; + this.realm = "ASDC"; + } + + public ExpectedAuthenticationAudit() { + + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getRealm() { + return realm; + } + + public void setRealm(String realm) { + this.realm = realm; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getAuthStatus() { + return authStatus; + } + + public void setAuthStatus(String authStatus) { + this.authStatus = authStatus; + } + + @Override + public String toString() { + return "ExpectedAuthenticationAudit [url=" + url + ", realm=" + realm + ", user=" + user + ", action=" + action + + ", authStatus=" + authStatus + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedCategoryAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedCategoryAudit.java new file mode 100644 index 0000000000..b11f7f585a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedCategoryAudit.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedCategoryAudit { + String action; + String modifier; + String modifierUid; + String modifierName; + String categoryName; + String subCategoryName; + String groupingName; + String resourceType; + String status; + String desc; + String details; + + public ExpectedCategoryAudit(String action, String modifier, String categoryName, String subCategoryName, + String groupingName, String resourceType, String status, String desc) { + super(); + this.action = action; + this.modifier = modifier; + this.categoryName = categoryName; + this.subCategoryName = subCategoryName; + this.groupingName = groupingName; + this.resourceType = resourceType; + this.status = status; + this.desc = desc; + } + + public ExpectedCategoryAudit() { + action = null; + modifier = null; + categoryName = null; + subCategoryName = null; + groupingName = null; + resourceType = null; + status = null; + desc = null; + details = null; + modifierName = null; + modifierUid = null; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + public String getSubCategoryName() { + return subCategoryName; + } + + public void setSubCategoryName(String subCategoryName) { + this.subCategoryName = subCategoryName; + } + + public String getGroupingName() { + return groupingName; + } + + public void setGroupingName(String groupingName) { + this.groupingName = groupingName; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + + public String getModifierUid() { + return modifierUid; + } + + public void setModifierUid(String modifierUid) { + this.modifierUid = modifierUid; + } + + public String getModifierName() { + return modifierName; + } + + public void setModifierName(String modifierName) { + this.modifierName = modifierName; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedDistDownloadAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedDistDownloadAudit.java new file mode 100644 index 0000000000..4b135f66f6 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedDistDownloadAudit.java @@ -0,0 +1,79 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedDistDownloadAudit { + + String action; + String consumerId; + String resourceUrl; + String status; + String desc; + + public ExpectedDistDownloadAudit(String action, String consumerId, String resourceUrl, String status, String desc) { + super(); + this.action = action; + this.consumerId = consumerId; + this.resourceUrl = resourceUrl; + this.status = status; + this.desc = desc; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getConsumerId() { + return consumerId; + } + + public void setConsumerId(String consumerId) { + this.consumerId = consumerId; + } + + public String getResourceUrl() { + return resourceUrl; + } + + public void setResourceUrl(String resourceUrl) { + this.resourceUrl = resourceUrl; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedEcomConsumerAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedEcomConsumerAudit.java new file mode 100644 index 0000000000..1414742423 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedEcomConsumerAudit.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedEcomConsumerAudit { + + String action; + String modifier; + String ecomUser; + String status; + String desc; + + public ExpectedEcomConsumerAudit(String action, String modifier, String ecomUser, String status, String desc) { + super(); + this.action = action; + this.modifier = modifier; + this.ecomUser = ecomUser; + this.status = status; + this.desc = desc; + } + + public ExpectedEcomConsumerAudit() { + action = null; + modifier = null; + ecomUser = null; + status = null; + desc = null; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getEcomUser() { + return ecomUser; + } + + public void setEcomUser(String ecomUser) { + this.ecomUser = ecomUser; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedExternalAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedExternalAudit.java new file mode 100644 index 0000000000..e689a3921b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedExternalAudit.java @@ -0,0 +1,179 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedExternalAudit { + + String ACTION; + String CONSUMER_ID; + String RESOURCE_URL; + String STATUS; + String DESC; + String RESOURCE_NAME; + String RESOURCE_TYPE; + String SERVICE_INSTANCE_ID;// resource/ service UUID + String MODIFIER; + String PREV_ARTIFACT_UUID; + String CURR_ARTIFACT_UUID; + String ARTIFACT_DATA; + + public ExpectedExternalAudit() { + super(); + // TODO Auto-generated constructor stub + } + + public String getRESOURCE_NAME() { + return RESOURCE_NAME; + } + + public void setRESOURCE_NAME(String rESOURCE_NAME) { + RESOURCE_NAME = rESOURCE_NAME; + } + + public String getRESOURCE_TYPE() { + return RESOURCE_TYPE; + } + + public void setRESOURCE_TYPE(String rESOURCE_TYPE) { + RESOURCE_TYPE = rESOURCE_TYPE; + } + + public String getSERVICE_INSTANCE_ID() { + return SERVICE_INSTANCE_ID; + } + + public void setSERVICE_INSTANCE_ID(String sERVICE_INSTANCE_ID) { + SERVICE_INSTANCE_ID = sERVICE_INSTANCE_ID; + } + + public ExpectedExternalAudit(String aCTION, String cONSUMER_ID, String rESOURCE_URL, String sTATUS, String dESC, + String rESOURCE_NAME, String rESOURCE_TYPE, String sERVICE_INSTANCE_ID) { + super(); + ACTION = aCTION; + CONSUMER_ID = cONSUMER_ID; + RESOURCE_URL = rESOURCE_URL; + STATUS = sTATUS; + DESC = dESC; + RESOURCE_NAME = rESOURCE_NAME; + RESOURCE_TYPE = rESOURCE_TYPE; + SERVICE_INSTANCE_ID = sERVICE_INSTANCE_ID; + } + + public ExpectedExternalAudit(String aCTION, String cONSUMER_ID, String rESOURCE_URL, String sTATUS, String dESC) { + super(); + ACTION = aCTION; + CONSUMER_ID = cONSUMER_ID; + RESOURCE_URL = rESOURCE_URL; + STATUS = sTATUS; + DESC = dESC; + } + + public ExpectedExternalAudit(String aCTION, String cONSUMER_ID, String rESOURCE_URL, String sTATUS, String dESC, + String rESOURCE_NAME, String rESOURCE_TYPE, String sERVICE_INSTANCE_ID, String mODIFIER, + String pREV_ARTIFACT_UUID, String cURR_ARTIFACT_UUID, String aRTIFACT_DATA) { + super(); + ACTION = aCTION; + CONSUMER_ID = cONSUMER_ID; + RESOURCE_URL = rESOURCE_URL; + STATUS = sTATUS; + DESC = dESC; + RESOURCE_NAME = rESOURCE_NAME; + RESOURCE_TYPE = rESOURCE_TYPE; + SERVICE_INSTANCE_ID = sERVICE_INSTANCE_ID; + MODIFIER = mODIFIER; + PREV_ARTIFACT_UUID = pREV_ARTIFACT_UUID; + CURR_ARTIFACT_UUID = cURR_ARTIFACT_UUID; + ARTIFACT_DATA = aRTIFACT_DATA; + } + + public String getACTION() { + return ACTION; + } + + public void setACTION(String aCTION) { + ACTION = aCTION; + } + + public String getCONSUMER_ID() { + return CONSUMER_ID; + } + + public void setCONSUMER_ID(String cONSUMER_ID) { + CONSUMER_ID = cONSUMER_ID; + } + + public String getRESOURCE_URL() { + return RESOURCE_URL; + } + + public void setRESOURCE_URL(String rESOURCE_URL) { + RESOURCE_URL = rESOURCE_URL; + } + + public String getSTATUS() { + return STATUS; + } + + public void setSTATUS(String sTATUS) { + STATUS = sTATUS; + } + + public String getDESC() { + return DESC; + } + + public void setDESC(String dESC) { + DESC = dESC; + } + + public String getMODIFIER() { + return MODIFIER; + } + + public void setMODIFIER(String mODIFIER) { + MODIFIER = mODIFIER; + } + + public String getPREV_ARTIFACT_UUID() { + return PREV_ARTIFACT_UUID; + } + + public void setPREV_ARTIFACT_UUID(String pREV_ARTIFACT_UUID) { + PREV_ARTIFACT_UUID = pREV_ARTIFACT_UUID; + } + + public String getCURR_ARTIFACT_UUID() { + return CURR_ARTIFACT_UUID; + } + + public void setCURR_ARTIFACT_UUID(String cURR_ARTIFACT_UUID) { + CURR_ARTIFACT_UUID = cURR_ARTIFACT_UUID; + } + + public String getARTIFACT_DATA() { + return ARTIFACT_DATA; + } + + public void setARTIFACT_DATA(String aRTIFACT_DATA) { + ARTIFACT_DATA = aRTIFACT_DATA; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGetUserListAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGetUserListAudit.java new file mode 100644 index 0000000000..561b92a317 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGetUserListAudit.java @@ -0,0 +1,88 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedGetUserListAudit { + + String action; + String modifier; + String status; + String desc; + String details; + + public ExpectedGetUserListAudit(String action, String modifier, String status, String desc, String details) { + super(); + this.action = action; + this.modifier = modifier; + this.status = status; + this.desc = desc; + this.details = details; + } + + public ExpectedGetUserListAudit() { + action = null; + modifier = null; + details = null; + status = null; + desc = null; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getDetails() { + return details; + } + + public void setDetails(String details) { + this.details = details; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGroupingAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGroupingAudit.java new file mode 100644 index 0000000000..b481cb77af --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedGroupingAudit.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedGroupingAudit { + String action; + String modifier; + String categoryName; + String subCategoryName; + String groupingName; + String resourceType; + String status; + String desc; + + public ExpectedGroupingAudit(String action, String modifier, String categoryName, String subCategoryName, + String groupingName, String resourceType, String status, String desc) { + super(); + this.action = action; + this.modifier = modifier; + this.categoryName = categoryName; + this.subCategoryName = subCategoryName; + this.groupingName = groupingName; + this.resourceType = resourceType; + this.status = status; + this.desc = desc; + } + + public ExpectedGroupingAudit() { + action = null; + modifier = null; + categoryName = null; + subCategoryName = null; + groupingName = null; + resourceType = null; + status = null; + desc = null; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getCategoryName() { + return categoryName; + } + + public void setCategoryName(String categoryName) { + this.categoryName = categoryName; + } + + public String getSubCategoryName() { + return subCategoryName; + } + + public void setSubCategoryName(String subCategoryName) { + this.subCategoryName = subCategoryName; + } + + public String getGroupingName() { + return groupingName; + } + + public void setGroupingName(String groupingName) { + this.groupingName = groupingName; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedProductAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedProductAudit.java new file mode 100644 index 0000000000..40b86fa528 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedProductAudit.java @@ -0,0 +1,142 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedProductAudit { + + String ACTION; + String MODIFIER; + String STATUS; + String DESC; + String RESOURCE_NAME; + String RESOURCE_TYPE; + String PREV_VERSION; + String CURR_VERSION; + String PREV_STATE; + String CURR_STATE; + String TIMESTAMP; + String SERVICE_INSTANCE_ID; + String COMMENT; + + public String getCOMMENT() { + return COMMENT; + } + + public void setCOMMENT(String cOMMENT) { + COMMENT = cOMMENT; + } + + public String getSERVICE_INSTANCE_ID() { + return SERVICE_INSTANCE_ID; + } + + public void setSERVICE_INSTANCE_ID(String sERVICE_INSTANCE_ID) { + SERVICE_INSTANCE_ID = sERVICE_INSTANCE_ID; + } + + public String getACTION() { + return ACTION; + } + + public void setACTION(String aCTION) { + ACTION = aCTION; + } + + public String getMODIFIER() { + return MODIFIER; + } + + public void setMODIFIER(String mODIFIER) { + MODIFIER = mODIFIER; + } + + public String getSTATUS() { + return STATUS; + } + + public void setSTATUS(String sTATUS) { + STATUS = sTATUS; + } + + public String getDESC() { + return DESC; + } + + public void setDESC(String dESC) { + DESC = dESC; + } + + public String getRESOURCE_NAME() { + return RESOURCE_NAME; + } + + public void setRESOURCE_NAME(String rESOURCE_NAME) { + RESOURCE_NAME = rESOURCE_NAME; + } + + public String getRESOURCE_TYPE() { + return RESOURCE_TYPE; + } + + public void setRESOURCE_TYPE(String rESOURCE_TYPE) { + RESOURCE_TYPE = rESOURCE_TYPE; + } + + public String getPREV_VERSION() { + return PREV_VERSION; + } + + public void setPREV_VERSION(String pREV_VERSION) { + PREV_VERSION = pREV_VERSION; + } + + public String getCURR_VERSION() { + return CURR_VERSION; + } + + public void setCURR_VERSION(String cURR_VERSION) { + CURR_VERSION = cURR_VERSION; + } + + public String getPREV_STATE() { + return PREV_STATE; + } + + public void setPREV_STATE(String pREV_STATE) { + PREV_STATE = pREV_STATE; + } + + public String getCURR_STATE() { + return CURR_STATE; + } + + public void setCURR_STATE(String cURR_STATE) { + CURR_STATE = cURR_STATE; + } + + public String getTIMESTAMP() { + return TIMESTAMP; + } + + public void setTIMESTAMP(String tIMESTAMP) { + TIMESTAMP = tIMESTAMP; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedResourceAuditJavaObject.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedResourceAuditJavaObject.java new file mode 100644 index 0000000000..cc78709888 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedResourceAuditJavaObject.java @@ -0,0 +1,300 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedResourceAuditJavaObject { + + String ACTION; + String MODIFIER_NAME; + String MODIFIER_UID; + String STATUS; + String DESC; + String RESOURCE_NAME; + String RESOURCE_TYPE; + String PREV_VERSION; + String CURR_VERSION; + String PREV_STATE; + String CURR_STATE; + String TIMESTAMP; + String ARTIFACT_DATA; + String DPREV_STATUS; + String DCURR_STATUS; + String COMMENT; + String DID; + String TOPIC_NAME; + String TOSCA_NODE_TYPE; + String CURR_ARTIFACT_UUID; + String PREV_ARTIFACT_UUID; + String ARTIFACT_TIMEOUT; + String MODIFIER; + String SERVICE_INSTANCE_ID; + String CONSUMER_ID; + String RESOURCE_URL; + + public String getCONSUMER_ID() { + return CONSUMER_ID; + } + + public void setCONSUMER_ID(String consumer_id) { + CONSUMER_ID = consumer_id; + } + + public String getRESOURCE_URL() { + return RESOURCE_URL; + } + + public void setRESOURCE_URL(String resource_url) { + RESOURCE_URL = resource_url; + } + + public String getSERVICE_INSTANCE_ID() { + return SERVICE_INSTANCE_ID; + } + + public void setSERVICE_INSTANCE_ID(String sERVICE_INSTANCE_ID) { + SERVICE_INSTANCE_ID = sERVICE_INSTANCE_ID; + } + + public String getMODIFIER() { + return MODIFIER; + } + + public void setMODIFIER(String mODIFIER) { + MODIFIER = mODIFIER; + } + + public String getArtifactTimeout() { + return ARTIFACT_TIMEOUT; + } + + public void setArtifactTimeout(String artifactTimeout) { + this.ARTIFACT_TIMEOUT = artifactTimeout; + } + + public String getCurrArtifactUuid() { + return CURR_ARTIFACT_UUID; + } + + public void setCurrArtifactUuid(String currArtifactUuid) { + this.CURR_ARTIFACT_UUID = currArtifactUuid; + } + + public String getPrevArtifactUuid() { + return PREV_ARTIFACT_UUID; + } + + public void setPrevArtifactUuid(String prevArtifactUuid) { + this.PREV_ARTIFACT_UUID = prevArtifactUuid; + } + + public String getToscaNodeType() { + return TOSCA_NODE_TYPE; + } + + public void setToscaNodeType(String ToscaNodeType) { + this.TOSCA_NODE_TYPE = ToscaNodeType; + } + + public String getTopicName() { + return TOPIC_NAME; + } + + public void setTopicName(String topicName) { + this.TOPIC_NAME = topicName; + } + + public String getDistributionId() { + return DID; + } + + public void setDistributionId(String did) { + this.DID = did; + } + + public ExpectedResourceAuditJavaObject() { + super(); + // TODO Auto-generated constructor stub + } + + public ExpectedResourceAuditJavaObject(String action, String modifierName, String modifierUid, String status, + String desc, String resourceName, String resourceType, String prevVersion, String currVersion, + String prevState, String currState, String timestamp, String toscaNodesType, String timeout, + String modifier, String serviceInstanceId) { + super(); + this.ACTION = action; + this.MODIFIER_NAME = modifierName; + this.MODIFIER_UID = modifierUid; + this.STATUS = status; + this.DESC = desc; + this.RESOURCE_NAME = resourceName; + this.RESOURCE_TYPE = resourceType; + this.PREV_VERSION = prevVersion; + this.CURR_VERSION = currVersion; + this.PREV_STATE = prevState; + this.CURR_STATE = currState; + this.TIMESTAMP = timestamp; + this.TOSCA_NODE_TYPE = toscaNodesType; + this.ARTIFACT_TIMEOUT = timeout; + this.MODIFIER = modifier; + this.SERVICE_INSTANCE_ID = serviceInstanceId; + } + + public String getAction() { + return ACTION; + } + + public void setAction(String action) { + this.ACTION = action; + } + + public String getModifierName() { + return MODIFIER_NAME; + } + + public void setModifierName(String modifierName) { + this.MODIFIER_NAME = modifierName; + } + + public String getModifierUid() { + return MODIFIER_UID; + } + + public void setModifierUid(String modifierUid) { + this.MODIFIER_UID = modifierUid; + } + + public String getStatus() { + return STATUS; + } + + public void setStatus(String status) { + this.STATUS = status; + } + + public String getDesc() { + return DESC; + } + + public void setDesc(String desc) { + this.DESC = desc; + } + + public String getResourceName() { + return RESOURCE_NAME; + } + + public void setResourceName(String resourceName) { + this.RESOURCE_NAME = resourceName; + } + + public String getResourceType() { + return RESOURCE_TYPE; + } + + public void setResourceType(String resourceType) { + this.RESOURCE_TYPE = resourceType; + } + + public String getPrevVersion() { + return PREV_VERSION; + } + + public void setPrevVersion(String prevVersion) { + this.PREV_VERSION = prevVersion; + } + + public String getCurrVersion() { + return CURR_VERSION; + } + + public void setCurrVersion(String currVersion) { + this.CURR_VERSION = currVersion; + } + + public String getPrevState() { + return PREV_STATE; + } + + public void setPrevState(String prevState) { + this.PREV_STATE = prevState; + } + + public String getCurrState() { + return CURR_STATE; + } + + public void setCurrState(String currState) { + this.CURR_STATE = currState; + } + + public String getTimestamp() { + return TIMESTAMP; + } + + public void setTimestamp(String timestamp) { + this.TIMESTAMP = timestamp; + } + + public String getArtifactData() { + return ARTIFACT_DATA; + } + + public void setArtifactData(String artifactData) { + this.ARTIFACT_DATA = artifactData; + } + + public String getDprevStatus() { + return DPREV_STATUS; + } + + public void setDprevStatus(String dprevStatus) { + this.DPREV_STATUS = dprevStatus; + } + + public String getDcurrStatus() { + return DCURR_STATUS; + } + + public void setDcurrStatus(String dcurrStatus) { + this.DCURR_STATUS = dcurrStatus; + } + + public String getComment() { + return COMMENT; + } + + public void setComment(String comment) { + this.COMMENT = comment; + } + + @Override + public String toString() { + return "ExpectedResourceAuditJavaObject [ACTION=" + ACTION + ", STATUS=" + STATUS + ", DESC=" + DESC + + ", RESOURCE_NAME=" + RESOURCE_NAME + ", RESOURCE_TYPE=" + RESOURCE_TYPE + ", PREV_VERSION=" + + PREV_VERSION + ", CURR_VERSION=" + CURR_VERSION + ", PREV_STATE=" + PREV_STATE + ", CURR_STATE=" + + CURR_STATE + ", TIMESTAMP=" + TIMESTAMP + ", ARTIFACT_DATA=" + ARTIFACT_DATA + ", DPREV_STATUS=" + + DPREV_STATUS + ", DCURR_STATUS=" + DCURR_STATUS + ", COMMENT=" + COMMENT + ", DID=" + DID + + ", TOPIC_NAME=" + TOPIC_NAME + ", TOSCA_NODE_TYPE=" + TOSCA_NODE_TYPE + ", CURR_ARTIFACT_UUID=" + + CURR_ARTIFACT_UUID + ", PREV_ARTIFACT_UUID=" + PREV_ARTIFACT_UUID + ", ARTIFACT_TIMEOUT=" + + ARTIFACT_TIMEOUT + ", MODIFIER=" + MODIFIER + ", SERVICE_INSTANCE_ID=" + SERVICE_INSTANCE_ID + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedUserCRUDAudit.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedUserCRUDAudit.java new file mode 100644 index 0000000000..2bc8625057 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/expected/ExpectedUserCRUDAudit.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.expected; + +public class ExpectedUserCRUDAudit { + String action; + String modifier; + String status; + String desc; + String userBefore; + String userAfter; + + public ExpectedUserCRUDAudit(String action, String modifier, String status, String desc, String userBefore, + String userAfter) { + super(); + this.action = action; + this.modifier = modifier; + this.status = status; + this.desc = desc; + this.userBefore = userBefore; + this.userAfter = userAfter; + } + + public ExpectedUserCRUDAudit() { + action = null; + modifier = null; + userBefore = null; + userAfter = null; + status = null; + desc = null; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public String getModifier() { + return modifier; + } + + public void setModifier(String modifier) { + this.modifier = modifier; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getDesc() { + return desc; + } + + public void setDesc(String desc) { + this.desc = desc; + } + + public String getUserBefore() { + return userBefore; + } + + public void setUserBefore(String userBefore) { + this.userBefore = userBefore; + } + + public String getUserAfter() { + return userAfter; + } + + public void setUserAfter(String userAfter) { + this.userAfter = userAfter; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderData.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderData.java new file mode 100644 index 0000000000..2c23b08717 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderData.java @@ -0,0 +1,114 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +public class HeaderData { + String contentMd5; + String contentType; + String HttpCspUserId; + String HttpCspFirstName; + String HttpCspLastName; + String HttpCspWsType; + String HttpIvRemoteAddress; + String HttpIvUser; + + public HeaderData() { + super(); + } + + public HeaderData(String contentMd5, String contentType, String httpCspUserId, String httpCspFirstName, + String httpCspLastName, String httpCspWsType, String httpIvRemoteAddress, String httpIvUser) { + super(); + this.contentMd5 = contentMd5; + this.contentType = contentType; + HttpCspUserId = httpCspUserId; + HttpCspFirstName = httpCspFirstName; + HttpCspLastName = httpCspLastName; + HttpCspWsType = httpCspWsType; + HttpIvRemoteAddress = httpIvRemoteAddress; + HttpIvUser = httpIvUser; + } + + public String getContentMd5() { + return contentMd5; + } + + public void setContentMd5(String contentMd5) { + this.contentMd5 = contentMd5; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getHttpCspUserId() { + return HttpCspUserId; + } + + public void setHttpCspUserId(String httpCspUserId) { + HttpCspUserId = httpCspUserId; + } + + public String getHttpCspFirstName() { + return HttpCspFirstName; + } + + public void setHttpCspFirstName(String httpCspFirstName) { + HttpCspFirstName = httpCspFirstName; + } + + public String getHttpCspLastName() { + return HttpCspLastName; + } + + public void setHttpCspLastName(String httpCspLastName) { + HttpCspLastName = httpCspLastName; + } + + public String getHttpCspWsType() { + return HttpCspWsType; + } + + public void setHttpCspWsType(String httpCspWsType) { + HttpCspWsType = httpCspWsType; + } + + public String getHttpIvRemoteAddress() { + return HttpIvRemoteAddress; + } + + public void setHttpIvRemoteAddress(String httpIvRemoteAddress) { + HttpIvRemoteAddress = httpIvRemoteAddress; + } + + public String getHttpIvUser() { + return HttpIvUser; + } + + public void setHttpIvUser(String httpIvUser) { + HttpIvUser = httpIvUser; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderValue.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderValue.java new file mode 100644 index 0000000000..4a2ad9ab82 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HeaderValue.java @@ -0,0 +1,38 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +public enum HeaderValue { + + APPLICATION_JSON("application/json"); + + String value; + + private HeaderValue(String value) { + this.value = value; + } + + public String getValue() { + + return value; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpHeaderEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpHeaderEnum.java new file mode 100644 index 0000000000..cd3beee150 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpHeaderEnum.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +public enum HttpHeaderEnum { + + Content_MD5("Content-MD5"), + USER_ID("USER_ID"), + HTTP_CSP_FIRSTNAME("HTTP_CSP_FIRSTNAME"), + HTTP_CSP_LASTNAME("HTTP_CSP_LASTNAME"), + HTTP_CSP_WSTYPE("HTTP_CSP_WSTYPE"), + HTTP_IV_REMOTE_ADDRESS("HTTP_IV_REMOTE_ADDRESS"), + HTTP_IV_USER("HTTP_IV_USER"), + HTTP_CSP_EMAIL("HTTP_CSP_EMAIL"), + CONTENT_TYPE("Content-Type"), + ACCEPT("Accept"), + X_ECOMP_REQUEST_ID_HEADER("X-ECOMP-RequestID"), + CACHE_CONTROL("Cache-Control"), + X_ECOMP_INSTANCE_ID("X-ECOMP-InstanceID"), + AUTHORIZATION("Authorization"), + CONTENT_LENGTH("Content-Length"), + CONTENT_DISPOSITION("Content-Disposition"), + HOST("Host"), + X_ECOMP_SERVICE_ID_HEADER("X-ECOMP-ServiceID"), + WWW_AUTHENTICATE("WWW-Authenticate"), + ECOMP_PASSWORD("password"), + ECOMP_USERNAME("username"); + + String value; + + private HttpHeaderEnum(String value) { + this.value = value; + } + + public String getValue() { + + return value; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpRequest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpRequest.java new file mode 100644 index 0000000000..7c2830ec5f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/HttpRequest.java @@ -0,0 +1,883 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +import java.io.BufferedReader; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.StringWriter; +import java.net.HttpURLConnection; +import java.net.URI; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Scanner; + +import javax.net.ssl.HttpsURLConnection; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.annotation.NotThreadSafe; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.StringEntity; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +public class HttpRequest { + + static Logger logger = LoggerFactory.getLogger(HttpRequest.class.getName()); + + public RestResponse httpSendGet(String url, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + // optional default is GET + con.setRequestMethod("GET"); + // add request header + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + + } + + int responseCode = con.getResponseCode(); + logger.debug("Send GET http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + String result; + + try { + + result = IOUtils.toString(con.getInputStream()); + response.append(result); + + } catch (Exception e) { + // logger.error("Error during getting input stream: ",e); + } + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e) { + // logger.error("Error during getting error stream: ",e); + } + + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + restResponse.setErrorCode(responseCode); + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + + return restResponse; + } + + public RestResponse httpsSendGet(String url, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); + // optional default is GET + con.setRequestMethod("GET"); + // add request header + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + + } + + int responseCode = con.getResponseCode(); + logger.debug("Send GET http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + + String result; + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + // result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + restResponse.setErrorCode(responseCode); + // restResponse.setResponse(result); + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + + return restResponse; + } + + public RestResponse httpSendByMethod(String url, String method, String body, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod(method); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + + } + if (body != null && !body.isEmpty() && !method.equals("DELETE")) { + // Send post request + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + } + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send {} http request, url: {}", method, url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + // response = null; + logger.debug("response body is null"); + } + + String result; + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + // if (response == null) { + // restResponse.setResponse(null); + // } else { + // restResponse.setResponse(response.toString()); + // } + + if (response != null) { + restResponse.setResponse(response.toString()); + } + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse sendHttpPost(String url, String body, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod("POST"); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + } + + // Send post request + if (body != null) { + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + } + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send POST http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + + String result; + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse httpSendPost(String url, String body, Map headers) throws IOException { + return httpSendPost(url, body, headers, "POST"); + } + + public RestResponse httpSendPut(String url, String body, Map headers) throws IOException { + return httpSendPost(url, body, headers, "PUT"); + } + + public RestResponse httpSendPost(String url, String body, Map headers, String methodType) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod(methodType); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + } + + // Send post request + if (body != null) { + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + } + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send POST http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + + String result; + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse httpSendDeleteWithBody2(String url, String body, Map headers) throws ClientProtocolException, IOException { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + RestResponse restResponse = new RestResponse(); + HttpDeleteWithBody httpDelete = new HttpDeleteWithBody(url); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + httpDelete.addHeader(key, value); + } + } + + // add body to request + StringEntity input = new StringEntity(body, ContentType.APPLICATION_JSON); + httpDelete.setEntity(input); + + // execute request + CloseableHttpResponse response = httpclient.execute(httpDelete); + + restResponse.setErrorCode(response.getStatusLine().getStatusCode()); + + return restResponse; + } + + public RestResponse httpSendDeleteWithBody(String url, String body, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod("DELETE"); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + } + + // Send post request + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send DELETE http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + + String result; + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse httpSendPostWithOutBody(String url, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod("POST"); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + } + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send POST http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + // response = null; + logger.debug("response body is null"); + } + + String result; + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + // if (response == null) { + // restResponse.setResponse(null); + // } else { + // restResponse.setResponse(response.toString()); + // } + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse httpSendPostMultipart(String url, Map headers, String jsonLocation, String zipLocation) throws IOException { + + Gson gson = new Gson(); + String gsonToSend = null; + RestResponse restResponse = new RestResponse(); + BufferedReader br = null; + // + // + // + // + // try { + // + // String sCurrentLine; + // + // br = new BufferedReader(new FileReader(jsonLocation)); + // + // while ((sCurrentLine = br.readLine()) != null) { + // System.out.println(sCurrentLine); + // } + // + // } catch (IOException e) { + // e.printStackTrace(); + // } finally { + // try { + // if (br != null)br.close(); + // gsonToSend = br.toString(); + // } catch (IOException ex) { + // ex.printStackTrace(); + // } + // } + + gsonToSend = new Scanner(new File(jsonLocation)).useDelimiter("\\Z").next(); + logger.debug("gsonToSend: {}", gsonToSend); + + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + mpBuilder.addPart("resourceZip", new FileBody(new File(zipLocation))); + mpBuilder.addPart("resourceMetadata", new StringBody(gsonToSend, ContentType.APPLICATION_JSON)); + + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("USER_ID", "adminid"); + httpPost.setEntity(mpBuilder.build()); + + CloseableHttpClient client = HttpClients.createDefault(); + CloseableHttpResponse response = client.execute(httpPost); + try { + logger.debug("----------------------------------------"); + logger.debug("response.getStatusLine(): {}", response.getStatusLine()); + HttpEntity resEntity = response.getEntity(); + if (resEntity != null) { + logger.debug("Response content length: {}", resEntity.getContentLength()); + } + EntityUtils.consume(resEntity); + } finally { + + response.close(); + client.close(); + } + + restResponse.setErrorCode(response.getStatusLine().getStatusCode()); + restResponse.setResponse(response.getEntity().toString()); + + return restResponse; + + } + + public RestResponse httpSendPostWithAuth(String url, String body, Map headers, String username, String password) throws IOException { + + String userPassword = username + ":" + password; + String encoding = Base64.encodeBase64String(userPassword.getBytes()); + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + // add request method + con.setRequestMethod("POST"); + + con.setRequestProperty("Authorization", "Basic " + encoding); + + // add request headers + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + + } + + // Send post request + con.setDoOutput(true); + DataOutputStream wr = new DataOutputStream(con.getOutputStream()); + wr.writeBytes(body); + wr.flush(); + wr.close(); + + // con.connect(); + + int responseCode = con.getResponseCode(); + logger.debug("Send POST http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + response = null; + + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + if (response == null) { + restResponse.setResponse(null); + } else { + restResponse.setResponse(response.toString()); + } + + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + return restResponse; + + } + + public RestResponse httpSendDelete(String url, Map headers) throws IOException { + + RestResponse restResponse = new RestResponse(); + URL obj = new URL(url); + HttpURLConnection con = (HttpURLConnection) obj.openConnection(); + + if (headers != null) { + for (Entry header : headers.entrySet()) { + String key = header.getKey(); + String value = header.getValue(); + con.setRequestProperty(key, value); + } + + } + + con.setDoOutput(true); + con.setRequestMethod("DELETE"); + int responseCode = con.getResponseCode(); + logger.debug("Send DELETE http request, url: {}", url); + logger.debug("Response Code: {}", responseCode); + + StringBuffer response = new StringBuffer(); + + try { + BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + response.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + + String result; + + try { + + result = IOUtils.toString(con.getErrorStream()); + response.append(result); + + } catch (Exception e2) { + result = null; + } + logger.debug("Response body: {}", response); + + // print result + + restResponse.setErrorCode(responseCode); + + if (response != null) { + restResponse.setResponse(response.toString()); + } + + restResponse.setErrorCode(con.getResponseCode()); + Map> headerFields = con.getHeaderFields(); + restResponse.setHeaderFields(headerFields); + String responseMessage = con.getResponseMessage(); + restResponse.setResponseMessage(responseMessage); + + con.disconnect(); + + return restResponse; + } + + public static RestResponse sendHttpPostWithEntity(HttpEntity requestEntity, String url, Map headers) throws IOException, ClientProtocolException { + CloseableHttpResponse response = null; + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + RestResponse restResponse = new RestResponse(); + for (Entry entry : headers.entrySet()) { + httpPost.addHeader(entry.getKey(), entry.getValue()); + } + + httpPost.setEntity(requestEntity); + response = client.execute(httpPost); + HttpEntity responseEntity = response.getEntity(); + String responseBody = null; + if (responseEntity != null) { + InputStream instream = responseEntity.getContent(); + StringWriter writer = new StringWriter(); + IOUtils.copy(instream, writer); + responseBody = writer.toString(); + try { + + } finally { + instream.close(); + } + } + + restResponse.setErrorCode(response.getStatusLine().getStatusCode()); + restResponse.setResponse(responseBody); + + return restResponse; + + } finally { + closeResponse(response); + closeHttpClient(client); + + } + } + + private static void closeHttpClient(CloseableHttpClient client) { + try { + if (client != null) { + client.close(); + } + } catch (IOException e) { + logger.debug("failed to close client or response: ", e); + } + } + + private static void closeResponse(CloseableHttpResponse response) { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + logger.debug("failed to close client or response: ", e); + } + } + + @NotThreadSafe + class HttpDeleteWithBody extends HttpEntityEnclosingRequestBase { + public static final String METHOD_NAME = "DELETE"; + + public String getMethod() { + return METHOD_NAME; + } + + public HttpDeleteWithBody(final String uri) { + super(); + setURI(URI.create(uri)); + } + + public HttpDeleteWithBody(final URI uri) { + super(); + setURI(uri); + } + + public HttpDeleteWithBody() { + super(); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/MustHeaders.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/MustHeaders.java new file mode 100644 index 0000000000..6937608d2a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/MustHeaders.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +import java.util.HashMap; +import java.util.Map; + +public class MustHeaders { + + private Map headers = new HashMap(); + + public MustHeaders(HeaderData headerData) { + + super(); + headers.put(HttpHeaderEnum.Content_MD5.getValue(), headerData.getContentMd5()); + headers.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), headerData.getContentType()); + headers.put(HttpHeaderEnum.ACCEPT.getValue(), headerData.getContentType()); + headers.put(HttpHeaderEnum.USER_ID.getValue(), headerData.getHttpCspUserId()); + headers.put(HttpHeaderEnum.HTTP_CSP_FIRSTNAME.getValue(), headerData.getHttpCspFirstName()); + headers.put(HttpHeaderEnum.HTTP_CSP_LASTNAME.getValue(), headerData.getHttpCspLastName()); + headers.put(HttpHeaderEnum.HTTP_CSP_WSTYPE.getValue(), headerData.getHttpCspWsType()); + headers.put(HttpHeaderEnum.HTTP_IV_REMOTE_ADDRESS.getValue(), headerData.getHttpIvRemoteAddress()); + headers.put(HttpHeaderEnum.HTTP_IV_USER.getValue(), headerData.getHttpIvUser()); + + } + + public MustHeaders() { + super(); + } + + public Map getMap() { + return headers; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/RestResponse.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/RestResponse.java new file mode 100644 index 0000000000..f11d35a646 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/datatypes/http/RestResponse.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.datatypes.http; + +import java.util.List; +import java.util.Map; + +public class RestResponse { + + Integer errorCode; + String response; + Map> headerFields; + String responseMessage; + + public RestResponse() { + super(); + } + + public RestResponse(Integer errorCode, String response, Map> headerFields, + String responseMessage) { + super(); + this.errorCode = errorCode; + this.response = response; + this.headerFields = headerFields; + this.responseMessage = responseMessage; + } + + public Integer getErrorCode() { + return errorCode; + } + + public void setErrorCode(Integer errorCode) { + this.errorCode = errorCode; + } + + public String getResponse() { + return response; + } + + public void setResponse(String response) { + this.response = response; + } + + public Map> getHeaderFields() { + return headerFields; + } + + public void setHeaderFields(Map> headerFields) { + this.headerFields = headerFields; + } + + public String getResponseMessage() { + return responseMessage; + } + + public void setResponseMessage(String responseMessage) { + this.responseMessage = responseMessage; + } + + @Override + public String toString() { + return "RestResponse [errorCode=" + errorCode + ", response=" + response + ", headerFields=" + headerFields + + ", responseMessage=" + responseMessage + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/TODO/ImportCapabilityTypeCITest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/TODO/ImportCapabilityTypeCITest.java new file mode 100644 index 0000000000..3af40c5bb8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/TODO/ImportCapabilityTypeCITest.java @@ -0,0 +1,135 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.TODO; + +import java.io.File; +import java.io.IOException; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.DbUtils.TitanState; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterClass; +import org.testng.annotations.Test; + +import fj.data.Either; + +public class ImportCapabilityTypeCITest { + public static final DbUtils DbUtils = new DbUtils(); + + @AfterClass + public static void afterClass() { + DbUtils.shutDowntitan(); + } + + static Config config = Config.instance(); + + // private final String IMPORT_CAPABILITY_TYPES_PATH = + // "src/test/resources/CI/importResourceTests/import_capabilitiesTypes/"; + + @Test + public void testAddingCapabilityTypes() throws IOException { + TitanState originalState = DbUtils.getCurrentTitanState(); + + String importResourceDir = config.getImportResourceConfigDir(); + + String capabilityTypes = importResourceDir + File.separator + "capabilityTypesCi.zip"; + // importCapabilityType("src/test/resources/CI/importResource/capabilityTypesCi.zip"); + importCapabilityType(capabilityTypes); + Either eitherVertex = DbUtils.getVertexByUId("tosca.capabilities.Test.Ci"); + AssertJUnit.assertTrue(eitherVertex.isLeft()); + DbUtils.restoreToTitanState(originalState); + eitherVertex = DbUtils.getVertexByUId("tosca.capabilities.Test.Ci"); + AssertJUnit.assertTrue(eitherVertex.isRight()); + } + + @Test + public void AddingCapabilityNotFound() throws IOException { + TitanState originalState = DbUtils.getCurrentTitanState(); + String importResourceTestsDir = config.getImportResourceTestsConfigDir(); + String capabilitiesTests = importResourceTestsDir + File.separator + "capabilityTypesCi.zip"; + importCapabilityType(capabilitiesTests); + Either eitherVertex = DbUtils.getVertexByUId("tosca.capabilities.NonExsitingCapability"); + AssertJUnit.assertTrue(eitherVertex.isRight()); + DbUtils.restoreToTitanState(originalState); + } + + public static Integer importAllCapabilityTypes() throws IOException { + + String importResourceDir = config.getImportResourceConfigDir() + File.separator + "capabilityTypes.zip"; + // return + // importCapabilityType("src/test/resources/CI/importResource/capabilityTypes.zip"); + return importCapabilityType(importResourceDir); + } + + private static Integer importCapabilityType(String filePath) throws IOException { + Config config = Utils.getConfig(); + CloseableHttpResponse response = null; + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("capabilityTypeZip", new FileBody(new File(filePath))); + + String url = String.format(Urls.IMPORT_CAPABILITY_TYPE, config.getCatalogBeHost(), config.getCatalogBePort()); + + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("USER_ID", "jh0003"); + httpPost.setEntity(mpBuilder.build()); + response = client.execute(httpPost); + return response.getStatusLine().getStatusCode(); + } finally { + closeResponse(response); + closeHttpClient(client); + + } + } + + private static void closeHttpClient(CloseableHttpClient client) { + try { + if (client != null) { + client.close(); + } + } catch (IOException e) { + System.out.println("failed to close client or response: " + e.getMessage()); + } + } + + private static void closeResponse(CloseableHttpResponse response) { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + System.out.println("failed to close client or response: " + e.getMessage()); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ArtifactServletTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ArtifactServletTest.java new file mode 100644 index 0000000000..cd0647d8b1 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ArtifactServletTest.java @@ -0,0 +1,656 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +import fj.data.Either; + +public class ArtifactServletTest extends ComponentBaseTest { + + private static Logger log = LoggerFactory.getLogger(ArtifactServletTest.class.getName()); + protected static final String UPLOAD_ARTIFACT_PAYLOAD = "UHVUVFktVXNlci1LZXktRmlsZS0yOiBzc2gtcnNhDQpFbmNyeXB0aW9uOiBhZXMyNTYtY2JjDQpDb21tZW5wOA0K"; + protected static final String UPLOAD_ARTIFACT_NAME = "TLV_prv.ppk"; + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + protected Gson gson = new Gson(); + protected JSONParser jsonParser = new JSONParser(); + protected String serviceVersion; + protected Resource resourceDetailsVFCcomp; + protected Service defaultService1; + + protected User sdncUserDetails; + + @Rule + public static TestName name = new TestName(); + + public ArtifactServletTest() { + super(name, ArtifactServletTest.class.getName()); + + } + + @BeforeMethod + public void create() throws Exception { + + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + Either resourceDetailsVFCcompE = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, NormativeTypesEnum.COMPUTE, + ResourceCategoryEnum.APPLICATION_L4_APP_SERVER, UserRoleEnum.DESIGNER, true); + resourceDetailsVFCcomp = resourceDetailsVFCcompE.left().value(); + Either defaultService1e = AtomicOperationUtils + .createDefaultService(UserRoleEnum.DESIGNER, true); + defaultService1 = defaultService1e.left().value(); + } + + @Test + public void upadteArtifactWithPayLoadToResourcseTest() throws Exception { + + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertEquals("add informational artifact request returned status: " + response.getErrorCode(), 200, + status); + + defaultArtifact.setDescription("kjglkh"); + defaultArtifact.setArtifactName("install_apache.sh"); + defaultArtifact.setArtifactType("SHELL"); + defaultArtifact.setPayload("new payload"); + + response = ArtifactRestUtils.updateInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to update artifact metatdata: " + response.getErrorCode(), 200, status); + + response = ArtifactRestUtils.deleteInformationalArtifactFromResource(resourceDetailsVFCcomp.getUniqueId(), + defaultArtifact, sdncUserDetails); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to remove artifact: " + response.getErrorCode(), 200, status); + + } + + @Test + public void createAndUpdateArtifactToInterface() throws Exception { + + CloseableHttpResponse response; + int status; + CloseableHttpClient httpclient = HttpClients.createDefault(); + + try { + // upload artifact to interface + String interfaceName = "Standard"; + String operationName = "configure"; + + String userBodyJson = createUploadArtifactBodyJson(); + String url = String.format(Urls.UPLOAD_ARTIFACT_BY_INTERFACE_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), interfaceName, operationName); + + HttpPost httpPost = createPostAddArtifactRequeast(userBodyJson, url, true); + response = httpclient.execute(httpPost); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, status, 200); + + // get artifact uniqueId + String artifactId = getLifecycleArtifactUid(response); + + Map jsonBody = new HashMap(); + jsonBody.put("artifactName", "TLV_prv.ppk"); + jsonBody.put("artifactDisplayName", "configure"); + jsonBody.put("artifactType", "SHELL"); + jsonBody.put("mandatory", "false"); + String newDescription = "new something"; + jsonBody.put("description", newDescription); + jsonBody.put("artifactLabel", "configure"); + userBodyJson = gson.toJson(jsonBody); + + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_BY_INTERFACE_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), interfaceName, operationName, + artifactId); + + httpPost = createPostAddArtifactRequeast(userBodyJson, url, false); + + response = httpclient.execute(httpPost); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, 200, status); + + url = String.format(Urls.GET_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceDetailsVFCcomp.getUniqueId()); + HttpGet httpGet = createGetRequest(url); + response = httpclient.execute(httpGet); + AssertJUnit.assertTrue(response.getStatusLine().getStatusCode() == 200); + String responseString = new BasicResponseHandler().handleResponse(response); + + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + responseMap = (JSONObject) responseMap.get("interfaces"); + responseMap = (JSONObject) responseMap.get(interfaceName.toLowerCase()); + responseMap = (JSONObject) responseMap.get("operations"); + responseMap = (JSONObject) responseMap.get(operationName.toLowerCase()); + responseMap = (JSONObject) responseMap.get("implementation"); + String description = (String) responseMap.get("description"); + + AssertJUnit.assertEquals("the new description value was not set", newDescription, description); + + // delete artifact + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_BY_INTERFACE_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), interfaceName, operationName, + artifactId); + HttpDelete httpDelete = createDeleteArtifactRequest(url); + + response = httpclient.execute(httpDelete); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, status, 200); + } finally { + httpclient.close(); + } + + } + + protected String createUploadArtifactBodyJson() { + Map jsonBody = new HashMap(); + jsonBody.put("artifactName", UPLOAD_ARTIFACT_NAME); + jsonBody.put("artifactDisplayName", "configure"); + jsonBody.put("artifactType", "SHELL"); + jsonBody.put("mandatory", "false"); + jsonBody.put("description", "ff"); + jsonBody.put("payloadData", UPLOAD_ARTIFACT_PAYLOAD); + jsonBody.put("artifactLabel", "configure"); + return gson.toJson(jsonBody); + } + + protected ArtifactDefinition getArtifactDataFromJson(String json) { + Gson gson = new Gson(); + ArtifactDefinition artifact = new ArtifactDefinition(); + artifact = gson.fromJson(json, ArtifactDefinition.class); + + /* + * atifact.setArtifactName(UPLOAD_ARTIFACT_NAME); + * artifact.setArtifactDisplayName("configure"); + * artifact.setArtifactType("SHELL"); artifact.setMandatory(false); + * artifact.setDescription("ff"); + * artifact.setPayloadData(UPLOAD_ARTIFACT_PAYLOAD); + * artifact.setArtifactLabel("configure"); + */ + return artifact; + } + + protected HttpGet createGetRequest(String url) { + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httpGet.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httpGet.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + return httpGet; + } + + protected String getArtifactUid(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected String getArtifactEsId(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String esId = (String) responseMap.get("EsId"); + return esId; + } + + protected ArtifactDefinition addArtifactDataFromResponse(HttpResponse response, ArtifactDefinition artifact) + throws HttpResponseException, IOException, ParseException { + // String responseString = new + // BasicResponseHandler().handleResponse(response); + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + artifact.setEsId((String) responseMap.get("esId")); + artifact.setUniqueId((String) responseMap.get("uniqueId")); + artifact.setArtifactGroupType(ArtifactGroupTypeEnum.findType((String) responseMap.get("artifactGroupType"))); + artifact.setTimeout(((Long) responseMap.get("timeout")).intValue()); + return artifact; + } + + protected String getLifecycleArtifactUid(CloseableHttpResponse response) + throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + responseMap = (JSONObject) responseMap.get("implementation"); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected HttpDelete createDeleteArtifactRequest(String url) { + HttpDelete httpDelete = new HttpDelete(url); + httpDelete.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + httpDelete.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + return httpDelete; + } + + protected HttpPost createPostAddArtifactRequeast(String jsonBody, String url, boolean addMd5Header) + throws UnsupportedEncodingException { + HttpPost httppost = new HttpPost(url); + httppost.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httppost.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httppost.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + if (addMd5Header) { + httppost.addHeader(HttpHeaderEnum.Content_MD5.getValue(), GeneralUtility.calculateMD5ByString(jsonBody)); + } + StringEntity input = new StringEntity(jsonBody); + input.setContentType("application/json"); + httppost.setEntity(input); + log.debug("Executing request {}", httppost.getRequestLine()); + return httppost; + } + + protected String createLoadArtifactBody() { + Map json = new HashMap(); + json.put("artifactName", "install_apache2.sh"); + json.put("artifactType", "SHELL"); + json.put("description", "ddd"); + json.put("payloadData", "UEsDBAoAAAAIAAeLb0bDQz"); + json.put("artifactLabel", "name123"); + + String jsonStr = gson.toJson(json); + return jsonStr; + } + + protected void checkDeleteResponse(RestResponse response) { + BaseRestUtils.checkStatusCode(response, "delete request failed", false, 204, 404); + } + + protected ArtifactUiDownloadData getArtifactUiDownloadData(String artifactUiDownloadDataStr) throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + try { + ArtifactUiDownloadData artifactUiDownloadData = mapper.readValue(artifactUiDownloadDataStr, + ArtifactUiDownloadData.class); + return artifactUiDownloadData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + // TODO + // @Ignore("") + @Test + public void addArtifactNoPayLoadToResourcseTest() throws Exception { + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + defaultArtifact.setPayload(null); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertTrue(status == 400); + + } + + @Test + public void upadteArtifactNoPayLoadToResourcseTest() throws Exception { + + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertEquals("add informational artifact request returned status: " + response.getErrorCode(), 200, + status); + + defaultArtifact.setDescription("kjglkh"); + defaultArtifact.setArtifactName("install_apache.sh"); + defaultArtifact.setArtifactType("SHELL"); + defaultArtifact.setPayload(null); + + response = ArtifactRestUtils.updateInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to update artifact metatdata: " + response.getErrorCode(), 200, status); + + response = ArtifactRestUtils.deleteInformationalArtifactFromResource(resourceDetailsVFCcomp.getUniqueId(), + defaultArtifact, sdncUserDetails); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to remove artifact: " + response.getErrorCode(), 200, status); + + } + + // TODO + @Test(enabled = false) + public void updateDeploymentArtifactToResourcseTest() throws Exception { + + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultDeploymentArtifactForType("HEAT"); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertEquals("add informational artifact request returned status: " + response.getErrorCode(), 200, + status); + + response = ArtifactRestUtils.updateInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to update artifact metatdata: " + response.getErrorCode(), 200, status); + + response = ArtifactRestUtils.deleteInformationalArtifactFromResource(resourceDetailsVFCcomp.getUniqueId(), + defaultArtifact, sdncUserDetails); + status = response.getErrorCode(); + AssertJUnit.assertEquals("failed to remove artifact: " + response.getErrorCode(), 200, status); + + } + + // -------------------- + @Test + public void addArtifactToResourcse_AlreadyExistsTest() throws Exception { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + String jsonBody = createLoadArtifactBody(); + + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId()); + HttpPost httppost = createPostAddArtifactRequeast(jsonBody, url, true); + CloseableHttpResponse response = httpclient.execute(httppost); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertTrue("failed to add artifact", status == 200); + + String artifactId = getArtifactUid(response); + + httppost = createPostAddArtifactRequeast(jsonBody, url, true); + response = httpclient.execute(httppost); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("the returned status code is in correct", status, 400); + + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), artifactId); + HttpDelete httpDelete = createDeleteArtifactRequest(url); + response = httpclient.execute(httpDelete); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertTrue("failed to remove artifact", status == 200); + } finally { + httpclient.close(); + } + + } + + @Test + public void addArtifactToResourcse_MissingContentTest() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + Map json = new HashMap(); + json.put("description", "desc"); + json.put("payloadData", "UEsDBAoAAAAIAAeLb0bDQz"); + json.put("Content-MD5", "YTg2Mjg4MWJhNmI5NzBiNzdDFkMWI="); + + String jsonBody = gson.toJson(json); + + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId()); + HttpPost httppost = createPostAddArtifactRequeast(jsonBody, url, true); + CloseableHttpResponse response = httpclient.execute(httppost); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("the returned status code is in correct", status, 400); + } finally { + httpclient.close(); + } + + } + + @Test + public void addArtifactToResourcse_MissingMd5Test() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + HashMap json = new HashMap(); + json.put("artifactName", "install_apache.sh"); + json.put("artifactType", "SHELL"); + json.put("description", "kjglkh"); + json.put("payloadData", "UEsDBYTEIWUYIFHWFMABCNAoAAAAIAAeLb0bDQz"); + json.put("artifactLabel", "name123"); + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId()); + String jsonBody = gson.toJson(json); + HttpPost httppost = createPostAddArtifactRequeast(jsonBody, url, false); + CloseableHttpResponse response = httpclient.execute(httppost); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertTrue("failed to update artifact metatdata", status == 400); + } finally { + httpclient.close(); + } + + } + + @Test + public void deleteArtifact_NotExistsTest() throws Exception { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), "someFakeId"); + HttpDelete httpDelete = createDeleteArtifactRequest(url); + CloseableHttpResponse response = httpclient.execute(httpDelete); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("the returned status code is in correct", status, 404); + } finally { + httpclient.close(); + } + + } + + @Test + public void createAndRemoveArtifactToInterface() throws Exception { + CloseableHttpResponse response; + int status; + CloseableHttpClient httpclient = HttpClients.createDefault(); + + try { + // upload artifact to interface + String interfaceName = "Standard"; + String operationName = "configure"; + + String userBodyJson = createUploadArtifactBodyJson(); + String url = String.format(Urls.UPLOAD_ARTIFACT_BY_INTERFACE_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), interfaceName, operationName); + + HttpPost httpPost = createPostAddArtifactRequeast(userBodyJson, url, true); + response = httpclient.execute(httpPost); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, status, 200); + + // get artifact uniqueId + String artifactId = getLifecycleArtifactUid(response); + + // delete artifact + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_BY_INTERFACE_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetailsVFCcomp.getUniqueId(), interfaceName, operationName, + artifactId); + HttpDelete httpDelete = createDeleteArtifactRequest(url); + + response = httpclient.execute(httpDelete); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, status, 200); + } finally { + httpclient.close(); + } + + } + + @Test + public void addArtifactToServiceTest() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + + try { + String jsonStr = createLoadArtifactBody(); + + String url = String.format(Urls.ADD_ARTIFACT_TO_SERVICE, config.getCatalogBeHost(), + config.getCatalogBePort(), defaultService1.getUniqueId()); + HttpPost httpPost = createPostAddArtifactRequeast(jsonStr, url, true); + CloseableHttpResponse result = httpclient.execute(httpPost); + int status = result.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, 200, status); + + String artifactId = getArtifactUid(result); + + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE, config.getCatalogBeHost(), + config.getCatalogBePort(), defaultService1.getUniqueId(), artifactId); + HttpDelete httpDelete = createDeleteArtifactRequest(url); + + result = httpclient.execute(httpDelete); + status = result.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 200, returned :" + status, 200, status); + } finally { + RestResponse response = ServiceRestUtils.deleteService(defaultService1.getName(), serviceVersion, + sdncUserDetails); + checkDeleteResponse(response); + httpclient.close(); + } + } + + @Test + public void addArtifactNotSupportedTypeToServiceTest() throws Exception { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + Map json = new HashMap(); + json.put("artifactName", "install_apache.sh"); + json.put("artifactType", "SHELL11"); + json.put("description", "fff"); + json.put("payloadData", "UEsDBAoAAAAIAAeLb0bDQz"); + json.put("artifactLabel", "name123"); + + String jsonStr = gson.toJson(json); + + String url = String.format(Urls.ADD_ARTIFACT_TO_SERVICE, config.getCatalogBeHost(), + config.getCatalogBePort(), defaultService1.getUniqueId()); + + HttpPost httpPost = createPostAddArtifactRequeast(jsonStr, url, true); + CloseableHttpResponse result = httpclient.execute(httpPost); + int status = result.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("response code is not 400, returned :" + status, 400, status); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name()); + + String responseString = EntityUtils.toString(result.getEntity()); + + JSONObject map = (JSONObject) jsonParser.parse(responseString); + JSONObject requestError = (JSONObject) map.get("requestError"); + JSONObject serviceException = (JSONObject) requestError.get("serviceException"); + + String msgId = (String) serviceException.get("messageId"); + AssertJUnit.assertEquals("message id did not match expacted", errorInfo.getMessageId(), msgId); + + String text = (String) serviceException.get("text"); + AssertJUnit.assertEquals("text did not match expacted", errorInfo.getMessage(), text); + + JSONArray variables = (JSONArray) serviceException.get("variables"); + String type = (String) variables.get(0); + AssertJUnit.assertEquals("variable did not match expacted", "SHELL11", type); + } finally { + RestResponse response = ServiceRestUtils.deleteService(defaultService1.getName(), serviceVersion, + sdncUserDetails); + checkDeleteResponse(response); + httpclient.close(); + } + + } + + @Test + public void addArtifactToResourceTest() throws Exception { + + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetailsVFCcomp.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertEquals("add informational artifact request returned status: " + response.getErrorCode(), 200, + status); + + RestResponse resourceResp = ResourceRestUtils.getResource(resourceDetailsVFCcomp.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + AssertJUnit.assertNotNull(resource); + + Map artifacts = resource.getArtifacts(); + boolean isExist = false; + for (Map.Entry entry : artifacts.entrySet()) { + if (entry.getKey().equals(defaultArtifact.getArtifactLabel())) { + isExist = true; + + } + } + AssertJUnit.assertTrue(isExist); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/CrudArt.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/CrudArt.java new file mode 100644 index 0000000000..b3c3f3f5b6 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/CrudArt.java @@ -0,0 +1,1750 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ArtifactValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.BaseValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class CrudArt extends ComponentBaseTest { + + private static Logger logger = LoggerFactory.getLogger(CrudArt.class.getName()); + private static final User sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + private static final String HEAT_NET_LABEL = "heatnet"; + private static final String HEAT_LABEL = "heat"; + + protected String testResourcesPath; + protected String testResourcesInstancesPath; + + protected static final String dcaeInventoryToscaFile = "toscaSampleArtifact.yml"; + protected static final String dcaeInventoryJsonFile = "jsonSampleArtifact.json"; + protected static final String dcaeInventoryPolicyFile = "emfSampleArtifact.emf"; + protected static final String dcaeInventoryDocFile = "docSampleArtifact.doc"; + protected static final String dcaeInventoryBlueprintFile = "bluePrintSampleArtifact.xml"; + protected static final String dcaeInventoryEventFile = "eventSampleArtifact.xml"; + + protected static final String heatSuccessFile = "asc_heat 0 2.yaml"; + protected static final String heatNetSuccessFile = "asc_heat_net 0 2.yaml"; + protected static final String yangFile = "addYangXmlArtifactToResource.xml"; + protected static final String jsonFile = "jsonArtifact.json"; + protected static final String invalidJsonFile = "invalidJson.json"; + protected static final String invalidYangFile = "invalidYangXml.xml"; + protected static final String otherFile = "other.txt"; + protected static final String muranoFile = "asc_heat 0 2.zip"; + protected static final String heatSuccessMiniFile = "heat_mini.yaml"; + protected static final String heatInvalidFormat = "heatInvalidFormat.yaml"; + protected static final String yamlInvalidFormat = "invalidYamlFormat.yaml"; + protected static final String heatEnvfile = "heatEnvfile.env"; + + protected ServiceReqDetails serviceDetails; + protected ResourceReqDetails vfResourceDetails; + protected ResourceReqDetails cpResourceDetails; + protected ResourceReqDetails vfcResourceDetails; + protected ResourceReqDetails vlResourceDetails; + + @Rule + public static TestName name = new TestName(); + + public CrudArt() { + super(name, CrudArt.class.getName()); + } + + @DataProvider + private static final Object[][] getDepArtByType() throws IOException, Exception { + return new Object[][] { { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()) }, { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_VOL.getType()) }, + { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_NET.getType()) }, { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_TOSCA.getType()) }, + { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_JSON.getType()) }, { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_POLICY.getType()) }, + { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_DOC.getType()) }, { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_BLUEPRINT.getType()) }, + { ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.DCAE_INVENTORY_EVENT.getType()) } }; + } + + @DataProvider + private static final Object[][] getServiceDepArtByType() throws IOException, Exception { + return new Object[][] { { ArtifactTypeEnum.OTHER.getType() }, { ArtifactTypeEnum.YANG_XML.getType() }, }; + } + + @BeforeMethod + public void init() throws Exception { + // Set files working directory + String sourceDir = config.getResourceConfigDir(); + String workDir = "HeatDeploymentArtifacts"; + testResourcesPath = sourceDir + File.separator + workDir; + String workDirResourceInstanceArtifacts = "ResourceInstanceArtifacts"; + testResourcesInstancesPath = sourceDir + File.separator + workDirResourceInstanceArtifacts; + + // Build the components + Service serviceObj = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + serviceDetails = new ServiceReqDetails(serviceObj); + + Resource vfcResourceObj = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + vfcResourceDetails = new ResourceReqDetails(vfcResourceObj); + + Resource vfResourceObj = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + vfResourceDetails = new ResourceReqDetails(vfResourceObj); + + Resource cpResourceObj = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.CP, UserRoleEnum.DESIGNER, true).left().value(); + cpResourceDetails = new ResourceReqDetails(cpResourceObj); + + Resource vlResourceObj = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VL, UserRoleEnum.DESIGNER, true).left().value(); + vlResourceDetails = new ResourceReqDetails(vlResourceObj); + } + + // ---------------------------------Resource + // success-------------------------------- + @Test + public void addHeatArtifactToResourceAndCertify() throws Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // certified resource + RestResponse changeResourceState = LifecycleRestUtils.certifyResource(vfResourceDetails); + int status = changeResourceState.getErrorCode(); + assertEquals("certify resource request returned status:" + status, BaseRestUtils.STATUS_CODE_SUCCESS, status); + + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(changeResourceState.getResponse()); + Map artifactsMap = resourceJavaObject.getDeploymentArtifacts(); + boolean flag = false; + if (artifactsMap != null) { + for (Entry art : artifactsMap.entrySet()) { + if (art.getValue().getArtifactName().equals(heatArtifactDetails.getArtifactName())) { + assertTrue("expected artifact type is " + ArtifactGroupTypeEnum.DEPLOYMENT.getType() + " but was " + art.getValue().getArtifactGroupType(), art.getValue().getArtifactGroupType().equals(ArtifactGroupTypeEnum.DEPLOYMENT)); + flag = true; + break; + } + } + assertTrue("expected artifact not found", flag == true); + } + + } + + // ---------------------------------Resource + // success-------------------------------- + @Test + public void addDcaeInventoryToscaArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryToscaFile; + String artifactName = dcaeInventoryToscaFile; + String artifactLabel = "dcae inv tosca label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_TOSCA; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addDcaeInventoryJsonArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryJsonFile; + String artifactName = dcaeInventoryJsonFile; + String artifactLabel = "dcae inv json label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_JSON; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addDcaeInventoryPolicyArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryPolicyFile; + String artifactName = dcaeInventoryPolicyFile; + String artifactLabel = "dcae inv policy label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_POLICY; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addDcaeInventoryDocArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryDocFile; + String artifactName = dcaeInventoryDocFile; + String artifactLabel = "dcae inv doc label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_DOC; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addDcaeInventoryBluePrintArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryBlueprintFile; + String artifactName = dcaeInventoryBlueprintFile; + String artifactLabel = "dcae inv blueprint label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_BLUEPRINT; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addDcaeInventoryEventArtifactToResourceInstanceAndCertify() throws Exception { + String artifactFileName = dcaeInventoryEventFile; + String artifactName = dcaeInventoryEventFile; + String artifactLabel = "dcae inv event label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_EVENT; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + private RestResponse addArtifactToResourceInstanceAndCertify(String artifactFileName, String artifactName, String artifactLabel, ArtifactTypeEnum artifactType) throws Exception { + + // Get the resource + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + + // Certify VF + Pair changeComponentState = AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + changeComponentState.getRight().getErrorCode(), changeComponentState.getRight().getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Add VF instance to service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource, service, UserRoleEnum.DESIGNER, true); + + // Get the VF instance + getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance VfInstance = service.getComponentInstances().get(0); + + // Create the artifact + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstance(artifactFileName, artifactName, artifactLabel, artifactType, VfInstance, serviceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addArtifactToResourceInstanceResponse.getResponseMessage()); + return addArtifactToResourceInstanceResponse; + } + + @Test + public void updateArtifactDescriptionToResourceInstance() throws Exception { + String artifactFileName = dcaeInventoryToscaFile; + String artifactName = dcaeInventoryToscaFile; + String artifactLabel = "dcae inv tosca label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_TOSCA; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addArtifactToResourceInstanceResponse.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Get the artifact from VF instance and change his description. + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance vfInstance = service.getComponentInstances().get(0); + Map deploymentArtifacts = vfInstance.getDeploymentArtifacts(); + ArtifactDefinition artifactDefinition = deploymentArtifacts.get("dcaeinvtoscalabel"); + artifactDefinition.setDescription("My new description"); + + // Update the artifact + RestResponse updateDeploymentArtifactToRI = ArtifactRestUtils.updateArtifactToResourceInstance(artifactDefinition, sdncDesignerDetails1, vfInstance.getUniqueId(), service.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", updateDeploymentArtifactToRI.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + updateDeploymentArtifactToRI.getErrorCode(), updateDeploymentArtifactToRI.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void deleteArtifactToResourceInstance() throws Exception { + String artifactFileName = dcaeInventoryToscaFile; + String artifactName = dcaeInventoryToscaFile; + String artifactLabel = "dcae inv tosca label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.DCAE_INVENTORY_TOSCA; + RestResponse addArtifactToResourceInstanceResponse = addArtifactToResourceInstanceAndCertify(artifactFileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addArtifactToResourceInstanceResponse.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addArtifactToResourceInstanceResponse.getErrorCode(), addArtifactToResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Get the artifact from VF instance and change his description. + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance vfInstance = service.getComponentInstances().get(0); + Map deploymentArtifacts = vfInstance.getDeploymentArtifacts(); + ArtifactDefinition artifactDefinition = deploymentArtifacts.get("dcaeinvtoscalabel"); + + // Delete the artifact + RestResponse deleteInformationalArtifactFromResource = ArtifactRestUtils.deleteArtifactFromResourceInstance(artifactDefinition, sdncDesignerDetails1, vfInstance.getUniqueId(), service.getUniqueId()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + deleteInformationalArtifactFromResource.getErrorCode(), deleteInformationalArtifactFromResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addHeatArtifactToResource() throws Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + } + + @Test + public void addHeatAndHeatNetArtifactsToResource() throws Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + + // Add HEAT + logger.debug("listFileName: {}", listFileName.toString()); + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Add HEAT_NET + String payloadNet = FileUtils.loadPayloadFile(listFileName, heatNetSuccessFile, true); + ArtifactReqDetails heatNetArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_NET.getType()); + heatNetArtifactDetails.setPayload(payloadNet); + heatNetArtifactDetails.setArtifactLabel(HEAT_NET_LABEL); + + RestResponse addInformationalArtifactToResource1 = ArtifactRestUtils.uploadArtifactToPlaceholderOnResource(heatNetArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId(), HEAT_NET_LABEL); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource1.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource1.getErrorCode(), addInformationalArtifactToResource1.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(vfResourceDetails, sdncDesignerDetails1); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + + ArtifactDefinition artifactDefinition = deploymentArtifacts.get(HEAT_LABEL); + assertNotNull(artifactDefinition); + String heatEsId = artifactDefinition.getEsId(); + assertNotNull(heatEsId); + + ArtifactDefinition artifactDefinitionNet = deploymentArtifacts.get(HEAT_NET_LABEL); + assertNotNull(artifactDefinitionNet); + String heatNetEsId = artifactDefinitionNet.getEsId(); + assertNotNull(heatNetEsId); + assertFalse(heatEsId.equalsIgnoreCase(heatNetEsId)); + } + + @Test + public void addDeleteAddHeatArtifactToResource() throws Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + RestResponse deleteInformationalArtifactFromResource = ArtifactRestUtils.deleteInformationalArtifactFromResource(vfResourceDetails.getUniqueId(), heatArtifactDetails, sdncDesignerDetails1); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + deleteInformationalArtifactFromResource.getErrorCode(), deleteInformationalArtifactFromResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + @Test + public void addYangXmlArtifactToResource() throws Exception { + + String fileName = yangFile; + String artifactName = "asc_heat 0 2.XML"; + String artifactLabel = "Label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.YANG_XML; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addOtherTypeDeploymentArtifactToResource() throws Exception { + + String fileName = otherFile; + String artifactName = "other.txt"; + String artifactLabel = "Label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.OTHER; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addYangXmlArtifactSameName() throws Exception { + + String fileName = yangFile; + String artifactName = "asc_heat_0_2.XML"; + String artifactLabel = "Label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.YANG_XML; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // Changing label but not name + artifactLabel = "Label1"; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is not 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == 400); + BaseValidationUtils.checkErrorResponse(addInformationalArtifactToResource, ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, new String[] { "Resource", vfResourceDetails.getName(), artifactName }); + + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addInvalidYangXmlFormat() throws Exception { + + String fileName = invalidYangFile; + String artifactName = "asc_heat_0_2.XML"; + String artifactLabel = "Label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.YANG_XML; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is not 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == 400); + BaseValidationUtils.checkErrorResponse(addInformationalArtifactToResource, ActionStatus.INVALID_XML, new String[] { "YANG_XML" }); + + } + + @Test + public void addSeveralYangXmlArtifacts() throws Exception { + + // Adding 4 artifacts + String fileName = yangFile; + String artifactName = "asc_heat_0_2.XML"; + String artifactLabel = "Label"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.YANG_XML; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // Changing label and name + artifactLabel = "Label1"; + artifactName = "asc_heat_0_3.XML"; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Changing label and name + artifactLabel = "Label2"; + artifactName = "asc_heat_0_4.XML"; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + + // Changing label and name + artifactLabel = "Label3"; + artifactName = "asc_heat_0_5.XML"; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 4); + } + + @Test(dataProvider = "getDepArtByType") + public void updateHeatArtifactToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + heatTypeArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // update + heatTypeArtifactDetails.setArtifactName("UPDATE.yaml"); + heatTypeArtifactDetails.setPayloadData(null); + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", updateInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + updateInformationalArtifactToResource.getErrorCode(), updateInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + } + + @Test(dataProvider = "getDepArtByType") + public void updateHeatArtifactTimeOutToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + Resource resource = getResourceByResDetails(vfResourceDetails, sdncDesignerDetails1); + int actualTimeout = resource.getDeploymentArtifacts().get(heatTypeArtifactDetails.getArtifactLabel().toLowerCase()).getTimeout(); + assertTrue("verify " + heatTypeArtifactDetails.getArtifactLabel().toLowerCase() + " artifact timout, expected " + heatTypeArtifactDetails.getTimeout() + ", but was " + actualTimeout, heatTypeArtifactDetails.getTimeout() == actualTimeout); + + // update + heatTypeArtifactDetails.setTimeout(35); + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", updateInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + updateInformationalArtifactToResource.getErrorCode(), updateInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + resource = getResourceByResDetails(vfResourceDetails, sdncDesignerDetails1); + actualTimeout = resource.getDeploymentArtifacts().get(heatTypeArtifactDetails.getArtifactLabel().toLowerCase()).getTimeout(); + assertTrue("verify " + heatTypeArtifactDetails.getArtifactLabel().toLowerCase() + " artifact timout, expected " + heatTypeArtifactDetails.getTimeout() + ", but was " + actualTimeout, heatTypeArtifactDetails.getTimeout() == actualTimeout); + } + + @Test(dataProvider = "getDepArtByType") + public void updateHeatArtifactDescriptionToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + Resource resource = getResourceByResDetails(vfResourceDetails, sdncDesignerDetails1); + String actualDescription = resource.getDeploymentArtifacts().get(heatTypeArtifactDetails.getArtifactLabel().toLowerCase()).getDescription(); + assertTrue("verify " + heatTypeArtifactDetails.getArtifactLabel().toLowerCase() + " artifact Description, expected " + heatTypeArtifactDetails.getDescription() + ", but was " + actualDescription, heatTypeArtifactDetails.getDescription().equals(actualDescription)); + + // update + heatTypeArtifactDetails.setDescription("the best description was ever"); + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", updateInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + updateInformationalArtifactToResource.getErrorCode(), updateInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + resource = getResourceByResDetails(vfResourceDetails, sdncDesignerDetails1); + actualDescription = resource.getDeploymentArtifacts().get(heatTypeArtifactDetails.getArtifactLabel().toLowerCase()).getDescription(); + assertTrue("verify " + heatTypeArtifactDetails.getArtifactLabel().toLowerCase() + " artifact Description, expected " + heatTypeArtifactDetails.getDescription() + ", but was " + actualDescription, heatTypeArtifactDetails.getDescription().equals(actualDescription)); + } + + private Resource getResourceByResDetails(ResourceReqDetails resDetails, User userDetails) throws IOException { + RestResponse response = ResourceRestUtils.getResource(resDetails, userDetails); + assertTrue("response code on get resource not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + response.getErrorCode(), response.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + return resource; + } + + // ---------------------------------Service + // success-------------------------------- + @Test() + public void addAllTypesDepArtifactToService() throws Exception, Exception { + + // String fileName = heatSuccessFile; + // List listFileName = + // FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + // logger.debug("listFileName: {}", listFileName.toString()); + + // String payload = FileUtils.loadPayloadFile(listFileName, fileName, + // true); + ArtifactReqDetails otherArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.OTHER.getType()); + // otherArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(otherArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + ArtifactReqDetails yangXmlArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.YANG_XML.getType()); + + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(yangXmlArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + } + + @Test(enabled = false) + public void addMuranoPkgArtifactToService() throws Exception, Exception { + + String fileName = muranoFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.MURANO_PKG.getType()); + heatArtifactDetails.setPayload(payload); + heatArtifactDetails.setArtifactName("asc_heat 0 2.zip"); + heatArtifactDetails.setArtifactLabel("Label"); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + } + + @Test(dataProvider = "getServiceDepArtByType") + public void addHeatArtifactToServiceAndCertify(String artType) throws Exception, Exception { + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(artType); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // certified service + RestResponse changeServiceState = LifecycleRestUtils.certifyService(serviceDetails); + int status = changeServiceState.getErrorCode(); + assertEquals("certify service request returned status:" + status, BaseRestUtils.STATUS_CODE_SUCCESS, status); + + Service resourceJavaObject = ResponseParser.convertServiceResponseToJavaObject(changeServiceState.getResponse()); + Map artifactsMap = resourceJavaObject.getDeploymentArtifacts(); + boolean flag = false; + if (artifactsMap != null) { + for (Entry art : artifactsMap.entrySet()) { + if (art.getValue().getArtifactName().equals(heatArtifactDetails.getArtifactName())) { + assertTrue("expected artifact type is " + ArtifactGroupTypeEnum.DEPLOYMENT.getType() + " but was " + art.getValue().getArtifactGroupType(), art.getValue().getArtifactGroupType().equals(ArtifactGroupTypeEnum.DEPLOYMENT)); + flag = true; + break; + } + } + assertTrue("expected artifact not found", flag == true); + } + + } + + @Test(enabled = false, dataProvider = "getServiceDepArtByType") + public void updateHeatArtifactToService(String artType) throws Exception, Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(artType); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // update + heatArtifactDetails.setPayloadData(payload); + RestResponse updateInformationalArtifactToService = ArtifactRestUtils.updateInformationalArtifactOfServiceByMethod(heatArtifactDetails, serviceDetails.getUniqueId(), sdncDesignerDetails1, "POST"); + logger.debug("updateInformationalArtifactToService response: {}", updateInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + updateInformationalArtifactToService.getErrorCode(), updateInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + } + + // --------------------------------------Resource Negative + // Tests------------------------------------- + + // TODO Andrey the method of DEPLOYMENT artifact is update and not add + @Test(dataProvider = "getServiceDepArtByType") + public void addTheSameAdditionalHeatArtifactToResource(String artType) throws Exception, Exception { + + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(artType); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // add the same artifact one more time + artifactDetails.setArtifactLabel("the second artifact"); + addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList("Resource", vfResourceDetails.getName(), artifactDetails.getArtifactName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + @Test + public void addHeatArtifactTwiceSameNameToResource() throws Exception, Exception { + + String filename1 = heatSuccessFile; + // String filename2 = heatSuccessMiniFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, filename1, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Add HEAT_NET + String payloadNet = FileUtils.loadPayloadFile(listFileName, heatNetSuccessFile, true); + ArtifactReqDetails heatNetArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_NET.getType()); + heatNetArtifactDetails.setPayload(payloadNet); + heatNetArtifactDetails.setArtifactLabel(HEAT_NET_LABEL); + heatNetArtifactDetails.setArtifactName(heatArtifactDetails.getArtifactName()); + + RestResponse addInformationalArtifactToResource1 = ArtifactRestUtils.uploadArtifactToPlaceholderOnResource(heatNetArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId(), HEAT_NET_LABEL); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource1.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource1.getErrorCode()); + + List variables = Arrays.asList("Resource", vfResourceDetails.getName(), heatNetArtifactDetails.getArtifactName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS.name(), variables, addInformationalArtifactToResource1.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatArtifactTwiceToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String filename1 = heatSuccessFile; + String filename2 = heatSuccessMiniFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, filename1, true); + heatTypeArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // add the second artifact + payload = FileUtils.loadPayloadFile(listFileName, heatSuccessMiniFile, true); + heatTypeArtifactDetails.setPayload(payload); + heatTypeArtifactDetails.setArtifactName(filename2); + heatTypeArtifactDetails.setArtifactLabel("the second artifact"); + + addInformationalArtifactToResource = ArtifactRestUtils.explicitAddInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList("Resource", vfResourceDetails.getName(), heatTypeArtifactDetails.getArtifactType(), heatTypeArtifactDetails.getArtifactType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatArtifactInvalidHeatFormatToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = heatInvalidFormat; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + heatTypeArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList(heatTypeArtifactDetails.getArtifactType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatArtifactInvalidYamlFormatToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = yamlInvalidFormat; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + heatTypeArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_YAML.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList(heatTypeArtifactDetails.getArtifactType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_YAML.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatArtifactInvalidFileExtensionToResource(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = yangFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + heatTypeArtifactDetails.setPayload(payload); + heatTypeArtifactDetails.setArtifactName(fileName); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList(heatTypeArtifactDetails.getArtifactType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatArtifactToResourceCertifyAndAddAdditionalHeatArtifact(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + heatTypeArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // certified resource + RestResponse changeResourceState = LifecycleRestUtils.certifyResource(vfResourceDetails); + int status = changeResourceState.getErrorCode(); + assertEquals("certify resource request returned status:" + status, BaseRestUtils.STATUS_CODE_SUCCESS, status); + + // add second HEAT artifact to the certified resource + changeResourceState = LifecycleRestUtils.changeResourceState(vfResourceDetails, sdncDesignerDetails1, LifeCycleStatesEnum.CHECKOUT); + assertTrue("expected code response on change resource state to CHECKOUT BaseRestUtils.STATUS_CODE_SUCCESS, but was " + changeResourceState.getErrorCode(), changeResourceState.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // ArtifactReqDetails heatArtifactDetails1 = + // ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatTypeArtifactDetails.setPayload(payload); + heatTypeArtifactDetails.setArtifactName(fileName); + heatTypeArtifactDetails.setArtifactLabel("the second artifact"); + + addInformationalArtifactToResource = ArtifactRestUtils.explicitAddInformationalArtifactToResource(heatTypeArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList("Resource", vfResourceDetails.getName(), heatTypeArtifactDetails.getArtifactType(), heatTypeArtifactDetails.getArtifactType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name(), variables, addInformationalArtifactToResource.getResponse()); + + } + + // -----------------Service Negative + // Tests-------------------------------------------------------- + + // Absolute + @Test(enabled = false) + public void addHeatArtifactTwiceToService() throws Exception, Exception { + + String fileName1 = heatSuccessFile; + String fileName2 = heatSuccessMiniFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName1, true); + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.OTHER.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // add the second artifact + payload = FileUtils.loadPayloadFile(listFileName, fileName2, true); + + ArtifactReqDetails heatArtifactDetails1 = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.OTHER.getType()); + heatArtifactDetails1.setPayload(payload); + heatArtifactDetails1.setArtifactName(fileName2); + heatArtifactDetails1.setArtifactLabel("the second artifact"); + + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails1, sdncDesignerDetails1, serviceDetails.getUniqueId()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToService.getErrorCode()); + + List variables = Arrays.asList("Service", serviceDetails.getName(), ArtifactTypeEnum.OTHER.getType(), ArtifactTypeEnum.OTHER.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS.name(), variables, addInformationalArtifactToService.getResponse()); + + } + + // TODO Andrey Obsolete + @Test(enabled = false) + public void addHeatArtifactInvalidHeatFormatToService() throws Exception, Exception { + + String fileName = heatInvalidFormat; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToService.getErrorCode()); + + List variables = Arrays.asList(ArtifactTypeEnum.HEAT.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT.name(), variables, addInformationalArtifactToService.getResponse()); + + } + + // TODO Andrey Obsolete + @Test(enabled = false) + public void addHeatArtifactInvalidYamlFormatToService() throws Exception, Exception { + + String fileName = yamlInvalidFormat; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_YAML.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToService.getErrorCode()); + + List variables = Arrays.asList(ArtifactTypeEnum.HEAT.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_YAML.name(), variables, addInformationalArtifactToService.getResponse()); + + } + + @Test + public void addHeatArtifactInvalidFileExtensionToService() throws Exception, Exception { + + String fileName = muranoFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.YANG_XML.getType()); + heatArtifactDetails.setPayload(payload); + heatArtifactDetails.setArtifactName(fileName); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + logger.debug("addInformationalArtifactToService response: {}", addInformationalArtifactToService.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToService.getErrorCode()); + + List variables = Arrays.asList(ArtifactTypeEnum.YANG_XML.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name(), variables, addInformationalArtifactToService.getResponse()); + + } + + @Test(dataProvider = "getDepArtByType") + public void addHeatEnvArtifactToResourceNotSupportedType(ArtifactReqDetails heatTypeArtifactDetails) throws Exception, Exception { + + String fileName = heatEnvfile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_ENV.getType()); + heatArtifactDetails.setPayload(payload); + heatArtifactDetails.setArtifactName("asc_heat 0 2.env"); + heatArtifactDetails.setArtifactLabel(heatTypeArtifactDetails.getArtifactLabel()); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToResource.getErrorCode()); + + List variables = Arrays.asList(ArtifactTypeEnum.HEAT_ENV.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name(), variables, addInformationalArtifactToResource.getResponse()); + } + + // TODO Andrey + @Test + public void addHeatArtifactToServiceNotSupportDeploymentArt() throws Exception, Exception { + + String fileName = heatSuccessFile; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, fileName, true); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(payload); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(heatArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), addInformationalArtifactToService.getErrorCode()); + + List variables = Arrays.asList(ArtifactTypeEnum.HEAT.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name(), variables, addInformationalArtifactToService.getResponse()); + + } + + protected RestResponse addArtifactToResourceInstance(String artifactFileName, String artifactName, String artifactLabel, ArtifactTypeEnum artifactType, ComponentInstance componentInstance, ServiceReqDetails serviceDetails) throws Exception { + ArtifactReqDetails dcaeArtifactDetails = buildArtifactReqDetailsObject(testResourcesInstancesPath, artifactFileName, artifactName, artifactLabel, artifactType); + RestResponse addArtifactToResourceInstance = ArtifactRestUtils.addArtifactToResourceInstance(dcaeArtifactDetails, sdncDesignerDetails1, componentInstance.getUniqueId(), serviceDetails.getUniqueId()); + return addArtifactToResourceInstance; + } + + protected RestResponse addDeploymentArtifactToResource(String artifactFileName, String artifactName, String artifactLabel, ArtifactTypeEnum artifactType) throws Exception { + ArtifactReqDetails heatArtifactDetails = buildArtifactReqDetailsObject(testResourcesPath, artifactFileName, artifactName, artifactLabel, artifactType); + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, vfResourceDetails.getUniqueId()); + return addInformationalArtifactToResource; + } + + protected RestResponse addDeploymentArtifactToResource(String artifactFileName, String artifactName, String artifactLabel, ArtifactTypeEnum artifactType, ResourceReqDetails resource) throws Exception { + ArtifactReqDetails heatArtifactDetails = buildArtifactReqDetailsObject(testResourcesPath, artifactFileName, artifactName, artifactLabel, artifactType); + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, resource.getUniqueId()); + return addInformationalArtifactToResource; + } + + // US672293 - Support new artifact type : BEVF_LICENSE , VENDOR_LICENSE + @Test + public void addNewArtifactsToVFResource() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + artifactName = "artifact2.xml"; + artifactLabel = "Label2"; + artifactType = ArtifactTypeEnum.VF_LICENSE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact6.xml"; + artifactLabel = "Label6"; + artifactType = ArtifactTypeEnum.APPC_CONFIG; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + fileName = jsonFile; + artifactName = "artifact7.json"; + artifactLabel = "Label7"; + artifactType = ArtifactTypeEnum.APPC_CONFIG; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 2); + + } + + @Test + public void addNewArtifactsToVFCResource() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact2.xml"; + artifactLabel = "Label2"; + artifactType = ArtifactTypeEnum.VF_LICENSE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifac5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactsToVfc() throws Exception { + String fileName = yangFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VF_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactsToCp() throws Exception { + String fileName = yangFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VF_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(cpResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(cpResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactsToVl() throws Exception { + String fileName = yangFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VF_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vlResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vlResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addVfInstanceWithNewArtifactsToService() throws Exception { + String fileName = yangFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VF_LICENSE; + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + // Certify VF + Pair changeComponentState = AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + changeComponentState.getRight().getErrorCode(), changeComponentState.getRight().getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // Add VF instance to service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource, service, UserRoleEnum.DESIGNER, true); + // get service and verify VF instance contain the Artifacts :VF_LICENSE + // and VENDOR_LICENSE + getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance VfInstance = service.getComponentInstances().get(0); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.VENDOR_LICENSE, 1); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.VF_LICENSE, 1); + } + + @Test + public void addNotSupportedArtifactsTypeToService01() throws Exception, Exception { + // Artifact type : VF_LICENSE + ArtifactReqDetails deploymentArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.VF_LICENSE.getType()); + RestResponse addDeploymentArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(deploymentArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code eturned :" + addDeploymentArtifactToService.getErrorCode(), addDeploymentArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add("VF_LICENSE"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name(), variables, addDeploymentArtifactToService.getResponse()); + } + + @Test + public void addNotSupportedArtifactsTypeToService02() throws Exception, Exception { + // Artifact type : VENDOR_LICENSE + ArtifactReqDetails deploymentArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.VENDOR_LICENSE.getType()); + RestResponse addDeploymentArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(deploymentArtifactDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code eturned :" + addDeploymentArtifactToService.getErrorCode(), addDeploymentArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add("VENDOR_LICENSE"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name(), variables, addDeploymentArtifactToService.getResponse()); + } + + @Test + public void addInvalidFileForArtifactTypeVendorLicenseToResource() throws Exception { + String fileName = yangFile; + String NonXmlFile = heatSuccessFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VF_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + // Artifact type VENDOR_LICENSE must be XML file + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + addDeploymentArtifactToResource = addDeploymentArtifactToResource(NonXmlFile, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code 400 returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add("VENDOR_LICENSE"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_XML.name(), variables, addDeploymentArtifactToResource.getResponse()); + // get resource and verify that file not exist within + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + } + + @Test + public void addInvalidFileForArtifactTypeVfLicenseToResource() throws Exception { + String fileName = yangFile; + String NonXmlFile = heatSuccessFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + // Artifact type VF_LICENSE must be XML file + artifactName = "artifact3.xml"; + artifactLabel = "Label3"; + artifactType = ArtifactTypeEnum.VF_LICENSE; + addDeploymentArtifactToResource = addDeploymentArtifactToResource(NonXmlFile, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code 400 returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add("VF_LICENSE"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_XML.name(), variables, addDeploymentArtifactToResource.getResponse()); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + } + + @Test + public void addVendorLicenseArtifactAlreadyExistsInResource() throws Exception { + String fileName = yangFile; + String artifactName = "artifact2.xml"; + String artifactLabel = "Label2"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VENDOR_LICENSE; + RestResponse addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + // Add same file again to resource + addDeploymentArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addDeploymentArtifactToResource.getResponseMessage()); + assertTrue("response code is not 400, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(artifactLabel.toLowerCase()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_EXIST.name(), variables, addDeploymentArtifactToResource.getResponse()); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + // US672294 + + @Test() + public void addVnfCatalogArtifactsToService() throws Exception, Exception { + + ArtifactReqDetails artDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.VNF_CATALOG.getType()); + RestResponse resp = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + resp.getErrorCode(), resp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // get service and verify the Artifacts :VNF_CATALOG + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(service, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.VNF_CATALOG, 1); + } + + @Test() + public void addModelInventoryProfileArtifactsToService() throws Exception, Exception { + + ArtifactReqDetails artDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.getType()); + RestResponse resp = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + resp.getErrorCode(), resp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // get service and verify the Artifacts :VNF_CATALOG + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(service, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, 1); + } + + @Test() + public void addModelQuerySpecArtifactsToService() throws Exception, Exception { + + ArtifactReqDetails artDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.MODEL_QUERY_SPEC.getType()); + RestResponse resp = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + resp.getErrorCode(), resp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // get service and verify the Artifacts :VNF_CATALOG + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(service, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_QUERY_SPEC, 1); + } + + @Test + public void addVfInstanceWithNewArtifactsToService02() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + fileName = yangFile; + artifactName = "artifact2.xml"; + artifactLabel = "Label2"; + artifactType = ArtifactTypeEnum.APPC_CONFIG; + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifac5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + // Certify VF + Pair changeComponentState = AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + changeComponentState.getRight().getErrorCode(), changeComponentState.getRight().getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Add VF instance to service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource, service, UserRoleEnum.DESIGNER, true); + + // get service and verify VF instance contain the Artifacts :VF_LICENSE + // and VENDOR_LICENSE + getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance VfInstance = service.getComponentInstances().get(0); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.VNF_CATALOG, 1); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, 1); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_QUERY_SPEC, 1); + ArtifactValidationUtils.validateArtifactsNumberInComponentInstance(VfInstance, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.APPC_CONFIG, 1); + } + + @Test + public void addAppcConfigArtifactToVfc() throws Exception { + String fileName = jsonFile; + String artifactName = "artifact7.json"; + String artifactLabel = "Label7"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.APPC_CONFIG; + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(artifactName); + variables.add("[VF]"); + variables.add("VFC (Virtual Function Component)"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE.name(), variables, addInformationalArtifactToResource.getResponse()); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + } + + @Test + public void addAppcConfigArtifactToCp() throws Exception { + String fileName = jsonFile; + String artifactName = "artifact7.json"; + String artifactLabel = "Label7"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.APPC_CONFIG; + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(artifactName); + variables.add("[VF]"); + variables.add("CP (Connection Point)"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE.name(), variables, addInformationalArtifactToResource.getResponse()); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + } + + @Test + public void addAppcConfigArtifactToVl() throws Exception { + String fileName = jsonFile; + String artifactName = "artifact7.json"; + String artifactLabel = "Label7"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.APPC_CONFIG; + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(artifactName); + variables.add("[VF]"); + variables.add("VL (Virtual Link)"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE.name(), variables, addInformationalArtifactToResource.getResponse()); + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + } + + @Test() + public void addAppcConfigArtifactsToService() throws Exception, Exception { + ArtifactReqDetails artDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.APPC_CONFIG.getType()); + RestResponse addDeploymentArtifactToResource = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code 400, returned :" + addDeploymentArtifactToResource.getErrorCode(), addDeploymentArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(ArtifactTypeEnum.APPC_CONFIG.toString()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED.name(), variables, addDeploymentArtifactToResource.getResponse()); + } + + @Test + public void addAppcConfigInvalidJsonToVFResourceFailed() throws Exception { + + String fileName = invalidJsonFile; + String artifactName = "invalidJson.json"; + String artifactLabel = "Label7"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.APPC_CONFIG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is 400, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + + ArrayList variables = new ArrayList<>(); + variables.add(ArtifactTypeEnum.APPC_CONFIG.toString()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_JSON.name(), variables, addInformationalArtifactToResource.getResponse()); + + RestResponse getResource = ResourceRestUtils.getResource(vfResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 0); + + } + + @Test + public void addNewArtifactsToCp02() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(cpResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(cpResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifac5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, cpResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(cpResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactsToVl02() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vlResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vlResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifac5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vlResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vlResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactsToVfc02() throws Exception { + + String fileName = yangFile; + String artifactName = "artifact1.xml"; + String artifactLabel = "Label1"; + ArtifactTypeEnum artifactType = ArtifactTypeEnum.VNF_CATALOG; + + RestResponse addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifact4.xml"; + artifactLabel = "Label4"; + artifactType = ArtifactTypeEnum.MODEL_INVENTORY_PROFILE; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + + artifactName = "artifac5.xml"; + artifactLabel = "Label5"; + artifactType = ArtifactTypeEnum.MODEL_QUERY_SPEC; + + addInformationalArtifactToResource = addDeploymentArtifactToResource(fileName, artifactName, artifactLabel, artifactType, vfcResourceDetails); + logger.debug("addInformationalArtifactToResource response: {}", addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToResource.getErrorCode(), addInformationalArtifactToResource.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + getResource = ResourceRestUtils.getResource(vfcResourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(resource, ArtifactGroupTypeEnum.DEPLOYMENT, artifactType, 1); + } + + @Test + public void addNewArtifactAlreadyExistsInService() throws Exception { + ArtifactReqDetails artDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.MODEL_QUERY_SPEC.getType()); + RestResponse addDeploymentArtifactoService = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addDeploymentArtifactoService.getErrorCode(), addDeploymentArtifactoService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + // get service and verify the Artifacts :VNF_CATALOG + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(service, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_QUERY_SPEC, 1); + // Add same file again to resource + addDeploymentArtifactoService = ArtifactRestUtils.addInformationalArtifactToService(artDetails, sdncDesignerDetails1, serviceDetails.getUniqueId()); + assertTrue("response code is 400, returned :" + addDeploymentArtifactoService.getErrorCode(), addDeploymentArtifactoService.getErrorCode() == BaseRestUtils.STATUS_CODE_INVALID_CONTENT); + ArrayList variables = new ArrayList<>(); + variables.add(artDetails.getArtifactLabel().toLowerCase()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.ARTIFACT_EXIST.name(), variables, addDeploymentArtifactoService.getResponse()); + // get service and verify the Artifacts :VNF_CATALOG is still exist and + // has one occurrences + getServiceResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails1); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ArtifactValidationUtils.validateArtifactsNumberInComponent(service, ArtifactGroupTypeEnum.DEPLOYMENT, ArtifactTypeEnum.MODEL_QUERY_SPEC, 1); + } + + private ArtifactReqDetails buildArtifactReqDetailsObject(String filesPath, String artifactFileName, String artifactName, String artifactLabel, ArtifactTypeEnum artifactType) throws IOException, Exception { + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(filesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, artifactFileName, true); + + ArtifactReqDetails dcaeArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(artifactType.getType()); + dcaeArtifactDetails.setPayload(payload); + dcaeArtifactDetails.setArtifactName(artifactName); + dcaeArtifactDetails.setArtifactLabel(artifactLabel); + return dcaeArtifactDetails; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/DownloadComponentArt.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/DownloadComponentArt.java new file mode 100644 index 0000000000..0ae975207b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/DownloadComponentArt.java @@ -0,0 +1,687 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ServiceValidationUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import fj.data.Either; + +public class DownloadComponentArt extends ComponentBaseTest { + + private static Logger log = LoggerFactory.getLogger(DownloadComponentArt.class.getName()); + protected static final String UPLOAD_ARTIFACT_PAYLOAD = "UHVUVFktVXNlci1LZXktRmlsZS0yOiBzc2gtcnNhDQpFbmNyeXB0aW9uOiBhZXMyNTYtY2JjDQpDb21tZW5wOA0K"; + protected static final String UPLOAD_ARTIFACT_NAME = "TLV_prv.ppk"; + + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + + protected Gson gson = new Gson(); + protected JSONParser jsonParser = new JSONParser(); + + protected String serviceVersion; + protected ResourceReqDetails resourceDetails; + protected User sdncUserDetails; + protected ServiceReqDetails serviceDetails; + + @BeforeMethod + public void init() throws Exception { + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + Resource resourceObj = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + Service serviceObj = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + resourceDetails = new ResourceReqDetails(resourceObj); + serviceDetails = new ServiceReqDetails(serviceObj); + } + + @Rule + public static TestName name = new TestName(); + + public DownloadComponentArt() { + super(name, DownloadComponentArt.class.getName()); + + } + + // External API - Download artifact for resource + @Test + public void downloadArtifactFromResourceViaExternalAPI() throws Exception { + Resource resourceDetailsVF; + Either createdResource = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory( + ResourceTypeEnum.VF, NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, + UserRoleEnum.DESIGNER, true); + resourceDetailsVF = createdResource.left().value(); + ArtifactDefinition heatArtifact = AtomicOperationUtils + .uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVF, UserRoleEnum.DESIGNER, true, true) + .left().value(); + resourceDetails = new ResourceReqDetails(resourceDetailsVF); + + String resourceUUID = resourceDetailsVF.getUUID(); + String artifactUUID = heatArtifact.getArtifactUUID(); + + System.out.println("Resource UUID: " + resourceUUID); + System.out.println("Artifact UUID: " + artifactUUID); + + RestResponse restResponse = ArtifactRestUtils.getResourceDeploymentArtifactExternalAPI(resourceUUID, + artifactUUID, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "Resource"); + + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + + String response = restResponse.getResponse(); + + String payloadData = "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + String decodedPaypload = Decoder.decode(payloadData); + + Assert.assertEquals(response, decodedPaypload, "Response deployment artifact not correct."); + + String auditAction = "ArtifactDownload"; + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setResourceName(resourceDetails.getName()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + + expectedResourceAuditJavaObject.setCONSUMER_ID("ci"); + String resource_url = String.format("/asdc/v1/catalog/resources/%s/artifacts/%s", resourceUUID, artifactUUID); + expectedResourceAuditJavaObject.setRESOURCE_URL(resource_url); + + AuditValidationUtils.validateAuditDownloadExternalAPI(expectedResourceAuditJavaObject, auditAction, null, + false); + } + + // External API - Download artifact for resource - negative test + @Test + public void downloadArtifactFromResourceViaExternalAPINegativeTest() throws Exception { + Resource resourceDetailsVF; + Either createdResource = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory( + ResourceTypeEnum.VF, NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, + UserRoleEnum.DESIGNER, true); + resourceDetailsVF = createdResource.left().value(); + ArtifactDefinition heatArtifact = AtomicOperationUtils + .uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVF, UserRoleEnum.DESIGNER, true, true) + .left().value(); + resourceDetails = new ResourceReqDetails(resourceDetailsVF); + + String resourceUUID = resourceDetailsVF.getUUID(); + String artifactUUID = heatArtifact.getArtifactUUID(); + + System.out.println("Resource UUID: " + resourceUUID); + System.out.println("Artifact UUID: " + artifactUUID); + + RestResponse restResponse = ArtifactRestUtils.getResourceDeploymentArtifactExternalAPI(resourceUUID, + "dfsgfdsg324", ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "Resource"); + + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + } + + // External API - Download artifact for service - negative test + @Test + public void downloadArtifactFromServiceViaExternalAPI() throws Exception { + + Service resourceDetailsService; + Either createdResource = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, + true); + resourceDetailsService = createdResource.left().value(); + + ArtifactDefinition heatArtifact = AtomicOperationUtils + .uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsService, UserRoleEnum.DESIGNER, true, true) + .left().value(); + + String resourceUUID = resourceDetailsService.getUUID(); + String artifactUUID = heatArtifact.getArtifactUUID(); + + System.out.println("Resource UUID: " + resourceUUID); + System.out.println("Artifact UUID: " + artifactUUID); + + RestResponse restResponse = ArtifactRestUtils.getResourceDeploymentArtifactExternalAPI(resourceUUID, + artifactUUID, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "Service"); + + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + + String response = restResponse.getResponse(); + + String payloadData = "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + String decodedPaypload = Decoder.decode(payloadData); + + Assert.assertEquals(response, decodedPaypload, "Response deployment artifact not correct."); + + String auditAction = "ArtifactDownload"; + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setResourceName(resourceDetailsService.getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + + expectedResourceAuditJavaObject.setCONSUMER_ID("ci"); + String resource_url = String.format("/asdc/v1/catalog/services/%s/artifacts/%s", resourceUUID, artifactUUID); + expectedResourceAuditJavaObject.setRESOURCE_URL(resource_url); + + AuditValidationUtils.validateAuditDownloadExternalAPI(expectedResourceAuditJavaObject, auditAction, null, + false); + } + + // External API - Download ComponentInstance artifact of service - negative + // test + @Test + public void downloadArtifactOfComponentInstanceFromServiceViaExternalAPI() throws Exception { + + Either resourceDetailsVF_01e = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, UserRoleEnum.DESIGNER, true); + Component resourceDetailsVF_01 = resourceDetailsVF_01e.left().value(); + ArtifactDefinition heatArtifact = AtomicOperationUtils + .uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVF_01, UserRoleEnum.DESIGNER, true, true) + .left().value(); + + resourceDetailsVF_01 = AtomicOperationUtils + .changeComponentState(resourceDetailsVF_01, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true) + .getLeft(); + + Service resourceDetailsService; + Either createdResource = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, + true); + resourceDetailsService = createdResource.left().value(); + + ComponentInstance resourceDetailsVF1ins_01 = AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceDetailsVF_01, resourceDetailsService, + UserRoleEnum.DESIGNER, true) + .left().value(); + + System.out.println("-----"); + + String resourceUUID = resourceDetailsService.getUUID(); + String componentInstanceUID = resourceDetailsVF1ins_01.getUniqueId(); + String artifactUUID = heatArtifact.getArtifactUUID(); + + System.out.println("Resource UUID: " + resourceUUID); + System.out.println("Component instance UID: " + componentInstanceUID); + System.out.println("Artifact UUID: " + artifactUUID); + + RestResponse restResponse = ArtifactRestUtils.getComponentInstanceDeploymentArtifactExternalAPI(resourceUUID, + componentInstanceUID, artifactUUID, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "Service"); + // + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + + String response = restResponse.getResponse(); + + String payloadData = "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + String decodedPaypload = Decoder.decode(payloadData); + + Assert.assertEquals(response, decodedPaypload, "Response deployment artifact not correct."); + + String auditAction = "ArtifactDownload"; + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setResourceName(resourceDetailsVF1ins_01.getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + + expectedResourceAuditJavaObject.setCONSUMER_ID("ci"); + String resource_url = String.format("/asdc/v1/catalog/services/%s/resourceInstances/%s/artifacts/%s", + resourceUUID, componentInstanceUID, artifactUUID); + expectedResourceAuditJavaObject.setRESOURCE_URL(resource_url); + + AuditValidationUtils.validateAuditDownloadExternalAPI(expectedResourceAuditJavaObject, auditAction, null, + false); + } + + @Test + public void downloadArtifactFromResourceTest() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + String jsonBody = createUploadArtifactBodyJson(); + + String resourceId = resourceDetails.getUniqueId(); + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceId); + HttpPost httppost = createPostAddArtifactRequeast(jsonBody, url, true); + HttpResponse response = httpclient.execute(httppost); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("failed to add artifact", 200, status); + + ArtifactDefinition origArtifact = getArtifactDataFromJson(jsonBody); + addArtifactDataFromResponse(response, origArtifact); + String artifactId = origArtifact.getUniqueId(); + + url = String.format(Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceId, artifactId); + HttpGet httpGet = createGetRequest(url); + response = httpclient.execute(httpGet); + status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("failed to download artifact", 200, status); + + InputStream inputStream = response.getEntity().getContent(); + ArtifactUiDownloadData artifactUiDownloadData = getArtifactUiDownloadData(IOUtils.toString(inputStream)); + AssertJUnit.assertEquals("Downloaded payload is different from uploaded one", UPLOAD_ARTIFACT_PAYLOAD, + artifactUiDownloadData.getBase64Contents()); + AssertJUnit.assertEquals("Downloaded artifact name is different from uploaded one", UPLOAD_ARTIFACT_NAME, + artifactUiDownloadData.getArtifactName()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceDetails.getVersion(), sdncUserDetails); + String auditAction = "ArtifactDownload"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setArtifactData(AuditValidationUtils.buildArtifactDataAudit(origArtifact)); + expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } finally { + httpclient.close(); + } + + } + + @Test + public void downloadArtifactFromServiceTest() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + + try { + + String jsonStr = createUploadArtifactBodyJson(); + + String url = String.format(Urls.ADD_ARTIFACT_TO_SERVICE, config.getCatalogBeHost(), + config.getCatalogBePort(), serviceDetails.getUniqueId()); + HttpPost httpPost = createPostAddArtifactRequeast(jsonStr, url, true); + CloseableHttpResponse result = httpclient.execute(httpPost); + int status = result.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("failed to add artifact", 200, status); + + ArtifactDefinition origArtifact = getArtifactDataFromJson(jsonStr); + addArtifactDataFromResponse(result, origArtifact); + String artifactId = origArtifact.getUniqueId(); + + url = String.format(Urls.UI_DOWNLOAD_SERVICE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), + serviceDetails.getUniqueId(), artifactId); + HttpGet httpGet = createGetRequest(url); + CloseableHttpResponse response2 = httpclient.execute(httpGet); + status = response2.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("failed to download artifact", 200, status); + InputStream inputStream = response2.getEntity().getContent(); + ArtifactUiDownloadData artifactUiDownloadData = getArtifactUiDownloadData(IOUtils.toString(inputStream)); + AssertJUnit.assertEquals("Downloaded payload is different from uploaded one", UPLOAD_ARTIFACT_PAYLOAD, + artifactUiDownloadData.getBase64Contents()); + AssertJUnit.assertEquals("Downloaded artifact name is different from uploaded one", UPLOAD_ARTIFACT_NAME, + artifactUiDownloadData.getArtifactName()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = AuditValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceDetails.getVersion(), sdncUserDetails); + String auditAction = "ArtifactDownload"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setArtifactData(AuditValidationUtils.buildArtifactDataAudit(origArtifact)); + expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } finally { + // RestResponse response = + // ServiceRestUtils.deleteService(serviceDetails, serviceVersion, + // sdncUserDetails ); + // checkDeleteResponse(response); + httpclient.close(); + } + } + + @Test + public void downloadArtifactFromResourceNotFound() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + + String resourceId = resourceDetails.getUniqueId(); + String artifactIdNotFound = "11111"; + + ArtifactDefinition origArtifact = new ArtifactDefinition(); + origArtifact.setUniqueId(artifactIdNotFound); + + String url = String.format(Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceId, artifactIdNotFound); + HttpGet httpGet = createGetRequest(url); + CloseableHttpResponse response = httpclient.execute(httpGet); + int status = response.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("expected 404 not found", 404, status); + + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceDetails.getVersion(), sdncUserDetails); + String auditAction = "ArtifactDownload"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + expectedResourceAuditJavaObject.setArtifactData(""); + expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + expectedResourceAuditJavaObject.setPrevArtifactUuid(null); + } finally { + httpclient.close(); + } + + } + + @Test + public void downloadArtifactFromServiceNotFound() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + + String artifactIdNotFound = "11111"; + ArtifactDefinition origArtifact = new ArtifactDefinition(); + origArtifact.setUniqueId(artifactIdNotFound); + + String url = String.format(Urls.UI_DOWNLOAD_SERVICE_ARTIFACT, config.getCatalogBeHost(), + config.getCatalogBePort(), serviceDetails.getUniqueId(), artifactIdNotFound); + HttpGet httpGet = createGetRequest(url); + CloseableHttpResponse response2 = httpclient.execute(httpGet); + int status = response2.getStatusLine().getStatusCode(); + AssertJUnit.assertEquals("expected 404 not found", 404, status); + + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceDetails.getVersion(), sdncUserDetails); + String auditAction = "ArtifactDownload"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + expectedResourceAuditJavaObject.setArtifactData(""); + expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } finally { + httpclient.close(); + } + + } + + @Test + public void addArtifactToResourceTest() throws Exception { + + ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, sdncUserDetails, + resourceDetails.getUniqueId()); + int status = response.getErrorCode(); + AssertJUnit.assertEquals("add informational artifact request returned status: " + response.getErrorCode(), 200, + status); + + RestResponse resourceResp = ResourceRestUtils.getResource(resourceDetails.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + AssertJUnit.assertNotNull(resource); + + Map artifacts = resource.getArtifacts(); + boolean isExist = false; + for (Map.Entry entry : artifacts.entrySet()) { + if (entry.getKey().equals(defaultArtifact.getArtifactLabel())) { + isExist = true; + + } + } + AssertJUnit.assertTrue(isExist); + } + + protected String createUploadArtifactBodyJson() { + Map jsonBody = new HashMap(); + jsonBody.put("artifactName", UPLOAD_ARTIFACT_NAME); + jsonBody.put("artifactDisplayName", "configure"); + jsonBody.put("artifactType", "SHELL"); + jsonBody.put("mandatory", "false"); + jsonBody.put("description", "ff"); + jsonBody.put("payloadData", UPLOAD_ARTIFACT_PAYLOAD); + jsonBody.put("artifactLabel", "configure"); + return gson.toJson(jsonBody); + } + + protected ArtifactDefinition getArtifactDataFromJson(String json) { + Gson gson = new Gson(); + JsonObject jsonElement = new JsonObject(); + jsonElement = gson.fromJson(json, jsonElement.getClass()); + ArtifactDefinition artifact = new ArtifactDefinition(); + String payload = null; + JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA); + if (artifactPayload != null && !artifactPayload.isJsonNull()) { + payload = artifactPayload.getAsString(); + } + jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA); + artifact = gson.fromJson(jsonElement, ArtifactDefinition.class); + artifact.setPayloadData(payload); + + /* + * atifact.setArtifactName(UPLOAD_ARTIFACT_NAME); + * artifact.setArtifactDisplayName("configure"); + * artifact.setArtifactType("SHELL"); artifact.setMandatory(false); + * artifact.setDescription("ff"); + * artifact.setPayloadData(UPLOAD_ARTIFACT_PAYLOAD); + * artifact.setArtifactLabel("configure"); + */ + return artifact; + } + + protected HttpGet createGetRequest(String url) { + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httpGet.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httpGet.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + return httpGet; + } + + protected String getArtifactUid(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected String getArtifactEsId(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String esId = (String) responseMap.get("EsId"); + return esId; + } + + protected ArtifactDefinition addArtifactDataFromResponse(HttpResponse response, ArtifactDefinition artifact) + throws HttpResponseException, IOException, ParseException { + // String responseString = new + // BasicResponseHandler().handleResponse(response); + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + artifact.setEsId((String) responseMap.get("esId")); + artifact.setUniqueId((String) responseMap.get("uniqueId")); + artifact.setArtifactGroupType(ArtifactGroupTypeEnum.findType((String) responseMap.get("artifactGroupType"))); + artifact.setTimeout(((Long) responseMap.get("timeout")).intValue()); + return artifact; + } + + protected String getLifecycleArtifactUid(CloseableHttpResponse response) + throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + responseMap = (JSONObject) responseMap.get("implementation"); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected HttpDelete createDeleteArtifactRequest(String url) { + HttpDelete httpDelete = new HttpDelete(url); + httpDelete.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + httpDelete.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + return httpDelete; + } + + protected HttpPost createPostAddArtifactRequeast(String jsonBody, String url, boolean addMd5Header) + throws UnsupportedEncodingException { + HttpPost httppost = new HttpPost(url); + httppost.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httppost.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httppost.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + if (addMd5Header) { + httppost.addHeader(HttpHeaderEnum.Content_MD5.getValue(), GeneralUtility.calculateMD5ByString(jsonBody)); + } + StringEntity input = new StringEntity(jsonBody); + input.setContentType("application/json"); + httppost.setEntity(input); + log.debug("Executing request {}", httppost.getRequestLine()); + return httppost; + } + + protected String createLoadArtifactBody() { + Map json = new HashMap(); + json.put("artifactName", "install_apache2.sh"); + json.put("artifactType", "SHELL"); + json.put("description", "ddd"); + json.put("payloadData", "UEsDBAoAAAAIAAeLb0bDQz"); + json.put("artifactLabel", "name123"); + + String jsonStr = gson.toJson(json); + return jsonStr; + } + + protected void checkDeleteResponse(RestResponse response) { + BaseRestUtils.checkStatusCode(response, "delete request failed", false, 204, 404); + } + + protected ArtifactUiDownloadData getArtifactUiDownloadData(String artifactUiDownloadDataStr) throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + try { + ArtifactUiDownloadData artifactUiDownloadData = mapper.readValue(artifactUiDownloadDataStr, + ArtifactUiDownloadData.class); + return artifactUiDownloadData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/PlaceHolderValidations.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/PlaceHolderValidations.java new file mode 100644 index 0000000000..02bef89f2c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/PlaceHolderValidations.java @@ -0,0 +1,696 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +//import static org.junit.Assert.assertTrue; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.javatuples.Pair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.cassandra.CassandraUtils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.datastax.driver.core.Row; + +import fj.data.Either; + +public class PlaceHolderValidations extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(PlaceHolderValidations.class.getName()); + private static final String heatExtension = "yaml"; + // private static final String yangXmlExtension = "xml"; + // private static final String muranoPkgExtension = "zip"; + private final String folderName = "addHeatArtifactToServiceAndSertify"; + private Resource resource; + private final int timeOut = 60; + private ArtifactReqDetails updateArtifactReqDetails = null; + protected User sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected User sdncDesignerDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + protected ResourceReqDetails resourceDetails1; + protected ResourceReqDetails resourceVF; + protected ResourceReqDetails resourceCP; + protected ResourceReqDetails resourceVL; + + protected ArtifactReqDetails heatArtifactDetails; + protected ArtifactReqDetails heatVolArtifactDetails; + protected ArtifactReqDetails heatNetArtifactDetails; + + public PlaceHolderValidations() { + super(name, PlaceHolderValidations.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + + @BeforeMethod + public void init() throws IOException, Exception { + + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatNetArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_NET.getType()); + heatVolArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_VOL.getType()); + Resource resourceObject = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resourceDetails1 = new ResourceReqDetails(resourceObject); + resourceObject = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true) + .left().value(); + resourceVF = new ResourceReqDetails(resourceObject); + resourceObject = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.CP, UserRoleEnum.DESIGNER, true) + .left().value(); + resourceCP = new ResourceReqDetails(resourceObject); + resourceObject = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VL, UserRoleEnum.DESIGNER, true) + .left().value(); + resourceVL = new ResourceReqDetails(resourceObject); + } + + @Test + public void validateDeploymentPlaceHoldersByConfig() throws IOException { + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + Resource resourceObject = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceObject.getDeploymentArtifacts(); + assertNotNull("deploymentArtifacts list is null", deploymentArtifacts); + List listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String resDepArtType : listOfResDepArtTypesFromConfig) { + assertNotNull("placeholder of " + resDepArtType + " type doesn't exist", + deploymentArtifacts.get(resDepArtType)); + } + } + + private void validateToscaArtifactsBeforeAndAfterSFT(ResourceReqDetails resourceDetails) + throws IOException, Exception { + RestResponse componentResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails1); + Component component = ResponseParser.convertResourceResponseToJavaObject(componentResponse.getResponse()); + Map toscaArtifacts = component.getToscaArtifacts(); + for (ArtifactDefinition artifact : toscaArtifacts.values()) { + assertNull(artifact.getEsId()); + } + + componentResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails1, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + component = ResponseParser.convertResourceResponseToJavaObject(componentResponse.getResponse()); + toscaArtifacts = component.getToscaArtifacts(); + + for (ArtifactDefinition artifact : toscaArtifacts.values()) { + assertEquals(artifact.getEsId(), artifact.getUniqueId()); + List> fields = new ArrayList(); + fields.add(new Pair("id", artifact.getEsId())); + List fetchFromTable = CassandraUtils.fetchFromTableQuery("sdcartifact", "resources", fields); + assertTrue(1 == fetchFromTable.size()); + } + } + + @Test + public void validateToscaArtifactsBeforeAndAfterSFT() throws IOException, Exception { + // TODO ADD VF and Service + validateToscaArtifactsBeforeAndAfterSFT(resourceDetails1); + validateToscaArtifactsBeforeAndAfterSFT(resourceCP); + validateToscaArtifactsBeforeAndAfterSFT(resourceVL); + } + + @Test + public void validateToscaPlaceHoldersByConfig() throws IOException, Exception { + List components = new ArrayList<>(); + RestResponse componentGetResponse = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + components.add(ResponseParser.convertResourceResponseToJavaObject(componentGetResponse.getResponse())); + + componentGetResponse = ResourceRestUtils.getResource(resourceCP, sdncDesignerDetails1); + components.add(ResponseParser.convertResourceResponseToJavaObject(componentGetResponse.getResponse())); + + componentGetResponse = ResourceRestUtils.getResource(resourceVF, sdncDesignerDetails1); + components.add(ResponseParser.convertResourceResponseToJavaObject(componentGetResponse.getResponse())); + + componentGetResponse = ResourceRestUtils.getResource(resourceVL, sdncDesignerDetails1); + components.add(ResponseParser.convertResourceResponseToJavaObject(componentGetResponse.getResponse())); + + Service service = AtomicOperationUtils + .createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + componentGetResponse = ServiceRestUtils.getService(service.getUniqueId(), + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + components.add(ResponseParser.parseToObjectUsingMapper(componentGetResponse.getResponse(), Service.class)); + + for (Component component : components) { + Map toscaArtifacts = component.getToscaArtifacts(); + assertNotNull("toscaArtifacts list is null", toscaArtifacts); + List listOfToscaArtTypesFromConfig = Utils.getListOfToscaArtLabels(true); + assertNotNull("tosca artifact types list is null", listOfToscaArtTypesFromConfig); + for (String toscaArtType : listOfToscaArtTypesFromConfig) { + assertNotNull("placeholder of " + toscaArtType + " type doesn't exist", + toscaArtifacts.get(toscaArtType)); + } + } + + } + + // test check configuration of "displayName" field for "heat" type + // deployment artifact + @Test + public void validateDeploymentPlaceHoldersDescriptionOfHeatByConfig() throws IOException { + + Map mapOfDepResArtTypesObjects = getMapOfDepResArtTypesObjects(); + assertNotNull("deployment artifact types list is null", mapOfDepResArtTypesObjects); + Object object = mapOfDepResArtTypesObjects.get("heat"); + if (object instanceof Map) { + Map map = (Map) object; + assertTrue(map.get("displayName").equals("Base HEAT Template")); + } else { + assertTrue("return object does not instance of map", false); + } + } + + @Test + public void addDepResArtEachType() throws Exception { + + String artType; + + addDeploymentArtifactByTypeToResource(resourceDetails1, heatArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatVolArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatNetArtifactDetails); + RestResponse response = ResourceRestUtils.getResource(resourceDetails1.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + List listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String iter : listOfResDepArtTypesFromConfig) { + artType = iter; + verifyDepArtPlaceHoldersByType(artType); + } + } + + @Test + public void checkHeatParametersExistingForEachType() throws Exception { + + String artType; + + addDeploymentArtifactByTypeToResource(resourceDetails1, heatArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatVolArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatNetArtifactDetails); + RestResponse response = ResourceRestUtils.getResource(resourceDetails1.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + List listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String iter : listOfResDepArtTypesFromConfig) { + artType = iter; + verifyDepArtPlaceHoldersByType(artType); + verifyHeatParametersExistance(artType, false); + } + } + + @Test + public void checkHeatParametersExistingForSpecificType() throws Exception { + + String artType; + + addDeploymentArtifactByTypeToResource(resourceDetails1, heatVolArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatNetArtifactDetails); + RestResponse response = ResourceRestUtils.getResource(resourceDetails1.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + List listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String iter : listOfResDepArtTypesFromConfig) { + artType = iter; + if (heatArtifactDetails.getArtifactLabel().equals(iter)) { + verifyHeatParametersExistance(artType, true); + } else { + verifyHeatParametersExistance(artType, false); + } + } + } + + @Test + public void addAndDeleteDepResArtEachType() throws Exception { + + String artType; + + addDeploymentArtifactByTypeToResource(resourceDetails1, heatArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatVolArtifactDetails); + addDeploymentArtifactByTypeToResource(resourceDetails1, heatNetArtifactDetails); + RestResponse response = ResourceRestUtils.getResource(resourceDetails1.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + List listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String iter : listOfResDepArtTypesFromConfig) { + artType = iter; + verifyDepArtPlaceHoldersByType(artType); + } + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, + sdncDesignerDetails1, LifeCycleStatesEnum.CHECKIN); + assertTrue("expected response code in CHECKIN 200", restResponseResource.getErrorCode() == 200); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, sdncDesignerDetails1, + LifeCycleStatesEnum.CHECKOUT); + assertTrue("expected response code in CHECKOUT 200", restResponseResource.getErrorCode() == 200); + + // delete all deployment artifacts + deleteDeploymentArtifactByTypeToResource(resourceDetails1, heatArtifactDetails); + deleteDeploymentArtifactByTypeToResource(resourceDetails1, heatVolArtifactDetails); + deleteDeploymentArtifactByTypeToResource(resourceDetails1, heatNetArtifactDetails); + response = ResourceRestUtils.getResource(resourceDetails1.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + listOfResDepArtTypesFromConfig = Utils.getListOfDepResArtLabels(true); + assertNotNull("deployment artifact types list is null", listOfResDepArtTypesFromConfig); + for (String iter : listOfResDepArtTypesFromConfig) { + artType = iter; + verifyDepArtPlaceHoldersByType(artType); + } + } + + @Test + public void addRemoveAddAgainArtifact() throws Exception { + + // get MAP before upload artifact + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + + ArtifactDefinition artifactDefinition = deploymentArtifacts.get("heat"); + + // validate place holder exist + assertNotNull(artifactDefinition); + + // add artifact + updateArtifactReqDetails = getUpdateArtifactDetails(ArtifactTypeEnum.HEAT.getType()); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + updateArtifactReqDetails, sdncDesignerDetails1, resourceDetails1.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + ArtifactDefinition artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef1 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + + // remove artifact + RestResponse deleteArtifactFromResource = ArtifactRestUtils.deleteInformationalArtifactFromResource( + resourceDetails1.getUniqueId(), updateArtifactReqDetails, sdncDesignerDetails1); + logger.debug( + "addInformationalArtifactToResource response: " + deleteArtifactFromResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + deleteArtifactFromResource.getErrorCode(), + deleteArtifactFromResource.getErrorCode() == 200); + + RestResponse getResourceResp = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + + artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(deleteArtifactFromResource.getResponse()); + assertTrue(artifactDefinitionResponseJavaObject.getArtifactName().isEmpty()); + assertTrue(artifactDefinitionResponseJavaObject.getDescription().isEmpty()); + assertTrue(artifactDefinitionResponseJavaObject.getArtifactChecksum().isEmpty()); + assertTrue(artifactDefinitionResponseJavaObject.getEsId().isEmpty()); + assertTrue(artifactDefinitionResponseJavaObject.getArtifactUUID().isEmpty()); + assertNull(artifactDefinitionResponseJavaObject.getHeatParameters()); + + // add artifact again with different user + addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails1, resourceDetails1.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef2 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + + assertFalse("check artifact checksum", artDef1.getArtifactChecksum().equals(artDef2.getArtifactChecksum())); + assertTrue("check artifact EsId", artDef1.getEsId().equals(artDef2.getEsId())); + assertFalse("check artifact UUID", artDef1.getArtifactUUID().equals(artDef2.getArtifactUUID())); + assertTrue("check UserIdCreator", artDef1.getUserIdCreator().equals(artDef2.getUserIdCreator())); + assertTrue("check UserIdLastUpdater", artDef1.getUserIdLastUpdater().equals(artDef2.getUserIdLastUpdater())); + } + + @Test + public void addUpdateArtifactByType() throws Exception { + + // get MAP before upload artifact + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + + ArtifactDefinition artifactDefinition = deploymentArtifacts.get("heat"); + + // validate place holder exist + assertNotNull(artifactDefinition); + + // add artifact + updateArtifactReqDetails = getUpdateArtifactDetails(ArtifactTypeEnum.HEAT.getType()); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + updateArtifactReqDetails, sdncDesignerDetails1, resourceDetails1.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + ArtifactDefinition artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef1 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, + sdncDesignerDetails1, LifeCycleStatesEnum.CHECKIN); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, sdncDesignerDetails2, + LifeCycleStatesEnum.CHECKOUT); + + // update with different user artifact + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setUniqueId(artifactDefinition.getUniqueId()); + heatArtifactDetails.setArtifactName("2.yaml"); + heatArtifactDetails.setArtifactLabel(artifactDefinition.getArtifactLabel()); + + addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails2, resourceDetails1.getUniqueId(), "heat"); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef2 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + verifyArtDefFields(artDef1, artDef2); + + } + + @Test + public void addUpdateDeleteArtifact() throws Exception { + + // get MAP before upload artifact + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails1, sdncDesignerDetails1); + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + + ArtifactDefinition artifactDefinition = deploymentArtifacts.get("heat"); + + // validate place holder exist + assertNotNull(artifactDefinition); + + updateArtifactReqDetails = getUpdateArtifactDetails(ArtifactTypeEnum.HEAT.getType()); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + updateArtifactReqDetails, sdncDesignerDetails1, resourceDetails1.getUniqueId()); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + ArtifactDefinition artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef1 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, + sdncDesignerDetails1, LifeCycleStatesEnum.CHECKIN); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails1, sdncDesignerDetails2, + LifeCycleStatesEnum.CHECKOUT); + + // update with different user artifact + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setArtifactName("2.yaml"); + + addInformationalArtifactToResource = ArtifactRestUtils.updateInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails2, resourceDetails1.getUniqueId(), "heat"); + logger.debug("addInformationalArtifactToResource response: " + + addInformationalArtifactToResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 200); + + artifactDefinitionResponseJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addInformationalArtifactToResource.getResponse()); + ArtifactDefinition artDef2 = fillArtDefFromResponse(artifactDefinitionResponseJavaObject); + + verifyArtDefFields(artDef1, artDef2); + + RestResponse delteArtifactFromResource = ArtifactRestUtils.deleteInformationalArtifactFromResource( + resourceDetails1.getUniqueId(), heatArtifactDetails, sdncDesignerDetails2); + logger.debug("addInformationalArtifactToResource response: {}", delteArtifactFromResource.getResponseMessage()); + assertTrue("response code is not 200, returned :" + delteArtifactFromResource.getErrorCode(), + delteArtifactFromResource.getErrorCode() == 200); + + } + + @Test + public void addHeatVolArtInvalidExtension() throws Exception { + + heatVolArtifactDetails.setArtifactName("heatVol.txt"); + RestResponse response = getResponseOnAddDeploymentArtifactByTypeToResource(resourceDetails1, + heatVolArtifactDetails); + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name()); + assertEquals("Check response code after upload artifact", errorInfo.getCode(), response.getErrorCode()); + List variables = Arrays.asList(ArtifactTypeEnum.HEAT_VOL.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name(), variables, + response.getResponse()); + } + + @Test + public void addHeatNetArtInvalidExtension() throws Exception { + + heatNetArtifactDetails.setArtifactName("yaml"); + RestResponse response = getResponseOnAddDeploymentArtifactByTypeToResource(resourceDetails1, + heatNetArtifactDetails); + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name()); + assertEquals("Check response code after upload artifact", errorInfo.getCode(), response.getErrorCode()); + List variables = Arrays.asList(ArtifactTypeEnum.HEAT_NET.getType()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION.name(), variables, + response.getResponse()); + } + + @Test + public void checkServiceSecurityTemplateInformationalArtifactsCreation() throws IOException, Exception { + + Either createServiceResponse = AtomicOperationUtils + .createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true); + Map artifacts = null; + ArtifactDefinition securitytemplate = null; + if (createServiceResponse.isLeft()) { + Component component = createServiceResponse.left().value(); + artifacts = component.getArtifacts(); + securitytemplate = artifacts.get("servicesecuritytemplate"); + assertNotNull(securitytemplate); + assertEquals("Service Security Template", securitytemplate.getArtifactDisplayName()); + } else { + logger.debug("checkSecurityTemplateInformationalArtifactsCreation service creation response: " + + createServiceResponse.right().value().getResponseMessage()); + } + } + + @Test + public void checkResourceSecurityTemplateInformationalArtifactsCreation() throws IOException, Exception { + + Resource resource = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.CONTAINER_APPLICATION, ResourceCategoryEnum.APPLICATION_L4_BORDER, + UserRoleEnum.DESIGNER, true).left().value(); + Map artifacts = resource.getArtifacts(); + ArtifactDefinition securitytemplate = artifacts.get("resourcesecuritytemplate"); + assertNotNull(securitytemplate); + assertEquals("Resource Security Template", securitytemplate.getArtifactDisplayName()); + } + + // Benny + @Test + public void serviceSecurityTemplateInformationalArtifact() throws IOException, Exception { + String artifactPlaceHolder = "servicesecuritytemplate"; + Service service = AtomicOperationUtils + .createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + Map artifacts = service.getArtifacts(); + ArtifactDefinition securitytemplate = artifacts.get(artifactPlaceHolder); + assertNotNull(securitytemplate); + assertEquals("Service Security Template", securitytemplate.getArtifactDisplayName()); + assertEquals("OTHER", securitytemplate.getArtifactType()); + assertEquals(artifactPlaceHolder, securitytemplate.getArtifactLabel()); + // Get service + RestResponse getService = ServiceRestUtils.getService(service.getUniqueId(), + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, getService.getErrorCode().intValue()); + service = ResponseParser.parseToObjectUsingMapper(getService.getResponse(), Service.class); + artifacts = service.getArtifacts(); + securitytemplate = artifacts.get(artifactPlaceHolder); + assertNotNull(securitytemplate); + assertEquals("Service Security Template", securitytemplate.getArtifactDisplayName()); + assertEquals("OTHER", securitytemplate.getArtifactType()); + assertEquals(artifactPlaceHolder, securitytemplate.getArtifactLabel()); + } + + @Test + public void resourceSecurityTemplateInformationalArtifacts() throws IOException, Exception { + String artifactPlaceHolder = "resourcesecuritytemplate"; + Resource resource = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.CONTAINER_APPLICATION, ResourceCategoryEnum.APPLICATION_L4_BORDER, + UserRoleEnum.DESIGNER, true).left().value(); + Map artifacts = resource.getArtifacts(); + ArtifactDefinition securitytemplate = artifacts.get("resourcesecuritytemplate"); + assertNotNull(securitytemplate); + assertEquals("Resource Security Template", securitytemplate.getArtifactDisplayName()); + assertEquals("OTHER", securitytemplate.getArtifactType()); + assertEquals(artifactPlaceHolder, securitytemplate.getArtifactLabel()); + // Get resource + RestResponse getresource = ResourceRestUtils.getResource(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), + resource.getUniqueId()); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, getresource.getErrorCode().intValue()); + resource = ResponseParser.parseToObjectUsingMapper(getresource.getResponse(), Resource.class); + artifacts = resource.getArtifacts(); + securitytemplate = artifacts.get(artifactPlaceHolder); + assertNotNull(securitytemplate); + assertEquals("Resource Security Template", securitytemplate.getArtifactDisplayName()); + assertEquals("OTHER", securitytemplate.getArtifactType()); + assertEquals(artifactPlaceHolder, securitytemplate.getArtifactLabel()); + } + + // ================================================ + + @SuppressWarnings("unchecked") + private Map getMapOfDepResArtTypesObjects() throws FileNotFoundException { + + return (Map) Utils.parseYamlConfig("deploymentResourceArtifacts"); + + } + + private void addDeploymentArtifactByTypeToResource(ResourceReqDetails resourceReqDetails, + ArtifactReqDetails artReqDetails) throws IOException, Exception { + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(artReqDetails, + sdncDesignerDetails1, resourceReqDetails.getUniqueId()); + assertTrue("add" + artReqDetails.getArtifactLabel() + " artifact to resource request returned status:" + + response.getErrorCode(), response.getErrorCode() == 200); + } + + private RestResponse getResponseOnAddDeploymentArtifactByTypeToResource(ResourceReqDetails resourceReqDetails, + ArtifactReqDetails artReqDetails) throws IOException, Exception { + + return ArtifactRestUtils.addInformationalArtifactToResource(artReqDetails, sdncDesignerDetails1, + resourceReqDetails.getUniqueId()); + } + + private void deleteDeploymentArtifactByTypeToResource(ResourceReqDetails resourceReqDetails, + ArtifactReqDetails artReqDetails) throws IOException, Exception { + + RestResponse response = ArtifactRestUtils.deleteInformationalArtifactFromResource( + resourceReqDetails.getUniqueId(), artReqDetails, sdncDesignerDetails1); + assertTrue("delete" + artReqDetails.getArtifactLabel() + " artifact to resource request returned status:" + + response.getErrorCode(), response.getErrorCode() == 200); + } + + private void verifyDepArtPlaceHoldersByType(String artType) { + + Map deploymentArtifacts = resource.getDeploymentArtifacts(); + assertNotNull("deployment artifact data is null", deploymentArtifacts.get(artType)); + assertNotNull("deployment artifact data is null", deploymentArtifacts.get(artType).getEsId()); + assertNotNull("deployment artifact data is null", deploymentArtifacts.get(artType).getDescription()); + assertTrue( + "deployment artifact timeout does not equal to default value " + timeOut + " expected " + timeOut + + ", actual - " + deploymentArtifacts.get(artType).getTimeout(), + deploymentArtifacts.get(artType).getTimeout() == timeOut); + assertTrue("deployment artifact label value ", + deploymentArtifacts.get(artType).getArtifactLabel().equals(artType)); + } + + private void verifyHeatParametersExistance(String artType, Boolean isNull) { + Map deploymentArtifacts = resource.getDeploymentArtifacts(); + if (isNull) { + assertNull("heatParameters list for type " + artType + " is not null", + deploymentArtifacts.get(artType).getHeatParameters()); + } else { + assertNotNull("heatParameters list for type " + artType + " is null", + deploymentArtifacts.get(artType).getHeatParameters()); + } + } + + private void verifyArtDefFields(ArtifactDefinition artDef1, ArtifactDefinition artDef2) { + + assertFalse("check artifact checksum", artDef1.getArtifactChecksum().equals(artDef2.getArtifactChecksum())); + assertFalse("check artifact EsId", artDef1.getEsId().equals(artDef2.getEsId())); + assertFalse("check artifact UUID", artDef1.getArtifactUUID().equals(artDef2.getArtifactUUID())); + assertTrue("check UserIdCreator", artDef1.getUserIdCreator().equals(artDef2.getUserIdCreator())); + assertFalse("check UserIdLastUpdater", artDef1.getUserIdLastUpdater().equals(artDef2.getUserIdLastUpdater())); + + } + + private ArtifactDefinition fillArtDefFromResponse(ArtifactDefinition artifactDefinitionResponseJavaObject) { + ArtifactDefinition artDef = new ArtifactDefinition(); + artDef.setArtifactChecksum(artifactDefinitionResponseJavaObject.getArtifactChecksum()); + artDef.setEsId(artifactDefinitionResponseJavaObject.getEsId()); + artDef.setArtifactUUID(artifactDefinitionResponseJavaObject.getArtifactUUID()); + artDef.setUserIdCreator(artifactDefinitionResponseJavaObject.getUserIdCreator()); + artDef.setUserIdLastUpdater(artifactDefinitionResponseJavaObject.getUserIdLastUpdater()); + return artDef; + } + + private ArtifactReqDetails getUpdateArtifactDetails(String artType) throws IOException, Exception { + String ext = heatExtension; + String sourceDir = config.getResourceConfigDir(); + String testResourcesPath = sourceDir + File.separator + folderName; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + logger.debug("listFileName: {}", listFileName.toString()); + + String payload = FileUtils.loadPayloadFile(listFileName, ext, true); + ArtifactReqDetails updateArtifactReqDetails = ElementFactory.getDefaultDeploymentArtifactForType(artType); + updateArtifactReqDetails.setPayload(payload); + updateArtifactReqDetails.setArtifactName("1.yaml"); + return updateArtifactReqDetails; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateArtResponse.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateArtResponse.java new file mode 100644 index 0000000000..01169630a4 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateArtResponse.java @@ -0,0 +1,631 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; +import org.yaml.snakeyaml.Yaml; + +public class ValidateArtResponse extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + protected String serviceVersion; + + public ValidateArtResponse() { + super(name, ArtifactServletTest.class.getName()); + + } + + protected final String pathToFile = "heatArtifactParameters"; + protected final String heatWithValidParams = "heatWithValidParams.yaml"; + protected final String heatWithParamsMissingDefault = "heatWithParamsMissingDefault.yaml"; + protected final String heatWithParamsMissingDesc = "heatWithParamsMissingDesc.yaml"; + protected final String heatWithParamsMissingType = "heatWithParamsMissingType.yaml"; + protected final String importNoDerivedFromFile = "myComputeDerivedFromNotExists.yml"; + protected final String decodedPayload = "decodedPayload"; + protected final String encodedPayload = "encodedPayload"; + + protected Resource resourceDetailsObj; + protected ResourceReqDetails resourceDetails; + protected User sdncDesignerDetails; + + @BeforeMethod + public void init() throws Exception { + + resourceDetailsObj = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resourceDetails = new ResourceReqDetails(resourceDetailsObj); + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + } + + @Test + public void compareParamtersVsYaml() throws Exception { + + // select file to upload + + Map filePayload = selectFileToUpload(pathToFile, heatWithValidParams); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + protected void assertnull(String string, boolean equals) { + // TODO Auto-generated method stub + + } + + public Map extractSingleParameter(Map curr) { + Map innerMap = new HashMap(); + if (curr.containsKey("description")) { + innerMap.put("description", curr.get("description")); + } + + if (curr.containsKey("defaultValue")) { + innerMap.put("default", curr.get("defaultValue")); + } else { + // System.out.println("kuku"); + } + innerMap.put("type", curr.get("type")); + return innerMap; + } + + public Map createMapFromYaml(String payload) { + ArrayList parametersList = new ArrayList(); + + Yaml yaml = new Yaml(); + + Map result = (Map) yaml.load(payload); + Map paramters = (Map) result.get("parameters"); + + for (Map.Entry entry : paramters.entrySet()) { + Map origInnerMap = (Map) entry.getValue(); + + if (origInnerMap.containsKey("label")) { + origInnerMap.remove("label"); + paramters.remove(entry); + paramters.put(entry.getKey(), origInnerMap); + } + } + return paramters; + } + + public Map> jsonToMap(RestResponse addInformationalArtifactToResource, + String section2extract, String createKeyMapBy) { + Map JsonToMap = new HashMap(); + JsonToMap = (Map) ResponseParser.parseToObject(addInformationalArtifactToResource.getResponse(), + JsonToMap.getClass()); + + List> listOfParamters = (List>) JsonToMap.get(section2extract); + Map> mapOfActualParameters = new HashMap>(); + + for (Map curr : listOfParamters) { + Map innerMap = extractSingleParameter(curr); + + mapOfActualParameters.put(curr.get(createKeyMapBy), innerMap); + } + return mapOfActualParameters; + } + + public Map selectFileToUpload(String pathToFile, String fileName) throws IOException { + String sourceDir = config.getResourceConfigDir(); + String testResourcesPath = sourceDir + File.separator + pathToFile; + String file = fileName; + Map filePayload = new HashMap(); + String payload = Decoder.readFileToString(testResourcesPath + File.separator + file); + filePayload.put(decodedPayload, payload); + filePayload.put(encodedPayload, Decoder.encode(payload.getBytes())); + + return filePayload; + } + + @Test + public void missingDescParam() throws Exception { + + // select file to upload + + Map filePayload = selectFileToUpload(pathToFile, heatWithParamsMissingDesc); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void missingDefaultParam() throws Exception { + + // select file to upload + + Map filePayload = selectFileToUpload(pathToFile, heatWithParamsMissingDefault); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void missingTypeParam() throws Exception { + + // select file to upload + + Map filePayload = selectFileToUpload(pathToFile, heatWithParamsMissingType); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // System.out.println(addInformationalArtifactToResource); + AssertJUnit.assertTrue( + "response code is not 400, returned :" + addInformationalArtifactToResource.getErrorCode(), + addInformationalArtifactToResource.getErrorCode() == 400); + + } + + @Test + public void updateValueParam() throws Exception { + + String updateValueParam = "changed"; + + Map filePayload = selectFileToUpload(pathToFile, heatWithValidParams); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + // System.out.println(resourceGetResponse.getResponse().toString()); + String atifactUniqueId = ResponseParser + .getValueFromJsonResponse(addInformationalArtifactToResource.getResponse(), "uniqueId"); + + ArtifactReqDetails artifacJavaObject = ResponseParser + .convertArtifactReqDetailsToJavaObject(addInformationalArtifactToResource.getResponse()); + List heatParameters2 = artifacJavaObject.getHeatParameters(); + + for (HeatParameterDefinition heatParameterDefinition : heatParameters2) { + heatParameterDefinition.setCurrentValue(updateValueParam); + } + artifacJavaObject.setHeatParameters(heatParameters2); + artifacJavaObject.setPayloadData(null); + + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateDeploymentArtifactToResource( + artifacJavaObject, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // verify change in update response + + ArtifactDefinition ArtifactDefinitionRespJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(updateInformationalArtifactToResource.getResponse()); + List heatParameters = ArtifactDefinitionRespJavaObject.getHeatParameters(); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // verify change in getResource + + resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + deploymentArtifacts.get(heatArtifactDetails.getArtifactName()); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void updateValueParamMissingDefault() throws Exception { + + String updateValueParam = "changed"; + + Map filePayload = selectFileToUpload(pathToFile, heatWithParamsMissingDefault); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + // System.out.println(resourceGetResponse.getResponse().toString()); + String atifactUniqueId = ResponseParser + .getValueFromJsonResponse(addInformationalArtifactToResource.getResponse(), "uniqueId"); + + ArtifactReqDetails artifacJavaObject = ResponseParser + .convertArtifactReqDetailsToJavaObject(addInformationalArtifactToResource.getResponse()); + List heatParameters2 = artifacJavaObject.getHeatParameters(); + + for (HeatParameterDefinition heatParameterDefinition : heatParameters2) { + heatParameterDefinition.setCurrentValue(updateValueParam); + } + artifacJavaObject.setHeatParameters(heatParameters2); + artifacJavaObject.setPayloadData(null); + + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateDeploymentArtifactToResource( + artifacJavaObject, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // verify change in update response + + ArtifactDefinition ArtifactDefinitionRespJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(updateInformationalArtifactToResource.getResponse()); + List heatParameters = ArtifactDefinitionRespJavaObject.getHeatParameters(); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // verify change in getResource + + resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + deploymentArtifacts.get(heatArtifactDetails.getArtifactName()); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void updateValueParamNull() throws Exception { + + String updateValueParam = null; + + Map filePayload = selectFileToUpload(pathToFile, heatWithValidParams); + + // upload HEAT file and save JSON response + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + // System.out.println(resourceGetResponse.getResponse().toString()); + String atifactUniqueId = ResponseParser + .getValueFromJsonResponse(addInformationalArtifactToResource.getResponse(), "uniqueId"); + + ArtifactReqDetails artifacJavaObject = ResponseParser + .convertArtifactReqDetailsToJavaObject(addInformationalArtifactToResource.getResponse()); + List heatParameters2 = artifacJavaObject.getHeatParameters(); + + for (HeatParameterDefinition heatParameterDefinition : heatParameters2) { + heatParameterDefinition.setCurrentValue(updateValueParam); + } + artifacJavaObject.setHeatParameters(heatParameters2); + artifacJavaObject.setPayloadData(null); + + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateDeploymentArtifactToResource( + artifacJavaObject, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // verify change in update response + ArtifactDefinition ArtifactDefinitionRespJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(updateInformationalArtifactToResource.getResponse()); + List heatParameters = ArtifactDefinitionRespJavaObject.getHeatParameters(); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + // String verify = updateValueParam; + if (heatParameterDefinition.getDefaultValue() != null) { + AssertJUnit.assertTrue( + heatParameterDefinition.getDefaultValue().equals(heatParameterDefinition.getCurrentValue())); + } else { + AssertJUnit.assertNull("verification failed", heatParameterDefinition.getCurrentValue()); + } + } + + // verify change in getResource + resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + deploymentArtifacts.get(heatArtifactDetails.getArtifactName()); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + // String verify = updateValueParam; + if (heatParameterDefinition.getDefaultValue() != null) { + AssertJUnit.assertTrue( + heatParameterDefinition.getDefaultValue().equals(heatParameterDefinition.getCurrentValue())); + } else { + AssertJUnit.assertNull("verification failed", heatParameterDefinition.getCurrentValue()); + } + } + + // create MAP from received JSON + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void updateValueParamEmpty() throws Exception { + + String updateValueParam = ""; + + Map filePayload = selectFileToUpload(pathToFile, heatWithValidParams); + + // upload HEAT file and save JSON response + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + // System.out.println(resourceGetResponse.getResponse().toString()); + String atifactUniqueId = ResponseParser + .getValueFromJsonResponse(addInformationalArtifactToResource.getResponse(), "uniqueId"); + + ArtifactReqDetails artifacJavaObject = ResponseParser + .convertArtifactReqDetailsToJavaObject(addInformationalArtifactToResource.getResponse()); + List heatParameters2 = artifacJavaObject.getHeatParameters(); + + for (HeatParameterDefinition heatParameterDefinition : heatParameters2) { + heatParameterDefinition.setCurrentValue(updateValueParam); + } + artifacJavaObject.setHeatParameters(heatParameters2); + artifacJavaObject.setPayloadData(null); + + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateDeploymentArtifactToResource( + artifacJavaObject, sdncDesignerDetails, resourceDetails.getUniqueId()); + + // verify change in update response + + ArtifactDefinition ArtifactDefinitionRespJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(updateInformationalArtifactToResource.getResponse()); + List heatParameters = ArtifactDefinitionRespJavaObject.getHeatParameters(); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // verify change in getResource + + resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + deploymentArtifacts.get(heatArtifactDetails.getArtifactName()); + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + String verify = updateValueParam; + AssertJUnit.assertTrue("verification failed", verify.equals(heatParameterDefinition.getCurrentValue())); + } + + // create MAP from received JSON + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + + @Test + public void onlyValueParamPermited() throws Exception { + + Map filePayload = selectFileToUpload(pathToFile, heatWithValidParams); + + // upload HEAT file and save JSON response + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatArtifactDetails.setPayload(filePayload.get(encodedPayload)); + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails, resourceDetails.getUniqueId()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + // System.out.println(resourceGetResponse.getResponse().toString()); + String atifactUniqueId = ResponseParser + .getValueFromJsonResponse(addInformationalArtifactToResource.getResponse(), "uniqueId"); + + ArtifactReqDetails artifacJavaObject = ResponseParser + .convertArtifactReqDetailsToJavaObject(addInformationalArtifactToResource.getResponse()); + List heatParameters2 = artifacJavaObject.getHeatParameters(); + + for (HeatParameterDefinition heatParameterDefinition : heatParameters2) { + heatParameterDefinition.setDefaultValue("changed"); + heatParameterDefinition.setName("changed"); + heatParameterDefinition.setDescription("changed"); + heatParameterDefinition.setType("changed"); + heatParameterDefinition.setCurrentValue("changed"); + } + artifacJavaObject.setHeatParameters(heatParameters2); + artifacJavaObject.setPayloadData(null); + + RestResponse updateInformationalArtifactToResource = ArtifactRestUtils.updateDeploymentArtifactToResource( + artifacJavaObject, sdncDesignerDetails, resourceDetails.getUniqueId()); + + resourceGetResponse = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails); + + // create MAP from received JSON + + String section2extract = "heatParameters"; + String createKeyMapBy = "name"; + Map> mapOfActualParameters = jsonToMap(addInformationalArtifactToResource, + section2extract, createKeyMapBy); + + // Prepare map to validate JS + + Map paramters = createMapFromYaml(filePayload.get(decodedPayload)); + + // compare MAPs + + ResourceValidationUtils.compareElements(mapOfActualParameters, paramters); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsFromUI.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsFromUI.java new file mode 100644 index 0000000000..c22dcb96d4 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsFromUI.java @@ -0,0 +1,444 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +// +//import java.util.Arrays; +//import java.util.List; +// +//import org.junit.Rule; +//import org.junit.rules.TestName; +//import org.testng.AssertJUnit; +//import org.testng.annotations.Test; +// +//import org.openecomp.sdc.be.dao.api.ActionStatus; +//import org.openecomp.sdc.be.model.ArtifactDefinition; +//import org.openecomp.sdc.be.model.ComponentInstance; +//import org.openecomp.sdc.be.model.HeatParameterDefinition; +//import org.openecomp.sdc.be.model.Resource; +//import org.openecomp.sdc.be.model.Service; +//import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +//import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +//import org.openecomp.sdc.ci.tests.datatypes.enums.RespJsonKeysEnum; +//import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +//import org.openecomp.sdc.ci.tests.preRequisites.HeatEnvBaseTest; +//import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +//import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +//import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +//import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +//import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +//import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +// +//public class ValidateHeatArtFieldsFromUI extends HeatEnvBaseTest { +public class ValidateHeatArtFieldsFromUI { + // + // + // + // private static final String heatExtension = "yaml"; + // private static final String yangXmlExtension = "xml"; + // private static final String muranoPkgExtension = "zip"; + // private final String folderName= "yamlFieldsValidation"; + // + // + // private final String uuidString = + // RespJsonKeysEnum.UUID.getRespJsonKeyName().toString(); + // + // public ValidateHeatArtFieldsFromUI() { + // super(name, ValidateHeatArtFieldsFromUI.class.getName()); + // } + // + // @Rule + // public static TestName name = new TestName(); + // + // + // @Test + // public void heatEnvValidateHeatArtFiledTypes_UpdateFailed() throws + // Exception { + // + // //get relevant service + // RestResponse serviceGetResponse = + // ServiceRestUtils.getService(serviceDetails2, sdncDesignerDetails); + // Service service = + // ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + // List resourceInstances = + // service.getComponentInstances(); + // ComponentInstance resourceInstance = resourceInstances.get(0); + // + // + // String defaultParam = null; + // + // //update heatEnv with invalid value in number field + // + // ArtifactDefinition artifact = getCurrentArtifactDefinitionFromService(); + // String currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "home_number", "Tel Aviv"); + // ArtifactReqDetails artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // RestResponse res = ArtifactRestUtils.updateDeploymentArtifactToRI(artReq, + // sdncDesignerDetails, resourceInstance.getUniqueId(), + // service.getUniqueId()); + // + // // validate negative response + // List variables = Arrays.asList("HEAT_ENV", "number", + // "home_number"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // artifact = getCurrentArtifactDefinitionFromService(); + // String currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "home_number"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // + // //update heatEnv with invalid value in boolean field + // + // artifact = getCurrentArtifactDefinitionFromService(); + // currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "private_building", "Tel Aviv"); + // artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // res = ArtifactRestUtils.updateDeploymentArtifactToRI(artReq, + // sdncDesignerDetails, resourceInstance.getUniqueId(), + // service.getUniqueId()); + // + // // validate negative response + // variables = Arrays.asList("HEAT_ENV", "boolean", "private_building"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // artifact = getCurrentArtifactDefinitionFromService(); + // currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "private_building"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // + // + // + // + // //update heatEnv with invalid value in boolean field + // + // artifact = getCurrentArtifactDefinitionFromService(); + // currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "city_name", "\uC2B5"); + // artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // res = ArtifactRestUtils.updateDeploymentArtifactToRI(artReq, + // sdncDesignerDetails, resourceInstance.getUniqueId(), + // service.getUniqueId()); + // // validate negative response + // variables = Arrays.asList("HEAT_ENV", "string", "city_name"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromService(); + // currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "city_name"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // } + // + // @Test + // public void heatValidateHeatArtFiledTypes_UpdateFailed() throws Exception + // { + // + // + // RestResponse checkOutResponse = + // LifecycleRestUtils.changeResourceState(resourceSC, sdncDesignerDetails, + // LifeCycleStatesEnum.CHECKOUT); + // AssertJUnit.assertTrue("response code is not 200, returned: " + + // checkOutResponse.getErrorCode(),checkOutResponse.getErrorCode() == 200); + // //get relevant service + // RestResponse resourceGetResponse = + // ResourceRestUtils.getResource(resourceSC, sdncDesignerDetails); + // Resource resource = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // + // //update heatEnv with invalid value in number field + // + // ArtifactDefinition artifact = getCurrentArtifactDefinitionFromResource(); + // String currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "home_number", "Tel Aviv"); + // ArtifactReqDetails artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // RestResponse res = + // ArtifactRestUtils.updateInformationalArtifactToResource(artReq, + // sdncDesignerDetails, resource.getUniqueId()); + // // validate negative response + // List variables = Arrays.asList("HEAT", "number", "home_number"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // String currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "home_number"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // + // + // //update heatEnv with invalid value in boolean field + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "private_building", "Tel Aviv"); + // artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // res = ArtifactRestUtils.updateDeploymentArtifactToResource(artReq, + // sdncDesignerDetails, resource.getUniqueId()); + // // validate negative response + // variables = Arrays.asList("HEAT", "boolean", "private_building"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // + // currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "private_building"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // + // + // //update heatEnv with invalid value in boolean field + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // currentHeatEnvParamBeforeUpdate = replaceHeatParamsValue(artifact, + // "city_name", "\uC2B5"); + // + // artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // res = ArtifactRestUtils.updateDeploymentArtifactToResource(artReq, + // sdncDesignerDetails, resource.getUniqueId()); + // // validate negative response + // variables = Arrays.asList("HEAT", "string", "city_name"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + // variables, res.getResponse()); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // currentHeatEnvParamAfterUpdate = getHeatParamsValue(artifact, + // "city_name"); + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBeforeUpdate, + // currentHeatEnvParamBeforeUpdate.equals(currentHeatEnvParamAfterUpdate)); + // + // } + // + // @Test + // public void heatEnvValidateHeatArtFiledTypes_boolNormalization_suc() + // throws Exception { + // + // //get relevant service + // RestResponse serviceGetResponse = + // ServiceRestUtils.getService(serviceDetails2, sdncDesignerDetails); + // Service service = + // ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + // List resourceInstances = + // service.getComponentInstances(); + // ComponentInstance resourceInstance = resourceInstances.get(0); + // + // String defaultParam = null; + // String currentHeatEnvParamBefore = null; + // String currentHeatEnvParamAfter = null; + // + // + // List listOfBoolValuesToValidate = Arrays.asList("T", "on", "1", + // "yes", "y"); + // + // for (String element : listOfBoolValuesToValidate) { + // + // //update heatEnv with invalid value in boolean field + // + // ArtifactDefinition artifact = getCurrentArtifactDefinitionFromService(); + // List heatParameters = + // artifact.getHeatParameters(); + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals("private_building")){ + // defaultParam = param.getDefaultValue(); + // currentHeatEnvParamBefore = param.getCurrentValue(); + // param.setCurrentValue(element); + // } + // } + // artifact.setHeatParameters(heatParameters); + // ArtifactReqDetails artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // RestResponse res = ArtifactRestUtils.updateDeploymentArtifactToRI(artReq, + // sdncDesignerDetails, resourceInstance.getUniqueId(), + // service.getUniqueId()); + // AssertJUnit.assertTrue("response code is not 200, returned: " + + // res.getErrorCode(), res.getErrorCode() == 200); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromService(); + // heatParameters = artifact.getHeatParameters(); + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals("private_building")){ + // currentHeatEnvParamAfter = param.getCurrentValue(); + // } + // } + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBefore, currentHeatEnvParamAfter.equals("true")); + // + // } + // + // } + // + // + // @Test + // public void heatValidateHeatArtFiledTypes_boolNormalization_suc() throws + // Exception { + // + // RestResponse checkOutResponse = + // LifecycleRestUtils.changeResourceState(resourceSC, sdncDesignerDetails, + // LifeCycleStatesEnum.CHECKOUT); + // AssertJUnit.assertTrue("response code is not 200, returned: " + + // checkOutResponse.getErrorCode(),checkOutResponse.getErrorCode() == 200); + // //get relevant service + // RestResponse resourceGetResponse = + // ResourceRestUtils.getResource(resourceSC, sdncDesignerDetails); + // Resource resource = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // + // + // String defaultParam = null; + // String currentHeatEnvParamBefore = null; + // String currentHeatEnvParamAfter = null; + // + // + // List listOfBoolValuesToValidate = Arrays.asList("T", "on", "1", + // "yes", "y"); + // + // for (String element : listOfBoolValuesToValidate) { + // + // //update heatEnv with invalid value in boolean field + // + // ArtifactDefinition artifact = getCurrentArtifactDefinitionFromResource(); + // List heatParameters = + // artifact.getHeatParameters(); + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals("private_building")){ + // defaultParam = param.getDefaultValue(); + // currentHeatEnvParamBefore = param.getCurrentValue(); + // param.setCurrentValue(element); + // } + // } + // artifact.setHeatParameters(heatParameters); + // ArtifactReqDetails artReq = + // ResponseParser.convertArtifactDefinitionToArtifactReqDetailsObject(artifact); + // RestResponse res = + // ArtifactRestUtils.updateInformationalArtifactToResource(artReq, + // sdncDesignerDetails, resource.getUniqueId()); + // AssertJUnit.assertTrue("response code is not 200, returned: " + + // res.getErrorCode(), res.getErrorCode() == 200); + // + // //validate current value not affected + // + // artifact = getCurrentArtifactDefinitionFromResource(); + // heatParameters = artifact.getHeatParameters(); + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals("private_building")){ + // currentHeatEnvParamAfter = param.getCurrentValue(); + // } + // } + // AssertJUnit.assertTrue("HeatEnvParam was not updated: " + + // currentHeatEnvParamBefore, currentHeatEnvParamAfter.equals("true")); + // + // } + // + // } + // + // + // private ArtifactDefinition getCurrentArtifactDefinitionFromResource() + // throws Exception { + // + // RestResponse resourceGetResponse = + // ResourceRestUtils.getResource(resourceSC, sdncDesignerDetails); + // Resource resource = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // + // ArtifactDefinition artifactDefinition = + // resource.getDeploymentArtifacts().get("heat"); + // + // + // return artifactDefinition; + // + // } + // + // + // private ArtifactDefinition getCurrentArtifactDefinitionFromService() + // throws Exception { + // + // RestResponse serviceGetResponse = + // ServiceRestUtils.getService(serviceDetails2, sdncDesignerDetails); + // Service service = + // ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + // ArtifactDefinition artifactDefinition = new ArtifactDefinition(); + // artifactDefinition = + // service.getComponentInstances().get(0).getDeploymentArtifacts().get("heatenv"); + // + // + // return artifactDefinition; + // + // } + // + // private String replaceHeatParamsValue(ArtifactDefinition artifact, String + // paramName, String paramValue) { + // String defaultParam; + // String currentHeatEnvParam = null; + // List heatParameters = + // artifact.getHeatParameters(); + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals(paramName)){ + // defaultParam = param.getDefaultValue(); + // currentHeatEnvParam = param.getCurrentValue(); + // param.setCurrentValue(paramValue); + // } + // } + // artifact.setHeatParameters(heatParameters); + // return currentHeatEnvParam; + // } + // + // private String getHeatParamsValue(ArtifactDefinition artifact, + // String paramName) { + // List heatParameters = + // artifact.getHeatParameters(); + // String currentHeatEnvParamValue = null; + // for(HeatParameterDefinition param : heatParameters){ + // if (param.getName().equals(paramName)){ + // currentHeatEnvParamValue = param.getCurrentValue(); + // } + // } + // return currentHeatEnvParamValue; + // } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsTypes.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsTypes.java new file mode 100644 index 0000000000..09cda0b73c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/artifacts/ValidateHeatArtFieldsTypes.java @@ -0,0 +1,176 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.artifacts; + +import java.util.Arrays; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.RespJsonKeysEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ArtifactValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +public class ValidateHeatArtFieldsTypes extends ComponentBaseTest { + + protected User sdncDesignerDetails; + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + + private static final String heatExtension = "yaml"; + private static final String yangXmlExtension = "xml"; + private static final String muranoPkgExtension = "zip"; + private final String folderName = "yamlFieldsValidation"; + + private final String uuidString = RespJsonKeysEnum.UUID.getRespJsonKeyName().toString(); + + public ValidateHeatArtFieldsTypes() { + super(name, ValidateHeatArtFieldsTypes.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + + @Test + public void validateHeatArtFiledTypes() throws Exception { + + // get relevant resource and service + + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + resourceDetails = ElementFactory.getDefaultResource(); + + RestResponse response = ResourceRestUtils.createResource(resourceDetails, sdncDesignerDetails); + AssertJUnit.assertTrue("create request returned status:" + response.getErrorCode(), + response.getErrorCode() == 201); + + // add artifact to resource1 + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + List listOfArtifactFromFolder = ArtifactValidationUtils.getListOfArtifactFromFolder(folderName); + for (int i = 0; i < listOfArtifactFromFolder.size(); i++) { + heatArtifactDetails = ArtifactValidationUtils.replaceDefaultArtWithArtFromList(heatArtifactDetails, + heatExtension, folderName, i); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails, + resourceDetails.getUniqueId()); + + if (heatArtifactDetails.getArtifactName().contains("bool")) { + if (heatArtifactDetails.getArtifactName().contains("negative")) { + // validate negative response + List variables = Arrays.asList("HEAT", "boolean", "city_name"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + variables, response.getResponse()); + } + if (heatArtifactDetails.getArtifactName().contains("positive")) { + AssertJUnit.assertTrue( + "add HEAT artifact to resource request returned status:" + response.getErrorCode() + + " fileName: " + heatArtifactDetails.getArtifactName(), + response.getErrorCode() == 200); + ArtifactDefinition artifactDefinitionJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(response.getResponse()); + List heatParameters = artifactDefinitionJavaObject.getHeatParameters(); + String currentValue = null; + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + if (heatParameterDefinition.getName().equals("city_name")) { + currentValue = heatParameterDefinition.getCurrentValue(); + } + } + if (heatArtifactDetails.getArtifactName().contains("true")) { + AssertJUnit.assertTrue(currentValue.equals("true")); + } + if (heatArtifactDetails.getArtifactName().contains("false")) { + AssertJUnit.assertTrue(currentValue.equals("false")); + } + RestResponse deleteInformationalArtifactFromResource = ArtifactRestUtils + .deleteInformationalArtifactFromResource(resourceDetails.getUniqueId(), heatArtifactDetails, + sdncDesignerDetails); + AssertJUnit.assertTrue( + "delete HEAT artifact from resource request returned status:" + + deleteInformationalArtifactFromResource.getErrorCode(), + deleteInformationalArtifactFromResource.getErrorCode() == 200); + } + + } else if (heatArtifactDetails.getArtifactName().contains("number")) { + if (heatArtifactDetails.getArtifactName().contains("negative")) { + // validate negative response + List variables = Arrays.asList("HEAT", "number", "city_name"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + variables, response.getResponse()); + } + if (heatArtifactDetails.getArtifactName().contains("positive")) { + AssertJUnit.assertTrue( + "add HEAT artifact to resource request returned status:" + response.getErrorCode() + + " fileName: " + heatArtifactDetails.getArtifactName(), + response.getErrorCode() == 200); + } + + } else if (heatArtifactDetails.getArtifactName().contains("string")) { + if (heatArtifactDetails.getArtifactName().contains("negative")) { + // validate negative response + List variables = Arrays.asList("HEAT", "string", "city_name"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_VALUE.name(), + variables, response.getResponse()); + } + if (heatArtifactDetails.getArtifactName().contains("positive")) { + AssertJUnit.assertTrue( + "add HEAT artifact to resource request returned status:" + response.getErrorCode() + + " fileName: " + heatArtifactDetails.getArtifactName(), + response.getErrorCode() == 200); + } + + } + + else if (heatArtifactDetails.getArtifactName().contains("unsupported")) { + + // validate negative response + List variables = Arrays.asList("HEAT", "number123"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_HEAT_PARAMETER_TYPE.name(), + variables, response.getResponse()); + + } + + else { + AssertJUnit.assertTrue( + "add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + } + } + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/attribute/ComponentInstanceAttributeTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/attribute/ComponentInstanceAttributeTest.java new file mode 100644 index 0000000000..58e27177d1 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/attribute/ComponentInstanceAttributeTest.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.attribute; + +import static org.junit.Assert.assertEquals; +import static org.openecomp.sdc.common.datastructure.FunctionalInterfaces.swallowException; + +import java.io.File; +import java.util.function.Function; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.testng.annotations.Test; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +public class ComponentInstanceAttributeTest extends ComponentBaseTest { + + public static Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + @Rule + public static TestName name = new TestName(); + + public ComponentInstanceAttributeTest() { + super(name, ComponentInstanceAttributeTest.class.getName()); + } + + @Test + public void testUpdateAttributeOnResourceInstance() { + // Prepare VF with vfc instance with Attributes + String testResourcesPath = config.getResourceConfigDir() + File.separator + "importToscaResourceByCreateUrl"; + final Resource vfcWithAttributes = AtomicOperationUtils.importResource(testResourcesPath, "CPWithAttributes.yml").left().value(); + swallowException(() -> AtomicOperationUtils.changeComponentState(vfcWithAttributes, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, false)); + Resource vf = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, false).left().value(); + ComponentInstance vfcInstance = AtomicOperationUtils.addComponentInstanceToComponentContainer(vfcWithAttributes, vf).left().value(); + + // util method to get the specific attribute from the vf + Function attributeGetter = resourceVf -> resourceVf.getComponentInstancesAttributes().values().iterator().next().stream().filter(att -> att.getName().equals("private_address")).findAny().get(); + // update attribute on vfc instance + final Resource vfWithInsatncePreUpdate = swallowException(() -> (Resource) AtomicOperationUtils.getCompoenntObject(vf, UserRoleEnum.DESIGNER)); + ComponentInstanceAttribute attributeOfRI = attributeGetter.apply(vfWithInsatncePreUpdate); + final String newAttValue = "NewValue"; + attributeOfRI.setValue(newAttValue); + String body = gson.toJson(attributeOfRI); + String url = String.format(Urls.UPDATE_ATTRIBUTE_ON_RESOURCE_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), ComponentTypeEnum.findParamByType(ComponentTypeEnum.RESOURCE), vf.getUniqueId(), vfcInstance.getUniqueId()); + swallowException(() -> BaseRestUtils.sendPost(url, body, UserRoleEnum.DESIGNER.getUserId(), BaseRestUtils.acceptHeaderData)); + // Retrieve updated vf and verify attribute was updated + final Resource vfWithInsatncePostUpdate = swallowException(() -> (Resource) AtomicOperationUtils.getCompoenntObject(vf, UserRoleEnum.DESIGNER)); + ComponentInstanceAttribute updatedAttribute = attributeGetter.apply(vfWithInsatncePostUpdate); + assertEquals(updatedAttribute.getValue(), newAttValue); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CatalogDataApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CatalogDataApiTest.java new file mode 100644 index 0000000000..d9df79350b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CatalogDataApiTest.java @@ -0,0 +1,234 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class CatalogDataApiTest extends ComponentBaseTest { + + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + + @Rule + public static TestName name = new TestName(); + protected User user; + protected RestResponse res1; + protected RestResponse res2; + protected RestResponse svc1; + protected ResourceReqDetails resourceDetails1; + protected ResourceReqDetails resourceDetails2; + protected ServiceReqDetails svcDetails1; + + public CatalogDataApiTest() { + super(name, CatalogDataApiTest.class.getName()); + } + + @BeforeMethod + public void setUp() throws Exception { + user = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + resourceDetails1 = buildResourceDetails(user, "TestResource1"); + resourceDetails2 = buildResourceDetails(user, "TestResource2"); + svcDetails1 = buildServiceDetails("TestService1"); + + res1 = createResource(user, resourceDetails1); + AssertJUnit.assertEquals("create resorce failed", 201, res1.getErrorCode().intValue()); + resourceDetails1.setUniqueId(ResponseParser.getUniqueIdFromResponse(res1)); + resourceDetails2.setVersion(ResponseParser.getVersionFromResponse(res1)); + + res2 = createResource(user, resourceDetails2); + AssertJUnit.assertEquals("create resorce failed", 201, res2.getErrorCode().intValue()); + resourceDetails2.setUniqueId(ResponseParser.getUniqueIdFromResponse(res2)); + resourceDetails2.setVersion(ResponseParser.getVersionFromResponse(res2)); + + svc1 = createService(user, svcDetails1); + AssertJUnit.assertEquals("create resorce failed", 201, svc1.getErrorCode().intValue()); + svcDetails1.setUniqueId(ResponseParser.convertServiceResponseToJavaObject(svc1.getResponse()).getUniqueId()); + svcDetails1.setVersion(ResponseParser.convertServiceResponseToJavaObject(svc1.getResponse()).getVersion()); + } + + @AfterMethod + public void tearDown() throws Exception { + deleteResource(resourceDetails1.getUniqueId(), user.getUserId()); + deleteResource(resourceDetails2.getUniqueId(), user.getUserId()); + deleteService(svcDetails1.getUniqueId(), user); + } + + // Keep 1 + @Test + public void getCatalogData() throws Exception { + + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails1, user, "0.1", + LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("check in operation failed", 200, checkInResponse.getErrorCode().intValue()); + + RestResponse res = CatalogRestUtils.getCatalog(user.getUserId()); + String json = res.getResponse(); + JSONObject jsonResp = (JSONObject) JSONValue.parse(json); + JSONArray resources = (JSONArray) jsonResp.get("resources"); + JSONArray services = (JSONArray) jsonResp.get("services"); + + // Verify all the expected resources received. + AssertJUnit.assertTrue("check resource1 is in response", + isComponentInArray(resourceDetails1.getUniqueId(), resources)); + AssertJUnit.assertTrue("check resource2 is in response", + isComponentInArray(resourceDetails2.getUniqueId(), resources)); + AssertJUnit.assertTrue("check service1 is in response", + isComponentInArray(svcDetails1.getUniqueId(), services)); + + } + + protected void deleteResource(String resourceUniqueId, String httpCspUserId) throws Exception { + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResource(resourceUniqueId, httpCspUserId); + + } + + protected RestResponse createResource(User user, ResourceReqDetails resourceDetails) throws Exception { + deleteResource(resourceDetails.getName(), user.getUserId()); + return ResourceRestUtils.createResource(resourceDetails, user); + } + + protected ResourceReqDetails buildResourceDetails(User user, String resourceName) { + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.0"; + String contactId = user.getUserId(); + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, + derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_DATABASE.getCategory(), + ResourceCategoryEnum.GENERIC_DATABASE.getSubCategory()); + return resourceDetails; + } + + protected boolean isComponentInArray(String id, JSONArray component) { + for (int i = 0; i < component.size(); i++) { + JSONObject jobject = (JSONObject) component.get(i); + if (jobject.get("uniqueId").toString().equals(id.toLowerCase())) { + return true; + } + } + return false; + } + + protected RestResponse createService(User user, ServiceReqDetails svcDetails) throws Exception { + + Config config = Utils.getConfig(); + + Map headersMap = getHeadersMap(user); + + Gson gson = new Gson(); + String body = gson.toJson(svcDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort()); + RestResponse res = http.httpSendPost(url, body, headersMap); + // System.out.println("Create service was finished with response: + // "+res.getErrorCode()); + return res; + } + + protected Map getHeadersMap(User user) { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), user.getUserId()); + return headersMap; + } + + protected ServiceReqDetails buildServiceDetails(String serviceName) { + String description = "description"; + ArrayList serviceTags = new ArrayList(); + serviceTags.add("tag1"); + serviceTags.add(serviceName); + String category = ServiceCategoriesEnum.MOBILITY.getValue(); + String vendorName = "Oracle"; + String vendorRelease = "0.1"; + String contactId = "al1976"; + String icon = "myIcon"; + + ServiceReqDetails svcdetails = new ServiceReqDetails(serviceName, category, serviceTags, description, + contactId, icon); + return svcdetails; + } + + public RestResponse deleteService(String serviceId, User user) throws Exception { + HttpRequest httpRequest = new HttpRequest(); + String url = String.format(Urls.DELETE_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), + serviceId); + + Map headersMap = getHeadersMap(user); + RestResponse res = httpRequest.httpSendDelete(url, headersMap); + // System.out.println("Delete service was finished with response: + // "+res.getErrorCode()); + return res; + } + + public class NewObject { + private String _name; + + public String getName() { + return _name; + } + + public void setName(String name) { + this._name = name; + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesBaseTest.java new file mode 100644 index 0000000000..d68f3f5582 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesBaseTest.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; + +public abstract class CategoriesBaseTest extends ComponentBaseTest { + + public CategoriesBaseTest(TestName testName, String className) { + super(testName, className); + } + + protected static final String AUDIT_SERVICE_TYPE = "Service"; + protected static final String AUDIT_RESOURCE_TYPE = "Resource"; + protected static final String AUDIT_PRODUCT_TYPE = "Product"; + protected static final String GET_CATEGORY_HIERARCHY = "GetCategoryHierarchy"; + protected static User sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected static User sdncAdminUserDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected static User sdncDesignerUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected static User sdncTesterUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + protected static User sdncGovernorUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + protected static User sdncOpsUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + protected static User sdncProductManagerUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + protected static User sdncProductStrategistUserDetails = ElementFactory + .getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesTests.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesTests.java new file mode 100644 index 0000000000..a3ee121611 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/CategoriesTests.java @@ -0,0 +1,2289 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.PRODUCT_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.RESOURCE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.SERVICE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_ALREADY_EXISTS; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_CREATED; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_MISSING_INFORMATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.text.WordUtils; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.json.JSONArray; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedCategoryAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.CategoryValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class CategoriesTests extends CategoriesBaseTest { + + private static final String GET_CATEGORY_HIERARCHY = "GetCategoryHierarchy"; + protected static final String ADD_CATEGORY = "AddCategory"; + protected static final String DELETE_CATEGORY = "DeleteCategory"; + + public CategoriesTests() { + super(name, CategoriesTests.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + private CategoryDefinition categoryDefinition; + private List categoryList; + private List subCategoryList; + private Map> subCategoriesToDeleteMap; + + @BeforeMethod + public void init() throws Exception { + subCategoriesToDeleteMap = new HashMap>(); + DbUtils.deleteFromEsDbByPattern("_all"); + + categoryDefinition = new CategoryDefinition(); + categoryDefinition.setName("Abcd"); + categoryList = defineCategories(); + subCategoryList = defineSubCategories(categoryList.size()); + } + + // pass + @Test + public void createServiceCategorySuccessFlow() throws Exception { + // Add New category + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + // get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); // also + // set + // catalog + // uniqeId + + } + + // pass + @Test + public void createResourceCategorySuccessFlow() throws Exception { + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get Category + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + // pass + @Test + public void createProductCategorySuccessFlow() throws Exception { + // Add Category by Product-strategist + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + + // Get Category + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void CategoryNameValidation_FirstWordStartWithAlphaNumeric_01() throws Exception { // category + // for + // service + categoryDefinition.setName("Category14AadE &&&---+++.'''###=:@@@____"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category14AadE &-+.'#=:@_"); + categoryDefinition.setNormalizedName("category14aade &-+.'#=:@_"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_FirstWordStartWithAlphaNumeric_02() throws Exception { // category + // for + // resource + categoryDefinition.setName("Category14AadE &&&---+++.'''###=:@@@____"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category14AadE &-+.'#=:@_"); + categoryDefinition.setNormalizedName("category14aade &-+.'#=:@_"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void categoryNameValidation_FirstWordStartWithAlphaNumeric_03() throws Exception { // category + // for + // resource + categoryDefinition.setName("Category14AadE &&&---+++.'''###=:@@@____"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category14AadE &-+.'#=:@_"); + categoryDefinition.setNormalizedName("category14aade &-+.'#=:@_"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + // pass + @Test + public void createServiceCategoryByNonAdminUser() throws Exception { + // Add New category + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncProductStrategistUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_RESTRICTED_OPERATION, + createCategotyRest.getErrorCode().intValue()); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncProductStrategistUserDetails, + ActionStatus.RESTRICTED_OPERATION, STATUS_CODE_RESTRICTED_OPERATION, AUDIT_SERVICE_TYPE); + } + + // pass + @Test + public void createResourceCategoryByNonAdminUser() throws Exception { + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncProductStrategistUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_RESTRICTED_OPERATION, + createCategotyRest.getErrorCode().intValue()); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncProductStrategistUserDetails, + ActionStatus.RESTRICTED_OPERATION, STATUS_CODE_RESTRICTED_OPERATION, AUDIT_RESOURCE_TYPE); + } + + // pass + @Test + public void createProductCategoryByNonProductStrategistUser() throws Exception { + // Add New product category not by Product-Strategist + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_RESTRICTED_OPERATION, + createCategotyRest.getErrorCode().intValue()); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.RESTRICTED_OPERATION, STATUS_CODE_RESTRICTED_OPERATION, AUDIT_PRODUCT_TYPE); + + } + + // pass + @Test + public void addCategoryByNonExistingUser() throws Exception { + User sdncAdminUserDetailsNonExisting = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncAdminUserDetailsNonExisting.setUserId("bt555h"); + // Add New category + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncAdminUserDetailsNonExisting, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_RESTRICTED_OPERATION, + createCategotyRest.getErrorCode().intValue()); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier("(" + sdncAdminUserDetailsNonExisting.getUserId() + ")"); + expectedCatrgoryAuditJavaObject.setCategoryName(categoryDefinition.getName()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(""); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_SERVICE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_RESTRICTED_OPERATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_CATEGORY); + } + + @Test + public void addServiceCategoryAllowedcharacters_01() throws Exception { + categoryDefinition.setName("1234AbcdE&"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde&"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_02() throws Exception { + categoryDefinition.setName("1234AbcdE-"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde-"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_03() throws Exception { + categoryDefinition.setName("1234AbcdE+"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde+"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_04() throws Exception { + categoryDefinition.setName("1234AbcdE."); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde."); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_05() throws Exception { + categoryDefinition.setName("1234AbcdE'"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde'"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_06() throws Exception { + categoryDefinition.setName("1234AbcdE="); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde="); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_07() throws Exception { + categoryDefinition.setName("1234AbcdE:"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde:"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_08() throws Exception { + categoryDefinition.setName("1234AbcdE@"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde@"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_09() throws Exception { + categoryDefinition.setName("1234AbcdE_"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde_"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_10() throws Exception { + categoryDefinition.setName("1234AbcdE#"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde#"); // normalization + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_11() throws Exception { + categoryDefinition.setName("1234AbcdE d"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde d"); // normalization + categoryDefinition.setName("1234AbcdE D"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void addServiceCategoryAllowedcharacters_12() throws Exception { + categoryDefinition.setName("1234AbcdE &_=+.-'#:@ d"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("1234abcde &_=+.-'#:@ d"); // normalization + categoryDefinition.setName("1234AbcdE &_=+.-'#:@ D"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveSpaceFromBeginning() throws Exception { + categoryDefinition.setName(" Category01"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("category01"); // normalization + categoryDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveSpaceFromEnd() throws Exception { + categoryDefinition.setName("Category01 "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("category01"); // normalization + categoryDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraSpace() throws Exception { + categoryDefinition.setName("Category 02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("category 02"); // normalization + categoryDefinition.setName("Category 02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraAmpersand() throws Exception { + categoryDefinition.setName("Category&& &02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("category& &02"); // normalization + categoryDefinition.setName("Category& &02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraDash() throws Exception { + categoryDefinition.setName("CategorY-- --02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("CategorY- -02"); + categoryDefinition.setNormalizedName("category- -02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraPlus() throws Exception { + categoryDefinition.setName("CateGory++++ +02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("CateGory+ +02"); + categoryDefinition.setNormalizedName("category+ +02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraPeriod() throws Exception { + categoryDefinition.setName("Category.... .02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category. .02"); + categoryDefinition.setNormalizedName("category. .02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraApostrophe() throws Exception { + categoryDefinition.setName("CaTegory''' '02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("CaTegory' '02"); + categoryDefinition.setNormalizedName("category' '02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraHashtag() throws Exception { + categoryDefinition.setName("Category### #02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category# #02"); + categoryDefinition.setNormalizedName("category# #02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtrEequal() throws Exception { + categoryDefinition.setName("Category=== =02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category= =02"); + categoryDefinition.setNormalizedName("category= =02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtrColon() throws Exception { + categoryDefinition.setName("Category::: :02"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category: :02"); + categoryDefinition.setNormalizedName("category: :02"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtrAt() throws Exception { + categoryDefinition.setName("Category@@@ @a2"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category@ @a2"); + categoryDefinition.setNormalizedName("category@ @a2"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_RemoveExtraUnderscore() throws Exception { + categoryDefinition.setName("Category___ _22"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Category_ _22"); + categoryDefinition.setNormalizedName("category_ _22"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_FirstWordStartWithNumber() throws Exception { + categoryDefinition.setName("1Category one"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("1Category One"); + categoryDefinition.setNormalizedName("1category one"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_FirstWordStartWithNonAlphaNumeric() throws Exception { // The + // first + // word + // must + // start + // with + // an + // alpha-numeric + // character + // [a-Z + // A..Z, + // 0..9] + char invalidChars[] = { '&', '-', '+', '.', '\'', '#', '=', ':', '@', '_' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + categoryDefinition.setName(invalidChars[i] + "AbcD123"); + categoryDefinition.setNormalizedName((invalidChars[i] + "AbcD123").toLowerCase()); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, + sdncAdminUserDetails1, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + + } + } + + @Test + public void addServiceCategoryAlreadyExist_uniqueness() throws Exception { // Verify + // category + // name + // duplication + // ("uniqueness") + // as + // non-case-sensitive, + // so + // we + // don’t + // create + // duplicate + // names + // with + // upper/lower + // case + // inconsistency. + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); // also + // set + // catalog + // uniqeId + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + // Create same category name again + DbUtils.deleteFromEsDbByPattern("_all"); + CategoryDefinition categoryDataDefinition2 = new CategoryDefinition(); + categoryDataDefinition2.setName(categoryDefinition.getName()); + RestResponse addDuplicateCategoryRest = CategoryRestUtils.createCategory(categoryDataDefinition2, + sdncAdminUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_ALREADY_EXISTS, + addDuplicateCategoryRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDataDefinition2, sdncAdminUserDetails, + ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, STATUS_CODE_ALREADY_EXISTS, AUDIT_SERVICE_TYPE, + "Service", categoryDefinition.getName()); + // Get Category and verify that category was created is not deleted + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_01() throws Exception { + categoryDefinition.setName("At and T"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("At & T"); + categoryDefinition.setNormalizedName("at & t"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_02() throws Exception { + categoryDefinition.setName("At and t"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("At & T"); + categoryDefinition.setNormalizedName("at & t"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_03() throws Exception { + categoryDefinition.setName("Atand T"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("atand t"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_04() throws Exception { + categoryDefinition.setName("At andT"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("at andt"); + categoryDefinition.setName("At AndT"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_05() throws Exception { + categoryDefinition.setName(" and AttT"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("and attt"); + categoryDefinition.setName("And AttT"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_06() throws Exception { + categoryDefinition.setName("AttT and "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("attt and"); + categoryDefinition.setName("AttT And"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + // Bug + @Test + public void categoryNameValidation_ReplaceAndWithAmpersand_07() throws Exception { + categoryDefinition.setName(" and a"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("and a"); + categoryDefinition.setName("And a"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationMaxLength() throws Exception { + categoryDefinition.setName("AsdfghjQ234567890@#.&:+-_"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("asdfghjq234567890@#.&:+-_"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + + } + + @Test + public void categoryNameValidationMaxLengthAfterNormalization() throws Exception { + categoryDefinition.setName(" A jQ234 @@@___ +++ At and T and and "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("A JQ234 @_ + At & T & And"); + categoryDefinition.setNormalizedName("a jq234 @_ + at & t & and"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + + } + + @Test + public void categoryNameValidationExceedMaxLengthAfterNormalization() throws Exception { + categoryDefinition.setName(" AbdfghBCVa jQ234 @@___ +++ At and T "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("abdfghbcva jq234 @_ + at&t"); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + } + + @Test + public void categoryNameValidationMinLengthAfterNormalization() throws Exception { // MinLengthAfterNormalization + // = + // 4 + // characters + categoryDefinition.setName(" At and T "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("At & T"); + categoryDefinition.setNormalizedName("at & t"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationLessThanMinLengthAfterNormalization() throws Exception { + categoryDefinition.setName(" A&&&&&&&&&&&&&&&&&T "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName("a&t"); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + } + + @Test + public void categoryNameValidationIsNull() throws Exception { + categoryDefinition.setName(null); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + } + + @Test + public void categoryNameValidationIsEmpty() throws Exception { + categoryDefinition.setName(""); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName(""); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + } + + @Test + public void categoryNameValidationInvalidCharacters() throws Exception { + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + // DbUtils.cleanAllAudits(); + categoryDefinition.setName("AbcD123" + invalidChars[i]); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setNormalizedName(""); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditFailure(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE, + "Service", "category"); + } + } + + @Test + public void categoryNameValidationSameNameDifferentResourceType() throws Exception { // same + // Catalog + // Name + // for + // service/resource/product + // is + // allowed + String name = ("Abcd"); + CategoryDefinition categoryDataDefinition1 = new CategoryDefinition(); + CategoryDefinition categoryDataDefinition2 = new CategoryDefinition(); + CategoryDefinition categoryDataDefinition3 = new CategoryDefinition(); + categoryDataDefinition1.setName(name); + categoryDataDefinition2.setName(name); + categoryDataDefinition3.setName(name); + // CREATE CATEGORY FOR SERVICE + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDataDefinition1, + sdncAdminUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDataDefinition1.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDataDefinition1); + // get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDataDefinition1); // also + // set + // catalog + // uniqeId + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDataDefinition1, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + // CREATE CATEGORY FOR RESOURCE_COMPONENT_TYPE + DbUtils.deleteFromEsDbByPattern("_all"); + createCategotyRest = CategoryRestUtils.createCategory(categoryDataDefinition2, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDataDefinition2.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDataDefinition2); + // Get Category + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDataDefinition2); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDataDefinition2, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + // CREATE CATEGORY FOR PRODUCT + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse addCategotyRest = CategoryRestUtils.createCategory(categoryDataDefinition3, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + addCategotyRest.getErrorCode().intValue()); + categoryDataDefinition3.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateCategoryResponse(addCategotyRest, categoryDataDefinition3); + + // Get Category + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDataDefinition3); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void categoryNameValidationFirstLetterOfKeyWordsCapitalized() throws Exception { // First + // letter + // of + // key + // words + // are + // capitalized + categoryDefinition.setName("beNNy shaY michEl"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("BeNNy ShaY MichEl"); + categoryDefinition.setNormalizedName("benny shay michel"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_01() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" bank OF america "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Bank of America"); + categoryDefinition.setNormalizedName("bank of america"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_02() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName("THE america bank "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("THE America Bank"); + categoryDefinition.setNormalizedName("the america bank"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_03() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" A bank OF america "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("A Bank of America"); + categoryDefinition.setNormalizedName("a bank of america"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_04() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" bank america is A big ban "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Bank America Is a Big Ban"); + categoryDefinition.setNormalizedName("bank america is a big ban"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_05() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" aN apple comPany inC "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("AN Apple ComPany InC"); + categoryDefinition.setNormalizedName("an apple company inc"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_06() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" eat AN apple ANAN"); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Eat an Apple ANAN"); + categoryDefinition.setNormalizedName("eat an apple anan"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_07() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" united states OF americA "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("United States of AmericA"); + categoryDefinition.setNormalizedName("united states of america"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + // need to re-check + @Test + public void categoryNameValidationConjunctions_08() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" oF united states OF amer "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("OF United States of Amer"); + categoryDefinition.setNormalizedName("of united states of amer"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_09() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" to Apple TO at&T TOO "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("To Apple to At&T TOO"); + categoryDefinition.setNormalizedName("to apple to at&t too"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_10() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" eat apple AS you liiikeas "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Eat Apple as You Liiikeas"); + categoryDefinition.setNormalizedName("eat apple as you liiikeas"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_11() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" as you may want "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("As You May Want"); + categoryDefinition.setNormalizedName("as you may want"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void categoryNameValidationConjunctions_12() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" the bank OF america "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("The Bank of America"); + categoryDefinition.setNormalizedName("the bank of america"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + // need to recheck + @Test + public void categoryNameValidationConjunctions_13() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" To tel-toto "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("To Tel-toto"); + categoryDefinition.setNormalizedName("to tel-toto"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + // recheck + @Test + public void categoryNameValidationConjunctions_14() throws Exception { // Normalize + // the + // category + // name + // conjunctions + // ('of', + // 'to', + // 'for', + // 'as', + // 'a', + // 'an' + // , + // 'the') + // are + // lower + // case. + categoryDefinition.setName(" tel-aviv To la "); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_CREATED, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Tel-aviv to La"); + categoryDefinition.setNormalizedName("tel-aviv to la"); + CategoryValidationUtils.validateCreateCategoryResponse(createCategotyRest, categoryDefinition); + // Get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + AuditValidationUtils.categoryAuditSuccess(ADD_CATEGORY, categoryDefinition, sdncAdminUserDetails, + STATUS_CODE_CREATED, AUDIT_SERVICE_TYPE); + } + + @Test + public void createServiceCategoryHttpCspUserIdIsEmpty() throws Exception { + User sdncAdminUserDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncAdminUserDetails1.setUserId(""); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Abcd"); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(categoryDefinition.getName()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(""); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_SERVICE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_CATEGORY); + } + + @Test + public void createServiceCategorHttpCspUserIdIsNull() throws Exception { + User sdncAdminUserDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncAdminUserDetails1.setUserId(null); + RestResponse createCategotyRest = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails1, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createCategotyRest.getErrorCode().intValue()); + categoryDefinition.setName("Abcd"); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(categoryDefinition.getName()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(""); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_SERVICE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_CATEGORY); + } + + @Test + public void createSrvcCategoryHttpCspUserIdHeaderIsMissing() throws Exception { + RestResponse createConsumerRest = CategoryRestUtils + .createServiceCategoryHttpCspAtuUidIsMissing(categoryDefinition, sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createConsumerRest.getErrorCode().intValue()); + categoryDefinition.setName("Abcd"); + // get service category and validate that category was not added + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyCategoryNotExistsInGetResponse(getAllCategoriesRest, categoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(categoryDefinition.getName()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(""); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_SERVICE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_CATEGORY); + } + + @Test + public void getServiceCategoryHierarchySuccessFlow() throws Exception { + + int numOfCategories = 3; + List categories = new ArrayList(); + RestResponse restResponse; + CategoryDefinition category; + String categoryName = categoryDefinition.getName(); + for (int i = 0; i < numOfCategories; i++) { + categoryDefinition.setName(categoryName + i); + restResponse = CategoryRestUtils.createCategory(categoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + category = ResponseParser.parseToObject(restResponse.getResponse(), CategoryDefinition.class); + categories.add(category); + } + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + + AuditValidationUtils.GetCategoryHierarchyAuditSuccess(GET_CATEGORY_HIERARCHY, AUDIT_SERVICE_TYPE, + sdncAdminUserDetails, STATUS_CODE_SUCCESS); + for (CategoryDefinition categoryCurr : categories) { + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryCurr); + } + } + + ///////////////////////////////// US570520 ///////////////////////////////// + private List defineCategories() throws Exception { + String firstCategory = "FirstCategory"; + String secondCategory = "secondCategory"; + String thirdCategory = "ThirdCategory"; + String forthCategory = "forthCategory"; + CategoryDefinition category1 = new CategoryDefinition(categoryDefinition); + category1.setName(firstCategory); + CategoryDefinition category2 = new CategoryDefinition(categoryDefinition); + category2.setName(secondCategory); + CategoryDefinition category3 = new CategoryDefinition(categoryDefinition); + category3.setName(thirdCategory); + CategoryDefinition category4 = new CategoryDefinition(categoryDefinition); + category4.setName(forthCategory); + ArrayList categoryList = new ArrayList(); + categoryList.add(category1); + categoryList.add(category2); + categoryList.add(category3); + categoryList.add(category4); + return categoryList; + } + + @Test + public void getAllResourceCategoriesHirarchy() throws Exception { + createAndValidateCategoriesExist(RESOURCE_COMPONENT_TYPE, categoryList); + + for (int i = 0; i < categoryList.size(); i++) { + List subCategorieUniqueIdList = new ArrayList(); + for (int j = 0; j < subCategoryList.size(); j++) { + RestResponse createSubCategory = CategoryRestUtils.createSubCategory(subCategoryList.get(j), + categoryList.get(i), sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + if (createSubCategory.getErrorCode().intValue() == STATUS_CODE_CREATED) { + String subCategoryUniqeId = ResponseParser.getUniqueIdFromResponse(createSubCategory); + subCategorieUniqueIdList.add(subCategoryUniqeId); + subCategoriesToDeleteMap.put(categoryList.get(i).getUniqueId(), subCategorieUniqueIdList); + } + } + } + + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + + for (int i = 0; i < categoryList.size(); i++) { + for (int j = 0; j < subCategoryList.size(); j++) { + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + categoryList.get(i).getUniqueId(), subCategoryList.get(j)); + } + } + + checkAuditSuccess(RESOURCE_COMPONENT_TYPE); + } + + private List defineSubCategories(int catListSize) { + List subCatList = new ArrayList(); + for (int j = 1; j <= catListSize; j++) { + SubCategoryDefinition subCategory = new SubCategoryDefinition(); + subCategory.setName("SubCategory" + String.valueOf(j)); + subCatList.add(subCategory); + } + return subCatList; + } + + private void createAndValidateCategoriesExist(String comp, List categoryList) throws Exception { + createCategories(comp, categoryList); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, comp); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + verifyCategoriesExist(categoryList, getAllCategoriesRest); + } + + private void verifyCategoriesExist(List categoryList, RestResponse getAllCategoriesRest) { + for (int i = 0; i < categoryList.size(); i++) { + categoryList.get(i).setName(WordUtils.capitalize(categoryList.get(i).getName())); + CategoryValidationUtils.verifyCategoryExistInGetResponse(getAllCategoriesRest, categoryList.get(i)); + } + } + + private void createCategories(String comp, List categoryList) throws Exception { + for (int i = 0; i < categoryList.size(); i++) { + CategoryRestUtils.createCategory(categoryList.get(i), sdncAdminUserDetails, comp); + } + } + + @Test + public void getAllServiceCategoriesHirarchy() throws Exception { + // deleteCategories(categoryList, SERVICE_COMPONENT_TYPE); + createAndValidateCategoriesExist(SERVICE_COMPONENT_TYPE, categoryList); + checkAuditSuccess(SERVICE_COMPONENT_TYPE); + // deleteCategories(categoryList, SERVICE_COMPONENT_TYPE); + } + + @Test + public void getAllResourceCategories_noAttUserHeader() throws Exception { + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(new User(), RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", 403, getAllCategoriesRest.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), + getAllCategoriesRest.getResponse()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(GET_CATEGORY_HIERARCHY); + expectedCatrgoryAuditJavaObject.setModifierName(""); + expectedCatrgoryAuditJavaObject.setModifierUid(""); + expectedCatrgoryAuditJavaObject.setDetails(RESOURCE_COMPONENT_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateGetCategoryHirarchy(expectedCatrgoryAuditJavaObject, GET_CATEGORY_HIERARCHY); + } + + @Test + public void getAllResourceCategories_userNotProvisioned() throws Exception { + User notProvisionedUser = new User(); + notProvisionedUser.setUserId("aa0001"); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(notProvisionedUser, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", 409, getAllCategoriesRest.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + getAllCategoriesRest.getResponse()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(GET_CATEGORY_HIERARCHY); + expectedCatrgoryAuditJavaObject.setModifierName(""); + expectedCatrgoryAuditJavaObject.setModifierUid(notProvisionedUser.getUserId()); + expectedCatrgoryAuditJavaObject.setDetails(RESOURCE_COMPONENT_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_RESTRICTED_OPERATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateGetCategoryHirarchy(expectedCatrgoryAuditJavaObject, GET_CATEGORY_HIERARCHY); + } + + @Test + public void getAllResourceCategories_unsupportedComponent() throws Exception { + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, "comp"); + assertEquals("Check response code after get all categories hirarchy", 400, + getAllCategoriesRest.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.UNSUPPORTED_ERROR.name(), + new ArrayList(Arrays.asList("component type")), getAllCategoriesRest.getResponse()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.UNSUPPORTED_ERROR.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(GET_CATEGORY_HIERARCHY); + expectedCatrgoryAuditJavaObject.setModifierUid(sdncAdminUserDetails.getUserId()); + expectedCatrgoryAuditJavaObject.setModifierName(sdncAdminUserDetails.getFullName()); + expectedCatrgoryAuditJavaObject.setDetails("comp"); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_INVALID_CONTENT)); + expectedCatrgoryAuditJavaObject.setDesc(AuditValidationUtils.buildAuditDescription(errorInfo, + new ArrayList(Arrays.asList("component type")))); + AuditValidationUtils.validateGetCategoryHirarchy(expectedCatrgoryAuditJavaObject, GET_CATEGORY_HIERARCHY); + } + + @Test(enabled = false) + public void getAllResourceCategories_emptyList() throws Exception { + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + JSONArray jArr = new JSONArray(getAllCategoriesRest.getResponse()); + assertTrue(jArr.length() == 0); + + checkAuditSuccess(RESOURCE_COMPONENT_TYPE); + } + + private void checkAuditSuccess(String componentType) throws Exception { + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(GET_CATEGORY_HIERARCHY); + expectedCatrgoryAuditJavaObject.setModifierName(sdncAdminUserDetails.getFullName()); + expectedCatrgoryAuditJavaObject.setModifierUid(sdncAdminUserDetails.getUserId()); + expectedCatrgoryAuditJavaObject.setDetails(componentType); + expectedCatrgoryAuditJavaObject.setStatus("200"); + expectedCatrgoryAuditJavaObject.setDesc("OK"); + AuditValidationUtils.validateGetCategoryHirarchy(expectedCatrgoryAuditJavaObject, GET_CATEGORY_HIERARCHY); + } + + @Test(enabled = false) + public void getAllServiceCategories_emptyList() throws Exception { + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + JSONArray jArr = new JSONArray(getAllCategoriesRest.getResponse()); + assertTrue(jArr.length() == 0); + + checkAuditSuccess(SERVICE_COMPONENT_TYPE); + } + + @Test(enabled = false) + public void getAllProductCategories_emptyList() throws Exception { + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get Category", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + JSONArray jArr = new JSONArray(getAllCategoriesRest.getResponse()); + assertTrue(jArr.length() == 0); + + checkAuditSuccess(PRODUCT_COMPONENT_TYPE); + } + + ////////////////////////////////////////////////////////////////////////////// + + @Test + public void importCategories() throws Exception { + + String importResourceDir = config.getImportTypesConfigDir() + File.separator + "categoryTypesTest.zip"; + + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + mpBuilder.addPart("categoriesZip", new FileBody(new File(importResourceDir))); + + RestResponse importResult = CategoryRestUtils.importCategories(mpBuilder, sdncAdminUserDetails.getUserId()); + assertEquals("Check response code after Import", BaseRestUtils.STATUS_CODE_CREATED, + importResult.getErrorCode().intValue()); + + Map map = ResponseParser.parseToObjectUsingMapper(importResult.getResponse(), Map.class); + assertEquals("Check entries count", 2, map.size()); + + List> resources = (List>) map.get("resources"); + assertEquals("Check resource category entries count", 1, resources.size()); + + List> services = (List>) map.get("services"); + assertEquals("Check resource category entries count", 2, services.size()); + + RestResponse allCategories = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, "resources"); + List resourceCategories = ResponseParser.parseCategories(allCategories); + for (Map resource : resources) { + boolean exist = false; + + for (CategoryDefinition categ : resourceCategories) { + if (categ.getName().equals(resource.get("name"))) { + exist = true; + break; + } + } + assertTrue("Check existance resource category " + resource.get("name"), exist); + } + + allCategories = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, "services"); + List servicesCategories = ResponseParser.parseCategories(allCategories); + for (Map service : services) { + boolean exist = false; + + for (CategoryDefinition categ : servicesCategories) { + if (categ.getName().equals(service.get("name"))) { + exist = true; + break; + } + } + assertTrue("Check existance service category " + service.get("name"), exist); + } + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/ElementsApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/ElementsApiTest.java new file mode 100644 index 0000000000..7f30f8ca92 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/ElementsApiTest.java @@ -0,0 +1,147 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.HashMap; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.testng.annotations.Test; + +public class ElementsApiTest extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public ElementsApiTest() { + super(name, ElementsApiTest.class.getName()); + } + + // public LCSbaseTest(TestName testName, String className) { + // super(testName, className); + // } + + // public ElementsApiTest(TestName name, String name2) { + //// super(name, name2); + // // TODO Auto-generated constructor stub + // } + + // Expected 200 Keep + @Test + public void getAllPropertyScopesSuccess() throws Exception { + RestResponse response = ResourceRestUtils.getAllPropertyScopesTowardsCatalogBe(); + String action = "Get All Property Scopes"; + int expectedCode = 200; + verifyErrorCode(response, action, expectedCode); + } + + // Expected 200 Keep + @Test + public void getAllArtifactTypes() throws Exception { + RestResponse response = ResourceRestUtils.getAllArtifactTypesTowardsCatalogBe(); + String action = "Get All Artifact Types"; + int expectedCode = 200; + verifyErrorCode(response, action, expectedCode); + } + + // Expected 200 Keep + @Test + public void getConfiguration() throws Exception { + RestResponse response = ResourceRestUtils.getConfigurationTowardsCatalogBe(); + String action = "Get All Artifact Types"; + int expectedCode = 200; + + String json = response.getResponse(); + JSONObject jsonResp = (JSONObject) JSONValue.parse(json); + + HashMap artifacts = (HashMap) jsonResp.get("artifacts"); + Long defaultHeatTimeout = (Long) jsonResp.get("defaultHeatTimeout"); + + if (defaultHeatTimeout == null) { + response.setErrorCode(500); + verifyErrorCode(response, action, expectedCode); + return; + } + + if (artifacts == null) { + response.setErrorCode(500); + verifyErrorCode(response, action, expectedCode); + return; + } + + JSONObject deploymentResources = (JSONObject) artifacts.get("deployment"); + JSONArray otherResources = (JSONArray) artifacts.get("other"); + if (deploymentResources == null || otherResources == null) { + response.setErrorCode(500); + verifyErrorCode(response, action, expectedCode); + return; + } + + JSONArray roles = (JSONArray) jsonResp.get("roles"); + if (roles == null) { + response.setErrorCode(500); + verifyErrorCode(response, action, expectedCode); + return; + } + + } + + public void verifyErrorCode(RestResponse response, String action, int expectedCode) { + assertNotNull("check response object is not null after " + action, response); + assertNotNull("check error code exists in response after " + action, response.getErrorCode()); + assertEquals("Check response code after + action" + action, expectedCode, response.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void getAllCategoriesSuccess() throws Exception { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + RestResponse response = CatalogRestUtils.getAllCategoriesTowardsCatalogBe(); + String action = "Get All Categories"; + int expectedCode = 200; + verifyErrorCode(response, action, expectedCode); + } + + @Test(enabled = false) + public void getAllTagSuccess() throws Exception { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + RestResponse response = ResourceRestUtils.getAllTagsTowardsCatalogBe(); + String action = "Get All Categories"; + int expectedCode = 200; + verifyErrorCode(response, action, expectedCode); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/GroupingTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/GroupingTest.java new file mode 100644 index 0000000000..7858b3259f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/GroupingTest.java @@ -0,0 +1,2003 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.PRODUCT_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.RESOURCE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.SERVICE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_ALREADY_EXISTS; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_CREATED; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_MISSING_INFORMATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_NOT_FOUND; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedCategoryAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.CategoryValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.SkipException; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GroupingTest extends CategoriesBaseTest { + + protected static final String ADD_GROUPING = "AddGrouping"; + protected static final String CATEGORY = "category"; + protected static final String SUB_CATEGORY = "sub-category"; + protected static final String GROUPING = "grouping"; + + public GroupingTest() { + super(name, GroupingTest.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + + private CategoryDefinition productCategoryDefinition; + private CategoryDefinition productCategoryDefinition2; + + private SubCategoryDefinition productSubCategoryDefinition; + private SubCategoryDefinition productSubCategoryDefinition2; + private SubCategoryDefinition productSubCategoryDefinition3; + + private GroupingDefinition productGroupingDefinition; + private GroupingDefinition productGroupingDefinition2; + private GroupingDefinition productGroupingDefinition3; + + @BeforeMethod + public void init() throws Exception { + + // Category setup + productCategoryDefinition = new CategoryDefinition(); + productCategoryDefinition.setName("Category1"); + productCategoryDefinition2 = new CategoryDefinition(); + productCategoryDefinition2.setName("Category2"); + + // Subcategory setup + productSubCategoryDefinition = new SubCategoryDefinition(); + productSubCategoryDefinition.setName("SubCategory1"); + + productSubCategoryDefinition2 = new SubCategoryDefinition(); + productSubCategoryDefinition2.setName("SubCategory2"); + + productSubCategoryDefinition3 = new SubCategoryDefinition(); + productSubCategoryDefinition3.setName("SubCategory1"); + + // Group setup + productGroupingDefinition = new GroupingDefinition(); + productGroupingDefinition.setName("Grouping1"); + + productGroupingDefinition2 = new GroupingDefinition(); + productGroupingDefinition2.setName("Grouping2"); + + productGroupingDefinition3 = new GroupingDefinition(); + productGroupingDefinition3.setName("Grouping1"); + + // Init product category + RestResponse createCategory = CategoryRestUtils.createCategory(productCategoryDefinition, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + CategoryDefinition category = ResponseParser.parseToObject(createCategory.getResponse(), + CategoryDefinition.class); + assertEquals("Check category name after creating category ", productCategoryDefinition.getName(), + category.getName()); + productCategoryDefinition = category; + + // Init product category1 + createCategory = CategoryRestUtils.createCategory(productCategoryDefinition2, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + category = ResponseParser.parseToObject(createCategory.getResponse(), CategoryDefinition.class); + assertEquals("Check category name after creating category ", productCategoryDefinition2.getName(), + category.getName()); + productCategoryDefinition2 = category; + + // Init product productSubCategoryDefinition to + // productCategoryDefinition + RestResponse createSubCategory = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createSubCategory.getErrorCode().intValue()); + SubCategoryDefinition subCategory = ResponseParser.parseToObject(createSubCategory.getResponse(), + SubCategoryDefinition.class); + assertEquals("Check category name after creating category ", productSubCategoryDefinition.getName(), + subCategory.getName()); + productSubCategoryDefinition = subCategory; + productCategoryDefinition.addSubCategory(productSubCategoryDefinition); + + // Init product productSubCategoryDefinition1 to + // productCategoryDefinition + createSubCategory = CategoryRestUtils.createSubCategory(productSubCategoryDefinition2, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createSubCategory.getErrorCode().intValue()); + subCategory = ResponseParser.parseToObject(createSubCategory.getResponse(), SubCategoryDefinition.class); + assertEquals("Check category name after creating category ", productSubCategoryDefinition2.getName(), + subCategory.getName()); + productSubCategoryDefinition2 = subCategory; + productCategoryDefinition.addSubCategory(productSubCategoryDefinition2); + + // Init product productSubCategoryDefinition3 to + // productCategoryDefinition2 + createSubCategory = CategoryRestUtils.createSubCategory(productSubCategoryDefinition3, + productCategoryDefinition2, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createSubCategory.getErrorCode().intValue()); + subCategory = ResponseParser.parseToObject(createSubCategory.getResponse(), SubCategoryDefinition.class); + assertEquals("Check category name after creating category ", productSubCategoryDefinition3.getName(), + subCategory.getName()); + productSubCategoryDefinition3 = subCategory; + productCategoryDefinition2.addSubCategory(productSubCategoryDefinition3); + } + + @Test + public void createProductGroupCategorySuccess() throws Exception { + createGroupingSuccess(productGroupingDefinition, productSubCategoryDefinition, productCategoryDefinition, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE, AUDIT_PRODUCT_TYPE); + } + + private void createGroupingSuccess(GroupingDefinition groupingDefinition, + SubCategoryDefinition subCategoryDefinition, CategoryDefinition categoryDefinition, + User sdncProductStrategistUserDetails, String productComponentType, String auditType) throws Exception { + + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(groupingDefinition, subCategoryDefinition, + categoryDefinition, sdncProductStrategistUserDetails, productComponentType); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("grouping1"); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + productComponentType); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, categoryDefinition.getUniqueId(), + subCategoryDefinition.getUniqueId(), groupingDefinition); + + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, categoryDefinition, subCategoryDefinition, + groupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, auditType); + } + + //// Benny + + @Test + public void createProductGroupByProductStrategist() throws Exception { + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("grouping1"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void createProductGroupAlreadyExistInSameCategorySubCategory() throws Exception { + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("grouping1"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + // Create Same Group already exist on same Category/SubCategory + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_ALREADY_EXISTS, + createGroupingRest.getErrorCode().intValue()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, STATUS_CODE_ALREADY_EXISTS, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, productGroupingDefinition.getName(), productSubCategoryDefinition.getName()); + } + + @Test + public void createProductGroupUnderSameCategoryButDifferentSubCategory() throws Exception { + // Setting : Category-A, Sub-category-B , group : aBcd (display-Name : + // ABcd, normalized: abcd)  [A, B, ABcd] + // Action : Category-A, Sub-category-C, group : abcD (display-Name : + // ABcd, normalized: abcd)  [A, C, ABcd] + productGroupingDefinition.setName("ABCd"); + productGroupingDefinition2.setName("abcD"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition2, productSubCategoryDefinition2, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition2.setName("ABCd"); + productGroupingDefinition2.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition2); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, + productSubCategoryDefinition2, productGroupingDefinition2, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition2.getUniqueId(), + productGroupingDefinition2); + } + + @Test + public void createProductGroupUnderSameSubCategoryButDifferentCategory() throws Exception { + // Setting : Category-A, Sub-category-B , group : aBcd (display-Name : + // ABcd, normalized: abcd)  [A, B, ABcd] + // : Category-A, Sub-category-C, group : abcD (display-Name : ABcd, + // normalized: abcd)  [A, C, ABcd] + // : Category-K, Sub-category-B, group : abcD (display-Name : ABcd, + // normalized: abcd)  [K, B, ABcd] + productGroupingDefinition.setName("ABCd"); + productGroupingDefinition2.setName("abcD"); + productGroupingDefinition3.setName("aBCd"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition2, productSubCategoryDefinition2, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition2.setName("ABCd"); + productGroupingDefinition2.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition2); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, + productSubCategoryDefinition2, productGroupingDefinition2, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition3, productSubCategoryDefinition3, + productCategoryDefinition2, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition3.setName("ABCd"); + productGroupingDefinition3.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition3); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition2, + productSubCategoryDefinition3, productGroupingDefinition3, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition2.getUniqueId(), + productGroupingDefinition2); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition2.getUniqueId(), productSubCategoryDefinition3.getUniqueId(), + productGroupingDefinition3); + + } + + @Test + public void createProductGroupsOnSameCategorySubCategory() throws Exception { + // Setting : Category-A, Sub-category-B , group : ABcd (display-Name : + // ABcd, normalized: abcd) [A ,B, ABcd] + // Action : Category-A, Sub-category-B, group : ZXcv (display-Name : + // ZXcv, normalized: zxcv) [A, B, ZXcv] + productGroupingDefinition.setName("ABcd"); + productGroupingDefinition2.setName("ZXcv"); + productGroupingDefinition2.setNormalizedName("zxcv"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition2, productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition2); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition2, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition2); + } + + @Test + public void createProductGroupUnderDifferentCategory() throws Exception { + // Setting : Category-A, Sub-category-B , group : aBcd (display-Name : + // ABcd, normalized: abcd) [A ,B, ABcd] + // Action : Category-K, Sub-category-B, group : abcD (display-Name : + // ABcd, normalized: abcd) [K, B, ABcd] + // productGroupingDefinition.setName("ABCd"); + productGroupingDefinition.setName("ABcD"); + productGroupingDefinition2.setName("abcD"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("abcd"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + DbUtils.deleteFromEsDbByPattern("_all"); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition2, productSubCategoryDefinition3, + productCategoryDefinition2, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition2.setNormalizedName("abcd"); + productGroupingDefinition2.setName("ABcD"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition2); + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition2, + productSubCategoryDefinition3, productGroupingDefinition2, sdncProductStrategistUserDetails, + STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition2.getUniqueId(), productSubCategoryDefinition3.getUniqueId(), + productGroupingDefinition2); + } + + /////////// + @Test + public void createProductGroupByNonProductStrategist() throws Exception { + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_RESTRICTED_OPERATION, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + productSubCategoryDefinition.setName(productSubCategoryDefinition.getUniqueId()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncAdminUserDetails, ActionStatus.RESTRICTED_OPERATION, + STATUS_CODE_RESTRICTED_OPERATION, AUDIT_PRODUCT_TYPE); + } + + // @Ignore("DE176245") + @Test + public void createProductGroupForNonExistingComponentType() throws Exception { + String nonSupportedComponentType = "NonExistingComponentType"; // instead + // resource/product + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + nonSupportedComponentType); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + productSubCategoryDefinition.setName(productSubCategoryDefinition.getUniqueId()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, nonSupportedComponentType); + } + + // @Ignore("DE176245") + @Test + public void createResourceGroup() throws Exception { + // Resource doesn't have group + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + productSubCategoryDefinition.setName(productSubCategoryDefinition.getUniqueId()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, AUDIT_RESOURCE_TYPE); + } + + // @Ignore("DE176245") + @Test + public void createServiceGroup() throws Exception { + // Service doesn't have group + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + productSubCategoryDefinition.setName(productSubCategoryDefinition.getUniqueId()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE); + } + + @Test + public void createProductGroupForNonExistingCategory() throws Exception { + + CategoryDefinition productCategoryDefinition100 = new CategoryDefinition(); + productCategoryDefinition100.setName("category.nonexistingCategory"); + productCategoryDefinition100.setUniqueId("category.nonexistingCategory"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition100, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_NOT_FOUND, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + productSubCategoryDefinition.setName(productSubCategoryDefinition.getUniqueId()); + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition100, + productSubCategoryDefinition, productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_CATEGORY_NOT_FOUND, STATUS_CODE_NOT_FOUND, AUDIT_PRODUCT_TYPE, + PRODUCT_COMPONENT_TYPE, CATEGORY, ""); + } + + @Test + public void createProductGroupForNonExistingSunCategory() throws Exception { + throw new SkipException( + "Skipping - failed in audit validation expected \"products\" actual result was \"product\" "); + // SubCategoryDefinition productSubCategoryDefinition100 = new + // SubCategoryDefinition(); + // productSubCategoryDefinition100.setUniqueId("category.nonexistingSubCategory"); + // RestResponse createGroupingRest = + // CategoryRestUtils.createGrouping(productGroupingDefinition, + // productSubCategoryDefinition100, productCategoryDefinition, + // sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + // assertEquals("Check response code after create Sub category", + // STATUS_CODE_NOT_FOUND, createGroupingRest.getErrorCode().intValue()); + // RestResponse getAllCategoriesRest = + // CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + // PRODUCT_COMPONENT_TYPE); + // assertEquals("Check response code after get all categories ", + // STATUS_CODE_SUCCESS, getAllCategoriesRest.getErrorCode().intValue()); + // CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + // productCategoryDefinition.getUniqueId(), + // productSubCategoryDefinition.getUniqueId(), + // productGroupingDefinition); + // //Audit validation + // productSubCategoryDefinition100.setName(productSubCategoryDefinition100.getUniqueId()); + // AuditValidationUtils.groupingAuditFailure(ADD_GROUPING , + // productCategoryDefinition, productSubCategoryDefinition100, + // productGroupingDefinition, sdncProductStrategistUserDetails, + // ActionStatus.COMPONENT_CATEGORY_NOT_FOUND, + // STATUS_CODE_NOT_FOUND,AUDIT_PRODUCT_TYPE, PRODUCT_COMPONENT_TYPE, + // SUB_CATEGORY, ""); + } + + @Test + public void ProductGroupAllowedcharacters_01() throws Exception { + productGroupingDefinition.setName("1234AbcdE-"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde-"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_02() throws Exception { + productGroupingDefinition.setName("1234AbcdE+"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde+"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_03() throws Exception { + productGroupingDefinition.setName("1234AbcdE&"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde&"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_04() throws Exception { + productGroupingDefinition.setName("1234AbcdE-"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde-"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_05() throws Exception { + productGroupingDefinition.setName("1234AbcdE+"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde+"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_06() throws Exception { + productGroupingDefinition.setName("1234AbcdE."); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde."); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_07() throws Exception { + productGroupingDefinition.setName("1234AbcdE'"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde'"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_08() throws Exception { + productGroupingDefinition.setName("1234AbcdE="); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde="); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_09() throws Exception { + productGroupingDefinition.setName("1234AbcdE:"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde:"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_10() throws Exception { + productGroupingDefinition.setName("1234AbcdE@"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde@"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_11() throws Exception { + productGroupingDefinition.setName("1234AbcdE_"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde_"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_12() throws Exception { + productGroupingDefinition.setName("1234AbcdE#"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("1234abcde#"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void ProductGroupAllowedcharacters_13() throws Exception { + productGroupingDefinition.setName("1234AbcdE d"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("1234AbcdE D"); + productGroupingDefinition.setNormalizedName("1234abcde d"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveSpaceFromBeginning() throws Exception { + productGroupingDefinition.setName(" Category01"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("category01"); + productGroupingDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveSpaceFromEnd() throws Exception { + productGroupingDefinition.setName("Category01 "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("category01"); + productGroupingDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraSpace() throws Exception { + productGroupingDefinition.setName("Category 02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("category 02"); + productGroupingDefinition.setName("Category 02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraAmpersand() throws Exception { + productGroupingDefinition.setName("Category&& &02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("category& &02"); + productGroupingDefinition.setName("Category& &02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraDash() throws Exception { + productGroupingDefinition.setName("CategorY-- --02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("category- -02"); + productGroupingDefinition.setName("CategorY- -02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraPlus() throws Exception { + productGroupingDefinition.setName("CateGory++++ +02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("CateGory+ +02"); + productGroupingDefinition.setNormalizedName("category+ +02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraPeriod() throws Exception { + productGroupingDefinition.setName("Category.... .02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category. .02"); + productGroupingDefinition.setNormalizedName("category. .02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraApostrophe() throws Exception { + productGroupingDefinition.setName("CaTegory''' '02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("CaTegory' '02"); + productGroupingDefinition.setNormalizedName("category' '02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraHashtag() throws Exception { + productGroupingDefinition.setName("Category### #02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category# #02"); + productGroupingDefinition.setNormalizedName("category# #02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtrEequal() throws Exception { + productGroupingDefinition.setName("Category=== =02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category= =02"); + productGroupingDefinition.setNormalizedName("category= =02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtrColon() throws Exception { + productGroupingDefinition.setName("Category::: :02"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category: :02"); + productGroupingDefinition.setNormalizedName("category: :02"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtrAt() throws Exception { + productGroupingDefinition.setName("Category@@@ @a2"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category@ @a2"); + productGroupingDefinition.setNormalizedName("category@ @a2"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_RemoveExtraUnderscore() throws Exception { + productGroupingDefinition.setName("Category___ _22"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Category_ _22"); + productGroupingDefinition.setNormalizedName("category_ _22"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_FirstWordStartWithNumber() throws Exception { + productGroupingDefinition.setName("1Category one"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("1Category One"); + productGroupingDefinition.setNormalizedName("1category one"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_FirstWordStartWithNonAlphaNumeric() throws Exception { // The + // first + // word + // must + // start + // with + // an + // alpha-numeric + // character + // [a-Z + // A..Z, + // 0..9] + char invalidChars[] = { '&', '-', '+', '.', '\'', '#', '=', ':', '@', '_' }; + RestResponse createGroupingRest; + RestResponse getAllCategoriesRest; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + productGroupingDefinition.setName(invalidChars[i] + "AbcD123"); + productGroupingDefinition.setNormalizedName((invalidChars[i] + "AbcD123").toLowerCase()); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + } + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_01() throws Exception { + productGroupingDefinition.setName("At and T"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("At & T"); + productGroupingDefinition.setNormalizedName("at & t"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_02() throws Exception { + productGroupingDefinition.setName("At and t"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("At & T"); + productGroupingDefinition.setNormalizedName("at & t"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_03() throws Exception { + productGroupingDefinition.setName("Atand T"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("atand t"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_04() throws Exception { + productGroupingDefinition.setName("At andT"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("at andt"); + productGroupingDefinition.setName("At AndT"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_05() throws Exception { + productGroupingDefinition.setName(" and AttT"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("and attt"); + productGroupingDefinition.setName("And AttT"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_06() throws Exception { + productGroupingDefinition.setName("AttT and "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("attt and"); + productGroupingDefinition.setName("AttT And"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidation_ReplaceAndWithAmpersand_07() throws Exception { + productGroupingDefinition.setName(" and a"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("and a"); + productGroupingDefinition.setName("And a"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationMaxLength() throws Exception { + productGroupingDefinition.setName("AsdfghjQ234567890@#.&:+-_"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("asdfghjq234567890@#.&:+-_"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationMaxLengthAfterNormalization() throws Exception { + productGroupingDefinition.setName(" A jQ234 @@@___ +++ At and T and and "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("a jq234 @_ + at & t & and"); + productGroupingDefinition.setName("A JQ234 @_ + At & T & And"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationExceedMaxLengthAfterNormalization() throws Exception { + productGroupingDefinition.setName(" AbdfghBCVa jQ234 @@___ +++ At and T "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("abdfghbcva jq234 @_ + at&t"); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, STATUS_CODE_INVALID_CONTENT, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, GROUPING); + } + + @Test + public void groupNameValidationMinLengthAfterNormalization() throws Exception { + productGroupingDefinition.setName(" At&&&&&&&&&&&&t "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("at&t"); + productGroupingDefinition.setName("At&t"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationLessThanMinLengthAfterNormalization() throws Exception { + productGroupingDefinition.setName(" A&&&&&&&&&&&&T "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("a&t"); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, STATUS_CODE_INVALID_CONTENT, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, GROUPING); + } + + @Test + public void groupNameValidationIsEmpty() throws Exception { + productGroupingDefinition.setName(""); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName(""); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, GROUPING); + } + + @Test + public void groupNameValidationInvalidCharacters() throws Exception { + RestResponse createGroupingRest; + RestResponse getAllCategoriesRest; + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + productGroupingDefinition.setName("AbcD123" + invalidChars[i]); + createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_INVALID_CONTENT, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName(""); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditFailure(ADD_GROUPING, productCategoryDefinition, + productSubCategoryDefinition, productGroupingDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, GROUPING); + } + } + + @Test + public void groupNameValidationConjunctions_01() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" bank OF america "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setNormalizedName("bank of america"); + productGroupingDefinition.setName("Bank of America"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_02() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName("THE america bank "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("THE America Bank"); + productGroupingDefinition.setNormalizedName("the america bank"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_03() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" A bank OF america "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("A Bank of America"); + productGroupingDefinition.setNormalizedName("a bank of america"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_04() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" bank america is A big ban "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Bank America Is a Big Ban"); + productGroupingDefinition.setNormalizedName("bank america is a big ban"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_05() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" aN apple comPany inC "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("AN Apple ComPany InC"); + productGroupingDefinition.setNormalizedName("an apple company inc"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_06() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" eat AN apple ANAN"); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Eat an Apple ANAN"); + productGroupingDefinition.setNormalizedName("eat an apple anan"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_07() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" united states OF americA "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("United States of AmericA"); + productGroupingDefinition.setNormalizedName("united states of america"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_08() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" oF united states OF amer "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("OF United States of Amer"); + productGroupingDefinition.setNormalizedName("of united states of amer"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_09() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" to Apple TO at&T TOO "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("To Apple to At&T TOO"); + productGroupingDefinition.setNormalizedName("to apple to at&t too"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_10() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" eat apple AS you liiikeas "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Eat Apple as You Liiikeas"); + productGroupingDefinition.setNormalizedName("eat apple as you liiikeas"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_11() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" as you may want "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("As You May Want"); + productGroupingDefinition.setNormalizedName("as you may want"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_12() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" the bank OF america "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("The Bank of America"); + productGroupingDefinition.setNormalizedName("the bank of america"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_13() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" To tel-toto "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("To Tel-toto"); + productGroupingDefinition.setNormalizedName("to tel-toto"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void groupNameValidationConjunctions_14() throws Exception { + // Normalize the grouping name conjunctions ('of', 'to', 'for', 'as', + // 'a', 'an' , 'the') are lower case. + productGroupingDefinition.setName(" tel-aviv To la "); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create product group", STATUS_CODE_CREATED, + createGroupingRest.getErrorCode().intValue()); + productGroupingDefinition.setName("Tel-aviv to La"); + productGroupingDefinition.setNormalizedName("tel-aviv to la"); + CategoryValidationUtils.validateCreateGroupResponse(createGroupingRest, productGroupingDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + AuditValidationUtils.groupingAuditSuccess(ADD_GROUPING, productCategoryDefinition, productSubCategoryDefinition, + productGroupingDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, AUDIT_PRODUCT_TYPE); + } + + @Test + public void createProductGroupHttpCspUserIdIsEmpty() throws Exception { + User sdncPS = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + sdncPS.setUserId(""); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncPS, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_GROUPING); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(productCategoryDefinition.getUniqueId()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(productSubCategoryDefinition.getUniqueId()); + expectedCatrgoryAuditJavaObject.setGroupingName(productGroupingDefinition.getName()); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_PRODUCT_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_GROUPING); + } + + @Test + public void createProductGroupHttpCspUserIdIsNull() throws Exception { + User sdncPS = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + sdncPS.setUserId(null); + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(productGroupingDefinition, + productSubCategoryDefinition, productCategoryDefinition, sdncPS, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createGroupingRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifyGroupingNotExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition.getUniqueId(), + productGroupingDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_GROUPING); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(productCategoryDefinition.getUniqueId()); + expectedCatrgoryAuditJavaObject.setSubCategoryName(productSubCategoryDefinition.getUniqueId()); + expectedCatrgoryAuditJavaObject.setGroupingName(productGroupingDefinition.getName()); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_PRODUCT_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_GROUPING); + } + + //////////////////////////////////////////////// + /////////////////////////////////////////////// + @Test + public void getProductCategoryHierarchySuccessFlow() throws Exception { + throw new SkipException( + "Skipping - failed in audit validation expected \"products\" actual result was \"product\" "); + // int numOfGrouping = 3; + // List groupingList = new ArrayList<>(); + // RestResponse restResponse; + // GroupingDefinition grouping; + // String groupingName = productGroupingDefinition.getName(); + // for (int i = 0; i < numOfGrouping; i++) { + // productGroupingDefinition.setName(groupingName+i); + // restResponse = + // CategoryRestUtils.createGrouping(productGroupingDefinition, + // productSubCategoryDefinition, productCategoryDefinition, + // sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + // grouping = ResponseParser.parseToObject(restResponse.getResponse(), + // GroupingDefinition.class); + // groupingList.add(grouping); + // } + // RestResponse getAllCategoriesRest = + // CategoryRestUtils.getAllCategories(sdncProductStrategistUserDetails, + // PRODUCT_COMPONENT_TYPE); + // assertEquals("Check response code after get all categories ", + // STATUS_CODE_SUCCESS, getAllCategoriesRest.getErrorCode().intValue()); + // AuditValidationUtils.GetCategoryHierarchyAuditSuccess(GET_CATEGORY_HIERARCHY, + // AUDIT_PRODUCT_TYPE, sdncProductStrategistUserDetails, + // STATUS_CODE_SUCCESS); + // + // for (GroupingDefinition group : groupingList) { + // CategoryValidationUtils.verifyGroupingExistInGetResponse(getAllCategoriesRest, + // productCategoryDefinition.getUniqueId(), + // productSubCategoryDefinition.getUniqueId(), group); + // } + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/SubCategoriesTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/SubCategoriesTest.java new file mode 100644 index 0000000000..dd96ebfc2f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/category/SubCategoriesTest.java @@ -0,0 +1,1907 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.category; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.PRODUCT_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.RESOURCE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.SERVICE_COMPONENT_TYPE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_ALREADY_EXISTS; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_CREATED; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_MISSING_INFORMATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_NOT_FOUND; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedCategoryAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.CategoryValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class SubCategoriesTest extends ComponentBaseTest { + + protected static final String ADD_SUB_CATEGORY = "AddSubCategory"; + protected static final String CATEGORY = "category"; + protected static final String SUB_CATEGORY = "sub-category"; + + protected static final String AUDIT_SERVICE_TYPE = "Service"; + protected static final String AUDIT_RESOURCE_TYPE = "Resource"; + protected static final String AUDIT_PRODUCT_TYPE = "Product"; + protected static final String GET_CATEGORY_HIERARCHY = "GetCategoryHierarchy"; + protected static User sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected static User sdncAdminUserDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected static User sdncDesignerUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected static User sdncTesterUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + protected static User sdncGovernorUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + protected static User sdncOpsUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + protected static User sdncProductManagerUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + protected static User sdncProductStrategistUserDetails = ElementFactory + .getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + + public SubCategoriesTest() { + super(name, SubCategoriesTest.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + + private CategoryDefinition resourceCategoryDefinition; + private CategoryDefinition resourceCategoryDefinition1; + private CategoryDefinition serviceCategoryDefinition; + private CategoryDefinition productCategoryDefinition; + private CategoryDefinition productCategoryDefinition1; + private CategoryDefinition resourceCategoryDefinition100; + private CategoryDefinition productCategoryDefinition200; + + private SubCategoryDefinition resourceSubCategoryDefinition; + private SubCategoryDefinition resourceSubCategoryDefinition1; + private SubCategoryDefinition serviceSubCategoryDefinition; + private SubCategoryDefinition productSubCategoryDefinition; + private SubCategoryDefinition productSubCategoryDefinition1; + + @BeforeMethod + public void init() throws Exception { + + // Category setup + resourceCategoryDefinition = new CategoryDefinition(); + resourceCategoryDefinition1 = new CategoryDefinition(); + serviceCategoryDefinition = new CategoryDefinition(); + productCategoryDefinition = new CategoryDefinition(); + productCategoryDefinition1 = new CategoryDefinition(); + resourceCategoryDefinition100 = new CategoryDefinition(); // for + // negative + // tests + productCategoryDefinition200 = new CategoryDefinition(); // for negative + // tests + + resourceCategoryDefinition.setName("Category1"); + resourceCategoryDefinition1.setName("Category2"); + serviceCategoryDefinition.setName("Category1"); + productCategoryDefinition.setName("Category2"); + productCategoryDefinition1.setName("Category3"); + resourceCategoryDefinition100.setName("Category100"); + productCategoryDefinition200.setName("Category100"); + + // Subcategory setup + resourceSubCategoryDefinition = new SubCategoryDefinition(); + resourceSubCategoryDefinition1 = new SubCategoryDefinition(); + serviceSubCategoryDefinition = new SubCategoryDefinition(); + productSubCategoryDefinition = new SubCategoryDefinition(); + productSubCategoryDefinition1 = new SubCategoryDefinition(); + + resourceSubCategoryDefinition.setName("Resource-subcat"); + // Service sub - for negative testing since it's not allowed + serviceSubCategoryDefinition.setName("Service-subcat"); + productSubCategoryDefinition.setName("Product-subcat"); + + // Init resource category + RestResponse createCategory = CategoryRestUtils.createCategory(resourceCategoryDefinition, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + CategoryDefinition category = ResponseParser.parseToObject(createCategory.getResponse(), + CategoryDefinition.class); + assertEquals("Check category name after creating category ", resourceCategoryDefinition.getName(), + category.getName()); + resourceCategoryDefinition = category; + + // Init resource category1 + createCategory = CategoryRestUtils.createCategory(resourceCategoryDefinition1, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + category = ResponseParser.parseToObject(createCategory.getResponse(), CategoryDefinition.class); + assertEquals("Check category name after creating category ", resourceCategoryDefinition1.getName(), + category.getName()); + resourceCategoryDefinition1 = category; + + // Init service category + createCategory = CategoryRestUtils.createCategory(serviceCategoryDefinition, sdncAdminUserDetails, + SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + category = ResponseParser.parseToObject(createCategory.getResponse(), CategoryDefinition.class); + assertEquals("Check category name after creating category ", serviceCategoryDefinition.getName(), + category.getName()); + serviceCategoryDefinition = category; + + // Init product category + createCategory = CategoryRestUtils.createCategory(productCategoryDefinition, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + category = ResponseParser.parseToObject(createCategory.getResponse(), CategoryDefinition.class); + assertEquals("Check category name after creating category ", productCategoryDefinition.getName(), + category.getName()); + productCategoryDefinition = category; + + // Init product category1 + createCategory = CategoryRestUtils.createCategory(productCategoryDefinition1, sdncProductStrategistUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create category", STATUS_CODE_CREATED, + createCategory.getErrorCode().intValue()); + category = ResponseParser.parseToObject(createCategory.getResponse(), CategoryDefinition.class); + assertEquals("Check category name after creating category ", productCategoryDefinition1.getName(), + category.getName()); + productCategoryDefinition1 = category; + + } + + @Test + public void createResourceSubCategorySuccess() throws Exception { + createSubCategorySuccess(resourceCategoryDefinition, resourceSubCategoryDefinition, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE, AUDIT_RESOURCE_TYPE); + } + + @Test + public void createProductSubCategorySuccess() throws Exception { + createSubCategorySuccess(productCategoryDefinition, productSubCategoryDefinition, + sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE, AUDIT_PRODUCT_TYPE); + } + + @Test + public void createProductSubCategoryTwoCategoriesCaseInsensitive() throws Exception { + String componentType = PRODUCT_COMPONENT_TYPE; + String auditType = AUDIT_PRODUCT_TYPE; + User user = sdncProductStrategistUserDetails; + // Create product sub Category2-->Product-subcat + createSubCategorySuccess(productCategoryDefinition, productSubCategoryDefinition, user, componentType, + auditType); + DbUtils.deleteFromEsDbByPattern("_all"); + + // Create product sub Category3-->PRoDUCT-SUBcat + // Should be created Category3-->Product-subcat + productSubCategoryDefinition1.setName("PRoDUCT-SUBcat"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition1, + productCategoryDefinition1, user, componentType); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(user, componentType); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + productSubCategoryDefinition1.setName(productSubCategoryDefinition.getName()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition1.getUniqueId(), productSubCategoryDefinition1); + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, productCategoryDefinition1, + productSubCategoryDefinition1, user, STATUS_CODE_CREATED, auditType); + } + + // Benny + @Test + public void createResourceSubCategoryAlreadyExistInDifferentResourceCategory() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + DbUtils.deleteFromEsDbByPattern("_all"); + resourceSubCategoryDefinition1.setName("ResourcE-subCat"); + createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition1, + resourceCategoryDefinition1, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + resourceSubCategoryDefinition1.setName(resourceSubCategoryDefinition.getName()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition1.getUniqueId(), resourceSubCategoryDefinition1); // also + // set + // catalog + // uniqeId + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition1, + resourceSubCategoryDefinition1, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void createProductSubCategoryAlreadyExistInDifferentProductCategory() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, + AUDIT_PRODUCT_TYPE); + DbUtils.deleteFromEsDbByPattern("_all"); + productSubCategoryDefinition1.setName("PRoDUCT-SUBcat"); + createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition1, + productCategoryDefinition1, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + productSubCategoryDefinition1.setName(productSubCategoryDefinition.getName()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition1.getUniqueId(), productSubCategoryDefinition1); // also + // set + // catalog + // uniqeId + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, productCategoryDefinition1, + productSubCategoryDefinition1, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, + AUDIT_PRODUCT_TYPE); + } + + @Test + public void createResourceSubCategoryAlreadyExistInCategory() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + DbUtils.deleteFromEsDbByPattern("_all"); + resourceSubCategoryDefinition1.setName("ResourcE-subCat"); + createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition1, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_ALREADY_EXISTS, + createSubCategoryRest.getErrorCode().intValue()); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition1, sdncAdminUserDetails, + ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, STATUS_CODE_ALREADY_EXISTS, + AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, resourceSubCategoryDefinition1.getName(), + resourceCategoryDefinition.getName()); + } + + @Test + public void createProductSubCategoryAlreadyExistInCategory() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, + AUDIT_PRODUCT_TYPE); + DbUtils.deleteFromEsDbByPattern("_all"); + productSubCategoryDefinition1.setName("ProducT-subCat"); + createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition1, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_ALREADY_EXISTS, + createSubCategoryRest.getErrorCode().intValue()); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition1, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, STATUS_CODE_ALREADY_EXISTS, AUDIT_PRODUCT_TYPE, + AUDIT_PRODUCT_TYPE, productSubCategoryDefinition1.getName(), productCategoryDefinition.getName()); + } + + @Test + public void addSameNormalizedSubCategoryNameForRecourceAndProductCategory() throws Exception { + // add sub-categoty name "SubCaT" to resource category + // add sub-categoty name "SUbcAt" to product category + resourceSubCategoryDefinition.setName("SubCaT"); // normalized 'subcat' + productSubCategoryDefinition.setName("SUbcAt"); // normalized 'subcat' + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + + DbUtils.deleteFromEsDbByPattern("_all"); + createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncProductStrategistUserDetails, STATUS_CODE_CREATED, + AUDIT_PRODUCT_TYPE); + } + + @Test + public void createResourceSubCategoryByNonAdminUser() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncTesterUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_RESTRICTED_OPERATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + resourceCategoryDefinition.setName(resourceCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncTesterUserDetails, ActionStatus.RESTRICTED_OPERATION, + STATUS_CODE_RESTRICTED_OPERATION, AUDIT_RESOURCE_TYPE); + } + + @Test + public void createResourceSubCategoryByProducStrategistUser() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncProductStrategistUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_RESTRICTED_OPERATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + resourceCategoryDefinition.setName(resourceCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncProductStrategistUserDetails, ActionStatus.RESTRICTED_OPERATION, + STATUS_CODE_RESTRICTED_OPERATION, AUDIT_RESOURCE_TYPE); + } + + @Test + public void createProductSubCategoryByNonProducStrategistUser() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncDesignerUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_RESTRICTED_OPERATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncDesignerUserDetails, ActionStatus.RESTRICTED_OPERATION, + STATUS_CODE_RESTRICTED_OPERATION, AUDIT_PRODUCT_TYPE); + } + + @Test + public void createProductSubCategoryByAdminUser() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncAdminUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_RESTRICTED_OPERATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.RESTRICTED_OPERATION, + STATUS_CODE_RESTRICTED_OPERATION, AUDIT_PRODUCT_TYPE); + } + + // @Ignore("DE176245") + @Test + public void createResourceSubCategoryForNonExistingComponentType() throws Exception { + String nonSupportedComponentType = "NonExistingComponentType"; // instead + // resource/product + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, nonSupportedComponentType); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + resourceCategoryDefinition.setName(resourceCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, nonSupportedComponentType); + } + + // @Ignore("DE176245") + @Test + public void createProductSubCategoryForNonExistingComponentType() throws Exception { + String nonSupportedComponentType = "NonExistingComponentType"; // instead + // resource/product + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, nonSupportedComponentType); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncProductStrategistUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, nonSupportedComponentType); + } + + @Test + public void createServiceSubCategoryByAdmin() throws Exception { + // Service doesn't have sub-category + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + resourceCategoryDefinition.setName(resourceCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE); + } + + @Test + public void createServiceSubCategoryByProductStrategist() throws Exception { + // Service doesn't have sub-category + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition, sdncProductStrategistUserDetails, SERVICE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + productCategoryDefinition.getUniqueId(), productSubCategoryDefinition); + // Audit validation + productCategoryDefinition.setName(productCategoryDefinition.getUniqueId()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition, + productSubCategoryDefinition, sdncProductStrategistUserDetails, ActionStatus.INVALID_CONTENT, + STATUS_CODE_INVALID_CONTENT, AUDIT_SERVICE_TYPE); + } + + @Test + public void createResourceSubCategoryForNonExistingCategory() throws Exception { + resourceCategoryDefinition100.setUniqueId(resourceCategoryDefinition100.getName()); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition100, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_NOT_FOUND, + createSubCategoryRest.getErrorCode().intValue()); + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition100, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.COMPONENT_CATEGORY_NOT_FOUND, + STATUS_CODE_NOT_FOUND, AUDIT_RESOURCE_TYPE, RESOURCE_COMPONENT_TYPE, CATEGORY, ""); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition100.getUniqueId(), resourceSubCategoryDefinition); + } + + @Test + public void createProductSubCategoryForNonExistingCategory() throws Exception { + productCategoryDefinition200.setUniqueId(productCategoryDefinition200.getName()); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(productSubCategoryDefinition, + productCategoryDefinition200, sdncProductStrategistUserDetails, PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_NOT_FOUND, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + PRODUCT_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + productCategoryDefinition200.getUniqueId(), productSubCategoryDefinition); + // Audit validation // need to change ActionStatus + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, productCategoryDefinition200, + productSubCategoryDefinition, sdncProductStrategistUserDetails, + ActionStatus.COMPONENT_CATEGORY_NOT_FOUND, STATUS_CODE_NOT_FOUND, AUDIT_PRODUCT_TYPE, + PRODUCT_COMPONENT_TYPE, CATEGORY, ""); + } + + // pass + @Test + public void subCategoryAllowedcharacters_01() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE-"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); // also + // set + // catalog + // uniqeId + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + // pass + @Test + public void subCategoryAllowedcharacters_02() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE+"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_03() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE&"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_04() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE."); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_05() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE'"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_06() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE="); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_07() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE:"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_08() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE@"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_09() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE_"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_10() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE#"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_11() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE d"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("1234AbcdE D"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryAllowedcharacters_12() throws Exception { + resourceSubCategoryDefinition.setName("1234AbcdE &_=+.-'#:@ d"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("1234AbcdE &_=+.-'#:@ D"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveSpaceFromBeginning() throws Exception { + resourceSubCategoryDefinition.setName(" Category01"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveSpaceFromEnd() throws Exception { + resourceSubCategoryDefinition.setName("Category01 "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category01"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraSpace() throws Exception { + resourceSubCategoryDefinition.setName("Category 02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category 02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraAmpersand() throws Exception { + resourceSubCategoryDefinition.setName("Category&& &02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category& &02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraDash() throws Exception { + resourceSubCategoryDefinition.setName("CategorY-- --02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("CategorY- -02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraPlus() throws Exception { + resourceSubCategoryDefinition.setName("CateGory++++ +02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("CateGory+ +02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraPeriod() throws Exception { + resourceSubCategoryDefinition.setName("Category.... .02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category. .02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraApostrophe() throws Exception { + resourceSubCategoryDefinition.setName("CaTegory''' '02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("CaTegory' '02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraHashtag() throws Exception { + resourceSubCategoryDefinition.setName("Category### #02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category# #02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtrEequal() throws Exception { + resourceSubCategoryDefinition.setName("Category=== =02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category= =02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtrColon() throws Exception { + resourceSubCategoryDefinition.setName("Category::: :02"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category: :02"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtrAt() throws Exception { + resourceSubCategoryDefinition.setName("Category@@@ @a2"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category@ @a2"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryRemoveExtraUnderscore() throws Exception { + resourceSubCategoryDefinition.setName("Category___ _22"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Category_ _22"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryFirstWordStartWithNumber() throws Exception { + resourceSubCategoryDefinition.setName("1Category one"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("1Category One"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + // Bug + // Desc= + // DESC=SVC4556: Error: InvalidResourcesub-categorynameformat., + // @Ignore + @Test + public void subCategoryFirstWordStartWithNonAlphaNumeric() throws Exception { + // The first word must start with an alpha-numeric character [a-Z A..Z, + // 0..9] + char invalidChars[] = { '&', '-', '+', '.', '\'', '#', '=', ':', '@', '_' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + resourceSubCategoryDefinition.setName(invalidChars[i] + "AbcD123"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, + AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, SUB_CATEGORY); + + } + } + + @Test + public void subCategoryReplaceAndWithAmpersand_01() throws Exception { + resourceSubCategoryDefinition.setName("At and T"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("At & T"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_02() throws Exception { + resourceSubCategoryDefinition.setName("At and t"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("At & T"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_03() throws Exception { + resourceSubCategoryDefinition.setName("Atand T"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_04() throws Exception { + resourceSubCategoryDefinition.setName("At andT"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("At AndT"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_05() throws Exception { + resourceSubCategoryDefinition.setName(" and AttT"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("And AttT"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_06() throws Exception { + resourceSubCategoryDefinition.setName("AttT and "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("AttT And"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryReplaceAndWithAmpersand_07() throws Exception { + resourceSubCategoryDefinition.setName(" and a"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("And a"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationMaxLength() throws Exception { + resourceSubCategoryDefinition.setName("AsdfghjQ234567890@#.&:+-_"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationMaxLengthAfterNormalization() throws Exception { + resourceSubCategoryDefinition.setName(" A jQ234 @@@___ +++ At and T and and "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("A JQ234 @_ + At & T & And"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + // bug : + // Desc= + @Test + public void subCategoryNameValidationExceedMaxLengthAfterNormalization() throws Exception { + resourceSubCategoryDefinition.setName(" AbdfghBCVa jQ234 @@___ +++ At and T "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, + STATUS_CODE_INVALID_CONTENT, AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, SUB_CATEGORY); + } + + @Test + public void subCategoryNameValidationMinLengthAfterNormalization() throws Exception { + resourceSubCategoryDefinition.setName(" AT&&&&&&&&&T "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("AT&T"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + // bug + // Desc= + @Test + public void subCategoryNameValidationLessThanMinLengthAfterNormalization() throws Exception { + resourceSubCategoryDefinition.setName(" A&&&T "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, + STATUS_CODE_INVALID_CONTENT, AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, SUB_CATEGORY); + } + + @Test + public void subCategoryNameIsEmpty() throws Exception { + resourceSubCategoryDefinition.setName(""); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, + STATUS_CODE_INVALID_CONTENT, AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, SUB_CATEGORY); + } + + // bug + // Desc= + @Test + public void subCategoryNameValidationInvalidCharacters() throws Exception { + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + resourceSubCategoryDefinition.setName("AbcD123" + invalidChars[i]); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_INVALID_CONTENT, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditFailure(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, STATUS_CODE_INVALID_CONTENT, + AUDIT_RESOURCE_TYPE, AUDIT_RESOURCE_TYPE, SUB_CATEGORY); + } + } + + @Test + public void subCategoryNameValidationFirstLetterOfKeyWordsCapitalized() throws Exception { + resourceSubCategoryDefinition.setName("beNNy shaY michEl"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("BeNNy ShaY MichEl"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_01() throws Exception { + resourceSubCategoryDefinition.setName(" bank OF america "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Bank of America"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_02() throws Exception { + resourceSubCategoryDefinition.setName("THE america bank "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("THE America Bank"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_03() throws Exception { + resourceSubCategoryDefinition.setName(" A bank OF america "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("A Bank of America"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_04() throws Exception { + resourceSubCategoryDefinition.setName(" bank america is A big ban "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Bank America Is a Big Ban"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_05() throws Exception { + resourceSubCategoryDefinition.setName(" aN apple comPany inC "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("AN Apple ComPany InC"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_06() throws Exception { + resourceSubCategoryDefinition.setName(" eat AN apple ANAN"); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Eat an Apple ANAN"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_07() throws Exception { + resourceSubCategoryDefinition.setName(" united states OF americA "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("United States of AmericA"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_08() throws Exception { + resourceSubCategoryDefinition.setName(" oF united states OF amer "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("OF United States of Amer"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_09() throws Exception { + resourceSubCategoryDefinition.setName(" to Apple TO at&T TOO "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("To Apple to At&T TOO"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_10() throws Exception { + resourceSubCategoryDefinition.setName(" eat apple AS you liiikeas "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Eat Apple as You Liiikeas"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_11() throws Exception { + resourceSubCategoryDefinition.setName(" as you may want "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("As You May Want"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_12() throws Exception { + resourceSubCategoryDefinition.setName(" the bank OF america "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("The Bank of America"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_13() throws Exception { + resourceSubCategoryDefinition.setName(" To tel-toto "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("To Tel-toto"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void subCategoryNameValidationConjunctions_14() throws Exception { + resourceSubCategoryDefinition.setName(" tel-aviv To la "); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + resourceSubCategoryDefinition.setName("Tel-aviv to La"); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, resourceSubCategoryDefinition); + + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, resourceCategoryDefinition, + resourceSubCategoryDefinition, sdncAdminUserDetails, STATUS_CODE_CREATED, AUDIT_RESOURCE_TYPE); + } + + @Test + public void createSubCategoryHttpCspUserIdHeaderIsMissing() throws Exception { + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategoryHttpCspAtuUidIsMissing( + resourceSubCategoryDefinition, resourceCategoryDefinition, sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_MISSING_INFORMATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_SUB_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(resourceCategoryDefinition.getUniqueId()); + // String subCategoryName = (resourceSubCategoryDefinition != null ? + // resourceSubCategoryDefinition.getName() : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setSubCategoryName(resourceSubCategoryDefinition.getName()); + // String groupingName = (groupingDefinition != null ? + // groupingDefinition.getName() : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_RESOURCE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_SUB_CATEGORY); + } + + @Test + public void createSubCategoryHttpCspUserIdIsEmpty() throws Exception { + User sdncAdminUserDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncAdminUserDetails1.setUserId(""); + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails1, RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after create Sub category", STATUS_CODE_MISSING_INFORMATION, + createSubCategoryRest.getErrorCode().intValue()); + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryNotExistsInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), resourceSubCategoryDefinition); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(ADD_SUB_CATEGORY); + expectedCatrgoryAuditJavaObject.setModifier(""); + expectedCatrgoryAuditJavaObject.setCategoryName(resourceCategoryDefinition.getUniqueId()); + // String subCategoryName = (resourceSubCategoryDefinition != null ? + // resourceSubCategoryDefinition.getName() : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setSubCategoryName(resourceSubCategoryDefinition.getName()); + // String groupingName = (groupingDefinition != null ? + // groupingDefinition.getName() : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setGroupingName(""); + expectedCatrgoryAuditJavaObject.setResourceType(AUDIT_RESOURCE_TYPE); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(STATUS_CODE_MISSING_INFORMATION)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, ADD_SUB_CATEGORY); + } + + //////////////////////////////////////////////////////////// + private void createSubCategorySuccess(CategoryDefinition categoryDefinition, + SubCategoryDefinition subCategoryDefinition, User sdncAdminUserDetails, String componentType, + String auditType) throws Exception { + + RestResponse createSubCategoryRest = CategoryRestUtils.createSubCategory(subCategoryDefinition, + categoryDefinition, sdncAdminUserDetails, componentType); + assertEquals("Check response code after create Sub category", STATUS_CODE_CREATED, + createSubCategoryRest.getErrorCode().intValue()); + CategoryValidationUtils.validateCreateSubCategoryResponse(createSubCategoryRest, subCategoryDefinition); + // Audit validation + AuditValidationUtils.subCategoryAuditSuccess(ADD_SUB_CATEGORY, categoryDefinition, subCategoryDefinition, + sdncAdminUserDetails, STATUS_CODE_CREATED, auditType); + // get service category and validate that category added as defined + // (also set catalog uniqeId) + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, componentType); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + categoryDefinition.getUniqueId(), subCategoryDefinition); // also + // set + // catalog + // uniqeId + } + + @Test + public void getResourceCategoryHierarchySuccessFlow() throws Exception { + int numOfSubCategories = 3; + List subCategories = new ArrayList(); + RestResponse restResponse; + SubCategoryDefinition subCategory; + String subName = resourceSubCategoryDefinition.getName(); + for (int i = 0; i < numOfSubCategories; i++) { + resourceSubCategoryDefinition.setName(subName + i); + restResponse = CategoryRestUtils.createSubCategory(resourceSubCategoryDefinition, + resourceCategoryDefinition, sdncAdminUserDetails, RESOURCE_COMPONENT_TYPE); + subCategory = ResponseParser.parseToObject(restResponse.getResponse(), SubCategoryDefinition.class); + subCategories.add(subCategory); + } + RestResponse getAllCategoriesRest = CategoryRestUtils.getAllCategories(sdncAdminUserDetails, + RESOURCE_COMPONENT_TYPE); + assertEquals("Check response code after get all categories ", STATUS_CODE_SUCCESS, + getAllCategoriesRest.getErrorCode().intValue()); + AuditValidationUtils.GetCategoryHierarchyAuditSuccess(GET_CATEGORY_HIERARCHY, AUDIT_RESOURCE_TYPE, + sdncAdminUserDetails, STATUS_CODE_SUCCESS); + for (SubCategoryDefinition sub : subCategories) { + CategoryValidationUtils.verifySubCategoryExistInGetResponse(getAllCategoriesRest, + resourceCategoryDefinition.getUniqueId(), sub); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/CRUDExternalAPI.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/CRUDExternalAPI.java new file mode 100644 index 0000000000..418e8f6dc8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/CRUDExternalAPI.java @@ -0,0 +1,1011 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.devCI; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpResponseException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicResponseHandler; +import org.apache.http.util.EntityUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceDetailedAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.AssetRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import fj.data.Either; + +public class CRUDExternalAPI extends ComponentBaseTest { + + private static Logger log = LoggerFactory.getLogger(CRUDExternalAPI.class.getName()); + protected static final String UPLOAD_ARTIFACT_PAYLOAD = "UHVUVFktVXNlci1LZXktRmlsZS0yOiBzc2gtcnNhDQpFbmNyeXB0aW9uOiBhZXMyNTYtY2JjDQpDb21tZW5wOA0K"; + protected static final String UPLOAD_ARTIFACT_NAME = "TLV_prv.ppk"; + + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + + protected Gson gson = new Gson(); + protected JSONParser jsonParser = new JSONParser(); + + protected String serviceVersion; + protected ResourceReqDetails resourceDetails; + protected User sdncUserDetails; + protected ServiceReqDetails serviceDetails; + + @BeforeMethod + public void init() throws Exception { + AtomicOperationUtils.createDefaultConsumer(true); + } + + @Rule + public static TestName name = new TestName(); + + public CRUDExternalAPI() { + super(name, CRUDExternalAPI.class.getName()); + + } + + @DataProvider(name = "uploadArtifactOnVFViaExternalAPI") + public static Object[][] dataProviderUploadArtifactOnVFViaExternalAPI() { + return new Object[][] { { LifeCycleStatesEnum.CHECKIN, "DCAE_JSON" }, + { LifeCycleStatesEnum.CHECKOUT, "DCAE_POLICY" }, { LifeCycleStatesEnum.CHECKOUT, "DCAE_EVENT" }, + { LifeCycleStatesEnum.CHECKOUT, "APPC_CONFIG" }, { LifeCycleStatesEnum.CHECKOUT, "DCAE_DOC" }, + { LifeCycleStatesEnum.CHECKOUT, "DCAE_TOSCA" }, { LifeCycleStatesEnum.CHECKOUT, "YANG_XML" }, + { LifeCycleStatesEnum.CHECKOUT, "VNF_CATALOG" }, { LifeCycleStatesEnum.CHECKOUT, "VF_LICENSE" }, + { LifeCycleStatesEnum.CHECKOUT, "VENDOR_LICENSE" }, + { LifeCycleStatesEnum.CHECKOUT, "MODEL_INVENTORY_PROFILE" }, + { LifeCycleStatesEnum.CHECKOUT, "MODEL_QUERY_SPEC" }, { LifeCycleStatesEnum.CHECKOUT, "OTHER" } }; + } + + // External API + // Upload artifact on VF via external API - happy flow + @Test(dataProvider = "uploadArtifactOnVFViaExternalAPI") + public void uploadArtifactOnVFViaExternalAPI(LifeCycleStatesEnum chosenLifeCycleState, String artifactType) + throws Exception { + // Method passed variable + // artifactType = "YANG_XML"; + // chosenLifeCycleState = LifeCycleStatesEnum.CHECKOUT; + + // String operationType = "Upload"; + UserRoleEnum creatorUser = UserRoleEnum.DESIGNER; + String specificUser = "DESIGNER"; + + Component resourceDetails = getComponentInTargetLifeCycleState("vf", creatorUser, chosenLifeCycleState); + + String resourceUUID = resourceDetails.getUUID(); + System.out.println("Resource UUID: " + resourceUUID); + + // get artifact data + ArtifactReqDetails artifactReqDetails = ElementFactory.getArtifactByType("Abcd", artifactType, true); + + RestResponse restResponse = ArtifactRestUtils.externalAPIUploadArtifactOfTheAsset(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.valueOf(specificUser.toUpperCase())), artifactReqDetails); + + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + + // ArtifactDefinition artifactJavaObject = + // ResponseParser.convertArtifactDefinitionResponseToJavaObject(restResponse.getResponse()); + // AuditingActionEnum action = + // AuditingActionEnum.ARTIFACT_UPLOAD_BY_API; + // ExpectedExternalAudit expectedExternalAudit = + // ElementFactory.getDefaultExternalArtifactAuditSuccess(AssetTypeEnum.RESOURCES, + // action, artifactJavaObject, resourceUUID); + // AuditValidationUtils.validateExternalAudit(expectedExternalAudit, + // AuditingActionEnum.ARTIFACT_UPLOAD_BY_API.getName(), null); + } + + @DataProvider(name = "uploadArtifactOnServiceViaExternalAPI") + public static Object[][] dataProviderUploadArtifactOnServiceViaExternalAPI() { + return new Object[][] { + // {LifeCycleStatesEnum.CHECKOUT, "YANG_XML"}, + // {LifeCycleStatesEnum.CHECKOUT, "VNF_CATALOG"}, + // {LifeCycleStatesEnum.CHECKOUT, "MODEL_INVENTORY_PROFILE"}, + // {LifeCycleStatesEnum.CHECKOUT, "MODEL_QUERY_SPEC"}, + // {LifeCycleStatesEnum.CHECKOUT, "OTHER"}, + { LifeCycleStatesEnum.CHECKIN, "YANG_XML" }, { LifeCycleStatesEnum.CHECKIN, "VNF_CATALOG" }, + { LifeCycleStatesEnum.CHECKIN, "MODEL_INVENTORY_PROFILE" }, + { LifeCycleStatesEnum.CHECKIN, "MODEL_QUERY_SPEC" }, { LifeCycleStatesEnum.CHECKIN, "OTHER" }, + { LifeCycleStatesEnum.CERTIFICATIONREQUEST, "YANG_XML" }, + { LifeCycleStatesEnum.CERTIFICATIONREQUEST, "VNF_CATALOG" }, + { LifeCycleStatesEnum.CERTIFICATIONREQUEST, "MODEL_INVENTORY_PROFILE" }, + { LifeCycleStatesEnum.CERTIFICATIONREQUEST, "MODEL_QUERY_SPEC" }, + { LifeCycleStatesEnum.CERTIFICATIONREQUEST, "OTHER" } }; + } + + @Test(dataProvider = "uploadArtifactOnServiceViaExternalAPI") + public void uploadArtifactOnServiceViaExternalAPI(LifeCycleStatesEnum chosenLifeCycleState, String artifactType) + throws Exception { + Component resourceDetails = getComponentInTargetLifeCycleState("service", UserRoleEnum.DESIGNER, + chosenLifeCycleState); + double resourceVersion = Double.parseDouble(resourceDetails.getVersion()); + + // get artifact data + ArtifactReqDetails artifactReqDetails = ElementFactory.getArtifactByType("Abcd", artifactType, true); + + System.out.println("Service UUID: " + resourceDetails.getUUID()); + System.out.println("Service Version: " + resourceVersion); + System.out.println("Service life cycle state: " + chosenLifeCycleState); + System.out.println("Artifact Type: " + artifactReqDetails.getArtifactType()); + + RestResponse restResponse = ArtifactRestUtils.externalAPIUploadArtifactOfTheAsset(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), artifactReqDetails); + + // Check response of external API + Integer responseCode = restResponse.getErrorCode(); + Integer expectedCode = 200; + Assert.assertEquals(responseCode, expectedCode, "Response code is not correct."); + + // TODO: Check auditing for upload opeartion + // ArtifactDefinition artifactJavaObject = + // ResponseParser.convertArtifactDefinitionResponseToJavaObject(restResponse.getResponse()); + // AuditingActionEnum action = + // AuditingActionEnum.ARTIFACT_UPLOAD_BY_API; + // ExpectedExternalAudit expectedExternalAudit = + // ElementFactory.getDefaultExternalArtifactAuditSuccess(AssetTypeEnum.RESOURCES, + // action, artifactJavaObject, resourceUUID); + // AuditValidationUtils.validateExternalAudit(expectedExternalAudit, + // AuditingActionEnum.ARTIFACT_UPLOAD_BY_API.getName(), null); + + // Check Service version (increase by one if not in checkout) + if (!chosenLifeCycleState.equals(LifeCycleStatesEnum.CHECKOUT)) { + double resourceNewVersion = Double.parseDouble(resourceDetails.getVersion()); + + System.out.println(resourceVersion); + System.out.println(resourceNewVersion); + } + } + + @Test + public void artifactOperationOnRIViaExternalAPI() throws Exception { + // Method passed variable + String operationType = "Upload"; + LifeCycleStatesEnum chosenLifeCycleState = LifeCycleStatesEnum.CHECKOUT; + UserRoleEnum creatorUser = UserRoleEnum.DESIGNER; + String specificUser = "DESIGNER"; + String artifactType = "OTHER"; + + Component resourceDetails = getComponentInTargetLifeCycleState("service", creatorUser, chosenLifeCycleState); + Component resourceInstanceDetails = getComponentInTargetLifeCycleState("vf", creatorUser, chosenLifeCycleState); + ComponentInstance componentResourceInstanceDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceInstanceDetails, resourceDetails, + UserRoleEnum.DESIGNER, true) + .left().value(); + + String resourceUUID = resourceDetails.getUUID(); + System.out.println("Resource UUID: " + resourceUUID); + + // get artifact data + ArtifactReqDetails artifactReqDetails = ElementFactory.getArtifactByType("Abcd", artifactType, true); + + RestResponse restResponse = null; + + if (operationType.toLowerCase().equals("upload")) { + restResponse = ArtifactRestUtils.externalAPIUploadArtifactOfTheAsset(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.valueOf(specificUser.toUpperCase())), + artifactReqDetails); + System.out.println("1234"); + } + + ArtifactDefinition artifactJavaObject = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(restResponse.getResponse()); + AuditingActionEnum action = AuditingActionEnum.ARTIFACT_UPLOAD_BY_API; + ExpectedExternalAudit expectedExternalAudit = ElementFactory.getDefaultExternalArtifactAuditSuccess( + AssetTypeEnum.RESOURCES, action, artifactJavaObject, resourceUUID); + AuditValidationUtils.validateExternalAudit(expectedExternalAudit, + AuditingActionEnum.ARTIFACT_UPLOAD_BY_API.getName(), null); + } + + // @Test + // public void artifactViaExternalAPI() throws Exception { + // // Method passed variable + // String operationType = "Upload"; + // String assetType = "vf"; + // LifeCycleStatesEnum chosenLifeCycleState = LifeCycleStatesEnum.CHECKOUT; + // String componentInstanceAssetType = "vf"; + // LifeCycleStatesEnum componentInstanceChosenLifeCycleState = + // LifeCycleStatesEnum.CHECKOUT; + // UserRoleEnum creatorUser = UserRoleEnum.DESIGNER; + // String specificUser = "DESIGNER"; + // String artifactType = "HEAT"; + // + // + // Component resourceDetails = null; + // Component resourceInstanceDetails = null; + // ComponentInstance componentResourceInstanceDetails = null; + // + // String resourceUUID = null; + // String resourceType = null; + // String resourceInstanceName = null; + // + // // Create resource & resource instance of requested type and state + // if (assetType.toLowerCase().equals("vf")) { + // resourceDetails = getComponentInTargetLifeCycleState("vf", creatorUser, + // chosenLifeCycleState); + // } else if (assetType.toLowerCase().equals("service")) { + // resourceDetails = getComponentInTargetLifeCycleState("service", + // creatorUser, chosenLifeCycleState); + // } else if (assetType.toLowerCase().equals("ri")) { + // resourceInstanceDetails = getComponentInTargetLifeCycleState("vf", + // creatorUser, chosenLifeCycleState); + // if(componentInstanceAssetType.toLowerCase().equals("vf")) { + // resourceDetails = getComponentInTargetLifeCycleState("vf", creatorUser, + // componentInstanceChosenLifeCycleState); + // componentResourceInstanceDetails = + // AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceInstanceDetails, + // resourceDetails, UserRoleEnum.DESIGNER, true).left().value(); + // } else if (componentInstanceAssetType.toLowerCase().equals("service")) { + // resourceDetails = getComponentInTargetLifeCycleState("service", + // creatorUser, componentInstanceChosenLifeCycleState); + // componentResourceInstanceDetails = + // AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceInstanceDetails, + // resourceDetails, UserRoleEnum.DESIGNER, true).left().value(); + // } else { + // Assert.assertEquals(false, true, "Component instance asset type is + // wrong."); + // } + // } else { + // Assert.assertEquals(false, true, "Asset type is wrong."); + // } + // + // + // // print uuid & resource instance name + // if (assetType.toLowerCase().equals("ri")) { + // resourceUUID = resourceDetails.getUUID(); + // resourceInstanceName = + // componentResourceInstanceDetails.getNormalizedName(); + // + // + // System.out.println("Resource UUID: " + resourceUUID); + // System.out.println("Resource instance name: " + resourceInstanceName); + // System.out.println("Resource type: " + resourceType); + // } else { + // resourceUUID = resourceDetails.getUUID(); + // + // System.out.println("Resource UUID: " + resourceUUID); + // System.out.println("Resource type: " + resourceType); + // } + // + // // get artifact data + // ArtifactReqDetails artifactReqDetails = + // ElementFactory.getArtifactByType("Abcd", artifactType, true); + // + //// RestResponse restResponse; + // // using rest external api + //// if(operationType.toLowerCase().equals("upload")) { + //// if (!assetType.toLowerCase().equals("ri")) { + // RestResponse restResponse = + // ArtifactRestUtils.externalAPIUploadArtifactOfTheAsset(resourceDetails, + // ElementFactory.getDefaultUser(UserRoleEnum.valueOf(specificUser.toUpperCase())), + // artifactReqDetails); + // System.out.println("1234"); + //// } else { + //// + //// } + //// } else { + //// + //// } + // + // ArtifactDefinition artifactJavaObject = + // ResponseParser.convertArtifactDefinitionResponseToJavaObject(restResponse.getResponse()); + //// AuditingActionEnum action = AuditingActionEnum.ARTIFACT_UPLOAD_BY_API; + // AuditingActionEnum action = AuditingActionEnum.ARTIFACT_UPLOAD_BY_API; + // ExpectedExternalAudit expectedExternalAudit = + // ElementFactory.getDefaultExternalArtifactAuditSuccess(AssetTypeEnum.RESOURCES, + // action, artifactJavaObject, resourceUUID); + // AuditValidationUtils.validateExternalAudit(expectedExternalAudit, + // AuditingActionEnum.ARTIFACT_UPLOAD_BY_API.getName(), null); + // + // + // + // + // } + // + + @Test + public void getResourceAssetMetadataWithNonCertifiedResourceInstancesAndArtifactsSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + // TODO + Either artifactDefinition = AtomicOperationUtils + .uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.APPC_CONFIG, resourceVF, UserRoleEnum.DESIGNER, true, + true); + resourceVF = ResponseParser.parseToObjectUsingMapper( + ResourceRestUtils.getResource(resourceVF.getUniqueId()).getResponse(), Resource.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + // AuditValidationUtils.validateAudit(expectedAssetListAudit, + // AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + + } + + public Component getComponentInTargetLifeCycleState(String componentType, UserRoleEnum creatorUser, + LifeCycleStatesEnum targetLifeCycleState) throws Exception { + Component resourceDetails = null; + + if (componentType.toLowerCase().equals("vf")) { + Either createdResource = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, creatorUser, true); + resourceDetails = createdResource.left().value(); + resourceDetails = AtomicOperationUtils + .changeComponentState(resourceDetails, creatorUser, targetLifeCycleState, true).getLeft(); + } else { + Either createdResource = AtomicOperationUtils.createDefaultService(creatorUser, + true); + resourceDetails = createdResource.left().value(); + resourceDetails = AtomicOperationUtils + .changeComponentState(resourceDetails, creatorUser, targetLifeCycleState, true).getLeft(); + } + + return resourceDetails; + } + + // // External API - Download artifact for resource - negative test + // @Test + // public void k() throws Exception { + // Resource resourceDetailsVF; + // Either createdResource = + // AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, + // NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, + // UserRoleEnum.DESIGNER, true); + // resourceDetailsVF = createdResource.left().value(); + // ArtifactDefinition heatArtifact = + // AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, + // resourceDetailsVF, UserRoleEnum.DESIGNER, true, true).left().value(); + // resourceDetails = new ResourceReqDetails(resourceDetailsVF); + // + // String resourceUUID = resourceDetailsVF.getUUID(); + // String artifactUUID = heatArtifact.getArtifactUUID(); + // + // System.out.println("Resource UUID: " + resourceUUID); + // System.out.println("Artifact UUID: " + artifactUUID); + // + // RestResponse restResponse = + // ArtifactRestUtils.getResourceDeploymentArtifactExternalAPI(resourceUUID, + // "dfsgfdsg324", ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), + // "Resource"); + // + // Integer responseCode = restResponse.getErrorCode(); + // Integer expectedCode = 200; + // Assert.assertEquals(responseCode,expectedCode, "Response code is not + // correct."); + // } + // + // + // + // + // + // // External API - Download artifact for service - negative test + // @Test + // public void downloadArtifactFromServiceViaExternalAPI() throws Exception + // { + // + // Service resourceDetailsService; + // Either createdResource = + // AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true); + // resourceDetailsService = createdResource.left().value(); + // + // ArtifactDefinition heatArtifact = + // AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, + // resourceDetailsService, UserRoleEnum.DESIGNER, true, + // true).left().value(); + // + // String resourceUUID = resourceDetailsService.getUUID(); + // String artifactUUID = heatArtifact.getArtifactUUID(); + // + // System.out.println("Resource UUID: " + resourceUUID); + // System.out.println("Artifact UUID: " + artifactUUID); + // + // RestResponse restResponse = + // ArtifactRestUtils.getResourceDeploymentArtifactExternalAPI(resourceUUID, + // artifactUUID, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), + // "Service"); + // + // Integer responseCode = restResponse.getErrorCode(); + // Integer expectedCode = 200; + // Assert.assertEquals(responseCode,expectedCode, "Response code is not + // correct."); + // + // String response = restResponse.getResponse(); + // + // String payloadData = + // "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + // String decodedPaypload = Decoder.decode(payloadData); + // + // Assert.assertEquals(response, decodedPaypload, "Response deployment + // artifact not correct."); + // + // String auditAction = "ArtifactDownload"; + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new + // ExpectedResourceAuditJavaObject(); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceName(resourceDetailsService.getName()); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setStatus("200"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // + // expectedResourceAuditJavaObject.setCONSUMER_ID("ci"); + // String resource_url = + // String.format("/asdc/v1/catalog/services/%s/artifacts/%s", resourceUUID, + // artifactUUID); + // expectedResourceAuditJavaObject.setRESOURCE_URL(resource_url); + // + // AuditValidationUtils.validateAuditDownloadExternalAPI(expectedResourceAuditJavaObject, + // auditAction, null, false); + // } + // + // + // + // + // + // + // // External API - Download ComponentInstance artifact of service - + // negative test + // @Test + // public void + // downloadArtifactOfComponentInstanceFromServiceViaExternalAPI() throws + // Exception { + // + // Either resourceDetailsVF_01e = + // AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, + // NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, + // UserRoleEnum.DESIGNER, true); + // Component resourceDetailsVF_01 = resourceDetailsVF_01e.left().value(); + // ArtifactDefinition heatArtifact = + // AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, + // resourceDetailsVF_01, UserRoleEnum.DESIGNER, true, true).left().value(); + // + // resourceDetailsVF_01 = + // AtomicOperationUtils.changeComponentState(resourceDetailsVF_01, + // UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + // + // Service resourceDetailsService; + // Either createdResource = + // AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true); + // resourceDetailsService = createdResource.left().value(); + // + // + // ComponentInstance resourceDetailsVF1ins_01 = + // AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVF_01, + // resourceDetailsService, UserRoleEnum.DESIGNER, true).left().value(); + // + // + // System.out.println("-----"); + // + // + // String resourceUUID = resourceDetailsService.getUUID(); + // String componentInstanceUID = resourceDetailsVF1ins_01.getUniqueId(); + // String artifactUUID = heatArtifact.getArtifactUUID(); + // + // System.out.println("Resource UUID: " + resourceUUID); + // System.out.println("Component instance UID: " + componentInstanceUID); + // System.out.println("Artifact UUID: " + artifactUUID); + // + // RestResponse restResponse = + // ArtifactRestUtils.getComponentInstanceDeploymentArtifactExternalAPI(resourceUUID, + // componentInstanceUID, artifactUUID, + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "Service"); + //// + // Integer responseCode = restResponse.getErrorCode(); + // Integer expectedCode = 200; + // Assert.assertEquals(responseCode,expectedCode, "Response code is not + // correct."); + // + // String response = restResponse.getResponse(); + // + // String payloadData = + // "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + // String decodedPaypload = Decoder.decode(payloadData); + // + // Assert.assertEquals(response, decodedPaypload, "Response deployment + // artifact not correct."); + // + // String auditAction = "ArtifactDownload"; + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new + // ExpectedResourceAuditJavaObject(); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceName(resourceDetailsVF1ins_01.getName()); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setStatus("200"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // + // expectedResourceAuditJavaObject.setCONSUMER_ID("ci"); + // String resource_url = + // String.format("/asdc/v1/catalog/services/%s/resourceInstances/%s/artifacts/%s", + // resourceUUID, componentInstanceUID, artifactUUID); + // expectedResourceAuditJavaObject.setRESOURCE_URL(resource_url); + // + // AuditValidationUtils.validateAuditDownloadExternalAPI(expectedResourceAuditJavaObject, + // auditAction, null, false); + // } + // + // + // + // + // + // + // + // + // + // @Test + // public void downloadArtifactFromResourceTest() throws Exception { + // + // CloseableHttpClient httpclient = HttpClients.createDefault(); + // try { + // String jsonBody = createUploadArtifactBodyJson(); + // + // String resourceId = resourceDetails.getUniqueId(); + // String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, + // config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + // HttpPost httppost = createPostAddArtifactRequeast(jsonBody, url, true); + // HttpResponse response = httpclient.execute(httppost); + // int status = response.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("failed to add artifact", 200, status); + // + // ArtifactDefinition origArtifact = getArtifactDataFromJson(jsonBody); + // addArtifactDataFromResponse(response, origArtifact); + // String artifactId = origArtifact.getUniqueId(); + // + // url = String.format(Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT, + // config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, + // artifactId); + // HttpGet httpGet = createGetRequest(url); + // response = httpclient.execute(httpGet); + // status = response.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("failed to download artifact", 200, status); + // + // InputStream inputStream = response.getEntity().getContent(); + // ArtifactUiDownloadData artifactUiDownloadData = + // getArtifactUiDownloadData(IOUtils.toString(inputStream)); + // AssertJUnit.assertEquals("Downloaded payload is different from uploaded + // one", UPLOAD_ARTIFACT_PAYLOAD, + // artifactUiDownloadData.getBase64Contents()); + // AssertJUnit.assertEquals("Downloaded artifact name is different from + // uploaded one", UPLOAD_ARTIFACT_NAME, + // artifactUiDownloadData.getArtifactName()); + // + // // validate audit + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // Convertor.constructFieldsForAuditValidation(resourceDetails, + // resourceDetails.getVersion(), sdncUserDetails); + // String auditAction = "ArtifactDownload"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("200"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // expectedResourceAuditJavaObject.setArtifactData(AuditValidationUtils.buildArtifactDataAudit(origArtifact)); + // expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + // expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // } finally { + // httpclient.close(); + // } + // + // } + // + // @Test + // public void downloadArtifactFromServiceTest() throws Exception { + // + // CloseableHttpClient httpclient = HttpClients.createDefault(); + // + // try { + // + // String jsonStr = createUploadArtifactBodyJson(); + // + // String url = String.format(Urls.ADD_ARTIFACT_TO_SERVICE, + // config.getCatalogBeHost(), config.getCatalogBePort(), + // serviceDetails.getUniqueId()); + // HttpPost httpPost = createPostAddArtifactRequeast(jsonStr, url, true); + // CloseableHttpResponse result = httpclient.execute(httpPost); + // int status = result.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("failed to add artifact", 200, status); + // + // ArtifactDefinition origArtifact = getArtifactDataFromJson(jsonStr); + // addArtifactDataFromResponse(result, origArtifact); + // String artifactId = origArtifact.getUniqueId(); + // + // url = String.format(Urls.UI_DOWNLOAD_SERVICE_ARTIFACT, + // config.getCatalogBeHost(), config.getCatalogBePort(), + // serviceDetails.getUniqueId(), artifactId); + // HttpGet httpGet = createGetRequest(url); + // CloseableHttpResponse response2 = httpclient.execute(httpGet); + // status = response2.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("failed to download artifact", 200, status); + // InputStream inputStream = response2.getEntity().getContent(); + // ArtifactUiDownloadData artifactUiDownloadData = + // getArtifactUiDownloadData(IOUtils.toString(inputStream)); + // AssertJUnit.assertEquals("Downloaded payload is different from uploaded + // one", UPLOAD_ARTIFACT_PAYLOAD, + // artifactUiDownloadData.getBase64Contents()); + // AssertJUnit.assertEquals("Downloaded artifact name is different from + // uploaded one", UPLOAD_ARTIFACT_NAME, + // artifactUiDownloadData.getArtifactName()); + // + // // validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // AuditValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // serviceDetails.getVersion(), sdncUserDetails); + // String auditAction = "ArtifactDownload"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("200"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // expectedResourceAuditJavaObject.setArtifactData(AuditValidationUtils.buildArtifactDataAudit(origArtifact)); + // expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + // expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + // + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // } finally { + //// RestResponse response = ServiceRestUtils.deleteService(serviceDetails, + // serviceVersion, sdncUserDetails ); + //// checkDeleteResponse(response); + // httpclient.close(); + // } + // } + // + // @Test + // public void downloadArtifactFromResourceNotFound() throws Exception { + // + // CloseableHttpClient httpclient = HttpClients.createDefault(); + // try { + // + // String resourceId = resourceDetails.getUniqueId(); + // String artifactIdNotFound = "11111"; + // + // ArtifactDefinition origArtifact = new ArtifactDefinition(); + // origArtifact.setUniqueId(artifactIdNotFound); + // + // String url = String.format(Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT, + // config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, + // artifactIdNotFound); + // HttpGet httpGet = createGetRequest(url); + // CloseableHttpResponse response = httpclient.execute(httpGet); + // int status = response.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("expected 404 not found", 404, status); + // + // // validate audit + // ErrorInfo errorInfo = + // ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()); + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // Convertor.constructFieldsForAuditValidation(resourceDetails, + // resourceDetails.getVersion(), sdncUserDetails); + // String auditAction = "ArtifactDownload"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + // expectedResourceAuditJavaObject.setArtifactData(""); + // expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + // expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // expectedResourceAuditJavaObject.setPrevArtifactUuid(null); + // } finally { + // httpclient.close(); + // } + // + // } + // + // @Test + // public void downloadArtifactFromServiceNotFound() throws Exception { + // + // CloseableHttpClient httpclient = HttpClients.createDefault(); + // try { + // + // String artifactIdNotFound = "11111"; + // ArtifactDefinition origArtifact = new ArtifactDefinition(); + // origArtifact.setUniqueId(artifactIdNotFound); + // + // String url = String.format(Urls.UI_DOWNLOAD_SERVICE_ARTIFACT, + // config.getCatalogBeHost(), config.getCatalogBePort(), + // serviceDetails.getUniqueId(), artifactIdNotFound); + // HttpGet httpGet = createGetRequest(url); + // CloseableHttpResponse response2 = httpclient.execute(httpGet); + // int status = response2.getStatusLine().getStatusCode(); + // AssertJUnit.assertEquals("expected 404 not found", 404, status); + // + // // validate audit + // ErrorInfo errorInfo = + // ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()); + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // serviceDetails.getVersion(), sdncUserDetails); + // String auditAction = "ArtifactDownload"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + // expectedResourceAuditJavaObject.setArtifactData(""); + // expectedResourceAuditJavaObject.setCurrArtifactUuid(origArtifact.getUniqueId()); + // expectedResourceAuditJavaObject.setPrevArtifactUuid(""); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // } finally { + // httpclient.close(); + // } + // + // } + // + // @Test + // public void addArtifactToResourceTest() throws Exception { + // + // ArtifactReqDetails defaultArtifact = ElementFactory.getDefaultArtifact(); + // + // RestResponse response = + // ArtifactRestUtils.addInformationalArtifactToResource(defaultArtifact, + // sdncUserDetails, resourceDetails.getUniqueId()); + // int status = response.getErrorCode(); + // AssertJUnit.assertEquals("add informational artifact request returned + // status: " + response.getErrorCode(), 200, status); + // + // RestResponse resourceResp = + // ResourceRestUtils.getResource(resourceDetails.getUniqueId()); + // Resource resource = + // ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + // AssertJUnit.assertNotNull(resource); + // + // Map artifacts = resource.getArtifacts(); + // boolean isExist = false; + // for (Map.Entry entry : artifacts.entrySet()) + // { + // if (entry.getKey().equals(defaultArtifact.getArtifactLabel())) { + // isExist = true; + // + // } + // } + // AssertJUnit.assertTrue(isExist); + // } + + protected String createUploadArtifactBodyJson() { + Map jsonBody = new HashMap(); + jsonBody.put("artifactName", UPLOAD_ARTIFACT_NAME); + jsonBody.put("artifactDisplayName", "configure"); + jsonBody.put("artifactType", "SHELL"); + jsonBody.put("mandatory", "false"); + jsonBody.put("description", "ff"); + jsonBody.put("payloadData", UPLOAD_ARTIFACT_PAYLOAD); + jsonBody.put("artifactLabel", "configure"); + return gson.toJson(jsonBody); + } + + protected ArtifactDefinition getArtifactDataFromJson(String json) { + Gson gson = new Gson(); + JsonObject jsonElement = new JsonObject(); + jsonElement = gson.fromJson(json, jsonElement.getClass()); + ArtifactDefinition artifact = new ArtifactDefinition(); + String payload = null; + JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA); + if (artifactPayload != null && !artifactPayload.isJsonNull()) { + payload = artifactPayload.getAsString(); + } + jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA); + artifact = gson.fromJson(jsonElement, ArtifactDefinition.class); + artifact.setPayloadData(payload); + + /* + * atifact.setArtifactName(UPLOAD_ARTIFACT_NAME); + * artifact.setArtifactDisplayName("configure"); + * artifact.setArtifactType("SHELL"); artifact.setMandatory(false); + * artifact.setDescription("ff"); + * artifact.setPayloadData(UPLOAD_ARTIFACT_PAYLOAD); + * artifact.setArtifactLabel("configure"); + */ + return artifact; + } + + protected HttpGet createGetRequest(String url) { + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httpGet.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httpGet.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + return httpGet; + } + + protected String getArtifactUid(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected String getArtifactEsId(HttpResponse response) throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + String esId = (String) responseMap.get("EsId"); + return esId; + } + + protected ArtifactDefinition addArtifactDataFromResponse(HttpResponse response, ArtifactDefinition artifact) + throws HttpResponseException, IOException, ParseException { + // String responseString = new + // BasicResponseHandler().handleResponse(response); + HttpEntity entity = response.getEntity(); + String responseString = EntityUtils.toString(entity); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + artifact.setEsId((String) responseMap.get("esId")); + artifact.setUniqueId((String) responseMap.get("uniqueId")); + artifact.setArtifactGroupType(ArtifactGroupTypeEnum.findType((String) responseMap.get("artifactGroupType"))); + artifact.setTimeout(((Long) responseMap.get("timeout")).intValue()); + return artifact; + } + + protected String getLifecycleArtifactUid(CloseableHttpResponse response) + throws HttpResponseException, IOException, ParseException { + String responseString = new BasicResponseHandler().handleResponse(response); + JSONObject responseMap = (JSONObject) jsonParser.parse(responseString); + responseMap = (JSONObject) responseMap.get("implementation"); + String artifactId = (String) responseMap.get("uniqueId"); + return artifactId; + } + + protected HttpDelete createDeleteArtifactRequest(String url) { + HttpDelete httpDelete = new HttpDelete(url); + httpDelete.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + httpDelete.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + return httpDelete; + } + + protected HttpPost createPostAddArtifactRequeast(String jsonBody, String url, boolean addMd5Header) + throws UnsupportedEncodingException { + HttpPost httppost = new HttpPost(url); + httppost.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + httppost.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + httppost.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + if (addMd5Header) { + httppost.addHeader(HttpHeaderEnum.Content_MD5.getValue(), GeneralUtility.calculateMD5ByString(jsonBody)); + } + StringEntity input = new StringEntity(jsonBody); + input.setContentType("application/json"); + httppost.setEntity(input); + log.debug("Executing request {}", httppost.getRequestLine()); + return httppost; + } + + protected String createLoadArtifactBody() { + Map json = new HashMap(); + json.put("artifactName", "install_apache2.sh"); + json.put("artifactType", "SHELL"); + json.put("description", "ddd"); + json.put("payloadData", "UEsDBAoAAAAIAAeLb0bDQz"); + json.put("artifactLabel", "name123"); + + String jsonStr = gson.toJson(json); + return jsonStr; + } + + protected void checkDeleteResponse(RestResponse response) { + BaseRestUtils.checkStatusCode(response, "delete request failed", false, 204, 404); + } + + protected ArtifactUiDownloadData getArtifactUiDownloadData(String artifactUiDownloadDataStr) throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + try { + ArtifactUiDownloadData artifactUiDownloadData = mapper.readValue(artifactUiDownloadDataStr, + ArtifactUiDownloadData.class); + return artifactUiDownloadData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarUpdate.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarUpdate.java new file mode 100644 index 0000000000..2c9d96d79d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarUpdate.java @@ -0,0 +1,356 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.devCI; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.imports.ImportCsarResourceTest; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.AfterTest; +import org.testng.annotations.BeforeTest; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class ImportCsarUpdate extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public ImportCsarUpdate() { + super(name, ImportCsarUpdate.class.getName()); + } + + @DataProvider(name = "happyArts") + public Object[][] getHappyArtifacts() { + + return new Object[][] { { "happy_VF_RI2_G2_two_different_artifacts_under_heatBaseheatVolheatNet2" }, + { "happy_VF_RI2_G2_two_different_artifacts_under_heatBaseheatVolheatNet" }, + { "happy_VF_RI2_G2_two_identical_artifacts_under_heatBaseheatVolheatNet" }, + { "happy_VF_RI2_G2_two_different_artifacts_under_nested" }, + { "happy_VF_RI2_G2_two_indentical_nested_under_different_groups" }, + { "happy_VF_RI2_G2_two_different_nested_under_different_groups" }, + { "happy_VF_RI2_G2_two_different_nested_under_same_group" }, + + }; + } + + @DataProvider(name = "negativeArts") + public Object[][] getNegativeArtifacts() { + + return new Object[][] { + + { "negative_VF_RI2_G2_same_heatVol_different_groups" }, + { "negative_VF_RI2_G2_same_heatBase_different_envs" }, + { "negative_VF_RI2_G2_heatBaseHeatVolHeatNet_under_nested" }, + { "negative_VF_RI2_G2_two_indentical_artifacts_under_nested" }, + { "negative_VF_RI2_G2_nested_under_nested" }, { "negative_VF_RI2_G2_same_heatVol_different_groups" }, }; + } + + @BeforeTest + public void resumeOrigCsarBefore() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, "orig.csar", "importCsar_2Gartifacts.csar"); + + } + + @AfterTest + public void resumeOrigCsarAfter() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, "orig.csar", "importCsar_2Gartifacts.csar"); + + } + + @Test + public void updateVFsearchByCsarIdCheckInState() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true) + .getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchByCsarIdCheckInState_checkSum() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true) + .getLeft(); + + // User sdncModifierDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // RestResponse copyRes = + // ImportCsarResourceTest.copyCsarRest(sdncModifierDetails,"updateImportCsar_2Gartifacts_topologyChanged.csar","importCsar_2Gartifacts.csar"); + + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchByCsarIdCheckOutState() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + // Component resourceObject = + // AtomicOperationUtils.changeComponentState(resourceFirstImport, + // UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchByCsarIdCertifyStat() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true) + .getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchByCsarStartCertificationState() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils.changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFICATIONREQUEST, true).getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchBySystemNameCheckInState() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true) + .getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setName("hardcodedNameChanged"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + + @Test + public void updateVFsearchBySystemNameCertifyState() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true) + .getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "updateImportCsar_2Gartifacts_topologyChanged.csar", "importCsar_2Gartifacts.csar"); + + resourceDetails.setName("hardcodedNameChanged"); + resourceDetails.setCsarUUID("importCsar_2Gartifacts"); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + } + + @Test + public void updateVFsearchBySystemNameCsarIdNotExist() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("hardcodedName"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceFirstImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + Component resourceObject = AtomicOperationUtils + .changeComponentState(resourceFirstImport, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true) + .getLeft(); + // User sdncModifierDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // RestResponse copyRes = + // ImportCsarResourceTest.copyCsarRest(sdncModifierDetails,"updateImportCsar_2Gartifacts_topologyChanged.csar","importCsar_2Gartifacts.csar"); + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + resourceDetails2.setName("hardcodedName"); + resourceDetails2.setCsarUUID("importCsar_2Gartifacts"); + resourceDetails2.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails2, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resourceSecondImport = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + // Validation Part + + resourceFirstImport.getGroups().equals(resourceSecondImport.getGroups()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarValidateArtifacts.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarValidateArtifacts.java new file mode 100644 index 0000000000..49e5950db5 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ImportCsarValidateArtifacts.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.devCI; + +import static org.testng.AssertJUnit.assertTrue; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.CsarValidationUtils; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class ImportCsarValidateArtifacts extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public ImportCsarValidateArtifacts() { + super(name, ImportCsarValidateArtifacts.class.getName()); + } + + @DataProvider(name = "happyArts") + public Object[][] getHappyArtifacts() { + + return new Object[][] { { "happy_VF_RI2_G2_two_different_artifacts_under_heatBaseheatVolheatNet2" }, + { "happy_VF_RI2_G2_two_different_artifacts_under_heatBaseheatVolheatNet" }, + { "happy_VF_RI2_G2_two_identical_artifacts_under_heatBaseheatVolheatNet" }, + { "happy_VF_RI2_G2_two_different_artifacts_under_nested" }, + { "happy_VF_RI2_G2_two_indentical_nested_under_different_groups" }, + { "happy_VF_RI2_G2_two_different_nested_under_different_groups" }, + { "happy_VF_RI2_G2_two_different_nested_under_same_group" }, + + }; + } + + @DataProvider(name = "negativeArts") + public Object[][] getNegativeArtifacts() { + + return new Object[][] { + + { "negative_VF_RI2_G2_same_heatVol_different_groups" }, + { "negative_VF_RI2_G2_same_heatBase_different_envs" }, + { "negative_VF_RI2_G2_heatBaseHeatVolHeatNet_under_nested" }, + { "negative_VF_RI2_G2_two_indentical_artifacts_under_nested" }, + { "negative_VF_RI2_G2_nested_under_nested" }, { "negative_VF_RI2_G2_same_heatVol_different_groups" }, }; + } + + @Test(dataProvider = "happyArts") + public void createResourceFromCsarArtsHappy(String artifactName) throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(artifactName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + CsarValidationUtils.validateCsarVfArtifact(artifactName, resource); + + } + + @Test(dataProvider = "negativeArts") + public void createResourceFromCsarArtsNegative(String artifactName) throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(artifactName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + assertTrue(createResource.getErrorCode() != 201 && createResource.getErrorCode() != 500); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ToscaGroupInsideVF.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ToscaGroupInsideVF.java new file mode 100644 index 0000000000..bb86f8f336 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/devCI/ToscaGroupInsideVF.java @@ -0,0 +1,578 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.devCI; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaDefinition; +import org.openecomp.sdc.ci.tests.utils.ToscaParserUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.CsarValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +public class ToscaGroupInsideVF extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(ToscaGroupInsideVF.class.getName()); + + @Rule + public static TestName name = new TestName(); + + public ToscaGroupInsideVF() { + super(name, ToscaGroupInsideVF.class.getName()); + } + + @Test + public void createResourceFromCsarArts() throws Exception { + + // String csar = getCsar(); + // parseCsar(csar); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VF_RI2_G6_withArtifacts"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + Component resourceObject = AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + Resource vfManual = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true) + .left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, vfManual, UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.changeComponentState(vfManual, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true) + .getLeft(); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceObject, service, UserRoleEnum.DESIGNER, true).left() + .value(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(vfManual, service, UserRoleEnum.DESIGNER, true) + .left().value(); + AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CANCELCERTIFICATION, true) + .getLeft(); + AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + } + + @Test + public void soferTest() throws Exception { + + // String csar = getCsar(); + // parseCsar(csar); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("sofer"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + } + + @Test + public void createVFwith2VLs() throws Exception { + + // String csar = getCsar(); + // parseCsar(csar); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VSPPackage"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + Component resourceObject = AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + Resource vfManual = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true) + .left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, vfManual, UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.changeComponentState(vfManual, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true) + .getLeft(); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceObject, service, UserRoleEnum.DESIGNER, true).left() + .value(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(vfManual, service, UserRoleEnum.DESIGNER, true) + .left().value(); + AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CANCELCERTIFICATION, true) + .getLeft(); + AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true) + .getLeft(); + + } + + @Test // (enabled = false) + public void createResourceFromCsarHappy() throws Exception { + // String csarUUID = "VF_RI2_G2_withArtifacts"; + String csarUUID = "VF_RI2_G1_Invalid"; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + } + + @Test // (enabled = false) + public void createResourceFromCsarWithProperty() throws Exception { + String csarUUID = "VF_RI2_G4_withArtifacts"; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + } + + @Test // (enabled = false) + public void UpdateCsarWithNonExistingResourceInstanceFail() throws Exception { + + // String csarUUID = "VF_RI2_G1-RI_NotExist"; + // String csarUUID = "nested3"; + + // String csarUUID = "VF_RI2_G1_Invalid_WithArtifacts"; + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifactsRI_FAIL.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails.setName(resource.getName()); + // resourceDetails.setVendorName("Govnuk"); + // resourceDetails.setDescription("Other"); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void UpdateCsarWithSameCsarDifferentMetadata() throws Exception { + + // User sdncModifierDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // RestResponse copyRes = + // copyCsarRest(sdncModifierDetails,"VF_RI2_G4_withArtifacts_a.csar","VF_RI2_G4_withArtifacts.csar"); + // BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + resourceDetails.setName(resource.getName()); + resourceDetails.setVendorName("Govnuk"); + resourceDetails.setDescription("Other"); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void UpdateCsarWithSameCsar() throws Exception { + + // User sdncModifierDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // RestResponse copyRes = + // copyCsarRest(sdncModifierDetails,"VF_RI2_G4_withArtifacts_a.csar","VF_RI2_G4_withArtifacts.csar"); + // BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + resourceDetails.setName(resource.getName()); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void UpdateCsarCertifiedVfWithSameCsar() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + Pair changeComponentState = AtomicOperationUtils.changeComponentState(resource, + UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + resource = (Resource) changeComponentState.getLeft(); + + resourceDetails.setName(resource.getName()); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void UpdateCsarDifferentTosca() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifactsUpdated.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails.setName(resource.getName()); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void UpdateCsarDifferentToscaAndArtifacts() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + String csarUUID = "VF_RI2_G4_withArtifacts.csar"; + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_UpdateToscaAndArtifacts.csar", + "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails.setName(resource.getName()); + RestResponse createResource2 = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource2); + Resource resource2 = ResponseParser.parseToObjectUsingMapper(createResource2.getResponse(), Resource.class); + + CsarValidationUtils.validateCsarVfArtifact(csarUUID, resource); + ToscaDefinition toscaDefinition = ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition, resource); + + // CsarValidationUtils.validateCsarVfArtifact(csarUUID2, resource2); + // ToscaDefinition toscaDefinition2 = + // ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID2); + // CsarValidationUtils.validateToscaDefinitonObjectVsResource(toscaDefinition2, + // resource2); + + // Csar csar = parserTocsarObject(csarUUID); + // validateCsarVsResourceObj(csar, resource); + // csar.node_types(); + + } + + @Test // (enabled = false) + public void migration() throws Exception { + String csarUUID = "VF_RI2_G4_withArtifacts"; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setName("Resource1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + resourceDetails.setName("Resource2"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + + resourceDetails.setName("Resource3"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + resourceDetails.setName("Resource4"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + resourceDetails.setName("Resource5"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + + resourceDetails.setName("Resource6"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.STARTCERTIFICATION, true) + .getLeft(); + + resourceDetails.setName("Resource7"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + logger.debug("7 VF resources were created"); + + } + + public static RestResponse copyCsarRest(User sdncModifierDetails, String sourceCsarUuid, String targetCsarUuid) + throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.COPY_CSAR_USING_SIMULATOR, config.getCatalogBeHost(), config.getCatalogBePort(), + sourceCsarUuid, targetCsarUuid); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + + RestResponse copyCsarResponse = http.httpSendPost(url, "dummy", headersMap); + if (copyCsarResponse.getErrorCode() != 200) { + return null; + } + return copyCsarResponse; + + } + + private static Map prepareHeadersMap(String userId) { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + return headersMap; + } + + public static void main(String[] args) throws Exception { + // String csarUUID = "VF_RI2_G4_withArtifacts"; + String csarUUID = "node_types"; + ToscaParserUtils.getToscaDefinitionObjectByCsarUuid(csarUUID); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/AuthanticationTests.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/AuthanticationTests.java new file mode 100644 index 0000000000..b4a9bb87ce --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/AuthanticationTests.java @@ -0,0 +1,186 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.distribution; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedAuthenticationAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class AuthanticationTests extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected User sdncUserDetails; + + protected static final String AUTH_SUCCESS = "AUTH_SUCCESS"; + + protected static final String AUTH_REQUIRED = "AUTH_REQUIRED"; + + // user ci password 123456 + // protected final String authorizationHeader = "Basic Y2k6MTIzNDU2"; + // user ci password 123456 + protected final String USER = "ci"; + protected final String PASSWORD = "123456"; + protected final String SALT = "2a1f887d607d4515d4066fe0f5452a50"; + protected final String HASHED_PASSWORD = "0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b"; + protected User sdncAdminUserDetails; + protected ConsumerDataDefinition consumerDataDefinition; + + public AuthanticationTests() { + super(name, AuthanticationTests.class.getName()); + } + + @DataProvider + private final Object[][] getServiceDepArtType() throws IOException, Exception { + return new Object[][] { { ArtifactTypeEnum.YANG_XML.getType() }, { ArtifactTypeEnum.OTHER.getType() } }; + } + + @BeforeMethod + public void setup() throws Exception { + resourceDetails = ElementFactory.getDefaultResource(); + serviceDetails = ElementFactory.getDefaultService(); + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + createComponents(); + consumerDataDefinition = createConsumer(); + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + ; + + RestResponse createResponse = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkCreateResponse(createResponse); + + } + + @AfterMethod + public void tearDown() throws Exception { + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + ; + + } + + protected ConsumerDataDefinition createConsumer() { + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName(USER); + consumer.setConsumerSalt(SALT); + consumer.setConsumerPassword(HASHED_PASSWORD); + return consumer; + + } + + protected void createComponents() throws Exception { + RestResponse response = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + ServiceRestUtils.checkCreateResponse(response); + } + + @Test(dataProvider = "getServiceDepArtType", description = "mumu") + public void downloadServiceArtifactSuccessWithAutantication(String serviceDepArtType) throws Exception { + String serviceUniqueId = serviceDetails.getUniqueId(); + + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(serviceDepArtType); + + RestResponse addArtifactResponse = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, + sdncUserDetails, serviceUniqueId, ArtifactRestUtils.calculateChecksum(artifactDetails)); + AssertJUnit.assertEquals("Check response code after adding interface artifact", 200, + addArtifactResponse.getErrorCode().intValue()); + + String artifactName = ValidationUtils.normalizeFileName(artifactDetails.getArtifactName()); + // Thread.sleep(5000); + Map authorizationHeaders = BaseRestUtils.addAuthorizeHeader(USER, PASSWORD); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, artifactDetails, + sdncUserDetails, authorizationHeaders); + AssertJUnit.assertEquals("Check response code after download resource", 200, + restResponse.getErrorCode().intValue()); + + List contDispHeaderList = restResponse.getHeaderFields().get(Constants.CONTENT_DISPOSITION_HEADER); + AssertJUnit.assertNotNull(contDispHeaderList); + AssertJUnit.assertEquals("Check content disposition header", + new StringBuilder().append("attachment; filename=\"").append(artifactName).append("\"").toString(), + contDispHeaderList.get(0)); + + String downloadUrl = ArtifactRestUtils + .getPartialUrlByArtifactName(serviceDetails, serviceDetails.getVersion(), artifactName).substring(6); + + ExpectedAuthenticationAudit expectedAuthenticationAudit = new ExpectedAuthenticationAudit(downloadUrl, USER, + AuditingActionEnum.AUTH_REQUEST.getName(), AUTH_SUCCESS); + AuditValidationUtils.validateAuthenticationAudit(expectedAuthenticationAudit); + } + + @Test(dataProvider = "getServiceDepArtType") + public void downloadServiceArtifactWithOutAutantication(String serviceDepArtType) throws Exception { + String serviceUniqueId = serviceDetails.getUniqueId(); + + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(serviceDepArtType); + + RestResponse addArtifactResponse = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, + sdncUserDetails, serviceUniqueId, ArtifactRestUtils.calculateChecksum(artifactDetails)); + assertEquals("Check response code after adding interface artifact", 200, + addArtifactResponse.getErrorCode().intValue()); + + Map authorizationHeaders = new HashMap(); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, artifactDetails, + sdncUserDetails, authorizationHeaders); + assertEquals("Check response code after download resource failure", 401, + restResponse.getErrorCode().intValue()); + + String downloadUrl = ArtifactRestUtils.getPartialUrlByArtifactName(serviceDetails, serviceDetails.getVersion(), + artifactDetails.getArtifactName()).substring(6); + ExpectedAuthenticationAudit expectedAuthenticationAudit = new ExpectedAuthenticationAudit(downloadUrl, "", + AuditingActionEnum.AUTH_REQUEST.getName(), AUTH_REQUIRED); + AuditValidationUtils.validateAuthenticationAudit(expectedAuthenticationAudit); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/DistributionDownloadArtifactTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/DistributionDownloadArtifactTest.java new file mode 100644 index 0000000000..6cf5626e7e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/distribution/DistributionDownloadArtifactTest.java @@ -0,0 +1,542 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.distribution; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.zip.ZipInputStream; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedDistDownloadAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class DistributionDownloadArtifactTest extends ComponentBaseTest { + + protected static ResourceReqDetails resourceDetails; + protected static User designerUser; + protected static User adminUser; + protected static String resourceBaseVersion; + // user ci password 123456 + protected final String authorizationHeader = "Basic Y2k6MTIzNDU2"; + protected ConsumerDataDefinition consumerDataDefinition; + + @Rule + public static TestName name = new TestName(); + protected static String artifactInterfaceType; + protected static String artifactOperationName; + + protected static ServiceReqDetails serviceDetails; + protected static String serviceBaseVersion; + protected static String serviceUniqueId; + protected final String USER = "ci"; + protected final String PASSWORD = "123456"; + protected final String SALT = "2a1f887d607d4515d4066fe0f5452a50"; + protected final String HASHED_PASSWORD = "0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b"; + + public DistributionDownloadArtifactTest() { + super(name, DistributionDownloadArtifactTest.class.getName()); + } + + // @BeforeClass + // public static void InitBeforeTest() throws Exception + // { + // + // + // resourceBaseVersion = "0.1"; + // serviceBaseVersion = "0.1"; + // designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + //// resourceDetails = + // ElementFactory.getDefaultResource("tosca.nodes.newnotgenericresource4testNew", + // NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + // "jh0003"); + // resourceDetails = + // ElementFactory.getDefaultResourceByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + // NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + // adminUser); + // serviceDetails = ElementFactory.getDefaultService(); + // serviceUniqueId = "svc_" + serviceDetails.getName().toLowerCase() + "." + + // serviceBaseVersion; + // artifactInterfaceType = "standard"; + // artifactOperationName = "start"; + // } + + @BeforeMethod + public void setup() throws Exception { + + resourceBaseVersion = "0.1"; + serviceBaseVersion = "0.1"; + designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // resourceDetails = + // ElementFactory.getDefaultResource("tosca.nodes.newnotgenericresource4testNew", + // NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + // "jh0003"); + resourceDetails = ElementFactory.getDefaultResourceByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, adminUser); + serviceDetails = ElementFactory.getDefaultService(); + serviceUniqueId = "svc_" + serviceDetails.getName().toLowerCase() + "." + serviceBaseVersion; + artifactInterfaceType = "standard"; + artifactOperationName = "start"; + consumerDataDefinition = createConsumer(); + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, adminUser); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + + RestResponse createResponse = ConsumerRestUtils.createConsumer(consumerDataDefinition, adminUser); + BaseRestUtils.checkCreateResponse(createResponse); + } + + @Test + public void downloadResourceArtifactSuccess() throws Exception { + // Create service + RestResponse serviceResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + AssertJUnit.assertEquals("Check response code after creating resource", 201, + serviceResponse.getErrorCode().intValue()); + + // Create resource + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, designerUser); + AssertJUnit.assertEquals("Check response code after creating resource", 201, + createResource.getErrorCode().intValue()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(createResource.getResponse()); + + ArtifactReqDetails artifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + // Setting the name to be with space + artifactDetails.setArtifactName("test artifact file.yaml"); + // artifactDetails.set(ArtifactRestUtils.calculateChecksum(artifactDetails)); + + RestResponse addArtifactResponse = ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, + designerUser, resource.getUniqueId(), ArtifactRestUtils.calculateChecksum(artifactDetails)); + AssertJUnit.assertEquals("Check response code after adding interface artifact", 200, + addArtifactResponse.getErrorCode().intValue()); + + // Getting expected artifact checksum + ArtifactDefinition artifactResp = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addArtifactResponse.getResponse()); + String expectedPayloadChecksum = artifactResp.getArtifactChecksum(); + + Config config = Utils.getConfig(); + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceBaseVersion, + ValidationUtils.convertToSystemName(resource.getName()), resource.getVersion(), + artifactResp.getArtifactName())); + // String fullUrlFormatted = + // String.format(Urls.DOWNLOAD_RESOURCE_ARTIFACT_FULL_URL, + // config.getCatalogBeHost(),config.getCatalogBePort(), relativeUrl); + // String consumerId = "dummy.ecomp"; + + ResourceReqDetails resourceInfo = new ResourceReqDetails(); + resourceInfo.setName(resource.getName()); + resourceInfo.setVersion(resource.getVersion()); + + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceDetails, resourceInfo, + artifactDetails, designerUser, authorizationHeaders); + // RestResponse restResponse = + // artifactUtils.downloadResourceArtifact(designerUser,fullUrlFormatted, + // consumerId,true); + AssertJUnit.assertEquals("Check response code after download resource", 200, + restResponse.getErrorCode().intValue()); + + // Validating headers + // content disposition + List contDispHeaderList = restResponse.getHeaderFields().get(Constants.CONTENT_DISPOSITION_HEADER); + AssertJUnit.assertNotNull(contDispHeaderList); + AssertJUnit + .assertEquals( + "Check content disposition header", new StringBuilder().append("attachment; filename=\"") + .append(artifactResp.getArtifactName()).append("\"").toString(), + contDispHeaderList.get(0)); + + // content type + List contTypeHeaderList = restResponse.getHeaderFields().get(Constants.CONTENT_TYPE_HEADER); + AssertJUnit.assertNotNull(contTypeHeaderList); + AssertJUnit.assertEquals("Check content type", "application/octet-stream", contTypeHeaderList.get(0)); + + String actualContents = restResponse.getResponse(); + + // Contents - comparing decoded content + AssertJUnit.assertEquals(artifactDetails.getPayload(), Base64.encodeBase64String(actualContents.getBytes())); + + // validating checksum + String actualPayloadChecksum = GeneralUtility.calculateMD5ByByteArray(actualContents.getBytes()); + AssertJUnit.assertEquals(expectedPayloadChecksum, actualPayloadChecksum); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + BaseRestUtils.ecomp, relativeUrl, "200", "OK"); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + protected void download_serviceNameNotFound_inner(String serviceName, String serviceVersion, String resourceName, + String resourceVersion) throws Exception { + Config config = Utils.getConfig(); + String artifactName = "kuku"; + ArtifactReqDetails artifact = new ArtifactReqDetails(); + artifact.setArtifactName(artifactName); + String relativeUrl; + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + ServiceReqDetails serviceInfo = new ServiceReqDetails(); + serviceInfo.setName(serviceName); + serviceInfo.setVersion(serviceVersion); + RestResponse restResponse = null; + if (resourceName != null) { + ResourceReqDetails resourceDetailes = new ResourceReqDetails(); + resourceDetailes.setName(resourceName); + resourceDetailes.setVersion(resourceVersion); + relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceName), serviceVersion, + ValidationUtils.convertToSystemName(resourceName), resourceVersion, artifactName)); + restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceInfo, resourceDetailes, artifact, + designerUser, authorizationHeaders); + } else { + relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceName), serviceVersion, artifactName)); + restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceInfo, artifact, designerUser, + authorizationHeaders); + } + + // RestResponse restResponse = + // artifactUtils.downloadResourceArtifact(designerUser,fullUrlFormatted, + // consumerId,true); + AssertJUnit.assertEquals("Check response code after download resource", 404, + restResponse.getErrorCode().intValue()); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + BaseRestUtils.ecomp, relativeUrl, "404", "SVC4503: Error: Requested '" + + ValidationUtils.convertToSystemName(serviceName) + "' service was not found."); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + protected void download_serviceVersionNotFound_inner(String serviceName, String serviceVersion, String resourceName, + String resourceVersion) throws Exception { + Config config = Utils.getConfig(); + String artifactName = "kuku"; + String relativeUrl; + ArtifactReqDetails artifact = new ArtifactReqDetails(); + artifact.setArtifactName(artifactName); + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + ServiceReqDetails serviceInfo = new ServiceReqDetails(); + serviceInfo.setName(serviceName); + serviceInfo.setVersion(serviceVersion); + RestResponse restResponse = null; + if (resourceName != null) { + ResourceReqDetails resourceDetailes = new ResourceReqDetails(); + resourceDetailes.setName(resourceName); + resourceDetailes.setVersion(resourceVersion); + relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceName), serviceVersion, + ValidationUtils.convertToSystemName(resourceName), resourceVersion, artifactName)); + restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceInfo, resourceDetailes, artifact, + designerUser, authorizationHeaders); + } else { + relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceName), serviceVersion, artifactName)); + restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceInfo, artifact, designerUser, + authorizationHeaders); + } + // String fullUrlFormatted = + // String.format(Urls.DOWNLOAD_RESOURCE_ARTIFACT_FULL_URL, + // config.getCatalogBeHost(),config.getCatalogBePort(), relativeUrl); + // String consumerId = "dummy.ecomp"; + + // RestResponse restResponse = + // artifactUtils.downloadResourceArtifact(designerUser,fullUrlFormatted, + // consumerId,true); + AssertJUnit.assertEquals("Check response code after download resource", 404, + restResponse.getErrorCode().intValue()); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + BaseRestUtils.ecomp, relativeUrl, "404", + "SVC4504: Error: Service version " + serviceVersion + " was not found."); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + protected String encodeUrlForDownload(String url) { + return url.replaceAll(" ", "%20"); + } + + protected ConsumerDataDefinition createConsumer() { + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName(USER); + consumer.setConsumerSalt(SALT); + consumer.setConsumerPassword(HASHED_PASSWORD); + return consumer; + + } + + @Test(enabled = false) + public void downloadServiceArtifactSuccess() throws Exception { + // Create service + RestResponse serviceResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, serviceResponse.getErrorCode().intValue()); + serviceUniqueId = ResponseParser.convertServiceResponseToJavaObject(serviceResponse.getResponse()) + .getUniqueId(); + + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultDeploymentArtifactForType("MURANO_PKG"); + + RestResponse addArtifactResponse = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, + designerUser, serviceUniqueId, ArtifactRestUtils.calculateMD5Header(artifactDetails)); + assertEquals("Check response code after adding interface artifact", 200, + addArtifactResponse.getErrorCode().intValue()); + + // Getting expected artifact checksum + + // ArtifactResJavaObject artifactResp = + // artifactUtils.parseInformationalArtifactResp(addArtifactResponse); + String expectedPayloadChecksum = ResponseParser + .convertArtifactDefinitionResponseToJavaObject(addArtifactResponse.getResponse()).getArtifactChecksum(); + + String artifactName = ValidationUtils.normalizeFileName(artifactDetails.getArtifactName()); + + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceBaseVersion, artifactName)); + + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, artifactDetails, + designerUser, authorizationHeaders); + assertEquals("Check response code after download resource", 200, restResponse.getErrorCode().intValue()); + + // Validating headers + // content disposition + List contDispHeaderList = restResponse.getHeaderFields().get(Constants.CONTENT_DISPOSITION_HEADER); + assertNotNull(contDispHeaderList); + assertEquals("Check content disposition header", + new StringBuilder().append("attachment; filename=\"").append(artifactName).append("\"").toString(), + contDispHeaderList.get(0)); + + // content type + List contTypeHeaderList = restResponse.getHeaderFields().get(Constants.CONTENT_TYPE_HEADER); + assertNotNull(contTypeHeaderList); + assertEquals("Check content type", "application/octet-stream", contTypeHeaderList.get(0)); + + String actualContents = restResponse.getResponse(); + + assertEquals(artifactDetails.getPayload(), Base64.encodeBase64String(actualContents.getBytes())); + + // validating checksum + byte[] bytes = actualContents.getBytes(); + String actualPayloadChecksum = GeneralUtility.calculateMD5ByByteArray(bytes); + assertEquals(expectedPayloadChecksum, actualPayloadChecksum); + + // validating valid zip + InputStream is = new ByteArrayInputStream(bytes); + InputStream zis = new ZipInputStream(is); + zis.close(); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + ResourceRestUtils.ecomp, encodeUrlForDownload(relativeUrl), "200", "OK"); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + @Test + public void downloadResourceArtifact_NoConsumerId() throws Exception { + + String artifactName = "kuku"; + ArtifactReqDetails artifact = new ArtifactReqDetails(); + artifact.setArtifactName(artifactName); + ResourceReqDetails resource = new ResourceReqDetails(); + resource.setName("notExisting"); + resource.setVersion("0.1"); + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceBaseVersion, + ValidationUtils.convertToSystemName(resource.getName()), resource.getVersion(), artifactName)); + serviceDetails.setVersion("0.1"); + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceDetails, resource, artifact, + designerUser, authorizationHeaders, false); + assertEquals("Check response code after download resource", 400, restResponse.getErrorCode().intValue()); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, "", + relativeUrl, "400", "POL5001: Error: Missing 'X-ECOMP-InstanceID' HTTP header."); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + @Test + public void downloadResourceArtifact_ResourceNameNotFound() throws Exception { + + String artifactName = "kuku"; + ArtifactReqDetails artifact = new ArtifactReqDetails(); + artifact.setArtifactName(artifactName); + ResourceReqDetails resource = new ResourceReqDetails(); + resource.setName("notExisting"); + resource.setVersion("0.1"); + serviceDetails.setVersion("0.1"); + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceDetails.getVersion(), + ValidationUtils.convertToSystemName(resource.getName()), resource.getVersion(), artifactName)); + + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceDetails, resource, artifact, + designerUser, authorizationHeaders); + + assertEquals("Check response code after download resource", 404, restResponse.getErrorCode().intValue()); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + BaseRestUtils.ecomp, relativeUrl, "404", + "SVC4063: Error: Requested 'Notexisting' resource was not found."); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + @Test + public void downloadResourceArtifact_ResourceVersionNotFound() throws Exception { + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, createResource.getErrorCode().intValue()); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(createResource.getResponse()); + ResourceReqDetails resourceDetailes = new ResourceReqDetails(); + resourceDetailes.setName(resource.getName()); + resourceDetailes.setVersion("0.2"); + + serviceDetails.setVersion("0.1"); + + String artifactName = "kuku"; + ArtifactReqDetails artifact = new ArtifactReqDetails(); + artifact.setArtifactName(artifactName); + + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, + ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceBaseVersion, + ValidationUtils.convertToSystemName(resourceDetailes.getName()), resourceDetailes.getVersion(), + artifactName)); + + Map authorizationHeaders = new HashMap(); + authorizationHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceDetails, resourceDetailes, + artifact, designerUser, authorizationHeaders); + assertEquals("Check response code after download resource", 404, restResponse.getErrorCode().intValue()); + + // validate audit + String auditAction = "DArtifactDownload"; + + ExpectedDistDownloadAudit expectedDistDownloadAudit = new ExpectedDistDownloadAudit(auditAction, + BaseRestUtils.ecomp, relativeUrl, "404", "SVC4504: Error: Resource version 0.2 was not found."); + AuditValidationUtils.validateAudit(expectedDistDownloadAudit, auditAction); + } + + @Test + public void downloadResourceArtifact_ServiceNameNotFound() throws Exception { + // Create resource + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, createResource.getErrorCode().intValue()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(createResource.getResponse()); + download_serviceNameNotFound_inner("notExistingServiceName", serviceBaseVersion, resource.getName(), + resource.getVersion()); + + } + + @Test + public void downloadResourceArtifact_ServiceVersionNotFound() throws Exception { + // Create resource + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, createResource.getErrorCode().intValue()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(createResource.getResponse()); + + // Create service + RestResponse serviceResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, serviceResponse.getErrorCode().intValue()); + serviceUniqueId = ResponseParser.convertServiceResponseToJavaObject(serviceResponse.getResponse()) + .getUniqueId(); + + download_serviceVersionNotFound_inner(serviceDetails.getName(), "0.3", resource.getName(), + resource.getVersion()); + } + + @Test + public void downloadServiceArtifact_ServiceNameNotFound() throws Exception { + download_serviceNameNotFound_inner("notExistingServiceName", serviceBaseVersion, null, null); + + } + + @Test + public void downloadServiceArtifact_ServiceVersionNotFound() throws Exception { + + // Create service + RestResponse serviceResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + assertEquals("Check response code after creating resource", 201, serviceResponse.getErrorCode().intValue()); + serviceUniqueId = ResponseParser.convertServiceResponseToJavaObject(serviceResponse.getResponse()) + .getUniqueId(); + + download_serviceVersionNotFound_inner(serviceDetails.getName(), "0.2", null, null); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/externalapi/DownloadArtifactsTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/externalapi/DownloadArtifactsTest.java new file mode 100644 index 0000000000..3325227ebc --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/externalapi/DownloadArtifactsTest.java @@ -0,0 +1,338 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.externalapi; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.Assert; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class DownloadArtifactsTest extends ComponentBaseTest { + @Rule + public static TestName name = new TestName(); + + Gson gson = new Gson(); + + public DownloadArtifactsTest() { + super(name, DownloadArtifactsTest.class.getName()); + } + + private User sdncDesignerDetails; + private User sdncAdminDetails; + private ImportReqDetails resourceDetailsVF_01; + private ResourceReqDetails resourceDetailsVF_02; + private ResourceReqDetails resourceDetailsVF_03; + private ResourceReqDetails resourceDetailsCP_01; + private ServiceReqDetails serviceDetails_01; + private ServiceReqDetails serviceDetails_02; + public static String rootPath = System.getProperty("user.dir"); + + @BeforeMethod(alwaysRun = true) + public void before() throws Exception { + init(); + createComponents(); + } + + private void createComponents() throws Exception { + createAtomicResource(resourceDetailsCP_01); + importVfWithArtifacts(resourceDetailsVF_01); + createVF(resourceDetailsVF_03); + createVF(resourceDetailsVF_02); + createService(serviceDetails_01); + } + + public void init() { + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + resourceDetailsVF_01 = ElementFactory.getDefaultImportResourceByType("VF100", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VF.toString()); + resourceDetailsVF_02 = ElementFactory.getDefaultResourceByType("VF200", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VF.toString()); + resourceDetailsVF_03 = ElementFactory.getDefaultResourceByType("VF300", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), ResourceTypeEnum.VF.toString()); + resourceDetailsCP_01 = ElementFactory.getDefaultResourceByType("CP100", NormativeTypesEnum.PORT, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), ResourceTypeEnum.CP.toString()); + serviceDetails_01 = ElementFactory.getDefaultService("newtestservice1", ServiceCategoriesEnum.MOBILITY, sdncDesignerDetails.getUserId()); + serviceDetails_02 = ElementFactory.getDefaultService("newtestservice2", ServiceCategoriesEnum.MOBILITY, sdncDesignerDetails.getUserId()); + } + + @Test + public void downloadResourceInstanceArtifactsFromServiceTest() throws Exception { + Service service = createServiceWithRIsWithArtifacts(); + Map deploymentArtifacts; + List resourceInstances = service.getComponentInstances(); + for (ComponentInstance ri : resourceInstances) { + deploymentArtifacts = ri.getDeploymentArtifacts(); + for (ArtifactDefinition artifact : deploymentArtifacts.values()) { + assertNotNull(downloadResourceInstanceArtifact(service, ri, artifact)); + } + } + } + + @Test + public void downloadServiceArtifactsTest() throws Exception { + Service service = createServiceWithArtifacts(); + Map deploymentArtifacts = service.getDeploymentArtifacts(); + for (ArtifactDefinition artifact : deploymentArtifacts.values()) { + assertNotNull(downloadServiceArtifact(service, artifact)); + } + + } + + private Service createServiceWithArtifacts() throws Exception { + + ArtifactReqDetails otherArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.OTHER.getType()); + + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(otherArtifactDetails, sdncDesignerDetails, serviceDetails_01.getUniqueId()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + ArtifactReqDetails yangXmlArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.YANG_XML.getType()); + + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(yangXmlArtifactDetails, sdncDesignerDetails, serviceDetails_01.getUniqueId()); + assertTrue("response code is not BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + addInformationalArtifactToService.getErrorCode(), addInformationalArtifactToService.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + RestResponse createServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + return ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()); + } + + private RestResponse downloadResourceInstanceArtifact(Service service, ComponentInstance ri, ArtifactDefinition artifact) throws Exception { + String url = String.format(Urls.GET_DOWNLOAD_SERVICE_RI_ARTIFACT, "localhost", "8080", service.getUUID(), ri.getNormalizedName(), artifact.getArtifactUUID()); + String userId = sdncDesignerDetails.getUserId(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.CACHE_CONTROL.getValue(), "no-cache"); + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), "Basic dGVzdDoxMjM0NTY="); + headersMap.put("X-ECOMP-InstanceID", "test"); + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + sendAuthorizationRequest(); + HttpRequest http = new HttpRequest(); + RestResponse response = http.httpSendGet(url, headersMap); + if (response.getErrorCode() != 200 && response.getResponse().getBytes() == null && response.getResponse().getBytes().length == 0) { + return null; + } + return response; + } + + private RestResponse downloadServiceArtifact(Service service, ArtifactDefinition artifact) throws Exception { + String url = String.format(Urls.GET_DOWNLOAD_SERVICE_ARTIFACT, "localhost", "8080", service.getUUID(), artifact.getArtifactUUID()); + String userId = sdncDesignerDetails.getUserId(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.CACHE_CONTROL.getValue(), "no-cache"); + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), "Basic dGVzdDoxMjM0NTY="); + headersMap.put("X-ECOMP-InstanceID", "test"); + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + sendAuthorizationRequest(); + HttpRequest http = new HttpRequest(); + RestResponse response = http.httpSendGet(url, headersMap); + if (response.getErrorCode() != 200 && response.getResponse().getBytes() == null && response.getResponse().getBytes().length == 0) { + return null; + } + return response; + + } + + private RestResponse sendAuthorizationRequest() throws IOException { + String url = String.format(Urls.POST_AUTHORIZATION, "localhost", "8080"); + String userId = sdncAdminDetails.getUserId(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.CACHE_CONTROL.getValue(), "no-cache"); + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + + HttpRequest http = new HttpRequest(); + RestResponse response = http.httpSendPost(url, "{\"consumerName\":\"test\",\"consumerPassword\":\"0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b\",\"consumerSalt\":\"2a1f887d607d4515d4066fe0f5452a50\"}", headersMap); + if (response.getErrorCode() != 201) { + return null; + } + return response; + } + + private Service createServiceWithRIsWithArtifacts() throws Exception { + serviceDetails_02.setUniqueId(serviceDetails_01.getUniqueId()); + createTreeCheckedinVFInstances(); + LifecycleRestUtils.changeResourceState(resourceDetailsCP_01, sdncDesignerDetails, "0.1", LifeCycleStatesEnum.CHECKIN); + createVFInstanceAndAtomicResourceInstanceWithoutCheckin(resourceDetailsVF_01, resourceDetailsCP_01, sdncDesignerDetails); + RestResponse updateServiceResp = ServiceRestUtils.updateService(serviceDetails_02, sdncDesignerDetails); + ServiceRestUtils.checkSuccess(updateServiceResp); + getComponentAndValidateRIs(serviceDetails_01, 5, 0); + + return ResponseParser.convertServiceResponseToJavaObject(updateServiceResp.getResponse()); + } + + private void createTreeCheckedinVFInstances() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createSecondVFInstResp); + RestResponse createThirdVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_03, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createThirdVFInstResp); + } + + private Component getComponentAndValidateRIs(ComponentReqDetails componentDetails, int numberOfRIs, int numberOfRelations) throws IOException, Exception { + + RestResponse getResponse = null; + Component component = null; + if (componentDetails instanceof ResourceReqDetails) { + getResponse = ResourceRestUtils.getResource(sdncAdminDetails, componentDetails.getUniqueId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Resource.class); + } else if (componentDetails instanceof ServiceReqDetails) { + getResponse = ServiceRestUtils.getService((ServiceReqDetails) componentDetails, sdncAdminDetails); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Service.class); + } else if (componentDetails instanceof ProductReqDetails) { + getResponse = ProductRestUtils.getProduct(componentDetails.getUniqueId(), sdncAdminDetails.getUserId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Product.class); + } else { + Assert.fail("Unsupported type of componentDetails - " + componentDetails.getClass().getSimpleName()); + } + ResourceRestUtils.checkSuccess(getResponse); + int numberOfActualRIs = component.getComponentInstances() != null ? component.getComponentInstances().size() : 0; + int numberOfActualRelations = component.getComponentInstancesRelations() != null ? component.getComponentInstancesRelations().size() : 0; + assertEquals("Check number of RIs meet the expected number", numberOfRIs, numberOfActualRIs); + assertEquals("Check number of RI relations meet the expected number", numberOfRelations, numberOfActualRelations); + + return component; + } + + private void createVFInstanceAndAtomicResourceInstanceWithoutCheckin(ResourceReqDetails vf, ResourceReqDetails atomicResource, User user) throws Exception { + RestResponse createVFInstance = createVFInstance(serviceDetails_01, vf, user); + ResourceRestUtils.checkCreateResponse(createVFInstance); + RestResponse atomicInstanceForService = createAtomicInstanceForService(serviceDetails_01, atomicResource, user); + ResourceRestUtils.checkCreateResponse(atomicInstanceForService); + } + + private RestResponse createCheckedinVFInstance(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + changeResourceLifecycleState(compInstOriginDetails, modifier.getUserId(), LifeCycleStatesEnum.CHECKIN); + return createVFInstance(containerDetails, compInstOriginDetails, modifier); + } + + private RestResponse createVFInstance(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + private RestResponse createAtomicInstanceForService(ServiceReqDetails containerDetails, ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + private RestResponse createComponentInstance(ComponentReqDetails containerDetails, ComponentReqDetails compInstOriginDetails, User modifier, ComponentTypeEnum containerComponentTypeEnum, boolean isHighestLevel) throws IOException, Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getComponentResourceInstance(compInstOriginDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, modifier, containerDetails.getUniqueId(), containerComponentTypeEnum); + return createResourceInstanceResponse; + } + + private void changeResourceLifecycleState(ResourceReqDetails resourceDetails, String userId, LifeCycleStatesEnum lifeCycleStates) throws Exception { + RestResponse response = LifecycleRestUtils.changeResourceState(resourceDetails, userId, lifeCycleStates); + LifecycleRestUtils.checkLCS_Response(response); + } + + private void createAtomicResource(ResourceReqDetails resourceDetails) throws Exception { + RestResponse createResourceResponse = ResourceRestUtils.createResource(resourceDetails, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceResponse); + + } + + private void createVF(ResourceReqDetails resourceDetails) throws Exception { + createVF(resourceDetails, sdncDesignerDetails); + + } + + private void createVF(ResourceReqDetails resourceDetails, User sdncModifier) throws Exception { + RestResponse createVfResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifier); + ResourceRestUtils.checkCreateResponse(createVfResponse); + } + + private void createService(ServiceReqDetails serviceDetails) throws Exception { + createService(serviceDetails, sdncDesignerDetails); + } + + private void createService(ServiceReqDetails serviceDetails, User sdncModifier) throws Exception { + RestResponse createServiceResponse = ServiceRestUtils.createService(serviceDetails, sdncModifier); + ResourceRestUtils.checkCreateResponse(createServiceResponse); + } + + private void importVfWithArtifacts(ImportReqDetails resourceDetailsVF_01) throws Exception { + String payloadName = "VF_RI2_G4_withArtifacts.csar"; + Path path = Paths.get(rootPath + "/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetailsVF_01.setPayloadData(payloadData); + + resourceDetailsVF_01.setPayloadName(payloadName); + resourceDetailsVF_01.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetailsVF_01, sdncDesignerDetails); + BaseRestUtils.checkCreateResponse(createResource); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/BasicHttpAuthenticationTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/BasicHttpAuthenticationTest.java new file mode 100644 index 0000000000..83a50baeeb --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/BasicHttpAuthenticationTest.java @@ -0,0 +1,403 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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========================================================= + */ + +//US505653 +package org.openecomp.sdc.ci.tests.execute.general; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedAuthenticationAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class BasicHttpAuthenticationTest extends ComponentBaseTest { + + protected static final String AUTH_FAILED_INVALID_AUTHENTICATION_HEADER = "AUTH_FAILED_INVALID_AUTHENTICATION_HEADER"; + + protected static final String AUTH_SUCCESS = "AUTH_SUCCESS"; + + protected static final String AUTH_FAILED_INVALID_PASSWORD = "AUTH_FAILED_INVALID_PASSWORD"; + + protected static final String AUTH_FAILED_USER_NOT_FOUND = "AUTH_FAILED_USER_NOT_FOUND"; + + protected static final String AUTH_REQUIRED = "AUTH_REQUIRED"; + + protected static final String WWW_AUTHENTICATE = "WWW-Authenticate"; + + // user ci password 123456 + // protected final String authorizationHeader = "Basic Y2k6MTIzNDU2"; + // user ci password 123456 + protected final String USER = "ci"; + + protected final String PASSWORD = "123456"; + + protected final String SALT = "2a1f887d607d4515d4066fe0f5452a50"; + + protected final String HASHED_PASSWORD = "0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b"; + + protected User sdncAdminUserDetails; + + protected ConsumerDataDefinition consumerDataDefinition; + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected User sdncUserDetails; + + protected ArtifactReqDetails deploymentArtifact; + + protected ExpectedAuthenticationAudit expectedAuthenticationAudit; + + protected final String auditAction = "HttpAuthentication"; + + protected String expectedDownloadServiceUrl; + protected String expectedDownloadResourceUrl; + protected ComponentInstanceReqDetails componentInstanceReqDetails; + + @Rule + public static TestName name = new TestName(); + + public BasicHttpAuthenticationTest() { + super(name, BasicHttpAuthenticationTest.class.getName()); + } + + @BeforeMethod + public void init() throws Exception { + + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + Resource resourceObject = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resourceDetails = new ResourceReqDetails(resourceObject); + Service serviceObject = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + serviceDetails = new ServiceReqDetails(serviceObject); + + deploymentArtifact = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(deploymentArtifact, sdncUserDetails, resourceDetails.getUniqueId()); + AssertJUnit.assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), response.getErrorCode() == 200); + + componentInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + // certified resource + response = LifecycleRestUtils.certifyResource(resourceDetails); + AssertJUnit.assertTrue("certify resource request returned status:" + response.getErrorCode(), response.getErrorCode() == 200); + + // add resource instance with HEAT deployment artifact to the service + componentInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(componentInstanceReqDetails, sdncUserDetails, serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + AssertJUnit.assertTrue("response code is not 201, returned: " + response.getErrorCode(), response.getErrorCode() == 201); + expectedAuthenticationAudit = new ExpectedAuthenticationAudit(); + + // RestResponse addDeploymentArtifactResponse = + // ArtifactRestUtils.addInformationalArtifactToService(deploymentArtifact, + // sdncUserDetails, serviceDetails.getUniqueId()); + // assertEquals("didn't succeed to upload deployment artifact", 200, + // addDeploymentArtifactResponse.getErrorCode().intValue()); + // + // downloadUrl = + // String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, + // ValidationUtils.convertToSystemName(serviceDetails.getServiceName()), + // serviceDetails.getVersion(), + // ValidationUtils.normalizeFileName(deploymentArtifact.getArtifactName())); + + expectedDownloadResourceUrl = String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceDetails.getVersion(), + ValidationUtils.convertToSystemName(resourceDetails.getName()), resourceDetails.getVersion(), ValidationUtils.normalizeFileName(deploymentArtifact.getArtifactName())); + expectedDownloadResourceUrl = expectedDownloadResourceUrl.substring("/asdc/".length(), expectedDownloadResourceUrl.length()); + + expectedDownloadServiceUrl = String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceDetails.getVersion(), + ValidationUtils.normalizeFileName(deploymentArtifact.getArtifactName())); + expectedDownloadServiceUrl = expectedDownloadServiceUrl.substring("/asdc/".length(), expectedDownloadServiceUrl.length()); + + sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + consumerDataDefinition = createConsumer(); + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + ; + + RestResponse createResponse = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkCreateResponse(createResponse); + + } + + @AfterMethod + public void tearDown() throws Exception { + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + ; + } + + @Test + public void sendAuthenticatedRequestTest_success() throws Exception, Exception { + DbUtils.cleanAllAudits(); + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(USER, PASSWORD); + // RestResponse restResponse = + // ArtifactRestUtils.downloadServiceArtifact(serviceDetails, + // deploymentArtifact, sdncUserDetails, authorizationHeader); + RestResponse restResponse = ArtifactRestUtils.downloadResourceArtifact(serviceDetails, resourceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + AssertJUnit.assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + AssertJUnit.assertFalse(restResponse.getHeaderFields().containsKey(HttpHeaderEnum.WWW_AUTHENTICATE.getValue())); + + validateAuditAuthentication(USER, AUTH_SUCCESS, ComponentTypeEnum.RESOURCE); + + } + + protected void validateAuditAuthentication(String userName, String AuthStatus, ComponentTypeEnum compType) throws Exception { + if (compType.equals(ComponentTypeEnum.RESOURCE)) { + expectedAuthenticationAudit = new ExpectedAuthenticationAudit(expectedDownloadResourceUrl, userName, auditAction, AuthStatus); + } else { + expectedAuthenticationAudit = new ExpectedAuthenticationAudit(expectedDownloadServiceUrl, userName, auditAction, AuthStatus); + } + AuditValidationUtils.validateAuthenticationAudit(expectedAuthenticationAudit); + } + + protected ConsumerDataDefinition createConsumer() { + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName(USER); + consumer.setConsumerSalt(SALT); + consumer.setConsumerPassword(HASHED_PASSWORD); + return consumer; + + } + + @Test + public void sendAuthenticatedRequestWithoutHeadersTest() throws Exception, Exception { + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, new HashMap()); + assertEquals("Check response code after download artifact", 401, restResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.AUTH_REQUIRED.name(), new ArrayList(), restResponse.getResponse()); + assertTrue(restResponse.getHeaderFields().containsKey(WWW_AUTHENTICATE)); + List getAuthenticateHeader = restResponse.getHeaderFields().get(WWW_AUTHENTICATE); + assertEquals("www-authenticate header contains more then one value", 1, getAuthenticateHeader.size()); + assertTrue(getAuthenticateHeader.get(0).equals("Basic realm=" + "\"ASDC\"")); + + validateAuditAuthentication("", AUTH_REQUIRED, ComponentTypeEnum.SERVICE); + } + + @Test + public void sendAuthenticatedRequestTest_userIsNotProvsioned() throws Exception, Exception { + String userName = "shay"; + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(userName, "123456"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 403, restResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.AUTH_FAILED.name(), new ArrayList(), restResponse.getResponse()); + assertFalse(restResponse.getHeaderFields().containsKey(WWW_AUTHENTICATE)); + + validateAuditAuthentication(userName, AUTH_FAILED_USER_NOT_FOUND, ComponentTypeEnum.SERVICE); + } + + @Test + public void sendAuthenticatedRequestTest_userIsNull() throws Exception, Exception { + String userName = ""; + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(userName, "123456"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 403, restResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.AUTH_FAILED.name(), new ArrayList(), restResponse.getResponse()); + assertFalse(restResponse.getHeaderFields().containsKey(WWW_AUTHENTICATE)); + + validateAuditAuthentication(userName, AUTH_FAILED_USER_NOT_FOUND, ComponentTypeEnum.SERVICE); + } + + @Test + public void sendAuthenticatedRequestTest_passwordIsNull() throws Exception, Exception { + String userName = "ci"; + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(userName, ""); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 403, restResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.AUTH_FAILED.name(), new ArrayList(), restResponse.getResponse()); + assertFalse(restResponse.getHeaderFields().containsKey(WWW_AUTHENTICATE)); + + validateAuditAuthentication(userName, AUTH_FAILED_INVALID_PASSWORD, ComponentTypeEnum.SERVICE); + } + + @Test + public void sendAuthenticatedRequestTest_passowrdIsNotValidated() throws Exception, Exception { + String userCi = "ci"; + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(userCi, "98765"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 403, restResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.AUTH_FAILED.name(), new ArrayList(), restResponse.getResponse()); + assertFalse(restResponse.getHeaderFields().containsKey(HttpHeaderEnum.WWW_AUTHENTICATE.getValue())); + + validateAuditAuthentication(userCi, AUTH_FAILED_INVALID_PASSWORD, ComponentTypeEnum.SERVICE); + } + + @Test + public void sendAuthenticatedRequestTest_InvalidHeader() throws Exception, Exception { + String userCredentials = USER + ":" + PASSWORD; + byte[] encodeBase64 = Base64.encodeBase64(userCredentials.getBytes()); + String encodedUserCredentials = new String(encodeBase64); + Map authorizationHeader = new HashMap(); + authorizationHeader.put(HttpHeaderEnum.AUTHORIZATION.getValue(), encodedUserCredentials); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 400, restResponse.getErrorCode().intValue()); + assertFalse(restResponse.getHeaderFields().containsKey(HttpHeaderEnum.WWW_AUTHENTICATE.getValue())); + + validateAuditAuthentication("", AUTH_FAILED_INVALID_AUTHENTICATION_HEADER, ComponentTypeEnum.SERVICE); + } + + @Test(enabled = false) + public void sendTwoAuthenticatedRequestsTest() throws Exception, Exception { + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(USER, PASSWORD); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + + RestResponse secondRestResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after second download artifact", 200, secondRestResponse.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void sendAuthenticatedRequestTest_userValidation_1() throws Exception, Exception { + + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName("cI2468"); + consumer.setConsumerPassword(HASHED_PASSWORD); + consumer.setConsumerSalt(SALT); + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + + RestResponse createResponse = ConsumerRestUtils.createConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkCreateResponse(createResponse); + + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(consumer.getConsumerName(), PASSWORD); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + + deleteResponse = ConsumerRestUtils.deleteConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + } + + // ECOMP Consumer Name - UTF-8 string up to 255 characters containing the + // following characters : ( maybe to limit 4-64 chars ? ) + // Lowercase characters {a-z} + // Uppercase characters {A-Z} + // Numbers {0-9} + // Dash {-}; this character is not supported as the first character in the + // user name + // Period {.}; this character is not supported as the first character in the + // user name + // Underscore {_} + // @Ignore("add manually user:password 24-!68:123456 to + // users-configuration.yaml in runtime") + @Test(enabled = false) + public void sendAuthenticatedRequestTest_userValidation_2() throws Exception, Exception { + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName("24-!68"); + consumer.setConsumerPassword(HASHED_PASSWORD); + consumer.setConsumerSalt(SALT); + RestResponse deleteResponse = ConsumerRestUtils.deleteConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + + RestResponse createResponse = ConsumerRestUtils.createConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkCreateResponse(createResponse); + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader(consumer.getConsumerName(), PASSWORD); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + + deleteResponse = ConsumerRestUtils.deleteConsumer(consumer, sdncAdminUserDetails); + BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", false, 404, 200); + } + + // this is invalide becouse we do not use the : any more + // @Ignore("can't exectue, yaml file does not allow to enter more then one + // colon continuously (\":\") ") + @Test(enabled = false) + public void sendAuthenticatedRequestTest_userValidation_3() throws Exception, Exception { + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader("a:", "123456"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + } + + // + // * ECOMP Consumer Password - expected to be SHA-2 256 encrypted value ( + // SALT + "real" password ) => maximal length 256 bytes = 32 characters + // Before storing/comparing please convert upper case letter to lower. + // The "normalized" encrypted password should match the following format : + // [a-z0-9] + // @Ignore("add manually user:password 2468:123:456 to + // users-configuration.yaml in runtime") + @Test(enabled = false) + public void sendAuthenticatedRequestTest_passwordValidation_1() throws Exception, Exception { + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader("A1", "123:456"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + } + + // * ECOMP Consumer Password - expected to be SHA-2 256 encrypted value ( + // SALT + "real" password ) => maximal length 256 bytes = 32 characters + // Before storing/comparing please convert upper case letter to lower. + // The "normalized" encrypted password should match the following format : + // [a-z0-9] + @Test(enabled = false) + // @Ignore("add manually user:password 2468:Sq123a456B to + // users-configuration.yaml in runtime") + public void sendAuthenticatedRequestTest_passwordValidation_2() throws Exception, Exception { + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader("B2", "Sq123a456B"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + } + + // * ECOMP Consumer Password - expected to be SHA-2 256 encrypted value ( + // SALT + "real" password ) => maximal length 256 bytes = 32 characters + // Before storing/comparing please convert upper case letter to lower. + // The "normalized" encrypted password should match the following format : + // [a-z0-9] + @Test + // @Ignore("add C3:111T-0-*# to file") + public void sendAuthenticatedRequestTest_passwordValidation_3() throws Exception, Exception { + Map authorizationHeader = BaseRestUtils.addAuthorizeHeader("C3", "111T-0-*#"); + RestResponse restResponse = ArtifactRestUtils.downloadServiceArtifact(serviceDetails, deploymentArtifact, sdncUserDetails, authorizationHeader); + assertEquals("Check response code after download artifact", 200, restResponse.getErrorCode().intValue()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/FeProxyTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/FeProxyTest.java new file mode 100644 index 0000000000..e4f7d396be --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/FeProxyTest.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.general; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +public class FeProxyTest extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public FeProxyTest() { + super(name, FeProxyTest.class.getName()); + } + + @Test + public void testFeProxy() throws Exception { + User defaultUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + RestResponse allCategoriesTowardsFe = CategoryRestUtils.getAllCategoriesTowardsFe(defaultUser, + BaseRestUtils.RESOURCE_COMPONENT_TYPE); + AssertJUnit.assertEquals("Check response code after get categories towards FE", 200, + allCategoriesTowardsFe.getErrorCode().intValue()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/ManageEcompConsumerCredentials.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/ManageEcompConsumerCredentials.java new file mode 100644 index 0000000000..9e1b151c49 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/ManageEcompConsumerCredentials.java @@ -0,0 +1,1388 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.general; + +import static org.testng.AssertJUnit.assertEquals; + +import java.util.HashMap; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedEcomConsumerAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ManageEcompConsumerCredentials extends ComponentBaseTest { + + protected static final String ADD_ECOMP_USER_CREDENTIALS = "AddECOMPUserCredentials"; + protected static final String DELETE_ECOMP_USER_CREDENTIALS = "DeleteECOMPUserCredentials"; + protected static final String GET_ECOMP_USER_CREDENTIALS = "GetECOMPUserCredentials"; + + public static final String contentTypeHeaderData = "application/json"; + public static final String acceptHeaderData = "application/json"; + + public static final int STATUS_CODE_SUCCESS = 200; + public static final int STATUS_CODE_SUCSESS_CREATED = 201; + public static final int STATUS_CODE_SUCCESS_DELETE_GET = 200; + public static final int STATUS_CODE_INVALID_CONTENT = 400; + public static final int STATUS_CODE_MISSING_DATA = 400; + public static final int STATUS_CODE_MISSING_INFORMATION = 403; + public static final int STATUS_CODE_RESTRICTED_ACCESS = 403; + + public static final int STATUS_CODE_NOT_FOUND = 404; + public static final int STATUS_CODE_RESTRICTED_OPERATION = 409; + + protected static Gson gson = new Gson(); + protected ConsumerDataDefinition consumerDataDefinition; + protected User sdncAdminUserDetails; + protected User sdncDesignerUserDetails; + protected User sdncTesterUserDetails; + protected User sdncGovernorUserDetails; + protected User sdncOpsUserDetails; + + public ManageEcompConsumerCredentials() { + super(name, ManageEcompConsumerCredentials.class.getName()); + } + + @Rule + public static TestName name = new TestName(); + + protected String salt = "123456789012345678901234567890ab"; + protected String password = "123456789012345678901234567890ab123456789012345678901234567890ab"; + protected String ecompUser = "benny"; + + protected Long consumerDetailsLastupdatedtime; + + @BeforeMethod + public void init() throws Exception { + sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncDesignerUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncTesterUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncGovernorUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + sdncOpsUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + + consumerDataDefinition = new ConsumerDataDefinition(); + consumerDataDefinition.setConsumerName(ecompUser); + consumerDataDefinition.setConsumerPassword(password); + consumerDataDefinition.setConsumerSalt(salt); + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + + } + + // US563681 manage ECOMP consumer credentials - DELETE/GET + @Test + public void deleteEcompCredentialsMethodDelete() throws Exception { + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + AssertJUnit.assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + AssertJUnit.assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + // DbUtils.deleteFromEsDbByPattern("_all"); + DbUtils.cleanAllAudits(); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + AssertJUnit.assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS_DELETE_GET, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCCESS_DELETE_GET); + // Get Consumer to verify that consumer user does not exist + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + AssertJUnit.assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + } + + //// US561728 CREATE ECOMP consumer credentials + @Test + public void createEcompCredentialsMethodPost() throws Exception { + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + // Validate actual consumerData to returned from response + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + } + + @Test(enabled = false) + public void createEcompCredentialsUserAlreayExist() throws Exception { + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + + // Create consumer which already exists with different password and Salt + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerPassword("zxcvb"); + consumerDataDefinition.setConsumerSalt("1234567890qwertyuiop1234567890as"); + createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer with new data + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsByDesigner() throws Exception { // HttpCspUserId header contains Designer UserId + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncDesignerUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_RESTRICTED_OPERATION, createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, sdncDesignerUserDetails, ActionStatus.RESTRICTED_OPERATION); + } + + @Test + public void createEcompCredentialsByTester() throws Exception { // HttpCspUserId header contains Tester UserId + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncTesterUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_RESTRICTED_OPERATION, createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, sdncTesterUserDetails, ActionStatus.RESTRICTED_OPERATION); + } + + @Test + public void createEcompCredentialsByOps() throws Exception { // HttpCspUserId header contains OPS UserId + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, sdncOpsUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_RESTRICTED_OPERATION, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncOpsUserDetails, ActionStatus.RESTRICTED_OPERATION); + } + + @Test + public void createEcompCredentialsByGovernor() throws Exception { // HttpCspUserId header contains Governor UserId Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncGovernorUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_RESTRICTED_OPERATION, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncGovernorUserDetails, ActionStatus.RESTRICTED_OPERATION); + } + + @Test + public void createEcompCredentialsByNoExistingIUser() throws Exception { + User noSdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + noSdncUserDetails.setRole("blabla"); + noSdncUserDetails.setUserId("bt750h"); + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, noSdncUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_RESTRICTED_OPERATION, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_ACCESS.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser( + consumerDataDefinition.getConsumerName() + "," + consumerDataDefinition.getConsumerSalt().toLowerCase() + + "," + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + expectedEcomConsumerAuditJavaObject.setModifier("(" + noSdncUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + // user name + @Test + public void createEcompCredentialsUserNameIsNull() throws Exception { + consumerDataDefinition.setConsumerName(null); // SVC4528 + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_DATA, + createConsumerRest.getErrorCode().intValue()); + // verify taht consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerSalt().toLowerCase() + "," + + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer name")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsUserNameIsEmpty() throws Exception { + consumerDataDefinition.setConsumerName(""); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerSalt().toLowerCase() + "," + + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer name")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsUserNameIsNotUTF8() throws Exception { + consumerDataDefinition.setConsumerName("בני"); // SVC4528 + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void createEcompCredentialsUserNameMaxLength() throws Exception { + consumerDataDefinition.setConsumerName( + "_ABCD-.abcdqwertyuiopasdfghjklzxcvbnmqw1234567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890pf34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfgghjklqwertyuiopzaiutrewasdfghjklqwertyuiopzasxcdferf123456.-"); // SVC4528 + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Validate actual consumerData to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameExceedMaxLength() throws Exception { + consumerDataDefinition.setConsumerName( + "_ABCD-.abcdqwertyuiopasdfghjklzxcvbnmqw1234567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890pf34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfgghjklqwertyuiopzaiutrewasdfghjklqwertyuiopzasxcdferf123456.--"); // SVC4528 + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.EXCEEDS_LIMIT, "Consumer name", "255"); + } + + @Test + public void createEcompCredentialsUserNameLastCharIsDash() throws Exception { // allowed + consumerDataDefinition.setConsumerName("ABCD34567890pf34567890poiutrew-"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject , Validate actual consumerData + // to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameLastCharIsPeriod() throws Exception { + consumerDataDefinition.setConsumerName("ABCD34567890pf34567890poiutrew."); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject , Validate actual consumerData + // to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameLastCharIsUnderscore() throws Exception { + consumerDataDefinition.setConsumerName("ABCD34567890pf34567890poiutrew_"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject , Validate actual consumerData + // to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameFirstCharIsUnderscore() throws Exception { + consumerDataDefinition.setConsumerName("_ABCD34567890pf34567890poiutre"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject , Validate actual consumerData + // to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameFirstCharIsPeriod() throws Exception { + consumerDataDefinition.setConsumerName(".ABCD34567890pf34567890poiutre"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_CONTENT_PARAM, "Consumer name"); + } + + @Test + public void createEcompCredentialsUserNameFirstCharIsDash() throws Exception { // Not + // allowed + consumerDataDefinition.setConsumerName("-ABCD34567890pf34567890poiutre"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_CONTENT_PARAM, "Consumer name"); + } + + /// Password + @Test + public void createEcompCredentialsPasswordIsNull() throws Exception { + consumerDataDefinition.setConsumerPassword(null); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_DATA, + createConsumerRest.getErrorCode().intValue()); + // verify taht consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer password")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsPasswordIsEmpty() throws Exception { + consumerDataDefinition.setConsumerPassword(""); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_DATA, + createConsumerRest.getErrorCode().intValue()); + // verify taht consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer password")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsPasswordMaxLength() throws Exception { // password + // must + // be + // 64 + // chars + consumerDataDefinition.setConsumerPassword("123456789012345678901234567890ab123456789012345678901234567890ab"); + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + // Validate actual consumerData to returned from response + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + // Delete Consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsPasswordExceeedMaxLength() throws Exception { // password + // must + // be + // 64 + // chars + consumerDataDefinition.setConsumerPassword("123456789012345678901234567890ab123456789012345678901234567890ab1"); + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_LENGTH, "Consumer password", "64"); + } + + @Test + public void createEcompCredentiaPasswordValid() throws Exception { + // Password Contains lowercase/uppercase characters and numbers - + // convert upper case letter to lower + consumerDataDefinition.setConsumerPassword("ABCabc1234567890POImnb12345678901234567890POIUzxcvbNMASDFGhjkl12"); + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + + } + + //// Salt + @Test + public void createEcompCredentialsSaltIsNull() throws Exception { + // Length must be 32 characters + consumerDataDefinition.setConsumerSalt(null); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_DATA, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerPassword().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + + } + + @Test + public void createEcompCredentialsSaltIsEmpty() throws Exception { + consumerDataDefinition.setConsumerSalt(""); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_DATA, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerPassword().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsSaltLengthLessThan32() throws Exception { + consumerDataDefinition.setConsumerSalt("123456789012345678901234567890a"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_LENGTH, "Consumer salt"); + + } + + // Bug + @Test + public void createEcompCredentialsSaltLengthMoreThan32() throws Exception { // Length + // must + // be + // 32 + // characters + // - + // SVC4529 + // "Error: + // Invalid + // Content. + // %1 + // exceeds + // limit + // of + // %2 + // characters." + consumerDataDefinition.setConsumerSalt("123456789012345678901234567890abc"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_LENGTH, "Consumer salt"); + + } + + @Test + public void createEcompCredentialsSaltUppercaseCharacters() throws Exception { + // Contains uppercase characters– exception invalid content + consumerDataDefinition.setConsumerSalt("123456789012345678901234567890AB"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // verify that consumer didn't created + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_CONTENT_PARAM.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt() + "," + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject + .setModifier(sdncAdminUserDetails.getFullName() + "(" + sdncAdminUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + // USER_ID (USER_ID is taken from USER_ID header) + + @Test + public void createEcompCredentialsHttpCspUserIdIsEmpty() throws Exception { + // USER_ID is taken from USER_ID header + sdncAdminUserDetails.setUserId(""); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt() + "," + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject.setModifier(""); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsHttpCspUserIdIsNull() throws Exception { // USER_ID is taken from USER_ID header + sdncAdminUserDetails.setUserId(null); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt() + "," + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject.setModifier(""); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + @Test + public void createEcompCredentialsHttpCspUserIdHeaderIsMissing() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumerHttpCspAtuUidIsMissing(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName() + "," + + consumerDataDefinition.getConsumerSalt() + "," + consumerDataDefinition.getConsumerPassword()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("Consumer salt")); + expectedEcomConsumerAuditJavaObject.setModifier(""); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + ADD_ECOMP_USER_CREDENTIALS); + } + + // add USER_ID in json body + @Test + public void createEcompCredentiaJsonBodyContainLastModfierAtuid() throws Exception { + // Add USER_ID (not admin) to json - we will ignore and create the user + HashMap jsonMap = new HashMap(); + jsonMap.put("consumerName", "benny"); + jsonMap.put("consumerPassword", "123456789012345678901234567890ab123456789012345678901234567890ab"); + jsonMap.put("consumerSalt", "123456789012345678901234567890ab"); + jsonMap.put("lastModfierAtuid", "cs0008"); // designer + Gson gson = new Gson(); + ConsumerDataDefinition consumer = gson.fromJson(jsonMap.toString(), ConsumerDataDefinition.class); + + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumer, sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Validate actual consumerData to returned from response + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumer, getConsumerDataObject); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumer, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumer, sdncAdminUserDetails, + STATUS_CODE_SUCSESS_CREATED); + // Delete consumer + ConsumerRestUtils.deleteConsumer(consumer, sdncAdminUserDetails); + } + + @Test + public void createEcompCredentialsUserNameNotAllowedCharacters() throws Exception { + char invalidChars[] = { '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '+', '=', '<', '>', '?', '/', + '"', ':', '}', ']', '[', '{', '|', '\\', ' ', '\t', '\n' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName(invalidChars[i] + "ABCdef123"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_CONTENT_PARAM, "Consumer name"); + } + } + + @Test + public void createEcompCredentialsPasswordIsInvalid() throws Exception { + char invalidChars[] = { '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '+', '=', '<', '>', '?', '/', + '"', ':', '}', ']', '[', '{', '|', '\\', ' ', '\t', '\n' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerPassword( + "ABC" + invalidChars[i] + "ABCabc1234567890POImnb12345678901234567890POIUzxcvbNMASDFGhj"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_CONTENT_PARAM, "Consumer password"); + } + } + + @Test + public void createEcompCredentialsSaltNotAllowedCharacters() throws Exception { // Salt + // must + // be + // 32 + // chars + char invalidChars[] = { '`', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '+', '=', '<', '>', '?', '/', + '"', ':', '}', ']', '[', '{', '|', '\\', ' ', '\t', '\n' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerSalt(invalidChars[i] + "1234567890123456789012345678901"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_INVALID_CONTENT, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.createEcompConsumerAuditFailure(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.INVALID_CONTENT_PARAM, "Consumer salt"); + } + } + + @Test + public void createEcompCredentialsPasswordEncoded() throws Exception { + consumerDataDefinition.setConsumerPassword("0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + // Validate actual consumerData to returned from response + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(ADD_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCSESS_CREATED); + } + + // + + @Test + public void deleteEcompUserAlreayDeleted() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete ECOMP consumer + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS_DELETE_GET, + deleteConsumerRest.getErrorCode().intValue()); + // Try to delete ECOMP consumer already deleted + DbUtils.deleteFromEsDbByPattern("_all"); + deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void deleteEcompUserByTester() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncTesterUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncTesterUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Verify that consumer is not deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void deleteEcompUserByOps() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncOpsUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncOpsUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Verify that consumer is not deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void deleteEcompUserByGovernor() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncGovernorUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncGovernorUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Verify that consumer is not deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void deleteEcompUserByDesigner() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncDesignerUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncDesignerUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Verify that consumer is not deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void deleteEcompUserByNoExistingIUser() throws Exception { + User noSdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + noSdncUserDetails.setRole("blabla"); + noSdncUserDetails.setUserId("bt750h"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, noSdncUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_ACCESS, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_ACCESS.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(ADD_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + expectedEcomConsumerAuditJavaObject.setModifier("(" + noSdncUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + DELETE_ECOMP_USER_CREDENTIALS); + // Verify that consumer is not deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void deleteEcompCredentialsUserDoesNotExist() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + + } + + @Test + public void deleteEcompCredentialsUserNameIsNull() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName(null); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void deleteEcompCredentialsUserNameMaxLength() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName( + "_BCD-.abcdqwertyuiopasdfghjklzxcvbnmqw1234567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890pf34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfgghjklqwertyuiopzaiutrewasdfghjklqwertyuiopzasxcdferf123456.--"); // SVC4528 + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void deleteEcompCredentialsUserNameExceedMaxLength() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName( + "_XXXBCD-.abcdqwertyuiopasdfghjklzxcvbnmqw1234567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890pf34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfgghjklqwertyuiopzaiutrewasdfghjklqwertyuiopzasxcdferf123456.--"); // SVC4528 + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void deleteEcompCredentialsHttpCspUserIdHeaderIsMissing() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse createConsumerRest = ConsumerRestUtils.deleteConsumerHttpCspAtuUidIsMissing(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_MISSING_INFORMATION, + createConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(DELETE_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc()); + expectedEcomConsumerAuditJavaObject.setModifier(""); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + DELETE_ECOMP_USER_CREDENTIALS); + } + + @Test + public void deleteEcompCredentialsNameIsUpperCase() throws Exception { + consumerDataDefinition.setConsumerName("benny"); + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete consumer + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName("BENNY"); + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + deleteConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(DELETE_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + // Get Consumer to verify that consumer user was not deleted + consumerDataDefinition.setConsumerName("benny"); + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + } + + @Test + public void getEcompCredentialsMethodGet() throws Exception { + // Create Consumer + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + // Validate actual consumerData to returned from response + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + DbUtils.deleteFromEsDbByPattern("_all"); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCCESS_DELETE_GET); + // Delete consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void getEcompUserAlreayDeleted() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + // Delete ECOMP consumer + RestResponse deleteConsumerRest = ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS_DELETE_GET, + deleteConsumerRest.getErrorCode().intValue()); + DbUtils.deleteFromEsDbByPattern("_all"); + // Try to get ECOMP consumer already deleted + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void getEcompUserByTester() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer by Tester user + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncTesterUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncTesterUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Get Consumer by Admin + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void getEcompUserByOps() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer by Ops user + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncOpsUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncOpsUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Get Consumer by Admin + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void getEcompUserByGovernor() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer by Ops user + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncGovernorUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncGovernorUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Get Consumer by Admin + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void getEcompUserByDesigner() throws Exception { + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // Get Consumer by Designer user + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncDesignerUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_OPERATION, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncDesignerUserDetails, ActionStatus.RESTRICTED_OPERATION); + // Get Consumer by Admin + getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } + + @Test + public void getEcompUserByNoExistingIUser() throws Exception { + User noSdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + noSdncUserDetails.setRole("blabla"); + noSdncUserDetails.setUserId("bt750h"); + // Get Consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, noSdncUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_RESTRICTED_ACCESS, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_ACCESS.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(GET_ECOMP_USER_CREDENTIALS); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc("")); + expectedEcomConsumerAuditJavaObject.setModifier("(" + noSdncUserDetails.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, + GET_ECOMP_USER_CREDENTIALS); + } + + @Test + public void getEcompCredentialsUserDoesNotExist() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + + } + + @Test + public void getEcompCredentialsUserNameIsNull() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + consumerDataDefinition.setConsumerName(null); + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_NOT_FOUND, + getConsumerRest.getErrorCode().intValue()); + // Audit validation + AuditValidationUtils.deleteEcompConsumerAuditFailure(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, ActionStatus.ECOMP_USER_NOT_FOUND, consumerDataDefinition.getConsumerName()); + } + + @Test + public void getEcompCredentialsUserNameMaxLength() throws Exception { + consumerDataDefinition.setConsumerName( + "_ABCD-.abcdqwertyuiopasdfghjklzxcvbnmqw1234567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfg34567890pf34567890poiutrewasdfghjklqwertyuiopzaiutrewasdfgghjklqwertyuiopzaiutrewasdfghjklqwertyuiopzasxcdferf123456.-"); // SVC4528 + RestResponse createConsumerRest = ConsumerRestUtils.createConsumer(consumerDataDefinition, + sdncAdminUserDetails); + assertEquals("Check response code after create Consumer", STATUS_CODE_SUCSESS_CREATED, + createConsumerRest.getErrorCode().intValue()); + // parse updated response to javaObject + ConsumerDataDefinition getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(createConsumerRest); + // Validate actual consumerData to returned from response + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Get Consumer + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse getConsumerRest = ConsumerRestUtils.getConsumer(consumerDataDefinition, sdncAdminUserDetails); + assertEquals("Check response code after get Consumer", STATUS_CODE_SUCCESS, + getConsumerRest.getErrorCode().intValue()); + getConsumerDataObject = ConsumerRestUtils.parseComsumerResp(getConsumerRest); + ConsumerRestUtils.validateConsumerReqVsResp(consumerDataDefinition, getConsumerDataObject); + // Audit validation + AuditValidationUtils.ecompConsumerAuditSuccess(GET_ECOMP_USER_CREDENTIALS, consumerDataDefinition, + sdncAdminUserDetails, STATUS_CODE_SUCCESS_DELETE_GET); + // Delete consumer + ConsumerRestUtils.deleteConsumer(consumerDataDefinition, sdncAdminUserDetails); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/UuidTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/UuidTest.java new file mode 100644 index 0000000000..acb7e15c6c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/general/UuidTest.java @@ -0,0 +1,104 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.general; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.List; +import java.util.UUID; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.common.api.Constants; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +public class UuidTest extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public UuidTest() { + super(name, UuidTest.class.getName()); + config = Config.instance(); + } + + @Test + public void testE2EUuidHeaderReturnedAndPreserved() throws IOException { + UUID randomUUID = UUID.randomUUID(); + String uuidStr = randomUUID.toString(); + RestResponse allTagsTowardsCatalogFe = CatalogRestUtils.getAllCategoriesTowardsCatalogFeWithUuid(uuidStr); + AssertJUnit.assertEquals(allTagsTowardsCatalogFe.getErrorCode(), new Integer(200)); + List list = allTagsTowardsCatalogFe.getHeaderFields().get(Constants.X_ECOMP_REQUEST_ID_HEADER); + // check that header is returned + AssertJUnit.assertTrue(list != null && !list.isEmpty()); + String receivedUuid = list.get(0); + // Check that same uuid returned + AssertJUnit.assertEquals(uuidStr, receivedUuid); + } + + @Test + public void testUuidHeaderGeneratedBe() throws IOException { + RestResponse allTagsTowardsCatalogBe = CatalogRestUtils.getAllCategoriesTowardsCatalogBe(); + List list = allTagsTowardsCatalogBe.getHeaderFields().get(Constants.X_ECOMP_REQUEST_ID_HEADER); + // check that response was OK + assertEquals(allTagsTowardsCatalogBe.getErrorCode(), new Integer(200)); + // check that header is returned + assertTrue(list != null && !list.isEmpty()); + String uuid = list.get(0); + // Check there is no conversion error + UUID.fromString(uuid); + } + + @Test + public void testE2EOptionsNoUuid() throws IOException { + RestResponse allTagsTowardsCatalogFe = ResourceRestUtils.sendOptionsTowardsCatalogFeWithUuid(); + assertEquals(allTagsTowardsCatalogFe.getErrorCode(), new Integer(200)); + List list = allTagsTowardsCatalogFe.getHeaderFields().get(Constants.X_ECOMP_REQUEST_ID_HEADER); + // check that header is returned (generated by BE) + assertTrue(list != null && !list.isEmpty()); + String receivedUuid = list.get(0); + // Check there is no conversion error + UUID.fromString(receivedUuid); + } + + @Test + public void testE2EMethodNotAllowedWithUuid() throws IOException { + UUID randomUUID = UUID.randomUUID(); + String uuidStr = randomUUID.toString(); + RestResponse allTagsTowardsCatalogFe = ResourceRestUtils + .putAllCategoriesTowardsCatalogFeWithUuidNotAllowed(uuidStr); + assertEquals(allTagsTowardsCatalogFe.getErrorCode(), new Integer(405)); + List list = allTagsTowardsCatalogFe.getHeaderFields().get(Constants.X_ECOMP_REQUEST_ID_HEADER); + // check that header is returned (generated by BE) + assertTrue(list != null && !list.isEmpty()); + String receivedUuid = list.get(0); + // Check that same uuid returned + assertEquals(uuidStr, receivedUuid); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/CsarUtilsTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/CsarUtilsTest.java new file mode 100644 index 0000000000..7aae0e9a4e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/CsarUtilsTest.java @@ -0,0 +1,430 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.zip.ZipEntry; +import java.util.zip.ZipInputStream; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.testng.annotations.Test; +import org.yaml.snakeyaml.Yaml; + +public class CsarUtilsTest extends ComponentBaseTest { + + public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate"; + + @Rule + public static TestName name = new TestName(); + + public CsarUtilsTest() { + super(name, CsarUtilsTest.class.getName()); + } + + @Test(enabled = true) + public void createServiceCsarBasicTest() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + Resource resourceVF = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, true, true); + resourceVF = (Resource) AtomicOperationUtils.changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + byte[] downloadCSAR = downloadCSAR(sdncModifierDetails, service); + + csarBasicValidation(service, downloadCSAR); + } + + @Test(enabled = true) + public void createResourceCsarBasicTest() throws Exception { + + Resource resourceVF = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + resourceVF = (Resource) AtomicOperationUtils.changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + byte[] downloadCSAR = downloadCSAR(sdncModifierDetails, resourceVF); + + csarBasicValidation(resourceVF, downloadCSAR); + } + + @Test(enabled = true) + public void createServiceCsarInclDeploymentArtTest() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + Resource resourceVF1 = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resourceVF2 = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + + resourceVF1 = (Resource) AtomicOperationUtils.changeComponentState(resourceVF1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + resourceVF2 = (Resource) AtomicOperationUtils.changeComponentState(resourceVF2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF1, service, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF2, service, UserRoleEnum.DESIGNER, true); + + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG_XML, service, UserRoleEnum.DESIGNER, true, true); + + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + byte[] downloadCSAR = downloadCSAR(sdncModifierDetails, service); + + csarBasicValidation(service, downloadCSAR); + + validateServiceCsar(resourceVF1, resourceVF2, service, downloadCSAR, 3, 5, 1); + } + + @Test(enabled = true) + public void createResourceCsarInclDeploymentArtTest() throws Exception { + + Resource resourceVF1 = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG_XML, resourceVF1, UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_ARTIFACT, resourceVF1, UserRoleEnum.DESIGNER, true, true); + resourceVF1 = (Resource) AtomicOperationUtils.changeComponentState(resourceVF1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + byte[] downloadCSAR = downloadCSAR(sdncModifierDetails, resourceVF1); + + csarBasicValidation(resourceVF1, downloadCSAR); + //TODO when feature is integrated to OS should modify expected deployment artifacts in csar Artifacts folder to (0,1,1) + validateVFCsar(resourceVF1, downloadCSAR, 1, 0, 0, 0); + } + + private void csarBasicValidation(Component mainComponent, byte[] downloadCSAR) { + try (ByteArrayInputStream ins = new ByteArrayInputStream(downloadCSAR); ZipInputStream zip = new ZipInputStream(ins);) { + + String resourceYaml = null; + byte[] buffer = new byte[1024]; + ZipEntry nextEntry = zip.getNextEntry(); + StringBuffer sb = new StringBuffer(); + int len; + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + assertTrue(nextEntry.getName().equals("TOSCA-Metadata/TOSCA.meta")); + + sb.setLength(0); + nextEntry = zip.getNextEntry(); + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + resourceYaml = sb.toString(); + + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + ArtifactDefinition artifactDefinition = mainComponent.getToscaArtifacts().get(ASSET_TOSCA_TEMPLATE); + String fileName = artifactDefinition.getArtifactName(); + assertEquals("Tosca-Template file name: ", "Definitions/" + fileName, nextEntry.getName()); + assertTrue("Tosca template Yaml validation: ", yamlToObjectConverter.isValidYaml(resourceYaml.getBytes())); + + ins.close(); + zip.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void validateServiceCsar(Component certifiedVFC1, Component certifiedVFC2, Service fetchedService, byte[] resultByte, int toscaEntryIndexToPass, int generatorEntryIndexToPass, int deploymentArtifactIndexToPass) { + + // TODO Test to validate everything is right (comment out after testing) + /* + * try { FileUtils.writeByteArrayToFile(new File("c:/TestCSAR/" + fetchedService.getName() + ".zip"), resultByte); } catch (IOException e) { // Auto-generated catch block e.printStackTrace(); } + */ + + try (ByteArrayInputStream ins = new ByteArrayInputStream(resultByte); ZipInputStream zip = new ZipInputStream(ins);) { + + String resourceYaml = null; + byte[] buffer = new byte[1024]; + ZipEntry nextEntry = zip.getNextEntry(); + StringBuffer sb = new StringBuffer(); + int len; + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + assertTrue(nextEntry.getName().equals("TOSCA-Metadata/TOSCA.meta")); + + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + + int toscaEntryIndex = 0; + int generatorEntryIndex = 0; + int deploymentArtifactIndex = 0; + String fileName = null; + ArtifactDefinition artifactDefinition; + Component componentToValidate = null; + + artifactDefinition = fetchedService.getToscaArtifacts().get(ASSET_TOSCA_TEMPLATE); + String serviceFileName = artifactDefinition.getArtifactName(); + artifactDefinition = certifiedVFC1.getToscaArtifacts().get(ASSET_TOSCA_TEMPLATE); + String vfc1FileName = artifactDefinition.getArtifactName(); + artifactDefinition = certifiedVFC2.getToscaArtifacts().get(ASSET_TOSCA_TEMPLATE); + String vfc2FileName = artifactDefinition.getArtifactName(); + + while ((nextEntry = zip.getNextEntry()) != null) { + sb.setLength(0); + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + String entryName = nextEntry.getName(); + + resourceYaml = sb.toString(); + if (entryName.contains(serviceFileName)) { + componentToValidate = fetchedService; + fileName = "Definitions/" + serviceFileName; + + assertEquals("Validate entry Name", (fileName), nextEntry.getName()); + assertTrue(yamlToObjectConverter.isValidYaml(resourceYaml.getBytes())); + validateContent(resourceYaml, componentToValidate); + ++toscaEntryIndex; + continue; + } + + if (entryName.contains(vfc1FileName)) { + componentToValidate = certifiedVFC1; + fileName = "Definitions/" + vfc1FileName; + + assertEquals("Validate entry Name", (fileName), nextEntry.getName()); + assertTrue(yamlToObjectConverter.isValidYaml(resourceYaml.getBytes())); + validateContent(resourceYaml, componentToValidate); + ++toscaEntryIndex; + continue; + } + if (entryName.contains(vfc2FileName)) { + componentToValidate = certifiedVFC2; + fileName = "Definitions/" + vfc2FileName; + + assertEquals("Validate entry Name", (fileName), nextEntry.getName()); + assertTrue(yamlToObjectConverter.isValidYaml(resourceYaml.getBytes())); + validateContent(resourceYaml, componentToValidate); + ++toscaEntryIndex; + continue; + } + + if (entryName.contains(".xml") && !entryName.startsWith("Artifacts/AAI")) { + ++deploymentArtifactIndex; + continue; + } + + if (entryName.startsWith("Artifacts/AAI")) { + ++generatorEntryIndex; + continue; + } + + assertTrue("Unexpected entry: " + entryName, true); + } + assertEquals("Validate amount of entries", toscaEntryIndexToPass, toscaEntryIndex); + assertEquals("Validate amount of generated AAI artifacts", generatorEntryIndexToPass, generatorEntryIndex); + assertEquals("Validate amount of generated Deployment artifacts", deploymentArtifactIndexToPass, deploymentArtifactIndex); + + ins.close(); + zip.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void validateVFCsar(Component certifiedVF, byte[] resultByte, int toscaEntryIndexToPass, int ymlDeploymentArtifactIndexToPass, int xmlDeploymentArtifactIndexToPass, int heatEnvDeploymentArtifactIndexToPass) { + + // TODO Test to validate everything is right (comment out after testing) + /* + * try { FileUtils.writeByteArrayToFile(new File("c:/TestCSAR/" + fetchedService.getName() + ".zip"), resultByte); } catch (IOException e) { // Auto-generated catch block e.printStackTrace(); } + */ + + try (ByteArrayInputStream ins = new ByteArrayInputStream(resultByte); ZipInputStream zip = new ZipInputStream(ins);) { + + String resourceYaml = null; + byte[] buffer = new byte[1024]; + ZipEntry nextEntry = zip.getNextEntry(); + StringBuffer sb = new StringBuffer(); + int len; + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + assertTrue(nextEntry.getName().equals("TOSCA-Metadata/TOSCA.meta")); + + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + + int toscaEntryIndex = 0; + int ymlEntryIndex = 0; + int xmlArtifactsIndex = 0; + int heatEnvDeploymentArtifactIndex = 0; + String fileName = null; + ArtifactDefinition artifactDefinition; + Component componentToValidate = null; + + artifactDefinition = certifiedVF.getToscaArtifacts().get(ASSET_TOSCA_TEMPLATE); + String vfFileName = artifactDefinition.getArtifactName(); + + while ((nextEntry = zip.getNextEntry()) != null) { + sb.setLength(0); + + while ((len = zip.read(buffer)) > 0) { + sb.append(new String(buffer, 0, len)); + } + + String entryName = nextEntry.getName(); + + resourceYaml = sb.toString(); + if (entryName.contains(vfFileName)) { + componentToValidate = certifiedVF; + fileName = "Definitions/" + vfFileName; + + assertEquals("Validate entry Name", (fileName), nextEntry.getName()); + assertTrue(yamlToObjectConverter.isValidYaml(resourceYaml.getBytes())); + validateContent(resourceYaml, componentToValidate); + ++toscaEntryIndex; + continue; + } + + if (entryName.contains(".xml") && entryName.startsWith("Artifacts/")) { + ++xmlArtifactsIndex; + continue; + } + + if (entryName.contains(".sh") && entryName.startsWith("Artifacts/")) { + ++heatEnvDeploymentArtifactIndex; + continue; + } + + if (entryName.contains(".yml") && entryName.startsWith("Artifacts/")) { + ++ymlEntryIndex; + continue; + } + + assertTrue("Unexpected entry: " + entryName, false); + } + assertEquals("Validate amount of entries", toscaEntryIndexToPass, toscaEntryIndex); + assertEquals("Validate amount of YAML artifacts", ymlDeploymentArtifactIndexToPass, ymlEntryIndex); + assertEquals("Validate amount of generated XML artifacts", xmlDeploymentArtifactIndexToPass, xmlArtifactsIndex); + assertEquals("Validate amount of generated HEAT ENV artifacts", heatEnvDeploymentArtifactIndexToPass, heatEnvDeploymentArtifactIndex); + + ins.close(); + zip.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void validateContent(String content, Component component) { + Yaml yaml = new Yaml(); + + InputStream inputStream = new ByteArrayInputStream(content.getBytes()); + @SuppressWarnings("unchecked") + Map load = (Map) yaml.load(inputStream); + @SuppressWarnings("unchecked") + Map metadata = (Map) load.get("metadata"); + assertNotNull(metadata); + + String name = (String) metadata.get("name"); + assertNotNull(name); + assertEquals("Validate component name", component.getName(), name); + + String invariantUUID = (String) metadata.get("invariantUUID"); + assertNotNull(invariantUUID); + assertEquals("Validate component invariantUUID", component.getInvariantUUID(), invariantUUID); + + String UUID = (String) metadata.get("UUID"); + assertNotNull(UUID); + assertEquals("Validate component invariantUUID", component.getUUID(), UUID); + + String type = (String) metadata.get("type"); + assertNotNull(type); + if (component.getComponentType().equals(ComponentTypeEnum.SERVICE)) { + assertEquals("Validate component type", component.getComponentType().getValue(), type); + } else { + assertEquals("Validate component type", ((Resource) component).getResourceType(), ResourceTypeEnum.valueOf(type)); + } + } + + private byte[] downloadCSAR(User sdncModifierDetails, Component createdComponent) throws Exception { + + String artifactUniqeId = createdComponent.getToscaArtifacts().get("assettoscacsar").getUniqueId(); + RestResponse getCsarResponse = null; + + switch (createdComponent.getComponentType()) { + case RESOURCE: + getCsarResponse = ArtifactRestUtils.downloadResourceArtifactInternalApi(createdComponent.getUniqueId(), sdncModifierDetails, artifactUniqeId); + break; + case SERVICE: + getCsarResponse = ArtifactRestUtils.downloadServiceArtifactInternalApi(createdComponent.getUniqueId(), sdncModifierDetails, artifactUniqeId); + break; + default: + break; + } + + assertNotNull(getCsarResponse); + BaseRestUtils.checkSuccess(getCsarResponse); + + ArtifactUiDownloadData artifactUiDownloadData = ResponseParser.parseToObject(getCsarResponse.getResponse(), ArtifactUiDownloadData.class); + + assertNotNull(artifactUiDownloadData); + + byte[] fromUiDownload = artifactUiDownloadData.getBase64Contents().getBytes(); + byte[] decodeBase64 = Base64.decodeBase64(fromUiDownload); + + return decodeBase64; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ExportToscaTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ExportToscaTest.java new file mode 100644 index 0000000000..e4360329ad --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ExportToscaTest.java @@ -0,0 +1,333 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.Test; +import org.yaml.snakeyaml.Yaml; + +import com.google.gson.Gson; +import com.google.gson.JsonParser; + +public class ExportToscaTest extends ComponentBaseTest { + @Rule + public static TestName name = new TestName(); + + public ExportToscaTest() { + super(name, ExportToscaTest.class.getName()); + } + + @Test(enabled = true) + public void exportVfModuleTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + Resource createdResource = createVfFromCSAR(sdncModifierDetails, "VSPPackage"); + + Map load = downloadAndParseToscaTemplate(sdncModifierDetails, createdResource); + assertNotNull(load); + Map topology_template = (Map) load.get("topology_template"); + assertNotNull(topology_template); + Map groups = (Map) topology_template.get("groups"); + assertNotNull(groups); + List groupsOrigin = createdResource.getGroups(); + + assertEquals("Validate groups size", groupsOrigin.size(), groups.size()); + for (GroupDefinition group : groupsOrigin) { + Map groupTosca = (Map) groups.get(group.getName()); + assertNotNull(groupTosca); + + Map metadata = (Map) groupTosca.get("metadata"); + assertNotNull(metadata); + + String invariantUUID; + String name; + String UUID; + String version; + Map properties = (Map) groupTosca.get("properties"); + + if (group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) { + invariantUUID = (String) metadata.get("vfModuleModelInvariantUUID"); + name = (String) metadata.get("vfModuleModelName"); + UUID = (String) metadata.get("vfModuleModelUUID"); + version = (String) metadata.get("vfModuleModelVersion"); + assertNotNull(properties); + + String vf_module_type = (String) properties.get("vf_module_type"); + List props = group.getProperties(); + for (GroupProperty prop : props) { + if (prop.getName().equals(Constants.IS_BASE)) { + String value = prop.getValue() == null ? prop.getDefaultValue() : prop.getValue(); + boolean bvalue = Boolean.parseBoolean(value); + if (bvalue) { + assertEquals("Validate vf_module_type", "Base", vf_module_type); + } else { + assertEquals("Validate vf_module_type", "Expansion", vf_module_type); + } + break; + } + } + String vf_module_description = (String) properties.get("vf_module_description"); + assertEquals("Validate vf_module_description", group.getDescription(), vf_module_description); + + Boolean volume_group = (Boolean) properties.get("volume_group"); + boolean isVolume = false; + List artifactsList = group.getArtifacts(); + List artifacts = new ArrayList<>(); + if (artifactsList != null && !artifactsList.isEmpty()) { + ArtifactDefinition masterArtifact = findMasterArtifact(createdResource.getDeploymentArtifacts(), + artifacts, artifactsList); + if (masterArtifact.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) { + isVolume = true; + } + } + assertEquals("Validate volume_group", isVolume, volume_group); + + } else { + invariantUUID = (String) metadata.get("invariantUUID"); + name = (String) metadata.get("name"); + UUID = (String) metadata.get("UUID"); + version = (String) metadata.get("version"); + assertNull(properties); + + } + assertEquals("Validate InvariantUUID", group.getInvariantUUID(), invariantUUID); + assertEquals("Validate name", group.getName(), name); + assertEquals("Validate UUID", group.getGroupUUID(), UUID); + assertEquals("Validate version", group.getVersion(), version); + + } + } + + @Test(enabled = true) + public void exportCsarInputsTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + Resource createdResource = createVfFromCSAR(sdncModifierDetails, "csar_1"); + Map load = downloadAndParseToscaTemplate(sdncModifierDetails, createdResource); + assertNotNull(load); + + Map topology_template = (Map) load.get("topology_template"); + assertNotNull(topology_template); + + Map inputs = (Map) topology_template.get("inputs"); + assertNotNull(inputs); + + List inputsFromResource = createdResource.getInputs(); + assertEquals("validate inputs size", inputsFromResource.size(), inputs.size()); + for (InputDefinition inputDef : inputsFromResource) { + Map inputInFile = (Map) inputs.get(inputDef.getName()); + assertNotNull(inputInFile); + validateInput(inputDef, inputInFile); + } + List componentInstances = createdResource.getComponentInstances(); + Map> componentInstancesProperties = createdResource + .getComponentInstancesProperties(); + Map node_templates = (Map) topology_template.get("node_templates"); + assertNotNull(node_templates); + + JsonParser jsonParser = new JsonParser(); + + for (Map.Entry> entry : componentInstancesProperties.entrySet()) { + + Optional findFirst = componentInstances.stream() + .filter(ci -> ci.getUniqueId().equals(entry.getKey())).findFirst(); + assertTrue(findFirst.isPresent()); + String resourceName = findFirst.get().getName(); + Map instance = (Map) node_templates.get(resourceName); + assertNotNull(instance); + Map properties = (Map) instance.get("properties"); + + for (ComponentInstanceProperty cip : entry.getValue()) { + if (cip.getValueUniqueUid() != null && !cip.getValueUniqueUid().isEmpty()) { + assertNotNull(properties); + if (cip.getValue().contains("get_input")) { + Object prop = properties.get(cip.getName()); + assertNotNull(prop); + + Gson gson = new Gson(); + String json = gson.toJson(prop); + assertEquals("validate json property", cip.getValue(), json); + } + + } + } + + } + + } + + @Test + public void importExportCsarWithJsonPropertyType() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "jsonPropertyTypeTest.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + path = Paths.get(rootPath + "/src/test/resources/CI/csars/jsonPropertyTypeTest.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + ComponentInstance pmaaServer = resource.getComponentInstances().stream() + .filter(p -> p.getName().equals("pmaa_server_0")).findAny().get(); + ComponentInstanceProperty jsonProp = resource.getComponentInstancesProperties().get(pmaaServer.getUniqueId()) + .stream().filter(p -> p.getType().equals(ToscaPropertyType.JSON.getType())).findAny().get(); + String jsonValue = "{\"pmaa.sb_nic\":{\"address\":{\"get_input\":\"pmaa_dpu_fixed_ip\"},\"cidr\":{\"get_input\":\"pmaa_dpu_cidr\"},\"gateway\":{\"get_input\":\"pmaa_dpu_gateway\"}}}"; + assertEquals(jsonProp.getValue(), jsonValue); + // download and compare + Map load = downloadAndParseToscaTemplate(sdncModifierDetails, resource); + assertNotNull(load); + Map topology_template = (Map) load.get("topology_template"); + assertNotNull(topology_template); + Map nodes = (Map) topology_template.get("node_templates"); + assertNotNull(nodes); + Map pmaaServerObj = (Map) nodes.get("pmaa_server_0"); + assertNotNull(pmaaServerObj); + Map props = (Map) pmaaServerObj.get("properties"); + assertNotNull(props); + Map jsonPropObj = (Map) props.get("metadata"); + assertNotNull(jsonPropObj); + Gson gson = new Gson(); + String json = gson.toJson(jsonPropObj); + assertEquals(json, jsonValue); + } + + private void validateInput(InputDefinition inputDef, Map inputInFile) { + assertEquals("validate input type", inputDef.getType(), (String) inputInFile.get("type")); + + if (inputDef.getDefaultValue() == null) { + assertNull(inputInFile.get("default")); + } else { + assertNotNull(inputInFile.get("default")); + String value = inputDef.getDefaultValue().replace("\"", ""); + value = value.replace(" ", ""); + String expValue = inputInFile.get("default").toString().replace(" ", ""); + assertEquals("validate input default", value, expValue); + } + assertEquals("validate input description", inputDef.getDescription(), (String) inputInFile.get("description")); + } + + // ---------------------------------------- + private Map downloadAndParseToscaTemplate(User sdncModifierDetails, Resource createdResource) + throws Exception { + String artifactUniqeId = createdResource.getToscaArtifacts().get("assettoscatemplate").getUniqueId(); + + RestResponse toscaTemplate = ArtifactRestUtils.downloadResourceArtifactInternalApi( + createdResource.getUniqueId(), sdncModifierDetails, artifactUniqeId); + ArtifactUiDownloadData artifactUiDownloadData = ResponseParser.parseToObject(toscaTemplate.getResponse(), + ArtifactUiDownloadData.class); + byte[] fromUiDownload = artifactUiDownloadData.getBase64Contents().getBytes(); + byte[] decodeBase64 = Base64.decodeBase64(fromUiDownload); + Yaml yaml = new Yaml(); + + InputStream inputStream = new ByteArrayInputStream(decodeBase64); + + Map load = (Map) yaml.load(inputStream); + return load; + } + + private Resource createVfFromCSAR(User sdncModifierDetails, String csarId) throws Exception { + // create new resource from Csar + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + + resourceDetails.setCsarUUID(csarId); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource createdResource = ResponseParser.convertResourceResponseToJavaObject(createResource.getResponse()); + return createdResource; + } + + public ArtifactDefinition findMasterArtifact(Map deplymentArtifact, + List artifacts, List artifactsList) { + for (String artifactUid : artifactsList) { + for (Entry entry : deplymentArtifact.entrySet()) { + ArtifactDefinition artifact = entry.getValue(); + if (artifactUid.equalsIgnoreCase(artifact.getUniqueId())) { + artifacts.add(artifact); + } + + } + } + ArtifactDefinition masterArtifact = null; + for (ArtifactDefinition artifactInfo : artifacts) { + String atrifactType = artifactInfo.getArtifactType(); + if (atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()) + || atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType())) { + masterArtifact = artifactInfo; + continue; + } + if (atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + masterArtifact = artifactInfo; + break; + } + } + return masterArtifact; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportCsarResourceTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportCsarResourceTest.java new file mode 100644 index 0000000000..eab4e5bed2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportCsarResourceTest.java @@ -0,0 +1,1538 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang.WordUtils; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.GroupRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ImportRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ImportCsarResourceTest extends ComponentBaseTest { + private static Logger log = LoggerFactory.getLogger(ImportCsarResourceTest.class.getName()); + @Rule + public static TestName name = new TestName(); + + Gson gson = new Gson(); + + public ImportCsarResourceTest() { + super(name, ImportCsarResourceTest.class.getName()); + } + + private String buildAssertMessage(String expectedString, String actualString) { + return String.format("expected is : %s , actual is: %s", expectedString, actualString); + } + + /** + * + * User Story : US640615 [BE] - Extend create VF API with Import TOSCA CSAR + */ + + @Test(enabled = true) + public void createResourceFromCsarHappy() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("AF7F231969C5463F9C968570070E8877"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void emptyStringInCsarUUIDFieldTest() throws Exception { + String emptyString = ""; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(emptyString); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(null, resource.getComponentInstances()); + + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(emptyString, resource.getCsarUUID()), resource.getCsarUUID() == emptyString); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(emptyString, getResource.getCsarUUID()), getResource.getCsarUUID() == emptyString); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void createResourceFromScratchTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(null, resource.getComponentInstances()); + + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(null, resource.getCsarUUID()), resource.getCsarUUID() == null); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(null, getResource.getCsarUUID()), getResource.getCsarUUID() == null); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void fileNotCsarTypeTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("valid_vf_zip"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_NOT_FOUND.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void missingToscaMetadataFolderTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("toscaFolderNotExists"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void missingToscaMetaFileTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("toscaMetaFileNotExists"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void toscaMetaFileOutsideTheFolderTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("toscaMetaOutsideTheFolder"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void caseSensitiveTest_1() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("caseSensitiveTest_1"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void caseSensitiveTest_2() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("caseSensitiveTest_2"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void missingOneLineInToscaMetaFileTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("missingOneLineInToscaMeta"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void noCSARVersionTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("noCSARVersion"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void noCreatedByValueTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("noCreatedByValue"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void noEntryDefinitionsValueTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("noEntryDefinitionsValue"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void noTOSCAMetaFileVersionValueTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("noTOSCAMetaFileVersionValue"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void invalidCsarVersionInMetaFileTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("invalidCsarVersion"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + + resourceDetails.setCsarUUID("invalidCsarVersion2"); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + + resourceDetails.setCsarUUID("invalidCsarVersion3"); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + + resourceDetails.setCsarUUID("invalidCsarVersion4"); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + + resourceDetails.setCsarUUID("invalidCsarVersion5"); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + + } + + @Test(enabled = true) + public void validCsarVersionInMetaFileTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("validCsarVersion"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void underscoreInToscaMetaFileVersionNameTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("underscoreInsteadOfDash"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void missingEntryDefintionInMetaFileTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("missingEntryDefintionPair"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = false) + public void noNewLineAfterBLock0Test() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("noNewLineAfterBLock0"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void moreThanOneYamlFileTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("moreThenOneYamlFile"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void moreThanOneMetaFileTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("moreThanOneMetaFile"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void csarNotContainsYamlAndMetaFilesTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("notContainYamlAndMetaFiles"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void csarNotContainsYamlFileTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("notContainYamlFile"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + variables.add("Definitions/tosca_mock_vf.yaml"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.YAML_NOT_FOUND_IN_CSAR.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void missingCsarFileTest() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("abc"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_NOT_FOUND.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void longNamesInToscaMetaFileTest_1() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("longNamesInToscaMetaFile1"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void longNamesInToscaMetaFileTest_2() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("longNamesInToscaMetaFile2"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void longNamesInToscaMetaFileTest_3() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("longNamesInToscaMetaFile3"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void longNamesInToscaMetaFileTest_4() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("longNamesInToscaMetaFile4"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void longNamesInToscaMetaFileTest_5() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("longNamesInToscaMetaFile5"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + // possible to have more than four lines in block 0 + // @Test (enabled = true) + public void fiveLinesAsBlock0Test() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + resourceDetails.setCsarUUID("fiveLinesAsBlock0"); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + List variables = new ArrayList(); + variables.add(resourceDetails.getCsarUUID()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.CSAR_INVALID_FORMAT.name(), variables, createResource.getResponse()); + } + + @Test(enabled = true) + public void lifecycleChangingToResourceFromCsarTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("valid_vf"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertTrue("0.1".equals(resource.getVersion())); + assertTrue(LifeCycleStatesEnum.CHECKOUT.getComponentState().equals(resource.getLifecycleState().toString())); + + String designerUserId = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId(); + String testerUserId = ElementFactory.getDefaultUser(UserRoleEnum.TESTER).getUserId(); + String csarUniqueId = resourceDetails.getUniqueId(); + assertNotNull(csarUniqueId); + + RestResponse lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUserId, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUserId, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUserId, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUserId, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUserId, LifeCycleStatesEnum.STARTCERTIFICATION); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUserId, LifeCycleStatesEnum.CERTIFY); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUserId, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + + resource = ResponseParser.parseToObjectUsingMapper(lifecycleChangeResponse.getResponse(), Resource.class); + Map allVersions = resource.getAllVersions(); + assertEquals(2, allVersions.keySet().size()); + assertEquals(2, allVersions.values().size()); + Set keySet = allVersions.keySet(); + assertTrue(keySet.contains("1.0")); + assertTrue(keySet.contains("1.1")); + } + + @Test(enabled = true) + public void csarWithJsonPromEnvTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VSPPackageJsonProp.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + } + + @Test(enabled = true) + public void uploadArtifactToResourceFromCsarTest() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("valid_vf"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + User designer = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultArtifact("firstArtifact"); + String firstArtifactLabel = artifactDetails.getArtifactLabel(); + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, designer, resourceDetails.getUniqueId()); + ArtifactRestUtils.checkSuccess(addInformationalArtifactToResource); + RestResponse getResourceResponse = ResourceRestUtils.getResource(resourceDetails.getUniqueId()); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + Map informationalArtifacts = resource.getArtifacts(); + assertEquals(1, informationalArtifacts.keySet().size()); + Set keySet = informationalArtifacts.keySet(); + assertTrue(keySet.contains(firstArtifactLabel.toLowerCase())); + Collection values = informationalArtifacts.values(); + assertEquals(1, values.size()); + Iterator iterator = values.iterator(); + while (iterator.hasNext()) { + ArtifactDefinition actualArtifact = iterator.next(); + assertTrue(firstArtifactLabel.equals(actualArtifact.getArtifactDisplayName())); + } + + RestResponse lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designer.getUserId(), LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + lifecycleChangeResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designer.getUserId(), LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(lifecycleChangeResponse); + + ArtifactReqDetails artifactDetails2 = ElementFactory.getDefaultArtifact("secondArtifact"); + artifactDetails2.setArtifactName("secondArtifact"); + addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails2, designer, resourceDetails.getUniqueId()); + ArtifactRestUtils.checkSuccess(addInformationalArtifactToResource); + + getResourceResponse = ResourceRestUtils.getResource(resourceDetails.getUniqueId()); + resource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + informationalArtifacts = resource.getArtifacts(); + assertEquals(2, informationalArtifacts.keySet().size()); + keySet = informationalArtifacts.keySet(); + assertTrue(keySet.contains(firstArtifactLabel.toLowerCase())); + assertTrue(keySet.contains(artifactDetails2.getArtifactLabel().toLowerCase())); + values = informationalArtifacts.values(); + assertEquals(2, values.size()); + ArtifactDefinition[] actualArtifacts = values.toArray(new ArtifactDefinition[2]); + assertTrue(firstArtifactLabel.equals(actualArtifacts[0].getArtifactDisplayName())); + assertTrue(artifactDetails2.getArtifactLabel().equals(actualArtifacts[1].getArtifactDisplayName())); + } + + /* + * // @Test (enabled = true) public void createUpdateImportResourceFromCsarArtifactsWereNotChangedTest() throws Exception { // User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); // //back original scar RestResponse + * copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); BaseRestUtils.checkSuccess(copyRes); + * + * // resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); // RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); resourceDetails.setName("test5"); + * resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); resourceDetails.setCsarVersion("1"); // String invariantUUID = resource.getInvariantUUID(); // // RestResponse changeResourceState = + * LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); // assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + * + * // BaseRestUtils.checkSuccess(copyRes); // //change name (temporary) resourceDetails.setCsarVersion("2"); resourceDetails.setName("test6"); createResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + * resourceDetails.getUniqueId()); Resource updatedResource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); Map updatedArtifacts = updatedResource.getDeploymentArtifacts(); for + * (Entry artifactEntry : resource.getDeploymentArtifacts().entrySet()) { if (updatedArtifacts.containsKey(artifactEntry.getKey())) { ArtifactDefinition currArt = updatedArtifacts.get(artifactEntry.getKey()); + * assertEquals(currArt.getArtifactVersion(), artifactEntry.getValue().getArtifactVersion()); assertEquals(currArt.getArtifactUUID(), artifactEntry.getValue().getArtifactUUID()); assertEquals(currArt.getArtifactChecksum(), + * artifactEntry.getValue().getArtifactChecksum()); } } // resourceDetails = ElementFactory.getDefaultResource(); // resourceDetails.setName("test5"); // resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); } + */ + + @Test(enabled = true) + public void createImportResourceFromCsarDissotiateArtifactFromGroupTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + + // create new resource from Csar + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + String invariantUUID = resource.getInvariantUUID(); + + // add artifact from metadata (resource metadata should be updated) + // RestResponse addInformationalArtifactToResource = + // ArtifactRestUtils.addInformationalArtifactToResource(ElementFactory.getDefaultArtifact(), + // sdncModifierDetails, resourceDetails.getUniqueId()); + // ArtifactRestUtils.checkSuccess(addInformationalArtifactToResource); + resourceDetails.setName("test4"); + RestResponse updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(invariantUUID, resource.getInvariantUUID()); + + // wrong RI (without node types, resource shouldn't be updated) + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_dissociate.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + // change name (temporary) + resourceDetails.setName("test4"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(invariantUUID, resource.getInvariantUUID()); + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + @Test(enabled = true) + public void createImportResourceFromCsarNewgroupTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + + // create new resource from Csar + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + String invariantUUID = resource.getInvariantUUID(); + + // update scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_UpdateToscaAndArtifacts.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails.setName("test2"); + // change resource metaData (resource should be updated) + resourceDetails.setDescription("It is new description bla bla bla"); + RestResponse updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + assertEquals(invariantUUID, resource.getInvariantUUID()); + + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + @Test(enabled = true) + public void createImportResourceFromCsarGetGroupTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // RestResponse copyRes = + // copyCsarRest(sdncModifierDetails,"VF_RI2_G4_withArtifacts_a.csar","VF_RI2_G4_withArtifacts.csar"); + + // create new resource from Csar + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("VSPPackage"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + String invariantUUID = resource.getInvariantUUID(); + List groups = resource.getGroups(); + + GroupDefinition groupWithArtifact = groups.stream().filter(p -> p.getArtifacts() != null && !p.getArtifacts().isEmpty()).findFirst().get(); + + RestResponse groupRest = GroupRestUtils.getGroupById(resource, groupWithArtifact.getUniqueId(), sdncModifierDetails); + BaseRestUtils.checkSuccess(groupRest); + + GroupDefinition groupWithoutArtifact = groups.stream().filter(p -> p.getArtifacts() == null || p.getArtifacts().isEmpty()).findFirst().get(); + + groupRest = GroupRestUtils.getGroupById(resource, groupWithoutArtifact.getUniqueId(), sdncModifierDetails); + BaseRestUtils.checkSuccess(groupRest); + } + + @Test(enabled = true) + public void createImportResourceFromCsarUITest() throws Exception { + RestResponse getResource = null; + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "valid_vf.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + // create new resource from Csar + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + RestResponse changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change composition (resource should be updated) + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_b.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + // change name + resourceDetails.setName("test1"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(2, resource.getComponentInstances().size()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change name + resourceDetails.setName("test2"); + // change resource metaData (resource should be updated) + resourceDetails.setDescription("It is new description bla bla bla"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(2, resource.getComponentInstances().size()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // wrong RI (without node types, resource shouldn't be updated) + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_c.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + // change name + resourceDetails.setName("test3"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.INVALID_NODE_TEMPLATE, "Definitions/tosca_mock_vf.yaml", "nodejs", "tosca.nodes.Weber"); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(null, resource); + getResource = ResourceRestUtils.getResourceByNameAndVersion(sdncModifierDetails.getUserId(), "test3", resourceDetails.getVersion()); + BaseRestUtils.checkErrorResponse(getResource, ActionStatus.RESOURCE_NOT_FOUND, "test3"); + + // create new resource from other Csar + resourceDetails = ElementFactory.getDefaultImportResource(); + path = Paths.get(rootPath + "/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setPayloadName("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setName("test4"); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // wrong RI (with node types) resource shouldn't be created + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts_b.csar"); + path = Paths.get(rootPath + "/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_b.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setPayloadName("VF_RI2_G4_withArtifacts_b.csar"); + resourceDetails.setName("test5"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.INVALID_NODE_TEMPLATE, "Definitions/VF_RI2_G1.yaml", "ps04_port_0", "org.openecomp.resource.cp.nodes.heat.network.neutron.Portur"); + } + + @Test(enabled = true) + public void createUpdateImportResourceFromCsarUITest() throws Exception { + RestResponse getResource = null; + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "valid_vf.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + // create new resource from Csar + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + RestResponse changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change composition and update resource + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_b.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setUniqueId(resource.getUniqueId()); + // change name + RestResponse updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(2, resource.getComponentInstances().size()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change name + resourceDetails.setName("test2"); + // change resource metaData (resource should be updated) + resourceDetails.setDescription("It is new description bla bla bla"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(2, resource.getComponentInstances().size()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // try to update resource with wrong RI (without node types, resource + // shouldn't be updated) + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_c.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + // change name + resourceDetails.setName("test3"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkErrorResponse(updateResource, ActionStatus.INVALID_NODE_TEMPLATE, "Definitions/tosca_mock_vf.yaml", "nodejs", "tosca.nodes.Weber"); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(null, resource); + getResource = ResourceRestUtils.getResourceByNameAndVersion(sdncModifierDetails.getUserId(), "test3", resourceDetails.getVersion()); + BaseRestUtils.checkErrorResponse(getResource, ActionStatus.RESOURCE_NOT_FOUND, "test3"); + } + + @Test(enabled = true) + public void createUpdateImportResourceFromCsarTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = null; + RestResponse getResource = null; + ResourceReqDetails resourceDetails = null; + RestResponse updateResource = null; + RestResponse createResource = null; + Resource resource = null; + RestResponse changeResourceState = null; + + // create new resource from Csar + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_a.csar", "valid_vf.csar"); + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("valid_vf.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + String invariantUUID = resource.getInvariantUUID(); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change composition and update resource + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_b.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + // change name + resourceDetails.setName("test1"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(2, resource.getComponentInstances().size()); + assertEquals(invariantUUID, resource.getInvariantUUID()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_a.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + + // change name + resourceDetails.setName("test2"); + // change resource metaData and update resource + resourceDetails.setDescription("It is new description bla bla bla"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + assertEquals(invariantUUID, resource.getInvariantUUID()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_a.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + + // try to update resource with wrong RI (without node types, resource + // shouldn't be updated) + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_c.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + // change name (temporary) + resourceDetails.setName("test3"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resource.getUniqueId()); + BaseRestUtils.checkErrorResponse(updateResource, ActionStatus.INVALID_NODE_TEMPLATE, "Definitions/tosca_mock_vf.yaml", "nodejs", "tosca.nodes.Weber"); + + getResource = ResourceRestUtils.getResourceByNameAndVersion(sdncModifierDetails.getUserId(), "test3", resourceDetails.getVersion()); + BaseRestUtils.checkErrorResponse(getResource, ActionStatus.RESOURCE_NOT_FOUND, "test3"); + getResource = ResourceRestUtils.getResourceByNameAndVersion(sdncModifierDetails.getUserId(), "test2", resourceDetails.getVersion()); + BaseRestUtils.checkSuccess(getResource); + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_a.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + + // create new resource from Csar + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // scar with wrong RI + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_b.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + // wrong RI (with node types) resource shouldn't be created + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkErrorResponse(updateResource, ActionStatus.INVALID_NODE_TEMPLATE, "Definitions/VF_RI2_G1.yaml", "ps04_port_0", "org.openecomp.resource.cp.nodes.heat.network.neutron.Portur"); + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + @Test(enabled = true) + public void createUpdateImportResourceFromCsarWithArtifactsTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = null; + ResourceReqDetails resourceDetails = null; + RestResponse updateResource = null; + RestResponse createResource = null; + Resource resource = null; + RestResponse changeResourceState = null; + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts.csar"); + resourceDetails.setCsarVersion("1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + // create new resource from Csar + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + List requiredArtifactsOld = resource.getDeploymentArtifacts().get("heat5").getRequiredArtifacts(); + assertTrue(requiredArtifactsOld != null && !requiredArtifactsOld.isEmpty() && requiredArtifactsOld.size() == 3); + assertTrue(requiredArtifactsOld.contains("hot-nimbus-pcm-volumes_v1.0.yaml")); + assertTrue(requiredArtifactsOld.contains("nested-pcm_v1.0.yaml")); + assertTrue(requiredArtifactsOld.contains("hot-nimbus-oam-volumes_v1.0.yaml")); + + // update scar with new artifacts + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_updated.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + resourceDetails.setCsarVersion("2"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + + List requiredArtifactsNew = resource.getDeploymentArtifacts().get("heat5").getRequiredArtifacts(); + assertTrue(requiredArtifactsNew != null && !requiredArtifactsNew.isEmpty() && requiredArtifactsNew.size() == 3); + assertTrue(requiredArtifactsNew.contains("hot-nimbus-swift-container_v1.0.yaml")); + assertTrue(requiredArtifactsNew.contains("hot-nimbus-oam-volumes_v1.0.yaml")); + assertTrue(requiredArtifactsNew.contains("nested-oam_v1.0.yaml")); + + // back original scar + copyRes = copyCsarRest(sdncModifierDetails, "VF_RI2_G4_withArtifacts_a.csar", "VF_RI2_G4_withArtifacts.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + @Test(enabled = true) + public void createUpdateImportWithPropertiesFromCsarUITest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "valid_vf.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + // create new resource from Csar + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + RestResponse changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change composition (add new RI with specified property values) + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_d.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + // change name + resourceDetails.setName("test1"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(6, resource.getComponentInstances().size()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + // change composition (add new specified property values to existing RI) + path = Paths.get(rootPath + "/src/test/resources/CI/csars/valid_vf_f.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + // change name + resourceDetails.setName("test2"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(6, resource.getComponentInstances().size()); + + } + + public static RestResponse copyCsarRest(User sdncModifierDetails, String sourceCsarUuid, String targetCsarUuid) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.COPY_CSAR_USING_SIMULATOR, config.getCatalogBeHost(), config.getCatalogBePort(), sourceCsarUuid, targetCsarUuid); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + + RestResponse copyCsarResponse = http.httpSendPost(url, "dummy", headersMap); + if (copyCsarResponse.getErrorCode() != 200) { + return null; + } + return copyCsarResponse; + + } + + public static RestResponse getCsarRest(User sdncModifierDetails, String sourceCsarUuid) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_CSAR_USING_SIMULATOR, config.getCatalogBeHost(), config.getCatalogBePort(), sourceCsarUuid); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + + RestResponse copyCsarResponse = http.httpSendGet(url, headersMap); + if (copyCsarResponse.getErrorCode() != 200) { + return null; + } + return copyCsarResponse; + + } + + @Test(enabled = true) + public void updateResourceFromCsarHappy() throws Exception { + RestResponse copyRes = copyCsarRest(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), "valid_vf_a.csar", "valid_vf.csar"); + BaseRestUtils.checkSuccess(copyRes); + // create + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("valid_vf"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getResource(resource.getUniqueId()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + + RestResponse updateResource = ResourceRestUtils.updateResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + + } + + @Test(enabled = true) + public void createResourceFromCsarWithGroupsHappy() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroups"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + assertEquals("verify there are 2 groups", 2, resource.getGroups().size()); + + Map compNameToUniqueId = resource.getComponentInstances().stream().collect(Collectors.toMap(p -> p.getName(), p -> p.getUniqueId())); + + // Verify 2 members on group1 + // members: [ app_server, mongo_server ] + String[] membersNameGroup1 = { "app_server", "mongo_server" }; + verifyMembersInResource(resource, compNameToUniqueId, "group1", membersNameGroup1); + // Verify 4 members on group2 + // members: [ mongo_db, nodejs, app_server, mongo_server ] + String[] membersNameGroup2 = { "app_server", "mongo_server", "mongo_db", "nodejs" }; + verifyMembersInResource(resource, compNameToUniqueId, "group2", membersNameGroup2); + + // Check OUT + resourceDetails.setUniqueId(resource.getUniqueId()); + RestResponse changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + changeResourceState = LifecycleRestUtils.changeResourceState(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + + Resource checkedOutResource = ResponseParser.parseToObjectUsingMapper(changeResourceState.getResponse(), Resource.class); + compNameToUniqueId = checkedOutResource.getComponentInstances().stream().collect(Collectors.toMap(p -> p.getName(), p -> p.getUniqueId())); + + // Verify 2 members on group1 + // members: [ app_server, mongo_server ] + verifyMembersInResource(checkedOutResource, compNameToUniqueId, "group1", membersNameGroup1); + // Verify 4 members on group2 + // members: [ mongo_db, nodejs, app_server, mongo_server ] + verifyMembersInResource(checkedOutResource, compNameToUniqueId, "group2", membersNameGroup2); + + } + + private void verifyMembersInResource(Resource resource, Map compNameToUniqueId, String groupName, String[] membersName) { + GroupDefinition groupDefinition = resource.getGroups().stream().filter(p -> p.getName().equals(groupName)).findFirst().get(); + assertEquals("Verify number of members", membersName.length, groupDefinition.getMembers().size()); + Map createdMembers = groupDefinition.getMembers(); + Arrays.asList(membersName).forEach(p -> { + assertTrue("check member name exist", createdMembers.containsKey(p)); + }); + + verifyMembers(createdMembers, compNameToUniqueId); + } + + @Test(enabled = true) + public void createResourceFromCsarWithGroupsAndPropertiesHappy() throws Exception { + + RestResponse importNewGroupTypeByName = ImportRestUtils.importNewGroupTypeByName("myHeatStack1", UserRoleEnum.ADMIN); + // BaseRestUtils.checkCreateResponse(importNewGroupTypeByName); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsWithProps"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + + assertEquals("verify there are 2 groups", 2, resource.getGroups().size()); + + Map compNameToUniqueId = resource.getComponentInstances().stream().collect(Collectors.toMap(p -> p.getName(), p -> p.getUniqueId())); + + // Verify 2 members on group1 + // members: [ app_server, mongo_server ] + List groupDefinition1 = resource.getGroups().stream().filter(p -> p.getName().equals("group1")).collect(Collectors.toList()); + assertEquals("Verify number of members", 2, groupDefinition1.get(0).getMembers().size()); + Map createdMembers = groupDefinition1.get(0).getMembers(); + verifyMembers(createdMembers, compNameToUniqueId); + + List properties = groupDefinition1.get(0).getProperties(); + assertEquals("Verify number of members", 2, properties.size()); + + GroupProperty heatFiles = properties.stream().filter(p -> p.getName().equals("heat_files")).findFirst().get(); + assertNotNull("check heat files not empty", heatFiles); + List heatFilesValue = new ArrayList<>(); + heatFilesValue.add("heat1.yaml"); + heatFilesValue.add("heat2.yaml"); + String heatFilesJson = gson.toJson(heatFilesValue); + log.debug(heatFiles.getValue()); + assertEquals("check heat files value", heatFilesJson, heatFiles.getValue()); + + GroupProperty urlCredential = properties.stream().filter(p -> p.getName().equals("url_credential")).findFirst().get(); + assertNotNull("check heat files not empty", urlCredential); + log.debug(urlCredential.getValue()); + assertEquals("check url credential", "{\"protocol\":\"protocol1\",\"keys\":{\"keya\":\"valuea\",\"keyb\":\"valueb\"}}", urlCredential.getValue()); + } + + @Test(enabled = true) + public void createResourceFromCsarWithGroupsAndPropertyInvalidValue() throws Exception { + + RestResponse importNewGroupTypeByName = ImportRestUtils.importNewGroupTypeByName("myHeatStack1", UserRoleEnum.ADMIN); + // BaseRestUtils.checkCreateResponse(importNewGroupTypeByName); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsInvalidPropertyValue"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkStatusCode(createResource, "Check bad request error", false, 400); + + } + + @Test(enabled = true) + public void createResourceFromCsarWithGroupsAndInvalidPropertyName() throws Exception { + + RestResponse importNewGroupTypeByName = ImportRestUtils.importNewGroupTypeByName("myHeatStack1", UserRoleEnum.ADMIN); + // BaseRestUtils.checkCreateResponse(importNewGroupTypeByName); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsPropertyNotExist"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkStatusCode(createResource, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.GROUP_PROPERTY_NOT_FOUND, "url_credential111", "group1", "org.openecomp.groups.MyHeatStack1"); + + } + + @Test(enabled = true) + public void createResourceFromCsarGroupTypeNotExist() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsInvalidGroupType"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkStatusCode(createResource, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.GROUP_TYPE_IS_INVALID, "org.openecomp.groups.stamGroupType"); + + } + + @Test(enabled = true) + public void createResourceFromCsarMemberNotExist() throws Exception { + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsInvalidMember"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkStatusCode(createResource, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, "mycomp", "mygroup", ValidationUtils.normaliseComponentName(resourceDetails.getName()), "VF"); + + } + + @Test(enabled = true) + public void createResourceFromCsarMemberNotAllowed() throws Exception { + + RestResponse importNewGroupTypeByName = ImportRestUtils.importNewGroupTypeByName("myHeatStack2", UserRoleEnum.ADMIN); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("csarWithGroupsNotAllowedMember"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + + BaseRestUtils.checkStatusCode(createResource, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE, "nodejs", "group1", "org.openecomp.groups.MyHeatStack2"); + + } + + @Test(enabled = true) + public void getResourceFromCsarUuidHappy() throws Exception { + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("tam"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(6, resource.getComponentInstances().size()); + + String expectedCsarUUID = resourceDetails.getCsarUUID(); + String expectedToscaResourceName = "org.openecomp.resource.vf." + WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, resource.getCsarUUID()), expectedCsarUUID.equals(resource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, resource.getToscaResourceName()), expectedToscaResourceName.equals(resource.getToscaResourceName())); + + RestResponse getResourceResponse = ResourceRestUtils.getLatestResourceFromCsarUuid(resource.getCsarUUID()); + Resource getResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), Resource.class); + assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, getResource.getCsarUUID()), expectedCsarUUID.equals(getResource.getCsarUUID())); + assertTrue("toscaResourceName : " + buildAssertMessage(expectedToscaResourceName, getResource.getToscaResourceName()), expectedToscaResourceName.equals(getResource.getToscaResourceName())); + } + + @Test(enabled = true) + public void getResourceFromCsarResourceNotFound() throws Exception { + String csarUUID = "tam"; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + + RestResponse resResponse = ResourceRestUtils.getLatestResourceFromCsarUuid(csarUUID); + + BaseRestUtils.checkStatusCode(resResponse, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(resResponse, ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUUID); + + } + + @Test(enabled = true) + public void getResourceFromMissingCsar() throws Exception { + String csarUUID = "abcdefg12345"; + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID(csarUUID); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + + RestResponse resResponse = ResourceRestUtils.getLatestResourceFromCsarUuid(csarUUID); + + BaseRestUtils.checkStatusCode(resResponse, "Check bad request error", false, 400); + BaseRestUtils.checkErrorResponse(resResponse, ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUUID); + + } + + @Test(enabled = true) + public void createUpdateCertifiedImportResourceFromCsarTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes = copyCsarRest(sdncModifierDetails, "valid_vf_a.csar", "valid_vf.csar"); + RestResponse updateResponse = null; + String oldName = null; + // create new resource from Csar + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setCsarUUID("valid_vf.csar"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + String invariantUUID = resource.getInvariantUUID(); + + // change metadata + // resource name, icon, vendor name, category, template derivedFrom + oldName = resourceDetails.getName(); + resourceDetails.setName("test1"); + resourceDetails.setIcon("newicon"); + resourceDetails.setVendorName("newname"); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.VSP_ALREADY_EXISTS, "valid_vf.csar", oldName); + + updateResponse = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResponse); + + LifecycleRestUtils.certifyResource(resourceDetails); + // change metadata + // resource name, icon, vendor name, category, template derivedFrom + resourceDetails.setName("test2"); + resourceDetails.setIcon("new icon1"); + resourceDetails.setVendorName("new name1"); + resourceDetails.setDescription("bla bla bla"); + updateResponse = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResponse); + resource = ResponseParser.parseToObjectUsingMapper(updateResponse.getResponse(), Resource.class); + assertEquals(5, resource.getComponentInstances().size()); + assertEquals(invariantUUID, resource.getInvariantUUID()); + assertEquals(resource.getName(), "test1"); + assertEquals(resource.getIcon(), "newicon"); + assertEquals(resource.getVendorName(), "newname"); + assertEquals(resource.getDescription(), "bla bla bla"); + assertEquals(resource.getTags().contains("test2"), false); + } + + @Test + public void createImportRIRelationByCapNameFromCsarUITest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "vmmc_relate_by_cap_name.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + + path = Paths.get(rootPath + "/src/test/resources/CI/csars/vmmc_relate_by_cap_name.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + // create new resource from Csar + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + // assert all relations created + assertEquals(80, resource.getComponentInstancesRelations().size()); + } + + @Test + public void createImportRIRelationByCapNameFromCsarUITest2() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "vf_relate_by_cap_name.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + String rootPath = System.getProperty("user.dir"); + Path path = null; + byte[] data = null; + String payloadData = null; + + path = Paths.get(rootPath + "/src/test/resources/CI/csars/vf_relate_by_cap_name.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + // create new resource from Csar + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + // assert relations created: 1.by name: virtual_linkable. 2.by name: + // link + Map nodes = resource.getComponentInstances().stream().collect(Collectors.toMap(n -> n.getName(), n -> n)); + Map capabilities = nodes.get("elinenode").getCapabilities().get("tosca.capabilities.network.Linkable").stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + String cp1Uid = nodes.get("cp1node").getUniqueId(); + String cp2Uid = nodes.get("cp2node").getUniqueId(); + Map> mappedByReqOwner = resource.getComponentInstancesRelations().stream().collect(Collectors.groupingBy(e -> e.getFromNode())); + assertEquals(mappedByReqOwner.get(cp1Uid).get(0).getRelationships().get(0).getCapabilityUid(), capabilities.get("virtual_linkable").getUniqueId()); + assertEquals(mappedByReqOwner.get(cp2Uid).get(0).getRelationships().get(0).getCapabilityUid(), capabilities.get("link").getUniqueId()); + } + + private void verifyMembers(Map createdMembers, Map compNameToUniqueId) { + for (Map.Entry entry : createdMembers.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue(); + String comparedValue = compNameToUniqueId.get(key); + + assertEquals("compare instance ids", comparedValue, value); + } + + } + + private static Map prepareHeadersMap(String userId) { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + return headersMap; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportGenericResourceCITest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportGenericResourceCITest.java new file mode 100644 index 0000000000..873d33979f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportGenericResourceCITest.java @@ -0,0 +1,599 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.HttpStatus; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.ImportTestTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.RespJsonKeysEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.TODO.ImportCapabilityTypeCITest; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ImportRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +import fj.data.Either; + +public class ImportGenericResourceCITest extends ComponentBaseTest { + private static Logger log = LoggerFactory.getLogger(ImportGenericResourceCITest.class.getName()); + private static final String FILE_NAME_MY_COMPUTE = "tosca.nodes.MyCompute"; + private static final String RESOURCE_NAME_UPDATE_COMPUTE = "userUpdateCompute"; + private static final String RESOURCE_NAME_MY_COMPUTE = "myCompute"; + private static final String RESOURCE_NAME_USER_COMPUTE = "userCompute"; + private static final String FILE_NAME_USER_COMPUTE = "tosca.nodes.userCompute"; + @Rule + public static TestName name = new TestName(); + + public ImportGenericResourceCITest() { + super(name, ImportGenericResourceCITest.class.getName()); + } + + @BeforeClass + public static void beforeImportClass() throws IOException { + ImportCapabilityTypeCITest.importAllCapabilityTypes(); + // removeAllNormativeTypeResources(); + // importAllNormativeTypesResources(UserRoleEnum.ADMIN); + } + + static Config config = Config.instance(); + + public static Map removeAllNormativeTypeResources() throws ClientProtocolException, IOException { + Map normativeExistInDB = new HashMap<>(); + + for (NormativeTypesEnum current : NormativeTypesEnum.values()) { + Boolean existedBeforeDelete = ImportRestUtils.removeNormativeTypeResource(current); + normativeExistInDB.put(current, existedBeforeDelete); + } + return normativeExistInDB; + } + + public static Either getNormativeTypeResource(NormativeTypesEnum current) throws ClientProtocolException, IOException { + return getResource(current.getNormativeName(), "1.0"); + } + + @Test + public void importAllTestResources() throws Exception { + for (ImportTestTypesEnum currResource : ImportTestTypesEnum.values()) { + DbUtils.cleanAllAudits(); + + RestResponse importResponse = ImportRestUtils.importTestResource(currResource, UserRoleEnum.ADMIN); + // System.err.println("import Resource + // "+"<"+currResource+">"+"response: + // "+importResponse.getErrorCode()); + ImportRestUtils.validateImportTestTypesResp(currResource, importResponse); + if (currResource.getvalidateAudit() == true) { + // validate audit + String baseVersion = "1.0"; + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(currResource.getActionStatus().name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.ADMIN.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.ADMIN.getUserName()); + expectedResourceAuditJavaObject.setResourceName(currResource.getNormativeName()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(baseVersion); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.toString()); + expectedResourceAuditJavaObject.setComment(null); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + List variables = (currResource.getErrorParams() != null ? currResource.getErrorParams() : new ArrayList()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAuditImport(expectedResourceAuditJavaObject, auditAction); + } + } + } + + // ----------------------------------------------------------------------------------- + protected void validateMyComputeCapabilities(Map map) { + assertTrue(map.containsKey("capabilities")); + Map capabilities = (Map) map.get("capabilities"); + assertTrue(capabilities.containsKey("tosca.capabilities.Container")); + List hostCapList = (List) capabilities.get("tosca.capabilities.Container"); + assertFalse(hostCapList.isEmpty()); + Map hostCap = (Map) hostCapList.get(0); + validateField(hostCap, "type", "tosca.capabilities.Container"); + validateField(hostCap, "name", "host"); + validateField(hostCap, "validSourceTypes", Arrays.asList(new String[] { "tosca.nodes.SoftwareComponent" })); + + assertTrue(capabilities.containsKey("tosca.capabilities.Endpoint.Admin")); + List endPointCapList = (List) capabilities.get("tosca.capabilities.Endpoint.Admin"); + assertFalse(endPointCapList.isEmpty()); + Map endPointCap = (Map) endPointCapList.get(0); + validateField(endPointCap, "name", "endpoint"); + validateField(endPointCap, "type", "tosca.capabilities.Endpoint.Admin"); + + assertTrue(capabilities.containsKey("tosca.capabilities.OperatingSystem")); + List osCapList = (List) capabilities.get("tosca.capabilities.OperatingSystem"); + assertFalse(osCapList.isEmpty()); + Map osCap = (Map) osCapList.get(0); + validateField(osCap, "name", "os"); + validateField(osCap, "type", "tosca.capabilities.OperatingSystem"); + + assertTrue(capabilities.containsKey("tosca.capabilities.Scalable")); + List scalableCapList = (List) capabilities.get("tosca.capabilities.Scalable"); + assertFalse(scalableCapList.isEmpty()); + Map scalableCap = (Map) scalableCapList.get(0); + validateField(scalableCap, "name", "scalable"); + validateField(scalableCap, "type", "tosca.capabilities.Scalable"); + + assertTrue(capabilities.containsKey("tosca.capabilities.network.Bindable")); + List bindingCapList = (List) capabilities.get("tosca.capabilities.network.Bindable"); + assertFalse(bindingCapList.isEmpty()); + Map bindingCap = (Map) bindingCapList.get(0); + validateField(bindingCap, "name", "binding"); + validateField(bindingCap, "type", "tosca.capabilities.network.Bindable"); + + } + + protected void validateMyComputeResource(String resourceName, String resourceVersion, String expectedState) throws ClientProtocolException, IOException { + Either eitherMyCompute = getResource(resourceName, resourceVersion); + assertTrue(eitherMyCompute.isLeft()); + String testComputeYml = eitherMyCompute.left().value(); + + Map map = new HashMap(); + map = (Map) new Gson().fromJson(testComputeYml, map.getClass()); + + validateMyComputeBasicFields(map, resourceName, resourceVersion, expectedState); + + validateMyComputeCapabilities(map); + + validateMyComputeRequirements(map); + validateField(map, RespJsonKeysEnum.RESOURCE_VERSION.getRespJsonKeyName(), resourceVersion); + + } + + protected void validateMyComputeResource(String uid, String resourceName, String resourceVersion, String expectedState) throws ClientProtocolException, IOException { + RestResponse resourceResponse = ResourceRestUtils.getResource(uid); + ResourceRestUtils.checkSuccess(resourceResponse); + String testComputeYml = resourceResponse.getResponse(); + + // Either eitherMyCompute = getResource(resourceName, + // resourceVersion); + // assertTrue( eitherMyCompute.isLeft() ); + // String testComputeYml = eitherMyCompute.left().value(); + + Map map = new HashMap(); + map = (Map) new Gson().fromJson(testComputeYml, map.getClass()); + + validateMyComputeBasicFields(map, resourceName, resourceVersion, expectedState); + + validateMyComputeCapabilities(map); + + validateMyComputeRequirements(map); + validateField(map, RespJsonKeysEnum.RESOURCE_VERSION.getRespJsonKeyName(), resourceVersion); + + } + + protected void validateMyComputeResourceAfterUpdate(String uid, String resourceName, String resourceVersion, String expectedState) throws ClientProtocolException, IOException { + RestResponse resourceResponse = ResourceRestUtils.getResource(uid); + ResourceRestUtils.checkSuccess(resourceResponse); + String testComputeYml = resourceResponse.getResponse(); + + // Either eitherMyCompute = getResource(resourceName, + // resourceVersion); + // assertTrue( eitherMyCompute.isLeft() ); + + // String testComputeYml = eitherMyCompute.left().value(); + + Map map = new HashMap(); + map = (Map) new Gson().fromJson(testComputeYml, map.getClass()); + + validateMyComputeBasicFields(map, resourceName, resourceVersion, expectedState); + validateField(map, RespJsonKeysEnum.DESCRIPTION.getRespJsonKeyName(), "Short description"); + validateField(map, RespJsonKeysEnum.VENDOR_NAME.getRespJsonKeyName(), "UserVendor"); + validateField(map, RespJsonKeysEnum.VENDOR_RELEASE.getRespJsonKeyName(), "1.1.2"); + + // validateMyComputeCapabilities(map); + // AssertJUnit.assertTrue(map.containsKey("capabilities")); + // Map capabilities = (Map) + // map.get("capabilities"); + // AssertJUnit.assertTrue(capabilities.containsKey("host")); + // Map hostCap = (Map) + // capabilities.get("host"); + // validateField(hostCap, "type", "tosca.capabilities.Container"); + // validateField(hostCap, "validSourceTypes", Arrays.asList(new + // String[]{"tosca.nodes.SoftwareComponent"})); + // + // AssertJUnit.assertTrue(capabilities.containsKey("endpoint")); + // Map endPointCap = (Map) + // capabilities.get("endpoint"); + // validateField(endPointCap, "type", + // "tosca.capabilities.Endpoint.Admin"); + + assertTrue(map.containsKey("capabilities")); + Map capabilities = (Map) map.get("capabilities"); + assertTrue(capabilities.containsKey("tosca.capabilities.Container")); + List hostCapList = (List) capabilities.get("tosca.capabilities.Container"); + assertFalse(hostCapList.isEmpty()); + Map hostCap = (Map) hostCapList.get(0); + validateField(hostCap, "type", "tosca.capabilities.Container"); + validateField(hostCap, "name", "host"); + validateField(hostCap, "validSourceTypes", Arrays.asList(new String[] { "tosca.nodes.SoftwareComponent" })); + + assertTrue(capabilities.containsKey("tosca.capabilities.Endpoint.Admin")); + List endPointCapList = (List) capabilities.get("tosca.capabilities.Endpoint.Admin"); + assertFalse(endPointCapList.isEmpty()); + Map endPointCap = (Map) endPointCapList.get(0); + validateField(endPointCap, "name", "endpoint"); + validateField(endPointCap, "type", "tosca.capabilities.Endpoint.Admin"); + + validateMyComputeRequirements(map); + validateField(map, RespJsonKeysEnum.RESOURCE_VERSION.getRespJsonKeyName(), resourceVersion); + + } + + protected void validateMyComputeRequirements(Map map) { + assertTrue(map.containsKey("requirements")); + Map requirements = (Map) map.get("requirements"); + + assertTrue(requirements.containsKey("tosca.capabilities.Attachment")); + List localStorageReqList = (List) requirements.get("tosca.capabilities.Attachment"); + assertFalse(localStorageReqList.isEmpty()); + Map localStorageReq = (Map) localStorageReqList.get(0); + validateField(localStorageReq, "capability", "tosca.capabilities.Attachment"); + validateField(localStorageReq, "node", "tosca.nodes.BlockStorage"); + validateField(localStorageReq, "relationship", "tosca.relationships.AttachesTo"); + validateField(localStorageReq, "name", "local_storage"); + } + + protected void validateMyComputeBasicFields(Map map, String resourceName, String resourceVersion, String expectedState) { + validateField(map, RespJsonKeysEnum.IS_ABSTRACT.getRespJsonKeyName(), false); + // validateField(map, RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName(), + // categoryDefinition); + // validateField(map, RespJsonKeysEnum.UNIQUE_ID.getRespJsonKeyName(), + // UniqueIdBuilder.buildResourceUniqueId(resourceName, + // resourceVersion)); + validateField(map, RespJsonKeysEnum.RESOURCE_NAME.getRespJsonKeyName(), resourceName); + validateField(map, RespJsonKeysEnum.TAGS.getRespJsonKeyName(), Arrays.asList(new String[] { resourceName })); + validateField(map, RespJsonKeysEnum.LIFE_CYCLE_STATE.getRespJsonKeyName(), expectedState); + + validateField(map, RespJsonKeysEnum.DERIVED_FROM.getRespJsonKeyName(), Arrays.asList(new String[] { "tosca.nodes.Root" })); + } + + protected static void validateField(Map map, String jsonField, Object expectedValue) { + if (expectedValue == null) { + assertTrue(!map.containsKey(jsonField)); + } else { + assertTrue("map does not contain field " + jsonField, map.containsKey(jsonField)); + Object foundValue = map.get(jsonField); + compareElements(expectedValue, foundValue); + } + } + + protected static void compareElements(Object expectedValue, Object foundValue) { + if (expectedValue instanceof String) { + assertTrue(foundValue instanceof String); + assertTrue(foundValue.equals(expectedValue)); + } + + else if (expectedValue instanceof Boolean) { + assertTrue(foundValue instanceof Boolean); + assertTrue(foundValue == expectedValue); + } else if (expectedValue instanceof Map) { + assertTrue(foundValue instanceof Map); + Map foundMap = (Map) foundValue; + Map excpectedMap = (Map) expectedValue; + assertTrue(foundMap.size() == excpectedMap.size()); + Iterator foundkeyItr = foundMap.keySet().iterator(); + while (foundkeyItr.hasNext()) { + String foundKey = foundkeyItr.next(); + assertTrue(excpectedMap.containsKey(foundKey)); + compareElements(excpectedMap.get(foundKey), foundMap.get(foundKey)); + } + + } else if (expectedValue instanceof List) { + assertTrue(foundValue instanceof List); + List foundList = (List) foundValue; + List excpectedList = (List) expectedValue; + assertTrue(foundList.size() == excpectedList.size()); + for (int i = 0; i < foundList.size(); i++) { + compareElements(excpectedList.get(i), foundList.get(i)); + } + + } else if (expectedValue instanceof CategoryDefinition) { + assertTrue(foundValue instanceof Map); + CategoryDefinition expCat = (CategoryDefinition) expectedValue; + Map actCat = (Map) foundValue; + assertEquals(expCat.getName(), actCat.get("name")); + + // assertEquals(expCat.getSubcategories().get(0).getName(), + // actCat.get("subcategories").getName()); + } else { + assertTrue(foundValue.equals(expectedValue)); + } + } + + public static void restoreToOriginalState(Map originalState, UserRoleEnum userRole) throws IOException { + removeAllNormativeTypeResources(); + + Iterator> iterator = originalState.entrySet().iterator(); + while (iterator.hasNext()) { + Entry entry = iterator.next(); + Boolean isExistBeforeDelete = entry.getValue(); + if (isExistBeforeDelete) { + importNormativeResource(entry.getKey(), userRole); + } + } + + } + + public static void importAllNormativeTypesResources(UserRoleEnum userRole) throws IOException { + for (NormativeTypesEnum currResource : NormativeTypesEnum.values()) { + Either resource = getResource(currResource.getNormativeName(), "1.0"); + if (resource.isRight()) { + importNormativeResource(currResource, userRole); + } + } + + } + + protected static Integer importNormativeResource(NormativeTypesEnum resource, UserRoleEnum userRole) throws IOException { + return importResource(resource.getFolderName(), userRole, true); + } + + protected static Integer importResource(String folderName, UserRoleEnum userRole, boolean isNormative) throws IOException { + Config config = Utils.getConfig(); + CloseableHttpResponse response = null; + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getZipFile(folderName))); + mpBuilder.addPart("resourceMetadata", new StringBody(getJsonStringOfFile(folderName, folderName + ".json"), ContentType.APPLICATION_JSON)); + + String url = String.format(Urls.IMPORT_RESOURCE_NORMATIVE, config.getCatalogBeHost(), config.getCatalogBePort()); + if (!isNormative) { + url = String.format(Urls.IMPORT_USER_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + } + + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("USER_ID", userRole.getUserId()); + httpPost.setEntity(mpBuilder.build()); + response = client.execute(httpPost); + return response.getStatusLine().getStatusCode(); + } finally { + closeResponse(response); + closeHttpClient(client); + + } + } + + public static void closeHttpClient(CloseableHttpClient client) { + try { + if (client != null) { + client.close(); + } + } catch (IOException e) { + log.debug("failed to close client or response: ", e); + } + } + + public static void closeResponse(CloseableHttpResponse response) { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + log.debug("failed to close client or response: ", e); + } + } + + protected static String getJsonStringOfFile(String folderName, String fileName) throws IOException { + String sourceDir = config.getImportResourceConfigDir(); + sourceDir += File.separator + "normative-types"; + + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + folderName, fileName); + byte[] fileContent = Files.readAllBytes(filePath); + String content = new String(fileContent); + return content; + } + + protected static File getZipFile(String elementName) throws IOException { + String sourceDir = config.getImportResourceConfigDir(); + sourceDir += File.separator + "normative-types"; + + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + elementName, "normative-types-new-" + elementName + ".zip"); + return filePath.toFile(); + } + + protected static String getTestJsonStringOfFile(String folderName, String fileName) throws IOException { + String sourceDir = config.getImportResourceTestsConfigDir(); + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + folderName, fileName); + byte[] fileContent = Files.readAllBytes(filePath); + String content = new String(fileContent); + return content; + } + + protected static File getTestZipFile(String elementName) throws IOException { + String sourceDir = config.getImportResourceTestsConfigDir(); + + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + elementName, "normative-types-new-" + elementName + ".zip"); + return filePath.toFile(); + } + + protected static Either getResource(String name, String version) throws IOException { + RestResponse resource = ResourceRestUtils.getResourceByNameAndVersion(UserRoleEnum.DESIGNER.getUserId(), name, version); + if (resource.getErrorCode() == ImportRestUtils.STATUS_CODE_GET_SUCCESS) { + return Either.left(resource.getResponse()); + // return Either.right(true); + + } + return Either.right(false); + } + + @Test + public void testImportWithRequirmentsAndCapabilities() throws IOException { + String fileName = FILE_NAME_MY_COMPUTE; + RestResponse response = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_MY_COMPUTE, UserRoleEnum.ADMIN); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "1.0", "CERTIFIED"); + } + + @Test + public void testImportWithUpdateNormativeType() throws IOException { + String fileName = FILE_NAME_MY_COMPUTE; + RestResponse response = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_MY_COMPUTE, UserRoleEnum.ADMIN); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == BaseRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "1.0", "CERTIFIED"); + + // update + response = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_MY_COMPUTE, UserRoleEnum.ADMIN); + statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_UPDATE_SUCCESS); + uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "2.0", "CERTIFIED"); + + } + + @Test + public void testImportWithInvalidDefaultValue() throws IOException { + RestResponse response = ImportRestUtils.importNewResourceByName("portInvalidDefaultValue", UserRoleEnum.DESIGNER); + assertTrue(response.getErrorCode() == HttpStatus.SC_BAD_REQUEST); + } + + @Test + public void testImportUserResource() throws IOException { + String fileName = FILE_NAME_USER_COMPUTE; + RestResponse response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_USER_COMPUTE, UserRoleEnum.DESIGNER); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "0.1", "NOT_CERTIFIED_CHECKOUT"); + + } + + @Test + public void testImportAndUpdateUserResource() throws IOException { + String fileName = FILE_NAME_USER_COMPUTE; + RestResponse response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_USER_COMPUTE, UserRoleEnum.DESIGNER); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "0.1", "NOT_CERTIFIED_CHECKOUT"); + response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_UPDATE_COMPUTE, UserRoleEnum.DESIGNER); + statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_UPDATE_SUCCESS); + uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResourceAfterUpdate(uid, fileName, "0.1", "NOT_CERTIFIED_CHECKOUT"); + + } + + @Test + public void testImportAndUpdateChangesUserResource() throws IOException { + String fileName = FILE_NAME_USER_COMPUTE; + RestResponse response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_USER_COMPUTE, UserRoleEnum.DESIGNER); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "0.1", "NOT_CERTIFIED_CHECKOUT"); + // Either resource = getResource(fileName, "0.1"); + // assertTrue(resource.isLeft()); + + response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_UPDATE_COMPUTE, UserRoleEnum.DESIGNER); + statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_UPDATE_SUCCESS); + validateMyComputeResourceAfterUpdate(uid, fileName, "0.1", "NOT_CERTIFIED_CHECKOUT"); + + } + + @Test + public void testImportCheckoutAndUpdateUserResource() throws IOException { + String fileName = FILE_NAME_USER_COMPUTE; + RestResponse response = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_USER_COMPUTE, UserRoleEnum.ADMIN); + Integer statusCode = response.getErrorCode(); + assertTrue(statusCode == ImportRestUtils.STATUS_CODE_IMPORT_SUCCESS); + String uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "1.0", "CERTIFIED"); + + response = ImportRestUtils.importNewResourceByName(RESOURCE_NAME_USER_COMPUTE, UserRoleEnum.DESIGNER); + statusCode = response.getErrorCode(); + assertEquals("check response code after update resource", ImportRestUtils.STATUS_CODE_UPDATE_SUCCESS, statusCode.intValue()); + uid = ResponseParser.getUniqueIdFromResponse(response); + validateMyComputeResource(uid, fileName, "1.1", "NOT_CERTIFIED_CHECKOUT"); + + } + + @Test + public void importNormativeTypesTesterUserRole() throws Exception { + Integer statusCode = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_MY_COMPUTE, UserRoleEnum.TESTER).getErrorCode(); + assertTrue(statusCode == ImportRestUtils.RESTRICTED_OPERATION); + } + + @Test + public void importNormativeTypesDesignerUserRole() throws Exception { + Integer statusCode = ImportRestUtils.importNormativeResourceByName(RESOURCE_NAME_MY_COMPUTE, UserRoleEnum.DESIGNER).getErrorCode(); + assertTrue(statusCode == 409); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportNewResourceCITest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportNewResourceCITest.java new file mode 100644 index 0000000000..ec335fa65f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportNewResourceCITest.java @@ -0,0 +1,1431 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.HttpStatus; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.ImportTestTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ImportRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ImportNewResourceCITest extends ComponentBaseTest { + + // public static UserUtils userUtils = new UserUtils(); + // public ResourceUtils resourceUtils = new ResourceUtils(); + // public AuditValidationUtils AuditValidationUtils = new + // AuditValidationUtils(); + // protected ArtifactUtils artifactUtils = new ArtifactUtils(); + + protected String resourceVersion = null; + protected String auditAction = null; + public User sdncModifierDetails = new User(); + protected String artifactName1 = "data_artifact1.sh"; + protected String artifactName2 = "data_artifact2.sh"; + protected String interfaze = "standard"; + protected String interfaceArtifactName = "data_interface1.sh"; + + private String SPECIAL_CHARACTERS = "~!#@~$%^*()[];:'\"|\\/"; + + public ResourceReqDetails resourceDetails = new ResourceReqDetails(); + + public Gson gson = new Gson(); + + @Rule + public static TestName name = new TestName(); + + public ImportNewResourceCITest() { + super(name, ImportNewResourceCITest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + + // init user + sdncModifierDetails.setUserId(UserRoleEnum.ADMIN.getUserId()); + // init resource details + resourceDetails = ElementFactory.getDefaultResource("importResource4test", NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, "jh0003"); + } + + @Test + public void importAllTestResources_toValidateNewAPI() throws Exception { + + for (ImportTestTypesEnum currResource : ImportTestTypesEnum.values()) { + // clean audit + DbUtils.cleanAllAudits(); + + // import testResources trough newResource API + RestResponse importResponse = ImportRestUtils.importNewResourceByName(currResource.getFolderName(), UserRoleEnum.ADMIN); + System.err.println("import Resource " + "<" + currResource.getFolderName() + ">" + "response: " + importResponse.getErrorCode()); + + // validate response + ImportRestUtils.validateImportTestTypesResp(currResource, importResponse); + if (currResource.getvalidateAudit() == true) { + // validate audit + // String baseVersion="0.1"; + String baseVersion = ""; + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(currResource.getActionStatus().name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.ADMIN.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.ADMIN.getUserName()); + expectedResourceAuditJavaObject.setResourceName(currResource.getNormativeName()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(baseVersion); + expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setComment(null); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + List variables = (currResource.getErrorParams() != null ? currResource.getErrorParams() : new ArrayList()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAuditImport(expectedResourceAuditJavaObject, auditAction); + } + } + } + + protected RestResponse importNewResource(UserRoleEnum userRoleEnum) throws Exception { + + // init user + sdncModifierDetails.setUserId(userRoleEnum.getUserId()); + // init resource details + resourceDetails = ElementFactory.getDefaultResource("importResource4test", NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, "jh0003"); + // clean ES DB + DbUtils.cleanAllAudits(); + // import new resource (expected checkOut state) + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4test", userRoleEnum); + return importResponse; + } + + @Test(enabled = false) + public void importUIResource() throws IOException { + String payload = "tosca_definitions_version: tosca_simple_yaml_1_0_0\r\n" + "node_types: \r\n" + " org.openecomp.resource.importResource4test:\r\n" + " derived_from: tosca.nodes.Root\r\n" + " description: someDesc"; + + String encodedPayload = new String(Base64.encodeBase64(payload.getBytes())); + + String json = "{\r\n" + " \"resourceName\": \"importResource4test\",\r\n" + " \"payloadName\": \"importResource4test.yml\",\r\n" + + " \"categories\": [{\"name\": \"Application L4+\",\"normalizedName\": \"application l4+\",\"uniqueId\": \"resourceNewCategory.application l4+\",\"subcategories\": [{\"name\": \"Web Server\"}]}],\r\n" + + " \"description\": \"ResourceDescription\",\r\n" + " \"vendorName\": \"VendorName\",\r\n" + " \"vendorRelease\": \"VendorRelease\",\r\n" + " \"contactId\": \"AT1234\",\r\n" + " \"icon\": \"router\",\r\n" + " \"tags\": [\r\n" + + " \"importResource4test\"\r\n" + " ],\r\n" + " \"payloadData\": \"" + encodedPayload + "\"\r\n" + "}"; + + String md5 = GeneralUtility.calculateMD5ByString(json); + + Map headers = new HashMap(); + headers.put(Constants.MD5_HEADER, md5); + headers.put(Constants.USER_ID_HEADER, UserRoleEnum.ADMIN.getUserId()); + headers.put(Constants.CONTENT_TYPE_HEADER, "application/json"); + + String url = String.format(Urls.CREATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + + HttpRequest httpUtil = new HttpRequest(); + RestResponse httpSendPost = httpUtil.httpSendPost(url, json, headers); + Integer errorCode = httpSendPost.getErrorCode(); + assertTrue(errorCode == HttpStatus.SC_CREATED); + + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_suc() throws Exception { + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + // validate response + + resourceVersion = "0.1"; + + // ResourceRespJavaObject resourceRespJavaObject = + // Convertor.constructFieldsForRespValidation(resourceDetails, + // resourceVersion); + // resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // ResourceValidationUtils.validateResp(importResponse, + // resourceRespJavaObject); + // + // //validate get response + // + // RestResponse resourceGetResponse = + // ResourceRestUtils.getResource(sdncModifierDetails, resourceVersion); + // ResourceValidationUtils.validateResp(resourceGetResponse, + // resourceRespJavaObject); + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromImport); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceRespJavaObject.getUniqueId()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // validate + ResourceValidationUtils.validateModelObjects(resourceFromImport, resourceFromGet); + + // validate audit + resourceDetails.setVersion(resourceDetails.getVersion()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + + auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void importNewResource_byTester_failed() throws Exception { + + RestResponse importResponse = importNewResource(UserRoleEnum.TESTER); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 409, importResponse.getErrorCode().intValue()); + + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existInCheckout_updateVendorName_updateCategory() throws Exception { + + // import new resource + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4testUpdateVendorNameAndCategory", UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 200, importResponse.getErrorCode().intValue()); + + // validate response + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromImport); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceRespJavaObject.getUniqueId()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // validate + ResourceValidationUtils.validateModelObjects(resourceFromImport, resourceFromGet); + + // validate audit + resourceDetails.setVersion(resourceDetails.getVersion()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails); + + auditAction = "ResourceImport"; + resourceVersion = "0.1"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void importNewResource_perfromByAdmin_ownedBy_diffrentUser() throws Exception { + + RestResponse importResponse = importNewResource(UserRoleEnum.DESIGNER); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + // clean audit + DbUtils.cleanAllAudits(); + + importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_IN_CHECKOUT_STATE.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), importResponse.getErrorCode()); + + String[] split = resourceFromImport.getLastUpdaterFullName().split(" "); + String firstName = split[0]; + String lastName = split[1]; + List variables = Arrays.asList(resourceFromImport.getName(), "resource", firstName, lastName, resourceFromImport.getLastUpdaterUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_IN_CHECKOUT_STATE.name(), variables, importResponse.getResponse()); + + } + + @Test + public void importNewResource_perfromByDesigner_ownedBy_diffrentUser() throws Exception { + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + // clean audit + DbUtils.cleanAllAudits(); + + importResponse = importNewResource(UserRoleEnum.DESIGNER); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_IN_CHECKOUT_STATE.name()); + assertEquals("Check response code after adding artifact", errorInfo.getCode(), importResponse.getErrorCode()); + + String[] split = resourceFromImport.getLastUpdaterFullName().split(" "); + String firstName = split[0]; + String lastName = split[1]; + List variables = Arrays.asList(resourceFromImport.getName(), "resource", firstName, lastName, resourceFromImport.getLastUpdaterUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_IN_CHECKOUT_STATE.name(), variables, importResponse.getResponse()); + + } + + @Test(enabled = false) + public void importNewResource_nameSpace_vf() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4testVF", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertTrue(resourceRespJavaObject.getResourceType().equals(ResourceTypeEnum.VF)); + + } + + @Test + public void importNewResource_nameSpace_vfc() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4testVFC", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertTrue(resourceRespJavaObject.getResourceType().equals(ResourceTypeEnum.VFC)); + } + + @Test + public void importNewResource_nameSpace_vl() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4testVL", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertTrue(resourceRespJavaObject.getResourceType().equals(ResourceTypeEnum.VL)); + + } + + @Test + public void importNewResource_nameSpace_cp() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4testCP", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertTrue(resourceRespJavaObject.getResourceType().equals(ResourceTypeEnum.CP)); + } + + @Test + public void importNewResource_nameSpace_unknown() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertTrue(resourceRespJavaObject.getResourceType().equals(ResourceTypeEnum.VFC)); + + } + + @Test + public void importNewResource_MissingNameSpace() throws Exception { + RestResponse importResponse = ImportRestUtils.importNewResourceByName("importResource4testMissingNameSpace", UserRoleEnum.DESIGNER); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 400, importResponse.getErrorCode().intValue()); + + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existInCheckOut() throws Exception { + + // import new resource + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in CHECKOUT state + + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 200, importResponse.getErrorCode().intValue()); + + // validate response + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromImport); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceRespJavaObject.getUniqueId()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // validate + ResourceValidationUtils.validateModelObjects(resourceFromImport, resourceFromGet); + + // validate audit + resourceDetails.setVersion(resourceDetails.getVersion()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails); + + auditAction = "ResourceImport"; + resourceVersion = "0.1"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existIn_CheckIn_state() throws Exception { + + // import new resource + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + // checkIn resource + + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in CHECKIN state + + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 200, importResponse.getErrorCode().intValue()); + + // validate response + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromImport); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceRespJavaObject.getUniqueId()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // validate + ResourceValidationUtils.validateModelObjects(resourceFromImport, resourceFromGet); + + // validate audit + resourceDetails.setVersion(resourceDetails.getVersion()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails); + + resourceVersion = "0.2"; + auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void importNewResource_existIn_Ready4cert_state_performByTester() throws Exception { + // import new resource + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + // add mandatory artifacts + // // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(checkInResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(checkInResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in CHECKIN state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.TESTER); + + // validate response + resourceVersion = resourceDetails.getVersion(); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + assertNotNull("check response object is not null after create resouce", importResponse); + assertNotNull("check error code exists in response after create resource", importResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), importResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, importResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setResourceName(""); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.TESTER.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.TESTER.getUserName()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existIn_Ready4cert_state_performByDesigner() throws Exception { + // import new resource + + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.DESIGNER); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_SENT_FOR_CERTIFICATION.name()); + assertNotNull("check response object is not null after create resouce", importResponse); + assertNotNull("check error code exists in response after create resource", importResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), importResponse.getErrorCode()); + String[] split = resourceFromGet.getLastUpdaterFullName().split(" "); + String firstName = split[0]; + String lastName = split[1]; + List variables = Arrays.asList(resourceFromGet.getName(), "resource", firstName, lastName, resourceFromGet.getLastUpdaterUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_SENT_FOR_CERTIFICATION.name(), variables, importResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.DESIGNER.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.DESIGNER.getUserName()); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.READY_FOR_CERTIFICATION).toString()); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existIn_Ready4cert_state_performByAdmin() throws Exception { + + // import new resource + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.ADMIN); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 200, importResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + resourceVersion = resourceDetails.getVersion(); + // resourceVersion="0.2"; + + // validate response + Resource resourceFromImport = ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + assertNotNull(resourceFromImport); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + // validate get response + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceRespJavaObject.getUniqueId()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // validate + ResourceValidationUtils.validateModelObjects(resourceFromImport, resourceFromGet); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void importNewResource_existIn_CerInProgress_state_performByTester() throws Exception { + + // import new resource + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // startCert + RestResponse startCert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertNotNull("check response object is not null after resource request start certification", startCert); + assertEquals("Check response code after checkout resource", 200, startCert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(startCert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(startCert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.TESTER); + + // validate response + resourceVersion = resourceDetails.getVersion(); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + assertNotNull("check response object is not null after create resouce", importResponse); + assertNotNull("check error code exists in response after create resource", importResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), importResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, importResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setResourceName(""); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.TESTER.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.TESTER.getUserName()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existIn_CerInProgress_state_performByDesigner() throws Exception { + + User sdncAdminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // import new resource + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // startCert + RestResponse startCert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertNotNull("check response object is not null after resource request start certification", startCert); + assertEquals("Check response code after checkout resource", 200, startCert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(startCert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(startCert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + resourceVersion = resourceDetails.getVersion(); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.DESIGNER); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE.name()); + assertNotNull("check response object is not null after create resouce", importResponse); + assertNotNull("check error code exists in response after create resource", importResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), importResponse.getErrorCode()); + List variables = Arrays.asList(resourceDetails.getName(), "resource", sdncAdminUser.getFirstName(), sdncAdminUser.getLastName(), sdncAdminUser.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE.name(), variables, importResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.DESIGNER.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.DESIGNER.getUserName()); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.CERTIFICATION_IN_PROGRESS).toString()); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + // TODO DE171337 + @Test(enabled = false) + public void importNewResource_existIn_CerInProgress_state_performByAdmin() throws Exception { + + User sdncAdminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // import new resource + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // checkIn resource + resourceVersion = resourceDetails.getVersion(); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + // startCert + RestResponse startCert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertNotNull("check response object is not null after resource request start certification", startCert); + assertEquals("Check response code after checkout resource", 200, startCert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(startCert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(startCert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + resourceVersion = resourceDetails.getVersion(); + + // clean audit + DbUtils.cleanAllAudits(); + + // import new resource while resource already exist in other state + importResponse = ImportRestUtils.importNewResourceByName("importResource4test", UserRoleEnum.ADMIN); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE.name()); + assertNotNull("check response object is not null after create resouce", importResponse); + assertNotNull("check error code exists in response after create resource", importResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), importResponse.getErrorCode()); + List variables = Arrays.asList(resourceDetails.getName(), "resource", sdncAdminUser.getFirstName(), sdncAdminUser.getLastName(), sdncAdminUser.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE.name(), variables, importResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "ResourceImport"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.ADMIN.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.ADMIN.getUserName()); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.CERTIFICATION_IN_PROGRESS).toString()); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + // TODO DE171337 + // @Test(enabled = false) + // public void + // importNewResource_existIn_Certified_state_chnage_reqAndCap_byDesigner() + // throws Exception{ + // + // // Andrey - set default artifact details + // ArtifactDefinition artifactDefinition = + // artifactUtils.constructDefaultArtifactInfo(); + // + // // import new resource + // RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + // assertNotNull("check response object is not null after import resource", + // importResponse); + // assertNotNull("check error code exists in response after import + // resource", importResponse.getErrorCode()); + // assertEquals("Check response code after import resource", 201, + // importResponse.getErrorCode().intValue()); + // String resourceId = + // ResponseParser.getUniqueIdFromResponse(importResponse); + // resourceDetails = + // ResponseParser.parseToObject(importResponse.getResponse(), + // ResourceReqDetails.class); + // resourceVersion = resourceDetails.getVersion(); + // RestResponse resourceGetResponse = + // ResourceRestUtils.getResource(sdncModifierDetails, + // resourceDetails.getUniqueId()); + // assertEquals("Check response code after get resource", 200, + // resourceGetResponse.getErrorCode().intValue()); + // Resource resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // assertNotNull(resourceFromGet); + // + // // add mandatory artifacts + // // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + // resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + // resourceDetails.getUniqueId()); + // assertEquals("Check response code after get resource", 200, + // resourceGetResponse.getErrorCode().intValue()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // assertNotNull(resourceFromGet); + // resourceDetails = + // ResponseParser.parseToObject(importResponse.getResponse(), + // ResourceReqDetails.class); + // resourceDetails.setVersion(resourceFromGet.getVersion()); + // + // // add artifact + // artifactDefinition.setArtifactName(artifactName1); + // ArtifactRestUtils.addInformationalArtifactToResource(resourceDetails, + // sdncModifierDetails, resourceVersion , artifactDefinition); + // + // // add artifact + // artifactDefinition.setArtifactName(artifactName2); + // resourceUtils.add_artifact(resourceDetails, sdncModifierDetails, + // resourceVersion , artifactDefinition); + // + // // add interface + // artifactDefinition.setArtifactName(interfaceArtifactName); + // ResourceRestUtils.add_interface(resourceDetails, sdncModifierDetails, + // resourceVersion , artifactDefinition); + // + // //construct fields for validation + // resourceVersion="1.0"; + // + // ResourceRespJavaObject resourceRespJavaObject = + // Convertor.constructFieldsForRespValidation(resourceDetails, + // resourceVersion); + // ArrayList artifacts = new ArrayList(); + // + // artifacts.add(resourceId+":"+artifactName1); + // artifacts.add(resourceId+":"+artifactName2); + // resourceRespJavaObject.setArtifacts(artifacts); + // ArrayList interfaces = new ArrayList(); + // + // interfaces.add(interfaze); + // resourceRespJavaObject.setInterfaces(interfaces); + // + // // checkIn resource + // resourceVersion = resourceDetails.getVersion(); + // String checkinComment = "good checkin"; + // String checkinComentJson = "{\"userRemarks\": \""+checkinComment+"\"}"; + // RestResponse checkInResponse = + // LifecycleRestUtils.changeResourceState(resourceDetails, + // sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CHECKIN, + // checkinComentJson); + // assertNotNull("check response object is not null after import resource", + // checkInResponse); + // assertEquals("Check response code after checkout resource", 200, + // checkInResponse.getErrorCode().intValue()); + // + // // req4cert resource + // RestResponse request4cert = + // LifecycleRestUtils.changeResourceState(resourceDetails, + // sdncModifierDetails, resourceVersion, + // LifeCycleStatesEnum.CERTIFICATIONREQUEST); + // assertNotNull("check response object is not null after resource request + // for certification", request4cert); + // assertEquals("Check response code after checkout resource", 200, + // request4cert.getErrorCode().intValue()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + // assertNotNull(resourceFromGet); + // resourceDetails = + // ResponseParser.parseToObject(request4cert.getResponse(), + // ResourceReqDetails.class); + // resourceDetails.setVersion(resourceFromGet.getVersion()); + // + // // startCert + // RestResponse startCert = + // LifecycleRestUtils.changeResourceState(resourceDetails, + // sdncModifierDetails, resourceVersion, + // LifeCycleStatesEnum.STARTCERTIFICATION); + // assertNotNull("check response object is not null after resource request + // start certification", startCert); + // assertEquals("Check response code after checkout resource", 200, + // startCert.getErrorCode().intValue()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(startCert.getResponse()); + // assertNotNull(resourceFromGet); + // resourceDetails = ResponseParser.parseToObject(startCert.getResponse(), + // ResourceReqDetails.class); + // resourceDetails.setVersion(resourceFromGet.getVersion()); + // + // // certify + // RestResponse certify = + // LifecycleRestUtils.changeResourceState(resourceDetails, + // sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFY); + // assertNotNull("check response object is not null after resource request + // certify", certify); + // assertEquals("Check response code after certify resource", 200, + // certify.getErrorCode().intValue()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(certify.getResponse()); + // assertNotNull(resourceFromGet); + // resourceDetails = ResponseParser.parseToObject(certify.getResponse(), + // ResourceReqDetails.class); + // resourceDetails.setVersion(resourceFromGet.getVersion()); + // + // // clean audit + // DbUtils.cleanAllAudits(); + // + // // change resource details + // resourceDetails = + // ElementFactory.getDefaultResource("tosca.nodes.importResource4test", + // NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + // "jh0003"); + // + // // import new resource while resource already exist in other state + // importResponse = + // ImportRestUtils.importNewResourceByName("importResource4testUpdateWithoutReqCap", + // UserRoleEnum.ADMIN); + // assertNotNull("check response object is not null after import resource", + // importResponse); + // assertNotNull("check error code exists in response after import + // resource", importResponse.getErrorCode()); + // assertEquals("Check response code after import resource", 200, + // importResponse.getErrorCode().intValue()); + // resourceDetails = + // ResponseParser.parseToObject(importResponse.getResponse(), + // ResourceReqDetails.class); + // resourceVersion = resourceDetails.getVersion(); + // resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + // resourceDetails.getUniqueId()); + // assertEquals("Check response code after get resource", 200, + // resourceGetResponse.getErrorCode().intValue()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // assertNotNull(resourceFromGet); + // + // // validate response + // Resource resourceFromImport = + // ResponseParser.convertResourceResponseToJavaObject(importResponse.getResponse()); + // assertNotNull(resourceFromImport); + // + // resourceDetails = + // ResponseParser.parseToObject(importResponse.getResponse(), + // ResourceReqDetails.class); + // resourceRespJavaObject = + // Convertor.constructFieldsForRespValidation(resourceDetails); + // resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // + // // validate get response + // resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + // resourceRespJavaObject.getUniqueId()); + // resourceFromGet = + // ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + // assertNotNull(resourceFromGet); + // + // // validate + // ResourceValidationUtils.validateModelObjects(resourceFromImport, + // resourceFromGet); + // + // // validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // Convertor.constructFieldsForAuditValidation(resourceDetails, + // resourceVersion); + // auditAction="ResourceImport"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setPrevVersion(resourceVersion); + // expectedResourceAuditJavaObject.setStatus("200"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // expectedResourceAuditJavaObject.setToscaNodeType(resourceFromGet.getToscaResourceName()); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // } + + @Test + public void importNewResource_uuidTest() throws Exception { + RestResponse importResponse = importNewResource(UserRoleEnum.ADMIN); + + assertNotNull("check response object is not null after import resource", importResponse); + assertNotNull("check error code exists in response after import resource", importResponse.getErrorCode()); + assertEquals("Check response code after import resource", 201, importResponse.getErrorCode().intValue()); + String oldUuid = ResponseParser.getValueFromJsonResponse(importResponse.getResponse(), "uuid"); + + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceVersion = resourceDetails.getVersion(); + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + Resource resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + // add mandatory artifacts + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // resourceGetResponse); + resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertEquals("Check response code after get resource", 200, resourceGetResponse.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(importResponse.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, "0.1", LifeCycleStatesEnum.CHECKIN); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + String newUuid = ResponseParser.getValueFromJsonResponse(checkInResponse.getResponse(), "uuid"); + assertTrue(ResourceValidationUtils.validateUuidAfterChangingStatus(oldUuid, newUuid)); + + // req4cert resource + RestResponse request4cert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertNotNull("check response object is not null after resource request for certification", request4cert); + assertEquals("Check response code after checkout resource", 200, request4cert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(request4cert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(request4cert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + String newUuid2 = ResponseParser.getValueFromJsonResponse(request4cert.getResponse(), "uuid"); + assertTrue(ResourceValidationUtils.validateUuidAfterChangingStatus(oldUuid, newUuid2)); + + // startCert + RestResponse startCert = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertNotNull("check response object is not null after resource request start certification", startCert); + assertEquals("Check response code after checkout resource", 200, startCert.getErrorCode().intValue()); + resourceFromGet = ResponseParser.convertResourceResponseToJavaObject(startCert.getResponse()); + assertNotNull(resourceFromGet); + resourceDetails = ResponseParser.parseToObject(startCert.getResponse(), ResourceReqDetails.class); + resourceDetails.setVersion(resourceFromGet.getVersion()); + + String newUuid3 = ResponseParser.getValueFromJsonResponse(startCert.getResponse(), "uuid"); + assertTrue(ResourceValidationUtils.validateUuidAfterChangingStatus(oldUuid, newUuid3)); + + RestResponse certify = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, "0.1", LifeCycleStatesEnum.CERTIFY); + assertNotNull("check response object is not null after import resource", certify); + assertEquals("Check response code after checkout resource", 200, certify.getErrorCode().intValue()); + + String newUuid4 = ResponseParser.getValueFromJsonResponse(certify.getResponse(), "uuid"); + assertTrue(ResourceValidationUtils.validateUuidAfterChangingStatus(oldUuid, newUuid4)); + + RestResponse checkoutResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, "1.0", LifeCycleStatesEnum.CHECKOUT); + assertNotNull("check response object is not null after import resource", checkInResponse); + assertEquals("Check response code after checkout resource", 200, checkInResponse.getErrorCode().intValue()); + + String newUuid5 = ResponseParser.getValueFromJsonResponse(checkoutResponse.getResponse(), "uuid"); + assertFalse(ResourceValidationUtils.validateUuidAfterChangingStatus(oldUuid, newUuid5)); + } + + @Test + public void importNewResource_propertiesMapInternalUrlCredential() throws Exception { + String folderName = "validateProporties_typeMap_valueUrlCredential"; + RestResponse importResponse = ImportRestUtils.importNewResourceByName(folderName, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.parseToObjectUsingMapper(importResponse.getResponse(), Resource.class); + + List properties = resource.getProperties(); + assertEquals("check properties size", 3, properties.size()); + + PropertyDefinition propertyDefinition = properties.stream().filter(p -> p.getName().equals("validation_test")).findFirst().get(); + String defaultValue = propertyDefinition.getDefaultValue(); + + Map mapValue = gson.fromJson(defaultValue, Map.class); + assertEquals("check Map value size", 2, mapValue.size()); + checkMapValues(mapValue, "key", 1, null); + checkMapValues(mapValue, "key", 2, null); + + System.err.println("import Resource " + "<" + folderName + ">" + "response: " + importResponse.getErrorCode()); + + } + + @Test + public void importNewResource_propertiesListInternalUrlCredential() throws Exception { + String folderName = "validateProporties_typeList_valueUrlCredential"; + RestResponse importResponse = ImportRestUtils.importNewResourceByName(folderName, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.parseToObjectUsingMapper(importResponse.getResponse(), Resource.class); + + List properties = resource.getProperties(); + assertEquals("check properties size", 3, properties.size()); + + PropertyDefinition propertyDefinition = properties.stream().filter(p -> p.getName().equals("validation_test")).findFirst().get(); + String defaultValue = propertyDefinition.getDefaultValue(); + + List listValue = gson.fromJson(defaultValue, List.class); + assertEquals("check List value size", 2, listValue.size()); + checkListValues(listValue.get(0), 1, SPECIAL_CHARACTERS); + checkListValues(listValue.get(1), 2, SPECIAL_CHARACTERS); + + // Verify attributes + List attributes = resource.getAttributes(); + + assertEquals("check properties size", 2, attributes.size()); + + // Verify attribute from type map + AttributeDefinition attributeMapDefinition = attributes.stream().filter(p -> p.getName().equals("validation_test_map")).findFirst().get(); + String defaultMapValue = attributeMapDefinition.getDefaultValue(); + Map attributeMapValue = gson.fromJson(defaultMapValue, Map.class); + assertEquals("check Map value size", 2, attributeMapValue.size()); + checkMapValues(attributeMapValue, "key", 1, SPECIAL_CHARACTERS); + checkMapValues(attributeMapValue, "key", 2, SPECIAL_CHARACTERS); + + // Verify attribute from type list + AttributeDefinition attributeListDefinition = attributes.stream().filter(p -> p.getName().equals("validation_test_list")).findFirst().get(); + String defaultListValue = attributeListDefinition.getDefaultValue(); + + List attributeListValue = gson.fromJson(defaultListValue, List.class); + assertEquals("check List value size", 2, attributeListValue.size()); + checkListValues(attributeListValue.get(0), 1, SPECIAL_CHARACTERS); + checkListValues(attributeListValue.get(1), 2, SPECIAL_CHARACTERS); + + System.err.println("import Resource " + "<" + folderName + ">" + "response: " + importResponse.getErrorCode()); + + } + + private void checkListValues(Object object, int index, String suffix) { + + Map map = (Map) object; + assertEquals("check Map protocol value", "protocol" + index + (suffix == null ? "" : suffix), map.get("protocol")); + assertEquals("check Map token value", "token" + index, map.get("token")); + } + + // @Test + public void importNewResource_validateProporties_typeTestDataType() throws Exception { + String folderName = "validateProporties_typeTestDataType"; + RestResponse importResponse = ImportRestUtils.importNewResourceByName(folderName, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.parseToObjectUsingMapper(importResponse.getResponse(), Resource.class); + + } + + private void checkMapValues(Map mapValue, String key, int index, String suffix) { + + Map map1 = (Map) mapValue.get(key + index); + assertEquals("check Map protocol value", "protocol" + index + (suffix == null ? "" : suffix), map1.get("protocol")); + assertEquals("check Map token value", "token" + index, map1.get("token")); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaCapabilitiesWithProperties.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaCapabilitiesWithProperties.java new file mode 100644 index 0000000000..3d7c81abae --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaCapabilitiesWithProperties.java @@ -0,0 +1,416 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +/** + * US US730518 Story [BE] - TOSCA capabilities with properties - import "As a + * resource designer, I would like to add my VFC capabilities with properties." + * + * @author ns019t + * + */ +public class ImportToscaCapabilitiesWithProperties extends ComponentBaseTest { + @Rule + public static TestName name = new TestName(); + + Gson gson = new Gson(); + + /** + * public Constructor ImportToscaCapabilitiesWithProperties + */ + public ImportToscaCapabilitiesWithProperties() { + super(name, ImportToscaCapabilitiesWithProperties.class.getName()); + } + + /** + * String constants + */ + public static String propertyForTestName = "propertyfortest"; + public static String rootPath = System.getProperty("user.dir"); + public static String scalable = "tosca.capabilities.Scalable"; + public static String container = "tosca.capabilities.Container"; + public static String minInstances = "min_instances"; + public static String userDefinedNodeYaml = "mycompute.yml"; + + /** + * Capability Type - capability type on the graph should already have + * properties modeled on it. please verify. The import of the capability + * types should support adding those properties. when importing, validate + * name uniqueness between the capability's properties see capability + * tosca.capabilities.Container + * + * Acceptance Criteria: validate capability type properties (for example, + * compute have capability Container -> the properties of this capability + * should be in the Json response) + * + * @throws IOException + */ + @Test + public void validateCapabilityTypePropertiesSucceed() throws IOException { + User user = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse createResourceRes = ResourceRestUtils.getResourceByNameAndVersion(user.getUserId(), "Compute", + "1.0"); + BaseRestUtils.checkSuccess(createResourceRes); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(createResourceRes.getResponse()); + Map> capabilities = resource.getCapabilities(); + assertEquals(capabilities.size(), 6); + + CapabilityDefinition capability = capabilities.get(scalable).get(0); + List properties = capability.getProperties(); + assertEquals(properties.size(), 3); + assertTrue(!properties.stream().filter(p -> p.getName().equalsIgnoreCase(propertyForTestName)).findAny() + .isPresent()); + + ComponentInstanceProperty originalProperty = properties.stream() + .filter(p -> p.getName().equalsIgnoreCase(minInstances)).findAny().get(); + assertEquals(originalProperty.getType(), "integer"); + assertEquals(originalProperty.getDefaultValue(), "1"); + + capability = capabilities.get(container).get(0); + properties = capability.getProperties(); + assertEquals(properties.size(), 4); + } + + /** + * Capability Definition on VFC / CP / VL - properties can also be defined + * on the capability when the capability is declared. (property definition + * with default value) If the property name (case insensitive) already + * defined on the capability type, it overrides the capability from the + * capability type Import of VFC / CP /VL should support adding properties + * to the capability. when importing, validate name uniqueness between the + * capability's properties + * + * Acceptance Criteria: import node type with capability definition on it. + * use the attached "myCompute" + * + * @throws Exception + */ + @Test + public void importNodeTypeWithCapabilityWithPropertiesFromYmlSucceed() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + RestResponse createResource = importUserDefinedNodeType(userDefinedNodeYaml, sdncModifierDetails, + resourceDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + Map> capabilities = resource.getCapabilities(); + assertEquals(capabilities.size(), 6); + + CapabilityDefinition capability = capabilities.get(scalable).get(0); + List properties = capability.getProperties(); + assertEquals(properties.size(), 4); + + ComponentInstanceProperty newProperty = properties.stream() + .filter(p -> p.getName().equalsIgnoreCase(propertyForTestName)).findAny().get(); + assertEquals(newProperty.getType(), "string"); + assertEquals(newProperty.getDescription(), "test"); + assertEquals(newProperty.getDefaultValue(), "success"); + + ComponentInstanceProperty overriddenProperty = properties.stream() + .filter(p -> p.getName().equalsIgnoreCase(minInstances)).collect(Collectors.toList()).get(0); + assertEquals(overriddenProperty.getType(), "integer"); + assertEquals(overriddenProperty.getDefaultValue(), "3"); + + } + + /** + * importNodeTypeWithCapabilityWithPropertiesFromYmlFailed + * + * @throws Exception + */ + @Test + public void importNodeTypeWithCapabilityWithPropertiesFromYmlFailed() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + RestResponse createResource = importUserDefinedNodeType("mycompute_failed.yml", sdncModifierDetails, + resourceDetails); + BaseRestUtils.checkErrorMessageResponse(createResource, ActionStatus.PROPERTY_NAME_ALREADY_EXISTS); + } + + /** + * Capability Assignment (on node_template / resource instance) - should + * support assignment of the property (property value). On the resource + * instance level, value can be assigned to either properties that are + * defined on the capability type or on the capability definition. When + * importing a VF - the node_template can have capability's property value. + * It should be imported and saved on the graph Acceptance Criteria: import + * a VF that assign values to property of capability that was defined on the + * capability type + * + * @throws Exception + */ + @Test + public void importResourceWithCapabilityWithPropertiesOverridingCapTypePropertiesSucceed() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "vf_with_cap_prop_override_cap_type_prop.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + Path path = Paths.get(rootPath + "/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + + List> propertyNamesValues = new ArrayList<>(); + propertyNamesValues.add(new ImmutablePair("num_cpus", "2")); + propertyNamesValues.add(new ImmutablePair("mem_size", "2000 MB")); + checkResource(createResource, 8, container, "DBMS", propertyNamesValues); + + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + resourceDetails2.setCsarUUID("vf_with_cap_prop_override_cap_type_prop.csar"); + resourceDetails2.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + + checkResource(createResource, 8, container, "DBMS", propertyNamesValues); + } + + /** + * importResourceWithCapabilityWithPropertiesOverridingCapTypePropertiesFailed + * + * @throws Exception + */ + @Test + public void importResourceWithCapabilityWithPropertiesOverridingCapTypePropertiesFailed() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String payloadName = "vf_with_cap_prop_override_cap_type_prop_failed.csar"; + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + Path path = Paths + .get(rootPath + "/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop_failed.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkErrorMessageResponse(createResource, ActionStatus.INVALID_PROPERTY); + + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + resourceDetails2.setCsarUUID("vf_with_cap_prop_override_cap_type_prop_failed.csar"); + resourceDetails2.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + BaseRestUtils.checkErrorMessageResponse(createResource, ActionStatus.INVALID_PROPERTY); + + } + + /** + * Capability Assignment (on node_template / resource instance) - should + * support assignment of the property (property value). On the resource + * instance level, value can be assigned to either properties that are + * defined on the capability type or on the capability definition. When + * importing a VF - the node_template can have capability's property value. + * It should be imported and saved on the graph Acceptance Criteria: import + * a VF that assign values to property of capability that was defined on the + * capability definition (on the node type) + * + * @throws Exception + */ + @Test + public void importResourceWithCapabilityWithPropertiesOverridingNodeTypeCapPropertiesSucceed() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + RestResponse createResource = importUserDefinedNodeType(userDefinedNodeYaml, sdncModifierDetails, + resourceDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource userDefinedNodeType = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), + Resource.class); + + String payloadName = "vf_with_cap_prop_override_cap_type_prop1.csar"; + resourceDetails = ElementFactory.getDefaultImportResource(); + Path path = Paths.get(rootPath + "/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + + List> propertyNamesValues = new ArrayList<>(); + propertyNamesValues.add(new ImmutablePair("num_cpus", "2")); + propertyNamesValues.add(new ImmutablePair("mem_size", "2000 MB")); + checkResource(createResource, 8, container, "DBMS", propertyNamesValues); + + List> propertyNamesValues1 = new ArrayList<>(); + propertyNamesValues1.add(new ImmutablePair(propertyForTestName, "success_again")); + propertyNamesValues1.add(new ImmutablePair(minInstances, "4")); + checkResource(createResource, 8, scalable, userDefinedNodeType.getName(), propertyNamesValues1); + + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + resourceDetails2.setCsarUUID("vf_with_cap_prop_override_cap_type_prop1.csar"); + resourceDetails2.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + + checkResource(createResource, 8, container, "DBMS", propertyNamesValues); + checkResource(createResource, 8, scalable, userDefinedNodeType.getName(), propertyNamesValues1); + + } + + /** + * importResourceWithCapabilityWithPropertiesOverridingNodeTypeCapPropertiesFailed + * + * @throws Exception + */ + @Test + public void importResourceWithCapabilityWithPropertiesOverridingNodeTypeCapPropertiesFailed() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + RestResponse createResource = importUserDefinedNodeType(userDefinedNodeYaml, sdncModifierDetails, + resourceDetails); + BaseRestUtils.checkCreateResponse(createResource); + + String payloadName = "vf_with_cap_prop_override_cap_type_prop1_failed.csar"; + resourceDetails = ElementFactory.getDefaultImportResource(); + Path path = Paths + .get(rootPath + "/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1_failed.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, + propertyForTestName); + + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + resourceDetails2.setCsarUUID("vf_with_cap_prop_override_cap_type_prop1_failed.csar"); + resourceDetails2.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + BaseRestUtils.checkErrorResponse(createResource, ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, + propertyForTestName); + } + + private RestResponse importUserDefinedNodeType(String payloadName, User sdncModifierDetails, + ImportReqDetails resourceDetails) throws Exception { + + Path path = Paths.get(rootPath + "/src/test/resources/CI/csars/" + payloadName); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VFC.name()); + return ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + } + + // TODO Tal: Since Cashing change partial resource returned that causes null + // pointer exception + // commented out till fixing + private void checkResource(RestResponse createResource, int capNum, String capType, String riName, + List> propertyNamesValues) { + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + Map> capabilities = resource.getCapabilities(); + // TODO Tal: Since Cashing change partial resource returned that causes + // null pointer exception + /* assertEquals(capabilities.size(), capNum); */ + /* + * List capabilitesContainer = + * capabilities.get(capType); + */ + + ComponentInstance resourceRI = resource.getComponentInstances().stream() + .filter(ri -> ri.getComponentName().equals(riName)).collect(Collectors.toList()).get(0); + // TODO Tal: Since Cashing change partial resource returned that causes + // null pointer exception + /* + * CapabilityDefinition capabilityFromContainer = + * capabilitesContainer.stream() + * .filter(cap->cap.getOwnerId().equals(resourceRI.getUniqueId())). + * collect(Collectors.toList()).get(0); + */ + + CapabilityDefinition capabilityFromRI = resourceRI.getCapabilities().get(capType).get(0); + for (ImmutablePair propValuePair : propertyNamesValues) { + // TODO Tal: Since Cashing change partial resource returned that + // causes null pointer exception + /* + * Map propertiesFromContainer = + * capabilityFromContainer.getProperties() + * .stream().filter(p->p.getName().equalsIgnoreCase(propValuePair. + * getLeft())) .collect(Collectors.toMap(p->p.getName(), p->p)); + */ + + List propertiesFromRI = capabilityFromRI.getProperties().stream() + .filter(p -> p.getName().equalsIgnoreCase(propValuePair.getLeft())).collect(Collectors.toList()); + // TODO Tal: Since Cashing change partial resource returned that + // causes null pointer exception + /* + * for(ComponentInstanceProperty riProp : propertiesFromRI){ + * assertTrue(propertiesFromContainer.containsKey(riProp.getName())) + * ; ComponentInstanceProperty containerProp = + * propertiesFromContainer.get(riProp.getName()); + * assertEquals(riProp.getValue(), containerProp.getValue()); + * if(riProp.getName().equals(propValuePair.getLeft())) + * assertEquals(riProp.getValue(), propValuePair.getRight()); + * + * } + */ + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaResourceTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaResourceTest.java new file mode 100644 index 0000000000..b78bf3de36 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportToscaResourceTest.java @@ -0,0 +1,2404 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_CREATED; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.general.ImportUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.api.ToscaNodeTypeInfo; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +/** + * + * @author Andrey + Pavel + Shay + * + */ + +public class ImportToscaResourceTest extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(ImportToscaResourceTest.class.getName()); + protected Utils utils = new Utils(); + + public ImportToscaResourceTest() { + super(name, ImportToscaResourceTest.class.getName()); + } + + public ImportReqDetails importReqDetails; + protected static User sdncUserDetails; + protected static User testerUser; + protected String testResourcesPath; + protected ResourceReqDetails resourceDetails; + private HashSet capabilitySources; + private int actualNumOfReqOrCap; + + @Rule + public static TestName name = new TestName(); + + @BeforeMethod + public void before() throws Exception { + importReqDetails = ElementFactory.getDefaultImportResource(); + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + testerUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + resourceDetails = ElementFactory.getDefaultResource(); + String sourceDir = config.getResourceConfigDir(); + final String workDir = "importToscaResourceByCreateUrl"; + testResourcesPath = sourceDir + File.separator + workDir; + capabilitySources = new HashSet(); + actualNumOfReqOrCap = 0; + } + + @DataProvider + private static final Object[][] getYmlWithInValidListProperties() throws IOException, Exception { + return new Object[][] { { "ListPropertyFalure02.yml", "[false,\"truee\"]", "boolean" }, { "ListPropertyFalure03.yml", "[false,3]", "boolean" }, { "ListPropertyFalure04.yml", "[false,3.56]", "boolean" }, + { "ListPropertyFalure05.yml", "[10000,3.56]", "integer" }, { "ListPropertyFalure06.yml", "[10000,\"aaaa\"]", "integer" }, { "ListPropertyFalure07.yml", "[10000,true]", "integer" }, + { "ListPropertyFalure08.yml", "[10.5,true]", "float" }, { "ListPropertyFalure09.yml", "[10.5,\"asdc\"]", "float" }, // type + // float + { "ListPropertyFalure11.yml", "[10.5,\"500.0@\"]", "float" }, // property + // list + // float + // type + // contain + // @ + // in + // default + // value + { "ListPropertyFalure12.yml", "[10000,\"3#\"]", "integer" }, // property + // list + // integer + // type + // contain + // # + // in + // default + // value + { "ListPropertyFalure13.yml", "[false,\"true%\"]", "boolean" }, // property + // list + // boolean + // type + // contain + // % + // in + // default + // value + { "ListPropertyFalure14.yml", "[false,\"falsee\",true]", "boolean" }, { "ListPropertyFalure15.yml", "[10.5,\"10.6x\",20.5,30.5]", "float" } // float + // with + // value + // 10.6x + // instead + // 10.6f + + }; + } + + @DataProvider + private static final Object[][] getYmlWithInValidMapProperties() throws IOException, Exception { + return new Object[][] { { "MapPropertyFalure02.yml", "[false,\"truee\"]", "boolean" }, { "MapPropertyFalure03.yml", "[false,3]", "boolean" }, { "MapPropertyFalure04.yml", "[false,3.56]", "boolean" }, + { "MapPropertyFalure05.yml", "[10000,3.56]", "integer" }, { "MapPropertyFalure06.yml", "[10000,\"aaaa\"]", "integer" }, { "MapPropertyFalure07.yml", "[10000,true]", "integer" }, { "MapPropertyFalure08.yml", "[10.5,true]", "float" }, + { "MapPropertyFalure09.yml", "[10.5,\"asdc\"]", "float" }, // type + // float + { "MapPropertyFalure11.yml", "[10.5,\"500.0@\"]", "float" }, // property + // list + // float + // type + // contain + // @ + // in + // default + // value + { "MapPropertyFalure12.yml", "[10000,\"3#\"]", "integer" }, // property + // list + // integer + // type + // contain + // # + // in + // default + // value + { "MapPropertyFalure13.yml", "[false,\"true%\"]", "boolean" }, // property + // list + // boolean + // type + // contain + // % + // in + // default + // value + { "MapPropertyFalure14.yml", "[false,\"falsee\",true]", "boolean" }, { "MapPropertyFalure15.yml", "[10.5,\"10.6x\",20.5,30.5]", "float" } // float + // with + // value + // 10.6x + // instead + // 10.6f + + }; + } + + @DataProvider + private static final Object[][] getYmlWithInValidOccurrences() throws IOException, Exception { + return new Object[][] { { "occurencyFalure01.yml" }, // requirements [2 + // , 0] + { "occurencyFalure02.yml" }, // requirements [-1, 2] + { "occurencyFalure03.yml" }, // requirements [1 ,-2] + { "occurencyFalure05.yml" }, // requirements MAX occurrences not + // exist [ 1 , ] + { "occurencyFalure06.yml" }, // requirements [ 0 , 0 ] + { "occurencyFalure08.yml" }, // requirements [ 1.0 , 2.0 ] + { "occurencyFalure09.yml" }, // requirements [ "1" , "2" ] + { "occurencyFalure10.yml" }, // requirements [ ] + { "occurencyFalure11.yml" }, // requirements [ UNBOUNDED , + // UNBOUNDED ] + { "occurencyFalure31.yml" }, // capability [ 2, 1] + { "occurencyFalure32.yml" }, // capability [-1, 2] + { "occurencyFalure33.yml" }, // capability [1, -2] + { "occurencyFalure35.yml" }, // capability MAX occurrences not + // exist [ 1 , ] + { "occurencyFalure36.yml" }, // capability [ 0 , 0 ] + { "occurencyFalure38.yml" }, // capability [ 1.0 , 2.0 ] + { "occurencyFalure39.yml" }, // capability [ "1" , "2" ] + { "occurencyFalure40.yml" }, // capability [ ] + { "occurencyFalure41.yml" } // capability [ UNBOUNDED , + // UNBOUNDED ] + }; + } + + @DataProvider + private static final Object[][] getInvalidYmlWithOccurrences() throws IOException, Exception { + return new Object[][] { { "occurencyFalure04.yml" }, // requirements MIN + // occurrences + // not exist [ , + // 1] + { "occurencyFalure07.yml" }, // requirements [ @ , 1 ] + { "occurencyFalure34.yml" }, // capability MIN occurrences not + // exist [ , 1] + { "occurencyFalure37.yml" } // capability [ 0 , # ] + + }; + } + + // US656928 + protected final String importMapPropertySuccess = "importMapPropertySuccessFlow.yml"; + protected final String importAttributeSuccess = "importAttributeSuccessFlow.yml"; + protected final String importSuccessFile = "myCompute.yml"; + protected final String derivedFromMyCompute = "derivedFromMyCompute.yml"; + protected final String importSuccessVFFile = "myComputeVF.yml"; + protected final String importNoDerivedFromFile = "myComputeDerivedFromNotExists.yml"; + protected final String importInvalidDefinitionVersionFile = "myComputeIncorrectDefenitionVersionValue.yml"; + protected final String importIncorrectNameSpaceFormatFile = "myComputeIncorrectNameSpaceFormat.yml"; + protected final String importNoDefenitionVersionFile = "myComputeNoDefenitionVersion.yml"; + protected final String importNodeTypesTwiceFile = "myComputeWithNodeTypesTwice.yml"; + protected final String importTopologyTemplateFile = "myComputeWithTopologyTemplate.yml"; + protected final String importNoContentFile = "noContent.yml"; + protected final String importWithOccurrences = "myComputeOccurencySuccess.yml"; + protected final String importListPropertyBadDefault = "importListPropertyBadDefault.yml"; + protected final String importListPropertyGoodDefault = "importListPropertyGoodDefault.yml"; + protected final String importListPropertySuccess = "importListPropertySuccessFlow.yml"; + // US631462 + protected final String importDuplicateRequirements = "importDuplicateRequirements.yml"; + protected final String importDuplicateCapability = "importDuplicateCapability.yml"; + protected final String importCapabilityNameExistsOnParent = "importCapabilityNameExistsOnParent.yml"; + protected final String importRequirementNameExistsOnParent = "importRequirementNameExistsOnParent.yml"; + protected final String importToscaResourceReqCapDerivedFromParent = "derivedFromWebAppDerivedReqCap.yml"; + protected final String missingCapInReqDef = "missingCapInReqDefinition.yml"; + protected final String missingCapInCapDef = "missingCapInCapDefinition.yml"; + + // US558432 - Support for Capability/Requirement "occurences" Import + @Test(dataProvider = "getYmlWithInValidOccurrences") + public void importToscaResourceWithOccurrencesFailuresFlow01(String ymlFileWithInvalidCapReqOccurrences) throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFileWithInvalidCapReqOccurrences); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_OCCURRENCES.name(), new ArrayList(), importResourceResponse.getResponse()); + } + + @Test(dataProvider = "getInvalidYmlWithOccurrences") + public void importToscaResourceWithOccurrencesFailuresFlow02(String ymlFileWithInvalidCapReqOccurrences) throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFileWithInvalidCapReqOccurrences); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_YAML_FILE.name(), new ArrayList(), importResourceResponse.getResponse()); + } + + @Test + public void importToscaResource() throws Exception { + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importSuccessFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + AssertJUnit.assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + AssertJUnit.assertTrue("validate toscaResourceName field", resourceJavaObject.getToscaResourceName().equals(parseToscaNodeYaml.getNodeName())); + AssertJUnit.assertTrue("validate resourceType field", resourceJavaObject.getResourceType().equals(ResourceTypeEnum.VFC)); + // find derived from resource details + // Validate resource details after import-create resource including + // capabilities, interfaces from derived_from resource + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceWithOccurrencesSuccessFlow() throws Exception { + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importWithOccurrences); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + AssertJUnit.assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + AssertJUnit.assertTrue("validate toscaResourceName field", resourceJavaObject.getToscaResourceName().equals(parseToscaNodeYaml.getNodeName())); + AssertJUnit.assertTrue("validate resourceType field", resourceJavaObject.getResourceType().equals(ResourceTypeEnum.VFC)); + String requirementsType = "tosca.capabilities.Attachment"; + String capabilitType = "tosca.capabilities.Endpoint.Admin"; + // Verify Occurrences of requirements and capabilities in resource + verifyRequirementsOccurrences(resourceJavaObject, requirementsType); + verifyCapabilitiesOccurrences(resourceJavaObject, capabilitType); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + // ------------------------------Success--------------------------------- + + @Test(enabled = false) + public void importToscaResourceVFResType() throws Exception { + + String resourceType = ResourceTypeEnum.VF.toString(); + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importSuccessVFFile); + // importReqDetails.setResourceType(resourceType); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + assertTrue("validate toscaResourceName field", resourceJavaObject.getToscaResourceName().equals(parseToscaNodeYaml.getNodeName())); + assertTrue("validate resourceType field, expected - " + resourceType + ", actual - " + resourceJavaObject.getResourceType(), resourceJavaObject.getResourceType().toString().equals(resourceType)); + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + // ------------------------------Failure--------------------------------- + + @Test + public void importToscaResourceDerivedFromNotExist() throws Exception { + + String fileName = importNoDerivedFromFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + // List derivedFrom = new ArrayList() ; + // derivedFrom.add("hh"); + // importReqDetails.setDerivedFrom(derivedFrom); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.PARENT_RESOURCE_NOT_FOUND.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PARENT_RESOURCE_NOT_FOUND.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceIncorrectDefinitionVersion() throws Exception { + + String fileName = importInvalidDefinitionVersionFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_TOSCA_TEMPLATE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_TOSCA_TEMPLATE.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceIncorrectSpaceNameFormat() throws Exception { + + String fileName = importIncorrectNameSpaceFormatFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_RESOURCE_NAMESPACE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_RESOURCE_NAMESPACE.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceNoDefinitionVersion() throws Exception { + + String fileName = importNoDefenitionVersionFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_TOSCA_TEMPLATE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_TOSCA_TEMPLATE.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceNoContent() throws Exception { + + String fileName = importNoContentFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_RESOURCE_PAYLOAD.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_RESOURCE_PAYLOAD.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceWithTopologyTemplate() throws Exception { + + String fileName = importTopologyTemplateFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceWithNodeTypesTwice() throws Exception { + + String fileName = importNodeTypesTwiceFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.NOT_SINGLE_RESOURCE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_SINGLE_RESOURCE.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + // failed case - uniqueness of toscaResourceName - RESOURCE_ALREADY_EXISTS + @Test + public void importToscaResourceTwice() throws Exception { + String fileName = importSuccessFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + RestResponse checkInresponse = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKIN); + assertTrue("checkIn resource request returned status:" + checkInresponse.getErrorCode(), checkInresponse.getErrorCode() == 200); + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + + // import the same tosca resource with different resourceName + DbUtils.cleanAllAudits(); + + importReqDetails.setName("kuku"); + List tags = new ArrayList(); + tags.add(importReqDetails.getName()); + importReqDetails.setTags(tags); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESOURCE_ALREADY_EXISTS.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_ALREADY_EXISTS.name(), variables, importResourceResponse.getResponse()); + + expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(importReqDetails.getToscaResourceName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + + } + + @Test + public void importToscaResourceWithTheSameNameAsCreatedResourceBefore() throws Exception { + + // create resource + String fileName = importSuccessFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName(importReqDetails.getName()); + + RestResponse response = ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + int status = response.getErrorCode(); + assertEquals("create request returned status:" + status, 201, status); + assertNotNull("resource uniqueId is null:", resourceDetails.getUniqueId()); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + // assertNull("validate toscaResourceName field", + // resourceJavaObject.getToscaResourceName()); + + // import the same tosca resource + DbUtils.cleanAllAudits(); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESOURCE_ALREADY_EXISTS.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_ALREADY_EXISTS.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + + } + + @Test + public void importToscaResourceInvalidChecksum() throws Exception { + String fileName = importSuccessFile; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), "invalidMd5Sum"); + + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, headersMap); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + assertNotNull("check response object is not null after import tosca resource", importResourceResponse); + assertNotNull("check error code exists in response after import tosca resource", importResourceResponse.getErrorCode()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_RESOURCE_CHECKSUM.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_RESOURCE_CHECKSUM.name(), variables, importResourceResponse.getResponse()); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceInvalidResType() throws Exception { + + String resourceType = "invalidResourceType"; + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importSuccessFile); + importReqDetails.setResourceType(resourceType); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_CONTENT.name()); + assertNotNull("check response object is not null after import resouce", importResourceResponse); + assertNotNull("check error code exists in response after import resource", importResourceResponse.getErrorCode()); + assertEquals("Check response code after import resource", errorInfo.getCode(), importResourceResponse.getErrorCode()); + + List variables = new ArrayList<>(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), variables, importResourceResponse.getResponse()); + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void derivedTemplateImportedSecondResourceAsFirstImportedNodeType() throws Exception { + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importSuccessFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + assertTrue("validate toscaResourceName field", resourceJavaObject.getToscaResourceName().equals(parseToscaNodeYaml.getNodeName())); + assertTrue("validate resourceType field, expected - " + importReqDetails.getResourceType() + ", actual - " + resourceJavaObject.getResourceType(), resourceJavaObject.getResourceType().toString().equals(importReqDetails.getResourceType())); + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + + RestResponse certifyResource = LifecycleRestUtils.certifyResource(importReqDetails); + assertTrue("certify resource request returned status:" + certifyResource.getErrorCode(), certifyResource.getErrorCode() == 200); + + // import second resource template derived from first resource + DbUtils.cleanAllAudits(); + importReqDetails.setName("kuku"); + List tags = new ArrayList(); + tags.add(importReqDetails.getName()); + importReqDetails.setTags(tags); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, derivedFromMyCompute); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + Resource resourceJavaObject2 = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + assertTrue("validate toscaResourceName field", resourceJavaObject2.getToscaResourceName().equals(parseToscaNodeYaml.getNodeName())); + assertTrue("validate resourceType field, expected - " + importReqDetails.getResourceType() + ", actual - " + resourceJavaObject2.getResourceType(), resourceJavaObject2.getResourceType().toString().equals(importReqDetails.getResourceType())); + + // Validate audit message + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject2 = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject2.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject2.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject2.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject2.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject2, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + + } + + @Test + public void importToscaResourceListPropertyGoodDefault() throws Exception { + + String fileName = importListPropertyGoodDefault; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + assertTrue("response code is not 201, returned :" + importResourceResponse.getErrorCode(), importResourceResponse.getErrorCode() == 201); + + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + assertTrue("Properties size : " + resourceJavaObject.getProperties().size(), resourceJavaObject.getProperties().size() == 1); + assertTrue("Property type : " + resourceJavaObject.getProperties().get(0).getType(), resourceJavaObject.getProperties().get(0).getType().equals(ToscaPropertyType.LIST.getType())); + assertTrue("actual Default values : " + resourceJavaObject.getProperties().get(0).getDefaultValue() + " , expected : " + "[false, true]", resourceJavaObject.getProperties().get(0).getDefaultValue().equals("[\"false\",\"true\"]")); + + } + + @Test + public void importToscaResourceListPropertyBadDefault() throws Exception { + + String fileName = importListPropertyBadDefault; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name()); + assertEquals("Check response code after tosca resource import", errorInfo.getCode(), importResourceResponse.getErrorCode()); + ArrayList variables = new ArrayList<>(); + variables.add("my_prop"); + variables.add("list"); + variables.add("boolean"); + variables.add("[12,true]"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, importResourceResponse.getResponse()); + + } + + // Benny US580744 - Add support for TOSCA "list" type - import + + @Test + public void importToscaResourceListPropertySuccessFlow() throws Exception { + String fileName = importListPropertySuccess; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + ResourceRestUtils.checkCreateResponse(importResourceResponse); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + // Verify Properties List in resource + verifyResourcePropertiesList(resourceJavaObject); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + // DE198534 + @Test(dataProvider = "getYmlWithInValidListProperties") // invalid default + // values + public void importToscaResourceListPropertyFailureFlows(String ymlFileWithInvalidPropertyDefualtValues, String defualtValues, String enterySchemaType) throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFileWithInvalidPropertyDefualtValues); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("my_property"); + variables.add("list"); + variables.add(enterySchemaType); + variables.add(defualtValues); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, importResourceResponse.getResponse()); + } + + // BUG DE198650 + @Test + public void importToscaResourceListPropertyNonSupportEntrySchemaType() throws Exception { + String ymlFile = "ListPropertyFalure01.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("booolean"); // property entry_schema data type + variables.add("my_boolean"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_INNER_TYPE.name(), variables, importResourceResponse.getResponse()); + } + + // BUG DE198676 + @Test // (enabled=false) + public void importToscaResourceListPropertyNonSupportedPropertyType() throws Exception { // Not + // "list" + // type + String ymlFile = "ListPropertyFalure16.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("koko"); // property data type (koko instead list) + variables.add("my_boolean"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_TYPE.name(), variables, importResourceResponse.getResponse()); + } + + /// US656928 - [BE] - Add support for TOSCA "map" type - Phase 1 import + @Test + public void importToscaResourceMapPropertySuccessFlow() throws Exception { + String fileName = importMapPropertySuccess; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + ResourceRestUtils.checkCreateResponse(importResourceResponse); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + // Verify Properties MAP in resource + verifyResourcePropertiesMap(resourceJavaObject); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test(dataProvider = "getYmlWithInValidMapProperties") // invalid default + // values + public void importToscaResourceMapPropertyFailureFlows(String ymlFileWithInvalidPropertyDefualtValues, String defualtValues, String enterySchemaType) throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFileWithInvalidPropertyDefualtValues); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("my_property"); + variables.add("map"); + variables.add(enterySchemaType); + variables.add(defualtValues); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, importResourceResponse.getResponse()); + } + + @Test + public void importToscaResourceMaptPropertyNonSupportedPropertyType() throws Exception { // Not + // "Map" + // type + String ymlFile = "MapPropertyFalure16.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, ymlFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("koko"); // property data type (koko instead list) + variables.add("my_boolean"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_TYPE.name(), variables, importResourceResponse.getResponse()); + } + + @Test + public void importToscaResourceMissingCapabilityInReqDefinition() throws Exception { + + String fileName = missingCapInReqDef; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_CAPABILITY_TYPE.name()); + String missingCapName = "org.openecomp.capabilities.networkInterfaceNotFound"; + BaseRestUtils.checkErrorResponse(importResourceResponse, ActionStatus.MISSING_CAPABILITY_TYPE, missingCapName); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, Arrays.asList(missingCapName)); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType("org.openecomp.resource.vSCP-03-16"); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceMissingCapabilityInCapDefinition() throws Exception { + + String fileName = missingCapInCapDef; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + logger.debug("import tosca resource response: {}", importResourceResponse.getResponseMessage()); + + // Validate audit message + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_CAPABILITY_TYPE.name()); + String missingCapName = "org.openecomp.capabilities.networkInterfaceNotFound"; + BaseRestUtils.checkErrorResponse(importResourceResponse, ActionStatus.MISSING_CAPABILITY_TYPE, missingCapName); + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, Arrays.asList(missingCapName)); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType("org.openecomp.resource.vSCP-03-16"); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceDuplicateRequirements() throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importDuplicateRequirements); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("requirement"); + variables.add("local_storage"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME.name(), variables, importResourceResponse.getResponse()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceDuplicateCapabilities() throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importDuplicateCapability); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("capability"); + variables.add("scalable"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME.name(), variables, importResourceResponse.getResponse()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceRequirementNameExistsOnParent() throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importRequirementNameExistsOnParent); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("requirement"); + variables.add("local_storage"); + variables.add("Compute"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name(), variables, importResourceResponse.getResponse()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceCapabilityNameExistsOnParent() throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importCapabilityNameExistsOnParent); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertTrue(importResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add("capability"); + variables.add("binding"); + variables.add("Compute"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name(), variables, importResourceResponse.getResponse()); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgFailure(errorInfo, variables); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + @Test + public void importToscaResourceReqCapDerivedFromParent() throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, importToscaResourceReqCapDerivedFromParent); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + BaseRestUtils.checkCreateResponse(importResourceResponse); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType("org.openecomp.resource.MyWebApp"); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + /************************ Shay ************************/ + + @Test + public void caseRequirementInsensitiveTest() throws Exception { + String fileName = "CaseInsensitiveReqTest_1.yml"; + int expectedNumOfRequirements = 2; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + importReqDetails.setRequirements(testResourcesPath, fileName, sdncUserDetails, null); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String fileName2 = "CaseInsensitiveReqTest_2.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName2); + importReqDetails.setName("secondImportedResource"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, null); + requirements = importReqDetails.getRequirements(); + requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + checkImportedAssetAssociated(importReqDetails); + + } + + private void checkImportedAssetAssociated(ImportReqDetails importDetails) throws IOException, Exception { + RestResponse importResourceResponse; + ImportReqDetails importReqDetails2 = ElementFactory.getDefaultImportResource(); + importReqDetails2 = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails2, testResourcesPath, "BindingAsset.yml"); + importReqDetails2.setName("bindingAsset"); + importReqDetails2.setTags(Arrays.asList(importReqDetails2.getName())); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails2, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + ResourceReqDetails vf = ElementFactory.getDefaultResourceByType("VF100", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncUserDetails.getUserId(), ResourceTypeEnum.VF.toString()); + RestResponse createResourceResponse = ResourceRestUtils.createResource(vf, sdncUserDetails); + ResourceRestUtils.checkCreateResponse(createResourceResponse); + + LifecycleRestUtils.changeResourceState(importDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + LifecycleRestUtils.changeResourceState(importReqDetails2, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + RestResponse response = ResourceRestUtils.createResourceInstance(importDetails, sdncUserDetails, vf.getUniqueId()); + ResourceRestUtils.checkCreateResponse(response); + ComponentInstance riCap = ResponseParser.parseToObject(response.getResponse(), ComponentInstance.class); + + response = ResourceRestUtils.createResourceInstance(importReqDetails2, sdncUserDetails, vf.getUniqueId()); + ResourceRestUtils.checkCreateResponse(response); + ComponentInstance riReq = ResponseParser.parseToObject(response.getResponse(), ComponentInstance.class); + + RestResponse getResourceBeforeAssociate = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncUserDetails, vf); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceBeforeAssociate.getResponse(), CapReqDef.class); + + String capbilityUid = capReqDef.getCapabilities().get("tosca.capabilities.network.Bindable").get(0).getUniqueId(); + String requirementUid = capReqDef.getRequirements().get("tosca.capabilities.network.Bindable").get(0).getUniqueId(); + + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(riReq.getUniqueId()); + requirementDef.setToNode(riCap.getUniqueId()); + + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(riReq.getUniqueId()); + pair.setCapabilityOwnerId(riCap.getUniqueId()); + pair.setRequirement("VirtualBinding"); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType("tosca.capabilities.network.Bindable"); + pair.setRelationships(relationship); + pair.setCapabilityUid(capbilityUid); + pair.setRequirementUid(requirementUid); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncUserDetails, vf.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + } + + @Test + public void caseCapabilitiesInsensitiveTest() throws Exception { + String fileName = "CaseInsensitiveCapTest_1.yml"; + int expectedNumOfCapabilities = 6; + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setCapabilities(testResourcesPath, fileName, sdncUserDetails, null); + Map capabilities = importReqDetails.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String fileName2 = "CaseInsensitiveCapTest_2.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName2); + importReqDetails.setName("secondImportedResource"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setCapabilities(testResourcesPath, fileName2, sdncUserDetails, null); + capabilities = importReqDetails.getCapabilities(); + capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + + } + + @Test + public void fatherAndChildHaveDifferentRequirementsTest() throws Exception { + String fileName = "DifferentReqFromCompute.yml"; + int expectedNumOfRequirements = 3; + + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, fileName, sdncUserDetails, "Compute"); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + checkImportedAssetAssociated(importReqDetails); + } + + @Test + public void fatherHasNoRequirementsTest() throws Exception { + String fatherFileName = "CPHasNoReqCap.yml"; + String childFileName = "DerivedFromCPWithOwnReq.yml"; + int expectedNumOfRequirements = 3; + + importReqDetails.setName("father"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String derivedFromResourceName = importReqDetails.getName(); + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromResourceName); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + } + + @Test + public void childHasSameReqNameAndTypeLikeFatherTest() throws Exception { + String childFileName = "SameReqAsCompute.yml"; + int expectedNumOfRequirements = 2; + + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, null); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + } + + @Test + public void childHasSameCapNameAndTypeLikeFatherTest() throws Exception { + String childFileName = "SameCapAsCompute.yml"; + int expectedNumOfCapabilities = 6; + + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setCapabilities(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, "Compute"); + Map capabilities = importReqDetails.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + } + + @Test + public void childGetsAllRequirementsOfFatherAndGrandfatherTest() throws Exception { + int expectedNumOfRequirements = 4; + + String fatherFileName = "DifferentReqFromCompute.yml"; + importReqDetails.setName("father"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String derivedFromName = importReqDetails.getName(); + String childFileName = "DifferentReqCapFromCompute1.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + } + + @Test + public void childOverridesGrandfatherRequirementsTest() throws Exception { + int expectedNumOfRequirements = 3; + + String fatherFileName = "DifferentReqFromCompute.yml"; + importReqDetails.setName("father"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String derivedFromName = importReqDetails.getName(); + String childFileName = "SameReqAsCompute_DerivedFromMyCompute1.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + } + + @Test + public void childAndGrandfatherHaveDifferenetReqiurementTypeTest() throws Exception { + int expectedNumOfRequirements = 3; + int expectedNumOfCapabilities = 6; + + String fatherName = "father"; + String fatherFileName = "DifferentReqFromCompute.yml"; + importReqDetails.setName(fatherName); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String fatherUniqueId = importReqDetails.getUniqueId(); + ImportReqDetails importReqDetailsFather = importReqDetails; + + String childFileName = "importRequirementNameExistsOnParent_DerivedFromMyCompute1.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_INVALID_CONTENT, importResourceResponse.getErrorCode().intValue()); + ArrayList variables = new ArrayList<>(); + variables.add("requirement"); + variables.add("local_storage"); + variables.add(fatherName); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name(), variables, importResourceResponse.getResponse()); + + importReqDetails.setUniqueId(fatherUniqueId); + + importReqDetailsFather.setRequirements(testResourcesPath, fatherFileName, sdncUserDetails, "Compute"); + Map requirements = importReqDetailsFather.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetailsFather, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetailsFather.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + importReqDetailsFather.setCapabilities(testResourcesPath, fatherFileName, sdncUserDetails, "Compute"); + Map capabilities = importReqDetailsFather.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetailsFather, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetailsFather.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + } + + @Test + public void childHasNoReqCapTest() throws Exception { + int expectedNumOfRequirements = 3; + int expectedNumOfCapabilities = 6; + + String fatherFileName = "DifferentReqFromCompute.yml"; + importReqDetails.setName("father"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String derivedFromName = importReqDetails.getName(); + String childFileName = "CPHasNoReqCap_DerivedFromMyCompute1.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + importReqDetails.setCapabilities(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map capabilities = importReqDetails.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + } + + @Test + public void fatherAndChildGetReqCapFromGrandfatherTest() throws Exception { + int expectedNumOfRequirements = 2; + int expectedNumOfCapabilities = 6; + + String fatherFileName = "MyFatherCompute_NoReqCap.yml"; + importReqDetails.setName("father"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String derivedFromName = importReqDetails.getName(); + String childFileName = "myChildCompute_NoReqCap.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map requirements = importReqDetails.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + importReqDetails.setCapabilities(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map capabilities = importReqDetails.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + } + + @Test + public void reverseInheritanceTest() throws Exception { + int expectedNumOfRequirements = 2; + int expectedNumOfCapabilities = 2; + + String fatherName = "father"; + String fatherFileName = "myFatherWebApp_derviedFromDocker.yml"; + importReqDetails.setName(fatherName); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String fatherUniqueId = importReqDetails.getUniqueId(); + ImportReqDetails importReqDetailsFather = importReqDetails; + String childFileName = "myChildWebApp_DerivedFromContainer.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_INVALID_CONTENT, importResourceResponse.getErrorCode().intValue()); + ArrayList variables = new ArrayList<>(); + variables.add("requirement"); + variables.add("host"); + variables.add(fatherName); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED.name(), variables, importResourceResponse.getResponse()); + + importReqDetails.setUniqueId(fatherUniqueId); + importReqDetailsFather.setRequirements(testResourcesPath, fatherFileName, sdncUserDetails, "Root"); + Map requirements = importReqDetailsFather.getRequirements(); + Map requirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetailsFather, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), requirementsFromResponse.keySet().size()); + importReqDetailsFather.compareRequirementsOrCapabilities(requirements, requirementsFromResponse); + + importReqDetailsFather.setCapabilities(testResourcesPath, fatherFileName, sdncUserDetails, "Root"); + Map capabilities = importReqDetailsFather.getCapabilities(); + Map capabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetailsFather, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), capabilitiesFromResponse.keySet().size()); + importReqDetailsFather.compareRequirementsOrCapabilities(capabilities, capabilitiesFromResponse); + } + + // DE202329 + @Test(enabled = false) + public void requirementWithMissingTypeTest() throws Exception { + String fatherName = "father"; + String fatherFileName = "DerivedFromWebApplication_HasNoReqType.yml"; + importReqDetails.setName(fatherName); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_INVALID_CONTENT, importResourceResponse.getErrorCode().intValue()); + ArrayList variables = new ArrayList<>(); + variables.add("diff"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_CAPABILITY_TYPE.name(), variables, importResourceResponse.getResponse()); + + } + + @Test + public void TwinBrothersHaveSameReqCapTest() throws Exception { + int expectedNumOfRequirements = 4; + int expectedNumOfCapabilities = 7; + + String derivedFromName = "father"; + String fatherFileName = "DifferentReqFromCompute.yml"; + importReqDetails.setName(derivedFromName); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fatherFileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + RestResponse changeResourceState1 = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState1.getErrorCode().intValue()); + RestResponse changeResourceState2 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState2.getErrorCode().intValue()); + RestResponse changeResourceState3 = LifecycleRestUtils.changeResourceState(importReqDetails, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState3.getErrorCode().intValue()); + + String childFileName = "DifferentReqCapFromCompute1.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("child"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, childFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + Map childRequirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + Map childCapabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities - 1); + + String twinFileName = "DifferentReqCapFromCompute2.yml"; + importReqDetails = ElementFactory.getDefaultImportResource(); + importReqDetails.setName("twin"); + importReqDetails.setTags(Arrays.asList(importReqDetails.getName())); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, twinFileName); + importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + + importReqDetails.setRequirements(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map requirements = importReqDetails.getRequirements(); + Map twinRequirementsFromResponse = parseReqOrCapFromResponse("requirements", importReqDetails, expectedNumOfRequirements); + assertEquals(requirements.keySet().size(), twinRequirementsFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(requirements, twinRequirementsFromResponse); + + importReqDetails.setCapabilities(testResourcesPath, importReqDetails.getPayloadName(), sdncUserDetails, derivedFromName); + Map capabilities = importReqDetails.getCapabilities(); + Map twinCapabilitiesFromResponse = parseReqOrCapFromResponse("capabilities", importReqDetails, expectedNumOfCapabilities); + assertEquals(capabilities.keySet().size(), twinCapabilitiesFromResponse.keySet().size()); + importReqDetails.compareRequirementsOrCapabilities(capabilities, twinCapabilitiesFromResponse); + + assertEquals(childRequirementsFromResponse.keySet().size(), twinRequirementsFromResponse.keySet().size()); + assertEquals(childCapabilitiesFromResponse.keySet().size(), twinCapabilitiesFromResponse.keySet().size()); + } + + /* + * invariantUUID - US672129 + */ + + private void checkInvariantUuidIsImmutableInDifferentAction(ImportReqDetails importReqDetails) throws Exception { + // create resource + importReqDetails.setName("import"); + String invariantUuidDefinedByUser = "abcd1234"; + RestResponse importResourceResponse = importResourceWithRequestedInvariantUuid(importReqDetails, invariantUuidDefinedByUser); + String invariantUUIDcreation = ResponseParser.getInvariantUuid(importResourceResponse); + assertFalse(checkInvariantUuidEqual(invariantUuidDefinedByUser, importResourceResponse)); + + // get resource + RestResponse getResource = ResourceRestUtils.getResource(importReqDetails.getUniqueId()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, getResource)); + + // checkin resource + RestResponse changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // checkout resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKOUT); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // checkin resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // checkout resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKOUT); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // checkin resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // certification request + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // start certification + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // certify + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.CERTIFY); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + String certifiedUniqueId = importReqDetails.getUniqueId(); + + // update resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKOUT); + ResourceReqDetails updatedResourceReqDetails = new ResourceReqDetails(importReqDetails, importReqDetails.getVersion()); + updatedResourceReqDetails.setDescription("updatedDescription"); + updatedResourceReqDetails.setVendorRelease("1.2.3.4"); + RestResponse updateResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceReqDetails, sdncUserDetails, importReqDetails.getUniqueId()); + assertEquals(STATUS_CODE_SUCCESS, updateResponse.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, updateResponse)); + + // certification request + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // checkout resource + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKOUT); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // certification request + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // start certification + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // cancel certification + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.CANCELCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // start certification + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // failure + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, testerUser, LifeCycleStatesEnum.FAILCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // upload artifact + changeResourceState = LifecycleRestUtils.changeResourceState(importReqDetails, sdncUserDetails, LifeCycleStatesEnum.CHECKOUT); + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultArtifact(); + ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, sdncUserDetails, importReqDetails.getUniqueId()); + assertEquals(STATUS_CODE_SUCCESS, changeResourceState.getErrorCode().intValue()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, changeResourceState)); + + // create instance + resourceDetails.setResourceType(ResourceTypeEnum.VF.toString()); + ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + importReqDetails.setUniqueId(certifiedUniqueId); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getComponentResourceInstance(importReqDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncUserDetails, resourceDetails.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals(STATUS_CODE_CREATED, createResourceInstanceResponse.getErrorCode().intValue()); + getResource = ResourceRestUtils.getResource(importReqDetails.getUniqueId()); + assertTrue(checkInvariantUuidEqual(invariantUUIDcreation, getResource)); + } + + private boolean checkInvariantUuidEqual(String expectedInvariantUuid, RestResponse response) { + String invariantUUIDFromResponse = ResponseParser.getInvariantUuid(response); + return expectedInvariantUuid.equals(invariantUUIDFromResponse); + } + + @Test + public void checkCPHasImmutableInvariantUuidTest() throws Exception { + String filename = "FatherHasNoReqCap.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, filename); + checkResourceHasImmutableInvariantUuidTest(importReqDetails); + } + + @Test + public void checkVFCHasImmutableInvariantUuidTest() throws Exception { + String filename = "computeCap11.yml"; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, filename); + checkResourceHasImmutableInvariantUuidTest(importReqDetails); + } + + public void checkResourceHasImmutableInvariantUuidTest(ImportReqDetails importReqDetails) throws Exception { + // invariantUuid is null + importReqDetails.setName("first"); + RestResponse importResourceResponse = importResourceWithRequestedInvariantUuid(importReqDetails, null); + String invariantUUIDcreation = ResponseParser.getInvariantUuid(importResourceResponse); + assertNotNull(invariantUUIDcreation); + + ResourceRestUtils.deleteResource(importReqDetails.getUniqueId(), sdncUserDetails.getUserId()); + + // invariantUuid is empty + importReqDetails.setName("second"); + String invariantUuidDefinedByUser = ""; + importResourceResponse = importResourceWithRequestedInvariantUuid(importReqDetails, invariantUuidDefinedByUser); + invariantUUIDcreation = ResponseParser.getInvariantUuid(importResourceResponse); + assertNotNull(invariantUUIDcreation); + + ResourceRestUtils.deleteResource(importReqDetails.getUniqueId(), sdncUserDetails.getUserId()); + + checkInvariantUuidIsImmutableInDifferentAction(importReqDetails); + } + + private static RestResponse importResourceWithRequestedInvariantUuid(ImportReqDetails importDetails, String invariantUuid) throws Exception { + importDetails.setInvariantUUID(invariantUuid); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importDetails, sdncUserDetails, null); + assertEquals(STATUS_CODE_CREATED, importResourceResponse.getErrorCode().intValue()); + return importResourceResponse; + } + + private Map parseReqOrCapFromResponse(String parsedFieldName, ImportReqDetails importReqDetails, int expectedNumOfReqCap) throws ClientProtocolException, IOException { + RestResponse getResource = ResourceRestUtils.getResource(importReqDetails.getUniqueId()); + assertTrue(getResource.getErrorCode().equals(STATUS_CODE_SUCCESS)); + Map parsedFieldFromResponseToMap = ResponseParser.getJsonValueAsMap(getResource, parsedFieldName); + Iterator iterator = parsedFieldFromResponseToMap.keySet().iterator(); + actualNumOfReqOrCap = 0; + while (iterator.hasNext()) { + String next = iterator.next(); + List object = (List) parsedFieldFromResponseToMap.get(next); + actualNumOfReqOrCap += object.size(); + } + assertEquals(expectedNumOfReqCap, actualNumOfReqOrCap); + return parsedFieldFromResponseToMap; + } + + // --------------------------------- + + private void verifyResourcePropertiesList(Resource resourceJavaObject) { // use + // importListPropertySuccessFlow.yml + boolean isPropertyAppear = false; + List propertiesList = resourceJavaObject.getProperties(); + for (PropertyDefinition pro : propertiesList) { + switch (pro.getName()) { + case "my_boolean": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[false,true]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "my_boolean_array": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[true,false]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "duplicate_boolean_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[true,false,true]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_values_Insensitive": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[true,false,true]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "my_integers": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[0,1000,-1000,50]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "my_integers_array": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[10,-1000,0]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "duplicate_integers_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[10,10,-1000,0]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "my_string": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"asdc\",\"$?^@ecomp$!#%()_-~@+*^...;;/w#\",\"uc\"]")); + // assertTrue("Check Property default values ", + // pro.getDefaultValue().equals("[\"asdc\",\"@=~!@#$%^&*()_+=?><:-w\",\"uc\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "my_string_array": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"AAA\",\"~$~#bbb%^*_-\",\"qwe\",\"1.3\",\"500\",\"true\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "duplicate_string_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"asdc\",\"asdc\",\"uc\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_null_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"asdc\",\"uc\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_space_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"asdc\",\"uc\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_array_null_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[\"aaa\",\"bbb\",\"500\"]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "my_float": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[6,1000.000001,-3.0]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "my_float_array": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[0.01,-5.0,2.1]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "duplicate_float_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[0.0,0.0,4.555555]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_no_default_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "integer_no_default_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "string_no_default_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "boolean_no_default_values": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "integer_null_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[1000,2000]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "boolean_null_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[true,false]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "float_null_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[6,-3.0]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_space_value": + assertTrue("Check Property Type ", pro.getType().equals("list")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("[6,-3.0]")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + + } + assertTrue(isPropertyAppear); + isPropertyAppear = false; + } + + } + + private void verifyRequirementsOccurrences(Resource resourceJavaObject, String requirementsType) { + boolean isRequirementAppear = false; + // List requerments = + // resourceJavaObject.getRequirements().get("tosca.capabilities.Attachment"); + List requerments = resourceJavaObject.getRequirements().get(requirementsType); + + for (RequirementDefinition req : requerments) { + switch (req.getName()) { + case "local_storage100": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("1")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("UNBOUNDED")); + isRequirementAppear = true; + break; + case "local_storage200": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("1")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("1")); + isRequirementAppear = true; + break; + case "local_storage300": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("1")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("10")); + isRequirementAppear = true; + break; + case "local_storage400": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("1")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("10000000")); + isRequirementAppear = true; + break; + case "local_storage500": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("2")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("3")); + isRequirementAppear = true; + break; + case "local_storageNoOccurrences600": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals("1")); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals("1")); + isRequirementAppear = true; + break; + } + assertTrue(isRequirementAppear); + isRequirementAppear = false; + } + + } + + private void verifyCapabilitiesOccurrences(Resource resourceJavaObject, String capabilitType) { + boolean isCapabilityAppear = false; + // List capabilities = + // resourceJavaObject.getCapabilities().get("tosca.capabilities.Endpoint.Admin"); + List capabilities = resourceJavaObject.getCapabilities().get(capabilitType); + + for (CapabilityDefinition cap : capabilities) { + switch (cap.getName()) { + case "endpointNoOccurrence": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("UNBOUNDED")); + isCapabilityAppear = true; + break; + case "endpoint200": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("2")); + isCapabilityAppear = true; + break; + case "endpoint300": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("1")); + isCapabilityAppear = true; + break; + case "endpoint400": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("10")); + isCapabilityAppear = true; + break; + case "endpoint500": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("10000000")); + isCapabilityAppear = true; + break; + case "endpoint600": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("1")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("UNBOUNDED")); + isCapabilityAppear = true; + break; + case "endpoint700": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals("2")); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals("4")); + isCapabilityAppear = true; + break; + + } + assertTrue(isCapabilityAppear); + isCapabilityAppear = false; + } + + } + + private void verifyResourcePropertiesMap(Resource resourceJavaObject) { // use + // importMapPropertySuccessFlow.yml + boolean isPropertyAppear = false; + List propertiesList = resourceJavaObject.getProperties(); + for (PropertyDefinition pro : propertiesList) { + switch (pro.getName()) { + case "string_prop01": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"val1\",\"keyB\":\"val2\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop02": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"val1\",\"keyB\":\"val2\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop03": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"val1\",\"keyB\":\"val2\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop04": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"10\",\"keyB\":\"true\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop05": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":\"Big\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop06": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"aaaA\",\"keyB\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop07": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop08": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"\",\"keyB\":\"abcd\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop09": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\" \",\"keyB\":\"abcd\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop10": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\" aaaa\",\"keyB\":\" bbbb\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop11": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"aaaa \",\"keyB\":\"bbbb \"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop12": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\" aaaa \",\"keyB\":\" bbbb ccccc \"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop13": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"aaaa\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop14": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\" aaaa \"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop15": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"AbcD\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop16": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"AbcD\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop17": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"AbcD\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop18": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"AbcD\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop19": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"AbcD\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop20": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":\"aaaa\",\"keya\":\"aaaa\",\"Keya\":\"Aaaa\",\"KEYA\":\"nnnn\"}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop21": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "string_prop22": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("string")); + isPropertyAppear = true; + break; + case "integer_prop01": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":1,\"keyB\":1000}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop02": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop03": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":800,\"keyB\":-600}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop04": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":-600}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop05": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":100,\"keyB\":0}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop06": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":100,\"keyB\":0}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop07": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":100,\"keyB\":100}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop08": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":100,\"keyB\":200}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop09": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":100,\"keyB\":200}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop10": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":2222}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop11": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null,\"keyD\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop12": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "integer_prop13": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":200}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("integer")); + isPropertyAppear = true; + break; + case "boolean_prop01": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":true,\"keyB\":false,\"keyC\":false}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop02": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":true,\"keyB\":false,\"keyC\":false}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop03": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null,\"keyD\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop04": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null,\"keyD\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop05": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":true,\"keyB\":false,\"keyC\":false}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop06": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":true,\"keyB\":true,\"keyC\":false}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop07": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop08": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":true,\"keyB\":false}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "boolean_prop09": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":false,\"keyB\":true}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("boolean")); + isPropertyAppear = true; + break; + case "float_prop01": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":1.2,\"keyB\":3.56,\"keyC\":33}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop02": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":0.0,\"keyB\":0.0,\"keyC\":0}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop03": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null,\"keyD\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop04": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":1.2,\"keyB\":3.56,\"keyC\":33}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop05": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":33,\"keyB\":1.2,\"keyC\":3.607,\"keyD\":0}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop06": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":33,\"keyB\":1.2,\"keyC\":3.607}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop07": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":null,\"keyB\":null,\"keyC\":null,\"keyD\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop08": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertEquals("Check Property default values ", pro.getDefaultValue(), null); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop09": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":0.01,\"keyB\":null}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop10": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":0.00020}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + case "float_prop11": + assertTrue("Check Property Type ", pro.getType().equals("map")); + assertTrue("Check Property default values ", pro.getDefaultValue().equals("{\"keyA\":3.56,\"keyB\":33}")); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType().equals("float")); + isPropertyAppear = true; + break; + } + assertTrue(isPropertyAppear); + isPropertyAppear = false; + } + + } + + @Test + public void importToscaResourceAttributeSuccessFlow() throws Exception { + + String fileName = importAttributeSuccess; + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, sdncUserDetails, null); + ResourceRestUtils.checkCreateResponse(importResourceResponse); + Resource resourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + ToscaNodeTypeInfo parseToscaNodeYaml = utils.parseToscaNodeYaml(Decoder.decode(importReqDetails.getPayloadData())); + + HashMap attr = new HashMap<>(); + + AttributeDefinition newAttr2 = new AttributeDefinition(); + newAttr2.setName("networks"); + newAttr2.setType("map"); + newAttr2.setDefaultValue("{\"keyA\" : val1 , \"keyB\" : val2}"); + SchemaDefinition schema = new SchemaDefinition(); + PropertyDataDefinition prop = new PropertyDataDefinition(); + prop.setType("string"); + schema.setProperty(prop); + newAttr2.setSchema(schema); + attr.put("networks", newAttr2); + + AttributeDefinition newAttr1 = new AttributeDefinition(); + newAttr1.setName("public_address"); + newAttr1.setType("string"); + attr.put("public_address", newAttr1); + + AttributeDefinition newAttr3 = new AttributeDefinition(); + newAttr3.setName("ports"); + newAttr3.setDescription("this is my description"); + attr.put("ports", newAttr3); + + AttributeDefinition newAttr = new AttributeDefinition(); + newAttr.setDefaultValue("myDefault"); + newAttr.setName("private_address"); + newAttr.setStatus("supported"); + newAttr.setType("string"); + attr.put("private_address", newAttr); + + // verify Resource Attributes + validateResourceAttribute(resourceJavaObject, attr); + + // TO DO + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ElementFactory.getDefaultImportResourceAuditMsgSuccess(); + expectedResourceAuditJavaObject.setResourceName(importReqDetails.getName()); + expectedResourceAuditJavaObject.setModifierName(sdncUserDetails.getFullName()); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + expectedResourceAuditJavaObject.setToscaNodeType(parseToscaNodeYaml.getNodeName()); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, AuditingActionEnum.IMPORT_RESOURCE.getName(), null, false); + } + + private void validateResourceAttribute(Resource resource, Map attr) { + List resList = resource.getAttributes(); + int size = resList.size(); + String attributeName; + for (int i = 0; i < size; i++) { + attributeName = resList.get(i).getName(); + assertEquals(attr.get(attributeName).getDefaultValue(), resList.get(i).getDefaultValue()); + assertEquals(attr.get(attributeName).getName(), resList.get(i).getName()); + assertEquals(attr.get(attributeName).getDescription(), resList.get(i).getDescription()); + assertEquals(attr.get(attributeName).getStatus(), resList.get(i).getStatus()); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportUpdateResourseCsarTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportUpdateResourseCsarTest.java new file mode 100644 index 0000000000..9e8b94e5a8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/imports/ImportUpdateResourseCsarTest.java @@ -0,0 +1,282 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.imports; + +import static org.testng.AssertJUnit.assertTrue; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.regex.Pattern; + +import org.apache.commons.codec.binary.Base64; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ImportUpdateResourseCsarTest extends ComponentBaseTest { + @Rule + public static TestName name = new TestName(); + + Gson gson = new Gson(); + public static String userDefinedNodeYaml = "mycompute2.yml"; + public static String rootPath = System.getProperty("user.dir"); + public static String csarFolderPath = "/src/test/resources/CI/csars/"; + + public ImportUpdateResourseCsarTest() { + super(name, ImportUpdateResourseCsarTest.class.getName()); + } + + @Test + public void createUpdateImportResourceFromCsarTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + RestResponse updateResource = null; + RestResponse createResource = null; + Resource resource = null; + String payloadName = "orig2G.csar"; + String rootPath = System.getProperty("user.dir"); + Path path = Paths.get(rootPath + csarFolderPath + "orig2G.csar"); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("orig2G.csar"); + resourceDetails.setCsarVersion("1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + // create new resource from Csar + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + // update scar with new artifacts + path = Paths.get(rootPath + csarFolderPath + "orig2G_update.csar"); + data = Files.readAllBytes(path); + payloadData = Base64.encodeBase64String(data); + resourceDetails.setDescription("update"); + resourceDetails.setCsarVersion("2"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + } + + @Test + public void createUpdateImportResourceFromCsarWithArtifactsGroupNamingTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes; + ResourceReqDetails resourceDetails; + RestResponse updateResource; + RestResponse createResource; + Resource resource; + + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "VF_RI2_G4_withArtifacts_group_naming_a.csar", "VF_RI2_G4_withArtifacts_group_naming.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("VF_RI2_G4_withArtifacts_group_naming.csar"); + resourceDetails.setCsarVersion("1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + // create new resource from Csar + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + List groups = resource.getGroups(); + assertTrue(groups != null && groups.size() == 6); + assertTrue(groups.stream() + .filter(g -> g.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) + && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(g.getName()).matches()) + .count() == 0); + // update scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "VF_RI2_G4_withArtifacts_group_naming_delete_update.csar", "VF_RI2_G4_withArtifacts_group_naming.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + resourceDetails.setCsarVersion("2"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + groups = resource.getGroups(); + assertTrue(groups != null && groups.size() == 5); + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "VF_RI2_G4_withArtifacts_group_naming_a.csar", "VF_RI2_G4_withArtifacts_group_naming.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + resourceDetails.setCsarVersion("3"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + groups = resource.getGroups(); + assertTrue(groups != null && groups.size() == 6); + assertTrue(groups.stream() + .filter(g -> g.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) + && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(g.getName()).matches()) + .count() == 0); + } + + @Test + public void createUpdateDeleteAllRequiredArtifactsTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes; + ResourceReqDetails resourceDetails; + RestResponse updateResource; + RestResponse createResource; + Resource resource; + String artifactName = "heatnested7"; + + ImportReqDetails resourceDetails0 = ElementFactory.getDefaultImportResource(); + createResource = importUserDefinedNodeType(userDefinedNodeYaml, sdncModifierDetails, resourceDetails0); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, "orig2GV001_a.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("orig2GV001.csar"); + resourceDetails.setCsarVersion("1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + // create new resource from Csar + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertTrue(resource.getDeploymentArtifacts().get(artifactName).getRequiredArtifacts().size() == 2); + List groups = resource.getGroups(); + // update scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "orig2GV006-remove-all-nested-artifacts.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + resourceDetails.setCsarVersion("2"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertTrue(resource.getDeploymentArtifacts().get(artifactName).getRequiredArtifacts().size() == 0); + groups = resource.getGroups(); + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, "orig2GV001_a.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + // First create from orig2GV006-remove-all-nested-artifacts.csar (without + // requiredArtifact) + // Submit for testing + // Login as tester -> Certification + // Login as designer + // then update to orig2GV008-change-nested-oam-fileContent.csar (with + // requiredArtifact) + // Expected: requiredArtifact: ["hot-nimbus-psm_v1.0.yaml", + // "hot-nimbus-swift-container_v1.0.yaml"] + // Actual: no requiredArtifact + @Test + public void createUpdateAddRequiredArtifactsTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse copyRes; + ResourceReqDetails resourceDetails; + RestResponse updateResource; + RestResponse createResource; + Resource resource; + String artifactName = "heatnested7"; + + ImportReqDetails resourceDetails0 = ElementFactory.getDefaultImportResource(); + createResource = importUserDefinedNodeType(userDefinedNodeYaml, sdncModifierDetails, resourceDetails0); + BaseRestUtils.checkCreateResponse(createResource); + createResource = LifecycleRestUtils.certifyResource(resourceDetails0); + BaseRestUtils.checkSuccess(createResource); + + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "orig2GV006-remove-all-nested-artifacts.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + + resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("TEST01"); + resourceDetails.setCsarUUID("orig2GV001.csar"); + resourceDetails.setCsarVersion("1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + // create new resource from Csar + createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + createResource = LifecycleRestUtils.certifyResource(resourceDetails); + BaseRestUtils.checkSuccess(createResource); + + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + assertTrue(resource.getDeploymentArtifacts().get(artifactName).getRequiredArtifacts().size() == 0); + List groups = resource.getGroups(); + // update scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, + "orig2GV008-change-nested-oam-fileContent.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + resourceDetails.setDescription("BLA BLA BLA"); + resourceDetails.setCsarVersion("2"); + updateResource = ResourceRestUtils.updateResource(resourceDetails, sdncModifierDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(updateResource); + resource = ResponseParser.parseToObjectUsingMapper(updateResource.getResponse(), Resource.class); + assertTrue(resource.getDeploymentArtifacts().get(artifactName).getRequiredArtifacts().size() == 2); + groups = resource.getGroups(); + // back original scar + copyRes = ImportCsarResourceTest.copyCsarRest(sdncModifierDetails, "orig2GV001_a.csar", "orig2GV001.csar"); + BaseRestUtils.checkSuccess(copyRes); + } + + private RestResponse importUserDefinedNodeType(String payloadName, User sdncModifierDetails, + ImportReqDetails resourceDetails) throws Exception { + + Path path = Paths.get(rootPath + csarFolderPath + payloadName); + byte[] data = Files.readAllBytes(path); + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(ResourceTypeEnum.VFC.name()); + return ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/inputs/InputsApiTests.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/inputs/InputsApiTests.java new file mode 100644 index 0000000000..345b81eb3e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/inputs/InputsApiTests.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.inputs; + +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.InputsRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.BaseValidationUtils; +import org.testng.annotations.Test; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; + +/** + * CI-Tests for inputs + * @author il0695 + * + */ +public class InputsApiTests extends ComponentBaseTest { + + private static String inputCsar1 = "FCGI_with_inputs.csar"; + private static String inputCsar2 = "LDSA1_with_inputs.csar"; + private static User sdncDesignerDetails = null; + + @Rule + public static TestName name = new TestName(); + + /** + * Constructor + */ + public InputsApiTests() { + super(name, InputsApiTests.class.getName()); + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + } + + /** + * Create VF with inputs from CSAR file + * + * @throws Exception + */ + @Test + public void testCreateResourceInstanceWithInputsFromCsar() throws Exception { + Resource vf = AtomicOperationUtils.importResourceFromCSAR(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, inputCsar1); + assertTrue("Success creating VF from CSAR", !vf.getInputs().isEmpty()); + } + + /** + * Create service and add to it VF instance with inputs + * + * @throws Exception + */ + @Test + public void testAddVfInstanceWithInputsToService() throws Exception { + createServiceWithVFInstanceWithInputs(); + } + + /** + * General test to check most functionality of inputs + *
    + *
  • Create service with VF instance that has inputs)
  • + *
  • Get all inputs of VF instance
  • + *
  • Add inputs to service
  • + *
  • Get service inputs
  • + *
  • Delete service inputs
  • + *
+ * + * @throws Exception + */ + @Test + public void testInputsMainFunctionality() throws Exception { + Service service = createServiceWithVFInstanceWithInputs(); + int totalInputsBeforeAdd = service.getInputs().size(); + + // Get component instances + RestResponse getInstancesResponse = ComponentInstanceRestUtils.getComponentInstances(ComponentTypeEnum.SERVICE, service.getUniqueId(), sdncDesignerDetails); + BaseValidationUtils.checkSuccess(getInstancesResponse); + List serviceInstances = new Gson().fromJson(getInstancesResponse.getResponse(), new TypeToken>(){}.getType()); + + // Get all inputs of first instance + ComponentInstance vfInstance = serviceInstances.get(0); + RestResponse getComponentInstanceInputsResponse = InputsRestUtils.getComponentInstanceInputs(service, vfInstance); + BaseValidationUtils.checkSuccess(getComponentInstanceInputsResponse); + List instanceInputs = new Gson().fromJson(getComponentInstanceInputsResponse.getResponse(), new TypeToken>(){}.getType()); + + // Take only the 2 first inputs + List inputsToAdd = instanceInputs.stream().limit(2).collect(Collectors.toList()); + + // Build component instances input map to add to server + ComponentInstInputsMap buildComponentInstInputsMap = buildComponentInstInputsMap(vfInstance.getUniqueId(), inputsToAdd); + RestResponse addInputResponse = InputsRestUtils.addInput(service, buildComponentInstInputsMap, UserRoleEnum.DESIGNER); + BaseValidationUtils.checkSuccess(addInputResponse); + + // Get service inputs count + RestResponse getComponentInputsResponse = InputsRestUtils.getComponentInputs(service); + BaseValidationUtils.checkSuccess(getComponentInputsResponse); + List serviceInputsAfterAdd = new Gson().fromJson(getComponentInputsResponse.getResponse(), new TypeToken>(){}.getType()); + if (serviceInputsAfterAdd.size()-totalInputsBeforeAdd!=2) { + assertTrue("Error adding inputs to service (service should have 2 inputs)", false); + } + + // Delete 1 input from service + RestResponse deleteInputFromComponentResponse = InputsRestUtils.deleteInputFromComponent(service, serviceInputsAfterAdd.get(0).getUniqueId()); + BaseValidationUtils.checkSuccess(deleteInputFromComponentResponse); + + // Get service inputs count after delete + RestResponse getComponentInputsResponseAfterDelete = InputsRestUtils.getComponentInputs(service); + BaseValidationUtils.checkSuccess(getComponentInputsResponseAfterDelete); + List serviceInputsAfterDelete = new Gson().fromJson(getComponentInputsResponseAfterDelete.getResponse(), new TypeToken>(){}.getType()); + if (serviceInputsAfterDelete.size()-totalInputsBeforeAdd!=1) { + assertTrue("Error deleting inputs from service (service should have 1 input)", false); + } + + assertTrue("Success testing inputs main functionality", true); + } + + /** + * Private method to create service with VF instance that has inputs + * This is private method to be used by multiple tests + * + * @return {@link org.openecomp.sdc.be.model} + * @throws Exception + * @throws IOException + */ + private Service createServiceWithVFInstanceWithInputs() throws Exception, IOException { + // Create default service + Either createDefaultServiceEither = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true); + if (createDefaultServiceEither.isRight()){ + assertTrue("Error creating default service", false); + } + Service service = createDefaultServiceEither.left().value(); + + // Create VF from CSAR file + Resource vfWithInputs = AtomicOperationUtils.importResourceFromCSAR(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, inputCsar2); + + // Certify VF + Pair changeComponentState = AtomicOperationUtils.changeComponentState(vfWithInputs, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + assertTrue("response code is BaseRestUtils.STATUS_CODE_SUCCESS, returned :" + changeComponentState.getRight().getErrorCode(), changeComponentState.getRight().getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + // Add VF instance to service + Either addComponentInstanceToComponentContainerEither = AtomicOperationUtils.addComponentInstanceToComponentContainer(vfWithInputs, service, UserRoleEnum.DESIGNER, true); + if (addComponentInstanceToComponentContainerEither.isRight()){ + assertTrue("Error adding VF to service", false); + } + + // Get service response + ServiceReqDetails serviceDetails = new ServiceReqDetails(service); + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + + // Get VF instance from service + ComponentInstance vfInstance = service.getComponentInstances().get(0); + if (vfInstance!=null){ + assertTrue("Success creating service with VF instance", true); + } else { + assertTrue("Error creating service with VF instance", false); + } + return service; + } + + /** + * Return default ComponentInstInputsMap + * + * @param addToInput + * @param inputs + * @return {@link org.openecomp.sdc.be.model.ComponentInstInputsMap} + */ + private ComponentInstInputsMap buildComponentInstInputsMap (String addToInput, List inputs) { + Map> map = new HashMap<>(); + map.put(addToInput, inputs); + ComponentInstInputsMap componentInstInputsMap = new ComponentInstInputsMap(); + componentInstInputsMap.setComponentInstanceInputsMap(map); + return componentInstInputsMap; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/lifecycle/LCSbaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/lifecycle/LCSbaseTest.java new file mode 100644 index 0000000000..e15652dddf --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/lifecycle/LCSbaseTest.java @@ -0,0 +1,274 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.lifecycle; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; + +import org.apache.log4j.lf5.util.ResourceUtils; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.ArtifactUtils; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.annotations.BeforeMethod; + +/** + * + * @author al714h + * + * resourceDetails - create, Add Heat, certify resourceDetails1 - create + * resource, LCS - CheckOut serviceDetails - create, add RI from + * resourceDetails serviceDetails2 - create, add RI from resourceDetails + * serviceDetailsEmpty - create, LCS - CheckOut serviceDetailsEmpty2 - + * create, LCS - CheckOut + * + */ +public abstract class LCSbaseTest extends ComponentBaseTest { + + protected ResourceReqDetails resourceDetails; + protected ResourceReqDetails resourceDetails1; + protected ServiceReqDetails serviceDetails; + protected ServiceReqDetails serviceDetails2; + protected ServiceReqDetails serviceDetailsEmpty; + protected ServiceReqDetails serviceDetailsEmpty2; + protected ComponentInstanceReqDetails componentInstanceReqDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails2; + protected User sdncDesignerDetails1; + protected User sdncDesignerDetails2; + protected static User sdncTesterDeatails1; + protected User sdncAdminDetails1; + protected ArtifactReqDetails heatArtifactDetails; + protected ArtifactReqDetails heatVolArtifactDetails; + protected ArtifactReqDetails heatNetArtifactDetails; + + protected ArtifactReqDetails defaultArtifactDetails; + protected ResourceUtils resourceUtils; + protected ArtifactUtils artifactUtils; + + // protected static ServiceUtils serviceUtils = new ServiceUtils(); + public LCSbaseTest(TestName testName, String className) { + super(testName, className); + } + + @BeforeMethod + public void before() throws Exception { + + initializeMembers(); + + createComponents(); + + } + + public void initializeMembers() throws IOException, Exception { + resourceDetails = ElementFactory.getDefaultResource(); + // resourceDetails = + // ElementFactory.getDefaultResource("myNewResource1234567890", + // NormativeTypesEnum.ROOT, ResourceServiceCategoriesEnum.ROUTERS, + // UserRoleEnum.DESIGNER.getUserId()); + resourceDetails1 = ElementFactory.getDefaultResource("secondResource", NormativeTypesEnum.ROOT); + serviceDetails = ElementFactory.getDefaultService(); + serviceDetails2 = ElementFactory.getDefaultService("newTestService2", ServiceCategoriesEnum.MOBILITY, "al1976"); + serviceDetailsEmpty = ElementFactory.getDefaultService("newEmptyService", ServiceCategoriesEnum.MOBILITY, + "al1976"); + serviceDetailsEmpty2 = ElementFactory.getDefaultService("newEmptyService2", ServiceCategoriesEnum.MOBILITY, + "al1976"); + sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncDesignerDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncAdminDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + heatNetArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_NET.getType()); + heatVolArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT_VOL.getType()); + componentInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + resourceInstanceReqDetails2 = ElementFactory.getDefaultComponentInstance(); + + } + + protected void createComponents() throws Exception { + + RestResponse response = ResourceRestUtils.createResource(resourceDetails1, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetails1.getUniqueId()); + + response = ResourceRestUtils.createResource(resourceDetails, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetails.getUniqueId()); + + response = ServiceRestUtils.createService(serviceDetails, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetails.getUniqueId()); + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, + resourceDetails.getUniqueId()); + assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + // certified resource + response = LCSbaseTest.certifyResource(resourceDetails, sdncDesignerDetails1); + assertTrue("certify resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + // add resource instance with HEAT deployment artifact to the service + componentInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(componentInstanceReqDetails, sdncDesignerDetails1, + serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + assertTrue("response code is not 201, returned: " + response.getErrorCode(), response.getErrorCode() == 201); + + response = ServiceRestUtils.createService(serviceDetails2, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetails2.getUniqueId()); + + componentInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(componentInstanceReqDetails, sdncDesignerDetails1, + serviceDetails2.getUniqueId(), ComponentTypeEnum.SERVICE); + assertTrue("response code is not 201, returned: " + response.getErrorCode(), response.getErrorCode() == 201); + + response = ServiceRestUtils.createService(serviceDetailsEmpty, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetailsEmpty.getUniqueId()); + + response = ServiceRestUtils.createService(serviceDetailsEmpty2, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetailsEmpty2.getUniqueId()); + + DbUtils.cleanAllAudits(); + + } + + public static RestResponse certifyResource(ResourceReqDetails resourceDetails, User user) throws Exception { + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user.getUserId(), + LifeCycleStatesEnum.CHECKIN); + // if (restResponseResource.getErrorCode() == 200){ + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + // }else + // return restResponseResource; + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + if (restResponseResource.getErrorCode() == 200) { + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, + sdncTesterDeatails1.getUserId(), LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponseResource; + if (restResponseResource.getErrorCode() == 200) { + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, + sdncTesterDeatails1.getUserId(), LifeCycleStatesEnum.CERTIFY); + } + return restResponseResource; + } + + public static RestResponse certifyService(ServiceReqDetails serviceDetails, User user) throws Exception { + RestResponse restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, user, + LifeCycleStatesEnum.CHECKIN); + // if (restResponseService.getErrorCode() == 200){ + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, user, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + // }else + // return restResponseService; + + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + if (restResponseService.getErrorCode() == 200) { + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDeatails1, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponseService; + if (restResponseService.getErrorCode() == 200) { + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDeatails1, + LifeCycleStatesEnum.CERTIFY); + } + return restResponseService; + } + + protected static RestResponse raiseResourceToTargetVersion(ResourceReqDetails resourceDetails, String targetVersion, + User user) throws Exception { + return raiseResourceToTargetVersion(resourceDetails, targetVersion, null, user); + } + + protected static RestResponse raiseResourceToTargetVersion(ResourceReqDetails resourceDetails, String targetVersion, + RestResponse prevResponse, User user) throws Exception { + + String[] splitParts = targetVersion.split("\\."); + + int version = Integer.parseInt(splitParts[1]); + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + + if (prevResponse != null) { + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(prevResponse.getResponse()); + if (resourceRespJavaObject.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, + user.getUserId(), LifeCycleStatesEnum.CHECKOUT); + } + } + + RestResponse restResponseResource = null; + for (int i = 0; i < (version - 1); i++) { + + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user, null, + LifeCycleStatesEnum.CHECKIN, checkinComentJson); + if (restResponseResource.getErrorCode() == 200) { + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user.getUserId(), + LifeCycleStatesEnum.CHECKOUT); + if (restResponseResource.getErrorCode() == 200) { + + } else + break; + + } else + break; + + } + + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user, null, + LifeCycleStatesEnum.CHECKIN, checkinComentJson); + assertEquals("Check response code ", 200, restResponseResource.getErrorCode().intValue()); + return restResponseResource; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ChangeServiceInstanceVersionTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ChangeServiceInstanceVersionTest.java new file mode 100644 index 0000000000..6a4fa3ba55 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ChangeServiceInstanceVersionTest.java @@ -0,0 +1,1478 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_MISSING_INFORMATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_NOT_FOUND; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS_DELETE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_UNSUPPORTED_ERROR; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ChangeServiceInstanceVersionTest extends ComponentInstanceBaseTest { + + protected ArtifactReqDetails heatArtifactDetails; + public String firstVfInstanceUniqueId; + public String firstVfInstanceName; + public String secondVfInstanceUniqueId; + public String secoundVfInstanceName; + public String serviceInstanceToReplaceUniqueId; + public String expectedServiceName; + public String expectedPosX; + public String expectedPosY; + public String actualServiceInstanceName; + public String actualPosX; + public String actualPosY; + + @Rule + public static TestName name = new TestName(); + + public ChangeServiceInstanceVersionTest() { + super(name, ChangeServiceInstanceVersionTest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + firstVfInstanceName = null; + secoundVfInstanceName = null; + firstVfInstanceUniqueId = null; + secondVfInstanceUniqueId = null; + serviceInstanceToReplaceUniqueId = null; + expectedServiceName = null; + expectedPosX = null; + expectedPosY = null; + actualServiceInstanceName = null; + actualPosX = null; + actualPosY = null; + init(); + createComponents(); + } + + private void createComponents() throws Exception { + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + createAtomicResource(resourceDetailsVFC_01); + changeResourceStateToCertified(resourceDetailsVFC_01); + createAtomicResource(resourceDetailsCP_01); + changeResourceStateToCertified(resourceDetailsCP_01); + createAtomicResource(resourceDetailsVL_01); + changeResourceStateToCertified(resourceDetailsVL_01); + createAtomicResource(resourceDetailsVFC_02); + changeResourceStateToCertified(resourceDetailsVFC_02); + createAtomicResource(resourceDetailsCP_02); + changeResourceStateToCertified(resourceDetailsCP_02); + createAtomicResource(resourceDetailsVL_02); + changeResourceStateToCertified(resourceDetailsVL_02); + createVF(resourceDetailsVF_02); + createVF(resourceDetailsVF_01); + // create check-In services + createService(serviceDetails_01); + createService(serviceDetails_02); + createService(serviceDetails_03); + createProduct(productDetails_01); + createProduct(productDetails_02); + + // add resourceDetailsCP_01 ,resourceDetailsVFC_01 and + // resourceDetailsCP_01 to resourceDetailsVF_01 and certify + // resourceDetailsVF_01 + certifyVf(resourceDetailsVF_01, resourceDetailsVFC_02, resourceDetailsCP_01); + // add resourceDetailsCP_02 ,resourceDetailsVFC_02 and + // resourceDetailsVL_02 to resourceDetailsVF_02 and certify + // resourceDetailsVF_02 + certifyVf(resourceDetailsVF_02, resourceDetailsVFC_02, resourceDetailsCP_02); + RestResponse createVFInstanceResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); // serviceDetails_01 has certified + // resourceDetailsVF_01 + firstVfInstanceName = ResponseParser.getNameFromResponse(createVFInstanceResponse); + createVFInstanceResponse = createVFInstanceDuringSetup(serviceDetails_02, resourceDetailsVF_02, + sdncDesignerDetails); // serviceDetails_01 has certified + // resourceDetailsVF_02 + secoundVfInstanceName = ResponseParser.getUniqueIdFromResponse(createVFInstanceResponse); + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + } + + @Test + public void changeServiceInstanceVersionByPm() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + @Test + public void changeServiceInstanceVersionByAdmin() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // service [0.2] state to CERTIFICATIONREQUEST + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ResourceRestUtils.checkSuccess(changeStatusResponse); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncAdminDetails, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncAdminDetails, ComponentTypeEnum.PRODUCT, + true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncAdminDetails, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + @Test + public void changeServiceInstanceToOlderVersion() throws Exception { + // Get VF Instance UniquId [Service version 0.1] + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + ComponentInstance actualComponentInstance = service.getComponentInstances().get(0); + firstVfInstanceUniqueId = actualComponentInstance.getUniqueId(); + String serviceOlderVersionUniquId = ResponseParser.getUniqueIdFromResponse(getServiceResponse); + + // Checkout service [0.2] + RestResponse changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, + sdncDesignerDetails, LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // Adding service instance (serviceDetails_01 V0.2) to product without + // saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to Older version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceOlderVersionUniquId, sdncPmDetails1, ComponentTypeEnum.PRODUCT, + true); + // RestResponse changeServiceInstanceVersionResponse = + // changeServiceInstanceVersion(productDetails_01.getUniqueId(), + // serviceInstanceToReplaceUniqueId , serviceNewUniqueUid, + // sdncPmDetails1, ComponentTypeEnum.PRODUCT , true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + // DE190201 + @Test + public void changeServiceInstanceVersionToCertifiedVersion() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + /* + * String serviceNewUniqueUid = + * ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + * serviceDetails_01.setUniqueId(serviceNewUniqueUid); + */ + // get the new VF instance uniqueId after checkout service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ResourceRestUtils.checkSuccess(changeStatusResponse); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ResourceRestUtils.checkSuccess(changeStatusResponse); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + // RestResponse changeServiceInstanceVersionResponse = + // changeServiceInstanceVersion(productDetails_01.getUniqueId(), + // serviceInstanceToReplaceUniqueId , serviceNewUniqueUid, + // sdncPmDetails1, ComponentTypeEnum.PRODUCT , true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + // DE191927 + @Test(enabled = false) + public void changeServiceInstanceVersionThenReCheckInProduct() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + ///////////////////// + productOldUniqueId = productDetails_01.getUniqueId(); + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + ///////////////////////////////////////////// + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + @Test + public void changeServiceInstanceToHisVersion() throws Exception { + // Get VF Instance UniquId [Service version 0.1] + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + String serviceOlderVersionUniquId = ResponseParser.getUniqueIdFromResponse(getServiceResponse); + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceOlderVersionUniquId, sdncPmDetails1, ComponentTypeEnum.PRODUCT, + true); + // RestResponse changeServiceInstanceVersionResponse = + // changeServiceInstanceVersion(productDetails_01.getUniqueId(), + // serviceInstanceToReplaceUniqueId , serviceNewUniqueUid, + // sdncPmDetails1, ComponentTypeEnum.PRODUCT , true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + @Test + public void changeServiceInstanceVersionByAdminNotByProductOwner() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncAdminDetails, ComponentTypeEnum.PRODUCT, + true); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + + } + + @Test + public void changeServiceInstanceVersionByPmNotByProductOwner() throws Exception { + // Adding service instance (serviceDetails_01) to product AND ---> + // saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // change uniqueId after product check-out in expected Req&Cap + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + updateNewComponentInstanceId(createServiceInstanceResp, productNewUniqueId); + // CHANGE Service Instance VERSION BY NON PRODUCT OWNER (sdncPmDetails1 + // instead sdncPmDetails1) + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion( + productDetails_01.getUniqueId(), serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails2, + ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceVersionByTester() throws Exception { + // Adding service instance (serviceDetails_01) to product AND ---> + // saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceToReplaceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // change uniqueId after product check-out in expected Req&Cap + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // CHANGE Service Instance VERSION BY NON PRODUCT OWNER (sdncPmDetails1 + // instead sdncPmDetails1) + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion( + productDetails_01.getUniqueId(), serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, + sdncTesterDetails, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceVersionProductIsNotCheckOut() throws Exception { + // Adding service instance (serviceDetails_01) to product AND ---> + // saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceToReplaceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // CHANGE Service Instance VERSION for Non checkedOut product + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productOldUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + // DE191727 + @Test(enabled = false) + public void changeServiceInstanceVersionServiceIsInCheckOutState() throws Exception { + // Adding service instance (serviceDetails_01) to product AND ---> + // saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceToReplaceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // change uniqueId after product check-out in expected Req&Cap + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // CHANGE Service Instance VERSION to service in checkOut state + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion( + productDetails_01.getUniqueId(), serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, + ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(serviceNewUniqueUid); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + + } + + @Test + public void changeServiceInstanceVersionServiceInstanceDoesNotExist() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // change service instance to newer version + String serviceUniqueUidNotExist = "1234567890"; + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceUniqueUidNotExist, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(serviceUniqueUidNotExist); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + // DE189392 + @Test(enabled = false) + public void changeServiceInstanceNonExistingProduct() throws Exception { + // Adding service instance (serviceDetails_01) to product saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // change service instance to newer version - Non existing Product + String productNewUniqueIdNotExist = "1234567890"; + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueIdNotExist, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(productNewUniqueIdNotExist); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceVersionToNonExisitingServiceVersion() throws Exception { + // Adding service instance (serviceDetails_01) to product saving Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + updateNewComponentInstanceId(createServiceInstanceResp, productNewUniqueId); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // change service instance to Non-existing version + String serviceUniqueUidNotExist = "1234567890"; + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceUniqueUidNotExist, sdncPmDetails1, ComponentTypeEnum.PRODUCT, + true); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(serviceUniqueUidNotExist); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceComponentTypeIsNotProduct() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version for NON-Component Type = + // Product (e.g. service) + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.SERVICE, true); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceComponentTypeNotSupported() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version for NON-Component Type = + // Product (e.g. service) + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, + ComponentTypeEnum.SERVICE_INSTANCE, true); + assertEquals("Check response code ", STATUS_CODE_UNSUPPORTED_ERROR, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("null"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.UNSUPPORTED_ERROR.name(), varibales, + changeServiceInstanceVersionResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void SeveralServiceInstanceFromSameServiceVersionChangeVersionOnlyForOneServiceInstance() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstanceDuringSetup(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + serviceDetails_01.setUniqueId(serviceNewUniqueUid); + // get the new VF instance uniqueId after checkout service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01.getUniqueId(), sdncPmDetails1); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + List serviceComponentInstances = service.getComponentInstances(); + for (ComponentInstance component : serviceComponentInstances) { + if (component.getName().equals(firstVfInstanceName)) { + firstVfInstanceUniqueId = component.getUniqueId(); + } + } + assertTrue(firstVfInstanceUniqueId != null); + // delete resource instance (resourceDetailsVF_01) from Service + RestResponse deleteVfFromServiceResponse = deleteVFInstanceDuringSetup(firstVfInstanceUniqueId, + serviceDetails_01, sdncDesignerDetails); + assertTrue(deleteVfFromServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Add different VF instance (resourceDetailsVF_02) to Service + RestResponse restResponse = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(restResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get service instance new uniqueId , name and position after checkout + // product + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, sdncPmDetails1, ComponentTypeEnum.PRODUCT, true); + ProductRestUtils.checkSuccess(changeServiceInstanceVersionResponse); + actualServiceInstanceName = ResponseParser.getNameFromResponse(changeServiceInstanceVersionResponse); + actualPosX = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posX"); + actualPosY = ResponseParser.getValueFromJsonResponse(changeServiceInstanceVersionResponse.getResponse(), + "posY"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(changeServiceInstanceVersionResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Verify that Service instance name and position didn't change after + // changing service instance version + assertTrue(actualServiceInstanceName.equals(expectedServiceName)); + assertTrue(actualPosX.equals(expectedPosX)); + assertTrue(actualPosY.equals(expectedPosY)); + } + + @Test + public void changeServiceInstanceVersionByNonAsdcUser() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + nonAsdcUser.setUserId("bt760h"); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, nonAsdcUser, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void changeServiceInstanceVersionEmptyUserId() throws Exception { + // Adding service instance (serviceDetails_01) to product without saving + // Req&Cap + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Adding service instance (serviceDetails_02) to product AND ---> Save + // Req&Cap + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // check-in product + RestResponse changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productOldUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Checkout service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeStatusResponse); + String serviceNewUniqueUid = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + // Check-In service [0.2] + changeStatusResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeStatusResponse); + // check-out product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeStatusResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(changeStatusResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + nonAsdcUser.setUserId(""); + // change service instance to newer version + RestResponse changeServiceInstanceVersionResponse = changeServiceInstanceVersion(productNewUniqueId, + serviceInstanceToReplaceUniqueId, serviceNewUniqueUid, nonAsdcUser, ComponentTypeEnum.PRODUCT, true); + assertEquals("Check response code ", STATUS_CODE_MISSING_INFORMATION, + changeServiceInstanceVersionResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), + changeServiceInstanceVersionResponse.getResponse()); + // Check-in product + changeStatusResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeStatusResponse); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + //////////////////////////////////// + private void updateNewComponentInstanceId(RestResponse createServiceInstanceResp, String productNewUniqueId) + throws Exception { + String firstServiceInstanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "normalizedName"); + RestResponse getProductResponse = ProductRestUtils.getProduct(productNewUniqueId, sdncPmDetails1.getUserId()); + Product product = ResponseParser.parseToObjectUsingMapper(getProductResponse.getResponse(), Product.class); + List componentInstances = product.getComponentInstances(); + for (ComponentInstance component : componentInstances) { + if (component.getNormalizedName().equals(firstServiceInstanceNormalizedName)) { + serviceInstanceToReplaceUniqueId = component.getUniqueId(); + expectedServiceName = component.getName(); + expectedPosX = component.getPosX(); + expectedPosY = component.getPosY(); + } + } + assertTrue(serviceInstanceToReplaceUniqueId != null); + } + + private RestResponse changeResourceStateToCertified(ResourceReqDetails resourceDetails) throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponse; + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponse.getErrorCode() == 200) { + String newVersion = ResponseParser.getVersionFromResponse(restResponse); + resourceDetails.setVersion(newVersion); + resourceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + resourceDetails.setLastUpdaterUserId(sdncTesterDetails.getUserId()); + resourceDetails.setLastUpdaterFullName(sdncTesterDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getValueFromJsonResponse(restResponse.getResponse(), + "uniqueId"); + resourceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponse; + } + + private void certifyVf(ResourceReqDetails resource, ResourceReqDetails computeResource, + ResourceReqDetails cpResource) throws Exception { + RestResponse createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, cpResource, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, computeResource, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, + sdncDesignerDetails, resource.getUniqueId()); + ResourceRestUtils.checkSuccess(response); + + String capOwnerId = toCompInstId; + User user = sdncDesignerDetails; + ComponentTypeEnum containerCompType = ComponentTypeEnum.RESOURCE; + + fulfillCpRequirement(resource, fromCompInstId, toCompInstId, capOwnerId, user, containerCompType); + + RestResponse changeResourceStateToCertified = changeResourceStateToCertified(resource); + ResourceRestUtils.checkSuccess(changeResourceStateToCertified); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductBaseTest.java new file mode 100644 index 0000000000..7891f4a46b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductBaseTest.java @@ -0,0 +1,195 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.PRODUCT_COMPONENT_TYPE; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.BeforeMethod; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +public abstract class ProductBaseTest extends ComponentBaseTest { + User productStrategistUser1; + User productStrategistUser2; + User productStrategistUser3; + User productManager1; + User productManager2; + User adminUser; + User designerUser; + + // Category1->Subcategory1->Grouping1 + protected List defaultCategories; + + protected static String auditAction; + protected static ComponentOperationEnum operation; + + public ProductBaseTest(TestName testName, String className) { + super(testName, className); + } + + @BeforeMethod + public void beforeProductTest() throws IOException, Exception { + productStrategistUser1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + productStrategistUser2 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST2); + productStrategistUser3 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST3); + productManager1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + productManager2 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER2); + adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + createDefaultChain(); + } + + private void createDefaultChain() throws Exception { + CategoryDefinition productCategoryDefinition = ElementFactory.getDefaultCategory(); + SubCategoryDefinition productSubCategoryDefinition = ElementFactory.getDefaultSubCategory(); + GroupingDefinition productGroupingDefinition = ElementFactory.getDefaultGroup(); + productCategoryDefinition.addSubCategory(productSubCategoryDefinition); + productSubCategoryDefinition.addGrouping(productGroupingDefinition); + List definitionsList = new ArrayList<>(); + definitionsList.add(productCategoryDefinition); + defaultCategories = createCategoriesChain(definitionsList); + } + + private List createCategoriesChain(List categoryDefinitions) throws Exception { + for (CategoryDefinition categoryDefinition : categoryDefinitions) { + RestResponse createCategory = CategoryRestUtils.createCategory(categoryDefinition, productStrategistUser1, PRODUCT_COMPONENT_TYPE); + int status = createCategory.getErrorCode().intValue(); + if (status == BaseRestUtils.STATUS_CODE_CREATED) { + String categoryId = ResponseParser.getUniqueIdFromResponse(createCategory); + categoryDefinition.setUniqueId(categoryId); + } + List subcategories = categoryDefinition.getSubcategories(); + for (SubCategoryDefinition subCategoryDefinition : subcategories) { + RestResponse createSubCategory = CategoryRestUtils.createSubCategory(subCategoryDefinition, categoryDefinition, productStrategistUser1, PRODUCT_COMPONENT_TYPE); + status = createSubCategory.getErrorCode().intValue(); + if (status == BaseRestUtils.STATUS_CODE_CREATED) { + String subCategoryId = ResponseParser.getUniqueIdFromResponse(createSubCategory); + subCategoryDefinition.setUniqueId(subCategoryId); + } + List groupings = subCategoryDefinition.getGroupings(); + for (GroupingDefinition groupingDefinition : groupings) { + RestResponse createGroupingRest = CategoryRestUtils.createGrouping(groupingDefinition, subCategoryDefinition, categoryDefinition, productStrategistUser1, PRODUCT_COMPONENT_TYPE); + status = createGroupingRest.getErrorCode().intValue(); + if (status == BaseRestUtils.STATUS_CODE_CREATED) { + String groupingId = ResponseParser.getUniqueIdFromResponse(createGroupingRest); + groupingDefinition.setUniqueId(groupingId); + } + } + } + } + RestResponse allCategories = CategoryRestUtils.getAllCategories(productStrategistUser1, PRODUCT_COMPONENT_TYPE); + Gson gson = new Gson(); + List res = gson.fromJson(allCategories.getResponse(), new TypeToken>() { + }.getType()); + return res; + } + + // Category1->Subcategory1->[Grouping1, Grouping11] + protected List addSecondGroupingToDefaultCategory() throws Exception { + GroupingDefinition productGroupingDefinition = ElementFactory.getDefaultGroup(); + productGroupingDefinition.setName("Grouping11"); + defaultCategories.get(0).getSubcategories().get(0).addGrouping(productGroupingDefinition); + return createCategoriesChain(defaultCategories); + } + + // Category1->[Subcategory1->[Grouping1, + // Grouping11],Subcategory2->[Grouping12]] + protected List addSubcategoryAndGroupingToDefaultCategory() throws Exception { + GroupingDefinition groupingDefinition1 = ElementFactory.getDefaultGroup(); + groupingDefinition1.setName("Grouping11"); + defaultCategories.get(0).getSubcategories().get(0).addGrouping(groupingDefinition1); + + SubCategoryDefinition subCategory2 = ElementFactory.getDefaultSubCategory(); + subCategory2.setName("Subcategory2"); + GroupingDefinition groupingDefinition2 = ElementFactory.getDefaultGroup(); + groupingDefinition2.setName("Grouping12"); + subCategory2.addGrouping(groupingDefinition2); + defaultCategories.get(0).addSubCategory(subCategory2); + return createCategoriesChain(defaultCategories); + } + + // [Category1->[Subcategory1->[Grouping1, + // Grouping11],Subcategory2->[Grouping12]], + // Category2->[Subcategory1->[Grouping1],Subcategory2->[Grouping1]], + // Category3->[Subcategory1->[Grouping11],Subcategory2->[Grouping11, + // Grouping22]]] + protected List addManyGroupingsDiffCategories() throws Exception { + CategoryDefinition category2 = ElementFactory.getDefaultCategory(); + category2.setName("Category2"); + CategoryDefinition category3 = ElementFactory.getDefaultCategory(); + category3.setName("Category3"); + SubCategoryDefinition subCategory1 = ElementFactory.getDefaultSubCategory(); + subCategory1.setName("Subcategory1"); + SubCategoryDefinition subCategory2 = ElementFactory.getDefaultSubCategory(); + subCategory2.setName("Subcategory2"); + SubCategoryDefinition subCategory1_2 = ElementFactory.getDefaultSubCategory(); + subCategory1_2.setName("Subcategory1"); + SubCategoryDefinition subCategory2_2 = ElementFactory.getDefaultSubCategory(); + subCategory2_2.setName("Subcategory2"); + SubCategoryDefinition subCategory1_3 = ElementFactory.getDefaultSubCategory(); + subCategory1_3.setName("Subcategory1"); + SubCategoryDefinition subCategory2_3 = ElementFactory.getDefaultSubCategory(); + subCategory2_3.setName("Subcategory2"); + + GroupingDefinition groupingDefinition1 = ElementFactory.getDefaultGroup(); + groupingDefinition1.setName("Grouping1"); + GroupingDefinition groupingDefinition11 = ElementFactory.getDefaultGroup(); + groupingDefinition11.setName("Grouping11"); + GroupingDefinition groupingDefinition12 = ElementFactory.getDefaultGroup(); + groupingDefinition12.setName("Grouping12"); + GroupingDefinition groupingDefinition22 = ElementFactory.getDefaultGroup(); + groupingDefinition22.setName("Grouping22"); + + defaultCategories.get(0).getSubcategories().get(0).addGrouping(groupingDefinition11); + subCategory2.addGrouping(groupingDefinition12); + defaultCategories.get(0).addSubCategory(subCategory2); + + defaultCategories.add(category2); + defaultCategories.add(category3); + category2.addSubCategory(subCategory1_2); + category2.addSubCategory(subCategory2_2); + subCategory1_2.addGrouping(groupingDefinition1); + subCategory2_2.addGrouping(groupingDefinition1); + category3.addSubCategory(subCategory1_3); + category3.addSubCategory(subCategory2_3); + subCategory1_3.addGrouping(groupingDefinition11); + subCategory2_3.addGrouping(groupingDefinition11); + subCategory2_3.addGrouping(groupingDefinition22); + return createCategoriesChain(defaultCategories); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckinTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckinTest.java new file mode 100644 index 0000000000..1820315841 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckinTest.java @@ -0,0 +1,199 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.enums.AuditJsonKeysEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ProductCheckinTest extends ProductLifecycleTest { + + @Rule + public static TestName name = new TestName(); + + public ProductCheckinTest() { + super(name, ProductCheckinTest.class.getName()); + } + + @BeforeClass + public static void staticInit() { + auditAction = CHECKIN_ACTION; + operation = ComponentOperationEnum.CHANGE_STATE_CHECKIN; + } + + @Test + public void checkInProductByCreator() throws Exception { + + String checkinComment = "good checkin"; + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN, checkinComment); + assertEquals("Check response code after checkin resource", 200, checkInResponse.getErrorCode().intValue()); + Product checkedInProduct = ResponseParser.parseToObjectUsingMapper(checkInResponse.getResponse(), + Product.class); + + expectedProduct.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, checkedInProduct, operation); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(checkedInProduct, + auditAction, productManager1, ActionStatus.OK, "0.1", "0.1", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, checkedInProduct.getUUID()); + expectedProductAudit.setCOMMENT(checkinComment); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction, AuditJsonKeysEnum.COMMENT); + } + + @Test + public void checkInProductByPM() throws Exception { + + String checkinComment = "good checkin"; + RestResponse response = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN, checkinComment); + assertEquals("Check response code after checkin resource", 200, response.getErrorCode().intValue()); + + User checkoutUser = productManager2; + response = LifecycleRestUtils.changeProductState(expectedProduct, checkoutUser, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkin resource", 200, response.getErrorCode().intValue()); + expectedProduct = ResponseParser.parseToObjectUsingMapper(response.getResponse(), Product.class); + + DbUtils.cleanAllAudits(); + checkinComment = "good checkin no 2"; + response = LifecycleRestUtils.changeProductState(expectedProduct, checkoutUser, LifeCycleStatesEnum.CHECKIN, + checkinComment); + assertEquals("Check response code after checkin resource", 200, response.getErrorCode().intValue()); + + Product checkedInProduct = ResponseParser.parseToObjectUsingMapper(response.getResponse(), Product.class); + + expectedProduct.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + expectedProduct.setVersion("0.2"); + expectedProduct.setLastUpdaterUserId(checkoutUser.getUserId()); + expectedProduct.setLastUpdaterFullName(checkoutUser.getFullName()); + + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, checkedInProduct, operation); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(checkedInProduct, + auditAction, checkoutUser, ActionStatus.OK, "0.2", "0.2", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, checkedInProduct.getUUID()); + expectedProductAudit.setCOMMENT(checkinComment); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction, AuditJsonKeysEnum.COMMENT); + } + + @Test + public void checkInProductByAdmin() throws Exception { + + String checkinComment = "good checkin"; + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, adminUser, + LifeCycleStatesEnum.CHECKIN, checkinComment); + assertEquals("Check response code after checkin resource", 200, checkInResponse.getErrorCode().intValue()); + Product checkedInProduct = ResponseParser.parseToObjectUsingMapper(checkInResponse.getResponse(), + Product.class); + + expectedProduct.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + expectedProduct.setLastUpdaterUserId(adminUser.getUserId()); + expectedProduct.setLastUpdaterFullName(adminUser.getFullName()); + + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, checkedInProduct, operation); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(checkedInProduct, + auditAction, adminUser, ActionStatus.OK, "0.1", "0.1", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, checkedInProduct.getUUID()); + expectedProductAudit.setCOMMENT(checkinComment); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction, AuditJsonKeysEnum.COMMENT); + } + + @Test + public void checkInProductByPMNotOwner() throws Exception { + + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager2, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 403, checkInResponse.getErrorCode().intValue()); + String[] auditParameters = new String[] { expectedProduct.getName(), "product", productManager1.getFirstName(), + productManager1.getLastName(), productManager1.getUserId() }; + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productManager2, ActionStatus.COMPONENT_CHECKOUT_BY_ANOTHER_USER, "0.1", "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + expectedProduct.getUUID(), auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + @Test + public void checkInProductByPsRoleNotAllowed() throws Exception { + + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productStrategistUser1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 409, checkInResponse.getErrorCode().intValue()); + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productStrategistUser1, ActionStatus.RESTRICTED_OPERATION, "0.1", "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + expectedProduct.getUUID()); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + @Test + public void checkInProductNotExist() throws Exception { + String notExisitingUuid = "1234"; + expectedProduct.setUniqueId(notExisitingUuid); + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 404, checkInResponse.getErrorCode().intValue()); + String[] auditParameters = new String[] { "", "product" }; + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productManager1, ActionStatus.PRODUCT_NOT_FOUND, Constants.EMPTY_STRING, + Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, auditParameters); + expectedProductAudit.setCURR_STATE(Constants.EMPTY_STRING); + expectedProductAudit.setRESOURCE_NAME(notExisitingUuid); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + @Test + public void checkInProductAlreadyCheckedIn() throws Exception { + RestResponse checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 200, checkInResponse.getErrorCode().intValue()); + DbUtils.cleanAllAudits(); + checkInResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager2, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 409, checkInResponse.getErrorCode().intValue()); + String[] auditParameters = new String[] { expectedProduct.getName(), "product", productManager1.getFirstName(), + productManager1.getLastName(), productManager1.getUserId() }; + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productManager2, ActionStatus.COMPONENT_ALREADY_CHECKED_IN, "0.1", "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + expectedProduct.getUUID(), auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckoutTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckoutTest.java new file mode 100644 index 0000000000..ec1f7ad38d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCheckoutTest.java @@ -0,0 +1,146 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.FileNotFoundException; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ProductCheckoutTest extends ProductLifecycleTest { + + @Rule + public static TestName name = new TestName(); + + @BeforeClass + public static void staticInit() { + auditAction = CHECKOUT_ACTION; + operation = ComponentOperationEnum.CHANGE_STATE_CHECKOUT; + } + + public ProductCheckoutTest() { + super(name, ProductCheckoutTest.class.getName()); + } + + @Test + public void checkOutProductByPmNotInContacts() throws Exception { + checkOutProductSuccess(productManager2); + } + + @Test + public void checkOutProductByPmInContacts() throws Exception { + checkOutProductSuccess(productManager1); + } + + @Test + public void checkOutProductByAdmin() throws Exception { + checkOutProductSuccess(adminUser); + } + + @Test + public void checkOutProductByPs() throws Exception { + // Changed in 1604 patch - now it's restricted + checkOutProductRestricted(productStrategistUser3); + // checkOutProductSuccess(productStrategistUser3); + } + + @Test + public void checkOutProductByDesignerRoleNotAllowed() throws Exception { + checkOutProductRestricted(designerUser); + } + + @Test + public void checkOutProductAlreadyCheckedOut() throws Exception { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkin resource", 200, lcsResponse.getErrorCode().intValue()); + Product checkedOutProduct = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + DbUtils.cleanAllAudits(); + + lcsResponse = LifecycleRestUtils.changeProductState(checkedOutProduct, productManager2, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkin resource", 403, lcsResponse.getErrorCode().intValue()); + String[] auditParameters = new String[] { checkedOutProduct.getName(), "product", productManager1.getFirstName(), productManager1.getLastName(), productManager1.getUserId() }; + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(checkedOutProduct, auditAction, productManager2, ActionStatus.COMPONENT_IN_CHECKOUT_STATE, "0.2", "0.2", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, checkedOutProduct.getUUID(), auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + private void checkOutProductSuccess(User checkoutUser) throws Exception, FileNotFoundException { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, checkoutUser, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkin resource", 200, lcsResponse.getErrorCode().intValue()); + + // 0.1 is not highest now + RestResponse prevVersionProductResp = ProductRestUtils.getProduct(expectedProduct.getUniqueId(), productStrategistUser1.getUserId()); + Product prevVersionProduct = ResponseParser.parseToObjectUsingMapper(prevVersionProductResp.getResponse(), Product.class); + Boolean falseParam = false; + assertEquals(falseParam, prevVersionProduct.isHighestVersion()); + + Product checkedOutProduct = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + expectedProduct.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + expectedProduct.setVersion("0.2"); + expectedProduct.setLastUpdaterUserId(checkoutUser.getUserId()); + expectedProduct.setLastUpdaterFullName(checkoutUser.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, checkedOutProduct, operation); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(checkedOutProduct, auditAction, checkoutUser, ActionStatus.OK, "0.1", "0.2", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, checkedOutProduct.getUUID()); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + private void checkOutProductRestricted(User checkoutUser) throws Exception, FileNotFoundException { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin resource", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, checkoutUser, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkin resource", 409, lcsResponse.getErrorCode().intValue()); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, auditAction, checkoutUser, ActionStatus.RESTRICTED_OPERATION, "0.1", "0.1", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, expectedProduct.getUUID()); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductComponentInstanceCRUDTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductComponentInstanceCRUDTest.java new file mode 100644 index 0000000000..ec3d9b75a5 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductComponentInstanceCRUDTest.java @@ -0,0 +1,1437 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_ALREADY_EXISTS; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_MISSING_INFORMATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_NOT_FOUND; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS_DELETE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_UNSUPPORTED_ERROR; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ProductComponentInstanceCRUDTest extends ComponentInstanceBaseTest { + + protected ArtifactReqDetails heatArtifactDetails; + @Rule + public static TestName name = new TestName(); + + public ProductComponentInstanceCRUDTest() { + super(name, ProductComponentInstanceCRUDTest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + init(); + createComponents(); + } + + private void createComponents() throws Exception { + + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + createAtomicResource(resourceDetailsVFC_01); + changeResourceStateToCertified(resourceDetailsVFC_01); + createAtomicResource(resourceDetailsCP_01); + changeResourceStateToCertified(resourceDetailsCP_01); + createAtomicResource(resourceDetailsVL_01); + changeResourceStateToCertified(resourceDetailsVL_01); + createAtomicResource(resourceDetailsVFC_02); + changeResourceStateToCertified(resourceDetailsVFC_02); + createAtomicResource(resourceDetailsCP_02); + changeResourceStateToCertified(resourceDetailsCP_02); + createAtomicResource(resourceDetailsVL_02); + changeResourceStateToCertified(resourceDetailsVL_02); + createVF(resourceDetailsVF_02); + createVF(resourceDetailsVF_01); + // create check-In services + createService(serviceDetails_01); + createService(serviceDetails_02); + createService(serviceDetails_03); + createProduct(productDetails_01); + createProduct(productDetails_02); + + // addresourceDetailsCP_02 ,resourceDetailsVFC_02 and + // resourceDetailsVL_02 to resourceDetailsVF_02 check-in VF + RestResponse createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resourceDetailsVF_02, + resourceDetailsVFC_02, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resourceDetailsVF_02, resourceDetailsCP_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resourceDetailsVF_02, resourceDetailsVL_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + resourceDetailsVF_02.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + // addresourceDetailsCP_01 ,resourceDetailsVFC_01 and + // resourceDetailsVL_01 to resourceDetailsVF_01 and certify + // resourceDetailsVF_01 + certifyVf(resourceDetailsVF_01); + createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); // serviceDetails_01 + // has + // certified + // VF + createVFInstanceDuringSetup(serviceDetails_02, resourceDetailsVF_02, sdncDesignerDetails); // serviceDetails_02 + // has + // check-in + // VF + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + } + + // pass + @Test + public void createServiceInstanceTest() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + // DE189427 + @Test(enabled = false) + public void createServiceInstanceFromCheckedOutState() throws Exception { + // can't create instance of checked-out component + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceInToAnotherServiceInstance() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String uniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance(serviceInstanceReqDetails, + sdncPmDetails1, uniqueIdFromResponse, ComponentTypeEnum.PRODUCT); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_NOT_FOUND); + } + + @Test + public void createSeveralServiceInstanceFromSameServices() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void createSeveralServiceInstanceFromDifferentServices() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void createCertifiedServiceInstance() throws Exception { + changeServiceStateToCertified(serviceDetails_01); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceByPm() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceWithoutVf() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails_03, sdncAdminDetails, "0.1", LifeCycleStatesEnum.CHECKIN); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_02, serviceDetails_03, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_02, 1, 0); + } + + @Test + public void createServiceInstanceByNonProductOwner() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails2); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceByNonAsdcUser() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + User nonExistingSdncUser = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + ; + nonExistingSdncUser.setUserId("bt1234"); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, nonExistingSdncUser); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceToNotCheckOutProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + // pass + @Test + public void createServiceInstanceNameIsEmpty() throws Exception { + String expectedServiceInstanceName = serviceDetails_01.getName() + " 1"; + String expectedServiceInstancenormalizedName = serviceDetails_01.getName() + "1"; + serviceDetails_01.setName(""); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), + "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "name"); + assertEquals("check Resource Instance normalizedName ", (expectedServiceInstancenormalizedName).toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance Name ", expectedServiceInstanceName, instanceName); + getComponentAndValidateRIs(productDetails_01, 1, 0); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(expectedServiceInstanceName, actualComponentInstance.getName()); + assertEquals((expectedServiceInstancenormalizedName).toLowerCase(), + actualComponentInstance.getNormalizedName()); + } + + // pass + @Test + public void createServiceInstanceNameIsNull() throws Exception { + String expectedServiceInstanceName = serviceDetails_01.getName() + " 1"; + String expectedServiceInstancenormalizedName = serviceDetails_01.getName() + "1"; + serviceDetails_01.setName(null); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), + "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "name"); + assertEquals("check Resource Instance normalizedName ", (expectedServiceInstancenormalizedName).toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance Name ", expectedServiceInstanceName, instanceName); + getComponentAndValidateRIs(productDetails_01, 1, 0); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(expectedServiceInstanceName, actualComponentInstance.getName()); + assertEquals((expectedServiceInstancenormalizedName).toLowerCase(), + actualComponentInstance.getNormalizedName()); + } + + @Test(enabled = false) + public void createServiceInstanceToNonExistingProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance(serviceInstanceReqDetails, + sdncPmDetails1, "blabla", ComponentTypeEnum.PRODUCT); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + createServiceInstanceResp.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("blabla"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PRODUCT_NOT_FOUND.name(), varibales, + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceToNonSupportedComponentType() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance(serviceInstanceReqDetails, + sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.RESOURCE_INSTANCE); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_UNSUPPORTED_ERROR); + ArrayList varibales = new ArrayList(); + varibales.add("null"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.UNSUPPORTED_ERROR.name(), varibales, + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + // pass + @Test + public void createServiceInstancePositionIsEmpty() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + serviceInstanceReqDetails.setPosX(""); + serviceInstanceReqDetails.setPosY(""); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createServiceInstanceResp.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstancePositionIsNull() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + serviceInstanceReqDetails.setPosX(null); + serviceInstanceReqDetails.setPosY(null); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createServiceInstanceResp.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.PRODUCT); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceByDesigner() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncDesignerDetails); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void createServiceInstanceUserIdIsEmpty() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + User nonSdncDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + nonSdncDetails.setUserId(""); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, nonSdncDetails); + assertTrue(createServiceInstanceResp.getErrorCode() == STATUS_CODE_MISSING_INFORMATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), + createServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + //// Update Service instance + + @Test + public void updateServiceInstanceNameByPm() throws Exception { + // Check-in Product by PM and Check-out by PM + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + // Create service instance by PM + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "abcD"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (newName).toLowerCase(), instanceNormalizedName); + assertEquals("check Resource Instance Name ", newName, instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(newName, actualComponentInstance.getName()); + assertEquals((newName).toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + @Test + public void updateServiceInstanceNewNameAndLocation() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "updaatedName100"; + serviceInstanceReqDetails.setPosX("100"); + serviceInstanceReqDetails.setPosY("100"); + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(serviceInstanceReqDetails.getPosX(), actualComponentInstance.getPosX()); + assertEquals(serviceInstanceReqDetails.getPosY(), actualComponentInstance.getPosY()); + assertEquals(newName, actualComponentInstance.getName()); + assertEquals(newName.toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + @Test(enabled = false) + public void updateServiceInstanceNameRemoveSpacesFromBiginningAndEnd() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = " Abcd "; + String expectedNewName = " Abcd "; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (expectedNewName).toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance Name ", expectedNewName, instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(expectedNewName, actualComponentInstance.getName()); + assertEquals((expectedNewName).toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + // pass + @Test + public void updateServiceInstanceNameAllowedCharacters() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "qwer-TYUIOP_asd_0987654321.Abcd"; + String ExpectedNormalizName = "qwertyuiopasd0987654321abcd"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", ExpectedNormalizName, instanceNormalizedName); + assertEquals("check Resource Instance Name ", newName, instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(newName, actualComponentInstance.getName()); + assertEquals(ExpectedNormalizName, actualComponentInstance.getNormalizedName()); + + } + + @Test + public void updateInstanceNameInvalidCharacters() throws Exception { + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "Abcd1"; + String updateName; + for (int i = 0; i < invalidChars.length; i++) { + updateName = newName + invalidChars[i]; + serviceInstanceReqDetails.setName(updateName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), + ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", STATUS_CODE_INVALID_CONTENT, + updateServiceInstanceResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("Service Instance"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPONENT_NAME.name(), varibales, + updateServiceInstanceResponse.getResponse()); + } + } + + // pass + @Test + public void updateInstanceNameMaxLength() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "Qwertyuiop1234567890asdfAhjklzxcvbnmasdfghjkl12345"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (newName).toLowerCase(), instanceNormalizedName); + assertEquals("check Resource Instance Name ", newName, instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(newName, actualComponentInstance.getName()); + assertEquals((newName).toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + @Test + public void updateInstanceNameExceedMaxLength() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String expectedName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), "name"); + String expectedNormalizedName = ResponseParser.getValueFromJsonResponse(createServiceInstanceResp.getResponse(), + "normalizedName"); + String newName = "Qwertyuiop1234567890asdfAhjklzxcvbnmasdfghjkl123456"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT, + updateServiceInstanceResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("Service Instance"); + varibales.add("50"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT.name(), varibales, + updateServiceInstanceResponse.getResponse()); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(expectedName, actualComponentInstance.getName()); + assertEquals(expectedNormalizedName, actualComponentInstance.getNormalizedName()); + } + + @Test + public void updateServiceInstanceNameEmpty() throws Exception { + // see US534663 In case a PS/PM removes the current service instance + // name then BE has to generate again the "default" service instance + // name + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = ""; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (serviceDetails_01.getName() + "2").toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance normalizedName ", (serviceDetails_01.getName() + " 2"), instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(instanceName, actualComponentInstance.getName()); + assertEquals(instanceNormalizedName, actualComponentInstance.getNormalizedName()); + } + + // pass + @Test + public void updateServiceInstanceNameNull() throws Exception { + // see US534663 In case a PS/PM removes the current service instance + // name then BE has to generate again the "default" service instance + // name + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = null; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (serviceDetails_01.getName() + "2").toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance normalizedName ", (serviceDetails_01.getName() + " 2"), instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(instanceName, actualComponentInstance.getName()); + assertEquals(instanceNormalizedName, actualComponentInstance.getNormalizedName()); + } + + @Test + public void updateServiceInstanceCheckedByOtherUser() throws Exception { + // see US534663 In case a PS/PM removes the current service instance + // name then BE has to generate again the "default" service instance + // name + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "blabla"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails2, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + updateServiceInstanceResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updateServiceInstanceResponse.getResponse()); + } + + @Test + public void updateServiceInstance_UserIdIsNonAsdcUser() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "blabla"; + serviceInstanceReqDetails.setName(newName); + User nonSdncUserDetails = new User(); + nonSdncUserDetails.setUserId("bt4567"); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, nonSdncUserDetails, productDetails_01.getUniqueId(), + ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + updateServiceInstanceResponse.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updateServiceInstanceResponse.getResponse()); + } + + @Test + public void updateServiceInstanceNameToAlreadyExisting() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String ServiceName1 = ResponseParser.getNameFromResponse(createServiceInstanceResp); + createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance(serviceInstanceReqDetails, + sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // Update service instance2 name to service instance1 + serviceInstanceReqDetails.setName(ServiceName1); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", STATUS_CODE_ALREADY_EXISTS, + updateServiceInstanceResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("Service Instance"); + varibales.add(ServiceName1); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name(), varibales, + updateServiceInstanceResponse.getResponse()); + } + + @Test + public void updateServiceInstanceForNonExistingProduct() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "blabla"; + serviceInstanceReqDetails.setName(newName); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, "blablabla", ComponentTypeEnum.PRODUCT); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + updateServiceInstanceResponse.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PRODUCT_NOT_FOUND.name(), varibales, + updateServiceInstanceResponse.getResponse()); + + } + + @Test + public void updateNonExistingServiceInstance() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String newName = "blabla"; + serviceInstanceReqDetails.setName(newName); + serviceInstanceReqDetails.setUniqueId("11111111"); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ArrayList varibales = new ArrayList(); + varibales.add(newName); + varibales.add("service instance"); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + updateServiceInstanceResponse.getErrorCode().intValue()); + // need to change ActionStatus.RESOURCE_INSTANCE_NOT_FOUND.name() to + // ActionStatus.SERVICE_INSTANCE_NOT_FOUND.name() + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND.name(), varibales, + updateServiceInstanceResponse.getResponse()); + } + + @Test + public void updateServiceInstanceLocation() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + serviceInstanceReqDetails.setPosX("50"); + serviceInstanceReqDetails.setPosY("100"); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(serviceInstanceReqDetails.getPosX(), actualComponentInstance.getPosX()); + assertEquals(serviceInstanceReqDetails.getPosY(), actualComponentInstance.getPosY()); + } + + @Test + public void updateServiceInstanceToNonExistingLocation() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + String nameFromResponse = ResponseParser.getNameFromResponse(createServiceInstanceResp); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + serviceInstanceReqDetails.setPosX("-50"); + serviceInstanceReqDetails.setPosY("-100"); + serviceInstanceReqDetails.setName(nameFromResponse); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(serviceInstanceReqDetails.getPosX(), actualComponentInstance.getPosX()); + assertEquals(serviceInstanceReqDetails.getPosY(), actualComponentInstance.getPosY()); + assertEquals(nameFromResponse, actualComponentInstance.getName()); + } + + @Test + public void updateServiceInstanceLocationNameIsEmpty() throws Exception { + String expectedServiceInstanceName = serviceDetails_01.getName() + " 2"; + String expectedServiceInstancenormalizedName = serviceDetails_01.getName() + "2"; + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + serviceInstanceReqDetails.setPosX("100"); + serviceInstanceReqDetails.setPosY("200"); + serviceInstanceReqDetails.setName(""); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String nameFromResponse = ResponseParser.getNameFromResponse(updateServiceInstanceResponse); + String postX = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "posX"); + String postY = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "posY"); + assertEquals(nameFromResponse, expectedServiceInstanceName); + assertEquals(postX, "100"); + assertEquals(postY, "200"); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(serviceInstanceReqDetails.getPosX(), actualComponentInstance.getPosX()); + assertEquals(serviceInstanceReqDetails.getPosY(), actualComponentInstance.getPosY()); + assertEquals(nameFromResponse, actualComponentInstance.getName()); + assertEquals(expectedServiceInstancenormalizedName.toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + // pass + @Test + public void updateServiceInstanceNameToProductName() throws Exception { + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_01); + RestResponse createServiceInstanceResp = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // ComponentInstance componentInstance = + // ResponseParser.parseToObjectUsingMapper(createServiceInstanceResp.getResponse(), + // ComponentInstance.class); + // addCompInstReqCapToExpected(componentInstance, + // ComponentTypeEnum.PRODUCT); + serviceInstanceReqDetails.setName(productDetails_01.getName()); + RestResponse updateServiceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ResourceRestUtils.checkSuccess(updateServiceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateServiceInstanceResponse.getResponse(), + "name"); + assertEquals("check Resource Instance normalizedName ", (serviceInstanceReqDetails.getName()).toLowerCase(), + instanceNormalizedName); + assertEquals("check Resource Instance Name ", serviceInstanceReqDetails.getName(), instanceName); + // get product and verify that service instanceName is correct + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + assertEquals(serviceInstanceReqDetails.getName(), actualComponentInstance.getName()); + assertEquals((serviceInstanceReqDetails.getName()).toLowerCase(), actualComponentInstance.getNormalizedName()); + } + + //// Delete Service Instance + + @Test + public void deleteAllServiceInstanceFromProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 0, 0); + } + + @Test + public void deleteServiceWhileServiceInstanceExistInProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + // Delete service while service instance of it exist in product + RestResponse deleteServiceResponse = ServiceRestUtils.deleteServiceById(serviceDetails_01.getUniqueId(), + sdncDesignerDetails.getUserId()); + assertTrue(deleteServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + // Get product and verify that service instance still exists + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + // ComponentInstance actualComponentInstance = + // actualProduct.getComponentInstances().get(0); + // assertTrue(serviceInstanceUniqueIdFromResponse == + // actualComponentInstance.getUniqueId()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + // pass + @Test + public void deleteServiceInstanceByPm() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void deleteServiceInstanceByPmCreatedByPm() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + productDetails_01.setUniqueId(ResponseParser.getUniqueIdFromResponse(restResponse)); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void deleteServiceInstanceByPmWhichIsCheckedOutByAnotherPm() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails2); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + // DE190189 + @Test + public void deleteServiceInstanceByPmCreatedByPs() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + String productOldUniqueId = productDetails_01.getUniqueId(); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(restResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get product and get service instance new uniquId + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPmDetails1.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + String serviceInstanceUniqueId = actualComponentInstance.getUniqueId(); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 0, 0); + } + + // DE190189 + @Test + public void deleteServiceInstanceByAdminCreatedByPs() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + String productOldUniqueId = productDetails_01.getUniqueId(); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncAdminDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + String productNewUniqueId = ResponseParser.getUniqueIdFromResponse(restResponse); + updateExpectedReqCapAfterChangeLifecycleState(productOldUniqueId, productNewUniqueId); + // get product and get service instance new uniquId + RestResponse getActualProductResponse = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncAdminDetails.getUserId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getActualProductResponse.getResponse(), + Product.class); + ComponentInstance actualComponentInstance = actualProduct.getComponentInstances().get(0); + String serviceInstanceUniqueId = actualComponentInstance.getUniqueId(); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncAdminDetails); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 0, 0); + } + + @Test + public void createAndDeleteServiceInstanceByAdmin() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncAdminDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + // productDetails_01.setUniqueId(ResponseParser.getUniqueIdFromResponse(restResponse)); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncAdminDetails); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncAdminDetails); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncAdminDetails); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void deleteServiceInstanceFromNonCheckOutProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + RestResponse restResponse = LifecycleRestUtils.changeProductState(productDetails_01, sdncPmDetails1, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void deleteServiceInstanceByDesigner() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncDesignerDetails); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceByTester() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncTesterDetails); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceByPsWhichIsCheckedOutByAnotherPs() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPsDetails2); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + // pass + @Test + public void deleteServiceInstanceByNonAsdcUser() throws Exception { + User nonExistingSdncUser = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + ; + nonExistingSdncUser.setUserId("bt1234"); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + nonExistingSdncUser); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceFromNonExistingProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncPmDetails1, + "1234567890", serviceInstanceUniqueId, ComponentTypeEnum.PRODUCT); + assertTrue(deleteResourceInstanceResponse.getErrorCode() == STATUS_CODE_NOT_FOUND); + ArrayList varibales = new ArrayList(); + varibales.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PRODUCT_NOT_FOUND.name(), varibales, + deleteResourceInstanceResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteNonExistingServiceInstanceFromProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + // String serviceInstanceUniqueId = + // ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncPmDetails1, + productDetails_01.getUniqueId(), "1234567890123456unExistingServiceInstance", + ComponentTypeEnum.PRODUCT); + assertTrue(deleteResourceInstanceResponse.getErrorCode() == STATUS_CODE_NOT_FOUND); + ArrayList varibales = new ArrayList(); + varibales.add("1234567890123456unExistingServiceInstance"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PRODUCT_NOT_FOUND.name(), varibales, + deleteResourceInstanceResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceFromNonSupportedComponentType() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncPmDetails1, + productDetails_01.getUniqueId(), serviceInstanceUniqueId, ComponentTypeEnum.RESOURCE_INSTANCE); + assertTrue(deleteResourceInstanceResponse.getErrorCode() == STATUS_CODE_UNSUPPORTED_ERROR); + ArrayList varibales = new ArrayList(); + varibales.add("null"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.UNSUPPORTED_ERROR.name(), varibales, + deleteResourceInstanceResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceComponentTypeIsNotProduct() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncPmDetails1, + productDetails_01.getUniqueId(), serviceInstanceUniqueId, ComponentTypeEnum.SERVICE); + assertTrue(deleteResourceInstanceResponse.getErrorCode() == STATUS_CODE_NOT_FOUND); + ArrayList varibales = new ArrayList(); + varibales.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), varibales, + deleteResourceInstanceResponse.getResponse()); + getComponentAndValidateRIs(productDetails_01, 2, 0); + } + + @Test + public void deleteServiceInstanceUserIdIsEmpty() throws Exception { + User nonSdncDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + nonSdncDetails.setUserId(""); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + nonSdncDetails); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_MISSING_INFORMATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), + deleteServiceInstanceResp.getResponse()); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + @Test + public void deleteCertifiedServiceInstance() throws Exception { + changeServiceStateToCertified(serviceDetails_01); + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + RestResponse deleteServiceInstanceResp = deleteServiceInstance(serviceInstanceUniqueId, productDetails_01, + sdncPmDetails1); + assertTrue(deleteServiceInstanceResp.getErrorCode() == STATUS_CODE_SUCCESS_DELETE); + getComponentAndValidateRIs(productDetails_01, 1, 0); + } + + //////////////////////////////////// + + private void certifyVf(ResourceReqDetails resource) throws Exception { + RestResponse createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String cpCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVFC_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String computeCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVL_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String vlCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + // Fixing Vl/Cp req/cap + ComponentTypeEnum containerCompType = ComponentTypeEnum.RESOURCE; + User user = sdncDesignerDetails; + fulfillCpRequirement(resource, cpCompInstId, computeCompInstId, computeCompInstId, user, containerCompType); + consumeVlCapability(resource, cpCompInstId, vlCompInstId, cpCompInstId, user, containerCompType); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, + sdncDesignerDetails, resource.getUniqueId()); + ResourceRestUtils.checkSuccess(response); + RestResponse changeResourceStateToCertified = changeResourceStateToCertified(resource); + ResourceRestUtils.checkSuccess(changeResourceStateToCertified); + } + + private RestResponse changeResourceStateToCertified(ResourceReqDetails resourceDetails) throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponse; + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponse.getErrorCode() == 200) { + String newVersion = ResponseParser.getVersionFromResponse(restResponse); + resourceDetails.setVersion(newVersion); + resourceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + resourceDetails.setLastUpdaterUserId(sdncTesterDetails.getUserId()); + resourceDetails.setLastUpdaterFullName(sdncTesterDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getValueFromJsonResponse(restResponse.getResponse(), + "uniqueId"); + resourceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponse; + } + + private RestResponse changeServiceStateToCertified(ServiceReqDetails serviceDetails) throws Exception { + /* + * RestResponse restResponse = + * LifecycleRestUtils.changeServiceState(serviceDetails, + * sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + * ResourceRestUtils.checkSuccess(restResponse); + */ + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponse; + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponse.getErrorCode() == 200) { + serviceDetails.setVersion("1.0"); + serviceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + serviceDetails.setLastUpdaterUserId(sdncTesterDetails.getUserId()); + serviceDetails.setLastUpdaterFullName(sdncTesterDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getValueFromJsonResponse(restResponse.getResponse(), + "uniqueId"); + serviceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponse; + } + + @Test + public void deleteServiceInstanceTest() throws Exception { + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + String compInstId = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + + createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_02, sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 2, 0); + String compInstId2 = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + + RestResponse deleteServiceInstanceResp = deleteServiceInstance(compInstId, productDetails_01, sdncPmDetails1); + ResourceRestUtils.checkDeleteResponse(deleteServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 1, 0); + + deleteServiceInstanceResp = deleteServiceInstance(compInstId2, productDetails_01, sdncPmDetails1); + ResourceRestUtils.checkDeleteResponse(deleteServiceInstanceResp); + getComponentAndValidateRIs(productDetails_01, 0, 0); + } + + @Test + public void returnedServiceInstanceTypeAttributeTest() throws Exception { + String expectedServiceType = ComponentTypeEnum.SERVICE.getValue().toUpperCase(); + + RestResponse createServiceInstanceResp = createServiceInstance(productDetails_01, serviceDetails_01, + sdncPmDetails1); + ResourceRestUtils.checkCreateResponse(createServiceInstanceResp); + String serviceUniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(createServiceInstanceResp); + ComponentInstanceRestUtils.checkComponentInstanceType(createServiceInstanceResp, expectedServiceType); + + RestResponse getProductResp = ProductRestUtils.getProduct(productDetails_01.getUniqueId(), + sdncPsDetails1.getUserId()); + ProductRestUtils.checkSuccess(getProductResp); + Product productObject = ResponseParser.parseToObjectUsingMapper(getProductResp.getResponse(), Product.class); + List productComponentInstances = productObject.getComponentInstances(); + for (ComponentInstance comp : productComponentInstances) { + String actualOriginType = comp.getOriginType().getValue().toUpperCase(); + assertTrue(expectedServiceType.equals(actualOriginType)); + } + + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails_02); + serviceInstanceReqDetails.setUniqueId(serviceUniqueIdFromResponse); + serviceInstanceReqDetails.setComponentUid(serviceDetails_01.getUniqueId()); + RestResponse updateResourceInstance = ComponentInstanceRestUtils.updateComponentInstance( + serviceInstanceReqDetails, sdncPmDetails1, productDetails_01.getUniqueId(), ComponentTypeEnum.PRODUCT); + ComponentInstanceRestUtils.checkSuccess(updateResourceInstance); + ComponentInstanceRestUtils.checkComponentInstanceType(updateResourceInstance, expectedServiceType); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCreateWithValidationsTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCreateWithValidationsTest.java new file mode 100644 index 0000000000..d2c2dfe77f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCreateWithValidationsTest.java @@ -0,0 +1,1710 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.Arrays; + +import org.json.JSONArray; +import org.json.JSONException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.Test; + +public class ProductCreateWithValidationsTest extends ProductBaseTest { + @Rule + public static TestName name = new TestName(); + + public static String INITIAL_PRODUCT_VERSION = "0.1"; + public static String CREATE_AUDIT_ACTION = "Create"; + public String normalizedName; + + public ProductCreateWithValidationsTest() { + super(name, ProductCreateWithValidationsTest.class.getName()); + } + + @Test + public void createProductSuccessValidation() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNotByPmUser() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productStrategistUser1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, + productStrategistUser1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productStrategistUser1, ActionStatus.RESTRICTED_OPERATION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNotByAsdcUser() throws Exception { + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + nonAsdcUser.setUserId("bt750k"); + nonAsdcUser.setFirstName(null); + nonAsdcUser.setLastName(null); + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, nonAsdcUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, + nonAsdcUser); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, nonAsdcUser, ActionStatus.RESTRICTED_OPERATION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductUserIdIsEmpty() throws Exception { + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + nonAsdcUser.setUserId(""); + nonAsdcUser.setFirstName(null); + nonAsdcUser.setLastName(null); + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, nonAsdcUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_MISSING_INFORMATION, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, + nonAsdcUser); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, nonAsdcUser, ActionStatus.MISSING_INFORMATION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationLessThanMinCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Pro"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING, "Product", "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationMaxLength() throws Exception { + // Max length = 25 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Qwertyuiop1234567890asdfA"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationExceedMaxLength() throws Exception { + // Max length = 25 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Qwertyuiop1234567890asdfAa"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING, "Product", "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationEmptyName() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName(""); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", + "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameAlreadyExist() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + // productReqDetails.setName("ProDuct1"); + DbUtils.deleteFromEsDbByPattern("_all"); + createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_ALREADY_EXISTS, + createProduct.getErrorCode().intValue()); + productReqDetails.setVersion("0.1"); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_NAME_ALREADY_EXIST, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", + productReqDetails.getName()); + constructFieldsForAuditValidation.setCURR_VERSION("0.1"); + constructFieldsForAuditValidation.setCURR_STATE(""); + constructFieldsForAuditValidation.setCURR_STATE("NOT_CERTIFIED_CHECKOUT"); + constructFieldsForAuditValidation.setSERVICE_INSTANCE_ID(null); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationNameIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", + "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + // DE193857 + @Test(enabled = false) + public void createProductNameValidationAllowedCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Ac_2@3:4& m=n+b-u.j-u'g#b"); // Bug @:&=+'# + normalizedName = "ac234mnbujugb"; + String expectedProductName = "Ac_2@3:4& M=n+b-u.j-u'g#b"; + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + productReqDetails.setName(expectedProductName); + productReqDetails.setName("Ac_2@3:4& M=n+b-u.j-u'g#b"); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setNormalizedName(normalizedName); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + // DE193857 + @Test(enabled = false) + public void createProductNameValidationREmoveExtraNonAlphanumericChars() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Ac____222----333......asd"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setName("Ac_222-333.asd"); + normalizedName = "ac222333asd"; + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationNotAllowedCharacters() throws Exception { + ExpectedProductAudit constructFieldsForAuditValidation; + char invalidChars[] = { '~', '!', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', '|', + '\\', ',', '$' }; + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("abc" + invalidChars[i]); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", + productManager1); + constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, + CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", + "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + } + + @Test + public void createProductFullNameContainSpecialCharacters() throws Exception { + char invalidChars[] = { '~', '!', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', '|', + '\\', ',', '$' }; + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + for (int i = 0; i < invalidChars.length; i++) { + DbUtils.deleteFromEsDbByPattern("_all"); + productReqDetails.setFullName("abc" + invalidChars[i]); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_CREATED, + createProduct.getErrorCode().intValue()); + RestResponse deleteProduct = ProductRestUtils.deleteProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, + deleteProduct.getErrorCode().intValue()); + } + } + + @Test(enabled = false) + public void createProductNameValidationRemoveSpaceFromBeginning() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName(" Qwertyuiop1234567890asdfA"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName().trim())); + normalizedName = productReqDetails.getName().trim().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test(enabled = false) + public void createProductNameValidationRemoveSpaceFromTheEnd() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Qwertyuiop1234567890asdfA "); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName().trim())); + normalizedName = productReqDetails.getName().trim().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationStartWithNumber() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("1Qwert"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName().trim())); + normalizedName = productReqDetails.getName().trim().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationStartWithNonAlphaNumeric() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("_Qwert"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName().trim())); + normalizedName = productReqDetails.getName().trim().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING, "Product", "abbreviated"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductNameValidationFirstLetterOfKeyWordsCapitalized() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + // productReqDetails.setTags(Arrays.asList("abba")); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + // productReqDetails.setName("Abba"); + /* + * String actualNormalizedNameFromResponse = + * ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), + * "normalizedName"); + * assertTrue(actualNormalizedNameFromResponse.equals(normalizedName)); + */ + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameValidationIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setFullName(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", "full"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameValidationIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setFullName(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", "full"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameLessThanMinLength() throws Exception { + // Min is 4 characters + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setFullName("abc"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING, "Product", "full"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameHasMinLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setFullName("abcd"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameHasMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setFullName( + "Abba1234567890asdfghjk l123zxcvbnm432adfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameExceedMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setFullName( + "Abba1234567890asdfghjk l123zxcvbnm432adfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.123"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, + ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING, "Product", "full"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductFullNameRemoveExtraSpaces() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setFullName("Abbaaa a1"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setFullName("Abbaaa a1"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionValidationIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setDescription(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_MISSING_DESCRIPTION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionValidationIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setDescription(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_MISSING_DESCRIPTION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionValidCharacters01() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setDescription("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionValidCharacters02() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription("~!@#$%^&*()_+<>?qwertyuiopasdfghjklzxcvbnm1234567890#"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setDescription("~!@#$%^&*()_+<>?qwertyuiopasdfghjklzxcvbnm1234567890#"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionInValidCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription("מה"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_INVALID_DESCRIPTION, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionRemoveSpacesFromBeginning() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription(" abcd12345"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setDescription("abcd12345"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionRemoveSpacesFromTheEnd() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription("abcd 12345 xcvb "); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setDescription("abcd 12345 xcvb"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription( + "Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12asdfghjklzxcvbnmqwertyui"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDescriptionExceedMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setDescription( + "Abxba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12Abba1234567890asdfghjkl123zxcvbnm432asdfghjkl_-.123Abba1234567890asdfghjkl23zxcvbnm432asdfghjkl_-.12asdfghjklzxcvbnmqwertyui"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", "1024"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductTagIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product"); + productReqDetails.setTags(Arrays.asList("")); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_FIELD_FORMAT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", "tag"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + // DE192351 + @Test + public void createProductTagValidationAllowedCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "Acde2@3:4& m=n+b-u.j-u'g#b")); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductTagsNameValidationProductNameIsNotInTag() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Qwertyuiop1234567890asdfA"); + productReqDetails.setTags(Arrays.asList("Abc")); + normalizedName = productReqDetails.getName().trim().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductSingleTagMaxLength() throws Exception { + // SingleTagMaxLength = 50 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags( + Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345678")); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductSingleTagExceedMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags( + Arrays.asList(productReqDetails.getName(), "Axbba1234567890asdfghjkl123zxcvbnm432asdfgh12345678")); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "50"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductAllTagsMaxLength() throws Exception { + // AllTagsMaxLength = 1024 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags( + Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345601", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345602", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345603", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345604", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345605", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345606", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345607", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345608", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh1234569", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345610", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345611", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345612", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345613", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345614", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345615", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345616", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345617", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345618", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345619", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345")); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductAllTagsExceedMaxLength() throws Exception { + // AllTagsMaxLength = 1024 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags( + Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345601", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345602", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345603", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345604", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345605", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345606", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345607", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345608", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh1234569", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345610", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345611", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345612", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345613", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345614", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345615", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345616", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345617", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345618", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345619", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh123456")); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "1024"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductDuplicateTagRemoved() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductContactsIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + productReqDetails.setContacts(Arrays.asList("")); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_INVALID_CONTACT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductContactsInvalidFormat() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + productReqDetails.setContacts(Arrays.asList("bt750345")); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_INVALID_CONTACT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductConvertContactsToLowerCase() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + productReqDetails.setContacts(Arrays.asList(productManager1.getUserId().toUpperCase())); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setContacts(Arrays.asList(productManager1.getUserId().toLowerCase())); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductContactsDoexNotContainTheProductCreator() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + productReqDetails.setContacts(Arrays.asList(productManager2.getUserId())); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setContacts(Arrays.asList(productManager2.getUserId(), productManager1.getUserId())); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductContactsNotAllowedAsdcUsers() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + productReqDetails.setContacts(Arrays.asList(designerUser.getUserId())); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_PRODUCT_CONTACT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, + designerUser.getUserId()); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductContactsNotAsdcUser() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); // Bug @:&=+'# + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase(); + String nonAsdcUser = "bh1234"; + productReqDetails.setContacts(Arrays.asList(nonAsdcUser)); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_PRODUCT_CONTACT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, nonAsdcUser); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_PROJECT_CODE, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.MISSING_PROJECT_CODE, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeIsNotNumeric() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode("asdfgh"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_PROJECT_CODE, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeHasnMinCharacters() throws Exception { + // Min =5 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode("12345"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeHasnMaxCharacters() throws Exception { + // Max =10 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode("1234567890"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeExceedMaxCharacters() throws Exception { + // Max =10 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode("12345678901"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_PROJECT_CODE, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductProjectCodeLessThanMinCharacters() throws Exception { + // Max =10 + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setProjectCode("1234"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_PROJECT_CODE, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconIsEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setIcon(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_MISSING_ICON, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setIcon(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_MISSING_ICON, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setIcon("asdfghjklqwertyuiozxcvbfv"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconExceedMaxLength() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setIcon("asdfghjklqwertyuiozxcvbf12"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product", "25"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconAllowedCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setIcon("a--s-fghjk_q__r1234567890"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIconInValidCharacters() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + String icon = "asdfg"; + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + RestResponse createProduct; + for (int i = 0; i < invalidChars.length; i++) { + productReqDetails.setIcon(icon + invalidChars[i]); + createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", + productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.COMPONENT_INVALID_ICON, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, "Product"); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + } + + @Test + public void createProductIsActiveisEmpty() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setActive(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setActive("false"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIsActiveisNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setActive(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + productReqDetails.setActive("false"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIsActiveisFalse() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setActive("false"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIsActiveisHasInvalidValue() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setActive("xfalse"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, + createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "", productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_CONTENT, + Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + constructFieldsForAuditValidation.setRESOURCE_NAME(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test + public void createProductIsActiveisTrue() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Product1"); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + productReqDetails.setActive("true"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + ////////////////////////////////////////////// + // DE192424 + @Test + public void createProductNameValidationNormalizationNameWithSpaces() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setName("Abba Emma"); + // productReqDetails.setName("abba emma"); + // productReqDetails.setTags(Arrays.asList("abba emma")); + normalizedName = productReqDetails.getName().toLowerCase().replaceAll("\\s+", ""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + String actualNormalizedNameFromResponse = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), + "normalizedName"); + assertTrue(actualNormalizedNameFromResponse.equals(normalizedName)); + // productReqDetails.setName("Abba Emma"); + String productUuid = ResponseParser.getUuidFromResponse(createProduct); + compareExpectedAndActualProducts(productReqDetails, createProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProductRes); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation( + expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, + "0.1", null, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, productUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + private void compareExpectedAndActualProducts(ProductReqDetails productReqDetails, RestResponse createProduct) + throws JSONException { + String productName = ResponseParser.getNameFromResponse(createProduct); + assertTrue(productReqDetails.getName().equals(productName)); + String productIcon = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "icon"); + assertTrue(productReqDetails.getIcon().equals(productIcon)); + String productFullName = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "fullName"); + assertTrue(productReqDetails.getFullName().equals(productFullName)); + String productProjectCode = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "projectCode"); + assertTrue(productReqDetails.getProjectCode().equals(productProjectCode)); + String productIsActive = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "isActive"); + String expectedIsActive = (productReqDetails.getActive() != null ? productReqDetails.getActive() : "false"); + assertTrue(productIsActive.equals(expectedIsActive)); + String productdescription = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "description"); + assertTrue(productReqDetails.getDescription().equals(productdescription)); + String productNormalizedName = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), + "normalizedName"); + assertTrue(normalizedName.equals(productNormalizedName)); + String productContacts = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "contacts"); + JSONArray reciviedContacts = new JSONArray(productContacts); + String actualContact = null; + for (int i = 0; i < reciviedContacts.length(); i++) { + actualContact = reciviedContacts.getString(i); + assertEquals(productReqDetails.getContacts().get(i), actualContact); + } + String productTags = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "tags"); + JSONArray reciviedTages = new JSONArray(productTags); + String actualTag = null; + for (int i = 0; i < reciviedTages.length(); i++) { + actualTag = reciviedTages.getString(i); + assertEquals(productReqDetails.getTags().get(i), actualTag); + } + } + + // END + /////////////////////////////////////////////////////// + @Test + public void createProductSuccessFlow() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, + createProduct.getErrorCode().intValue()); + + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + assertEquals("Check response code after getting created Product", BaseRestUtils.STATUS_CODE_SUCCESS, + getProductRes.getErrorCode().intValue()); + + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(false)); + } + + @Test + public void createProductSetIsActive() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setActive("true"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, + createProduct.getErrorCode().intValue()); + + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), + productManager1.getUserId()); + assertEquals("Check response code after getting created Product", BaseRestUtils.STATUS_CODE_SUCCESS, + getProductRes.getErrorCode().intValue()); + + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, + ComponentOperationEnum.GET_COMPONENT); + assertEquals(actualProduct.getIsActive(), new Boolean(true)); + } + + @Test + public void createProductNoIcon() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setIcon(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_MISSING_DATA, + createProduct.getErrorCode().intValue()); + + } + + @Test + public void createProductNoProjectCode() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + productReqDetails.setProjectCode(null); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_MISSING_DATA, + createProduct.getErrorCode().intValue()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCrudTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCrudTest.java new file mode 100644 index 0000000000..f234708b7a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductCrudTest.java @@ -0,0 +1,2197 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class ProductCrudTest extends ProductBaseTest { + private static Logger log = LoggerFactory.getLogger(ProductCrudTest.class.getName()); + @Rule + public static TestName name = new TestName(); + + public static String INITIAL_PRODUCT_VERSION = "0.1"; + public static String CREATE_AUDIT_ACTION = "Create"; + public static String UPDATE_AUDIT_ACTION = "Update"; + public static String COMPONENT_TYPE = "Product"; + + private ProductReqDetails productReqDetails; + private RestResponse createProduct; + private Product product; + + public ProductCrudTest() { + super(name, ProductCrudTest.class.getName()); + } + + @Test // (enabled=false) + public void createAndGetAll() throws Exception { + createProductAndGet(UserRoleEnum.DESIGNER); + } + + private void createProductAndGet(UserRoleEnum user) throws Exception, IOException { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + + RestResponse catalog = CatalogRestUtils.getCatalog(user.getUserId()); + assertEquals("Check response code after get catalog", BaseRestUtils.STATUS_CODE_SUCCESS, catalog.getErrorCode().intValue()); + + try { + JsonElement jElement = new JsonParser().parse(catalog.getResponse()); + JsonObject jObject = jElement.getAsJsonObject(); + JsonArray products = (JsonArray) jObject.get("products"); + assertEquals("Check product array size", 1, products.size()); + Iterator iter = products.iterator(); + while (iter.hasNext()) { + JsonElement next = iter.next(); + Product product = ResponseParser.parseToObjectUsingMapper(next.toString(), Product.class); + assertNotNull(product); + assertEquals("Check product name", productReqDetails.getName(), product.getName()); + // Map allVersions = product.getAllVersions(); + // assertEquals("Check product name", 1, allVersions.size()); + } + + } catch (Exception e) { + log.debug("exception", e); + } + } + + @Test + public void getAllNoProcduts() throws Exception { + + RestResponse catalog = CatalogRestUtils.getCatalog(); + assertEquals("Check response code after get catalog", BaseRestUtils.STATUS_CODE_SUCCESS, catalog.getErrorCode().intValue()); + + try { + JsonElement jElement = new JsonParser().parse(catalog.getResponse()); + JsonObject jObject = jElement.getAsJsonObject(); + JsonArray products = (JsonArray) jObject.get("products"); + assertEquals("Check product array size", 0, products.size()); + } catch (Exception e) { + log.debug("exception", e); + } + + } + + @Test + public void getAllNoAttHeader() throws Exception { + String url = String.format(Urls.GET_CATALOG_DATA, config.getCatalogBeHost(), config.getCatalogBePort()); + + List headersToRemove = new ArrayList(); + headersToRemove.add(HttpHeaderEnum.USER_ID.getValue()); + + RestResponse catalog = CatalogRestUtils.sendGetAndRemoveHeaders(url, null, headersToRemove); + assertEquals("Check response code after get catalog", BaseRestUtils.STATUS_CODE_MISSING_INFORMATION, catalog.getErrorCode().intValue()); + + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), catalog.getResponse()); + } + + @Test + public void getAllWrongUser() throws Exception { + RestResponse catalog = CatalogRestUtils.getCatalog("kj8976"); + assertEquals("Check response code after get catalog", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, catalog.getErrorCode().intValue()); + + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), catalog.getResponse()); + } + + @Test // (enabled=false) + public void getAllWithProductStrategist_User() throws Exception { + createProductAndGet(UserRoleEnum.PRODUCT_STRATEGIST1); + } + + @Test // (enabled=false) + public void getAllWithProductManager_User() throws Exception { + createProductAndGet(UserRoleEnum.PRODUCT_MANAGER1); + } + + @Test // (enabled=false) + public void createProductNoCategories() throws Exception { + createProductWithCategories(null); + } + + @Test // (enabled=false) + public void createProductOneGrouping() throws Exception { + // Category1->[Subcategory1->[Grouping1]] + createProductWithCategories(defaultCategories); + } + + @Test // (enabled=false) + public void createProductTwoGroupingsSameSubCategory() throws Exception { + // Category1->Subcategory1->[Grouping1, Grouping11] + List addSecondGroupingToDefaultCategory = addSecondGroupingToDefaultCategory(); + createProductWithCategories(addSecondGroupingToDefaultCategory); + } + + @Test // (enabled=false) + public void createProductTwoSubsDifferentGroupings() throws Exception { + // Category1->[Subcategory1->[Grouping1, + // Grouping11],Subcategory2->[Grouping12]] + List addSubcategoryAndGroupingToDefaultCategory = addSubcategoryAndGroupingToDefaultCategory(); + createProductWithCategories(addSubcategoryAndGroupingToDefaultCategory); + } + + @Test // (enabled=false) + public void createManyGroupingsDiffCategories() throws Exception { + // [Category1->[Subcategory1->[Grouping1, + // Grouping11],Subcategory2->[Grouping12]], + // Category2->[Subcategory1->[Grouping1],Subcategory2->[Grouping1]], + // Category3->[Subcategory1->[Grouping11],Subcategory2->[Grouping11, + // Grouping22]]] + List addSubcategoryAndGroupingToDefaultCategory = addManyGroupingsDiffCategories(); + createProductWithCategories(addSubcategoryAndGroupingToDefaultCategory); + } + + @Test // (enabled=false) + public void createProductEmptyUserId() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + User emptyUser = new User(); + emptyUser.setUserId(""); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, emptyUser); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_MISSING_INFORMATION, createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, emptyUser); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, emptyUser, ActionStatus.MISSING_INFORMATION, Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, + null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test // (enabled=false) + public void createProductNonExistingUserId() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + User notExistingUser = new User(); + notExistingUser.setUserId("jj6444"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, notExistingUser); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, notExistingUser); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, notExistingUser, ActionStatus.RESTRICTED_OPERATION, Constants.EMPTY_STRING, Constants.EMPTY_STRING, + null, null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test // (enabled=false) + public void createProductInvalidJson() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct_Invalid_Json(productManager1.getUserId()); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, productManager1); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.INVALID_CONTENT, Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, + null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setRESOURCE_NAME(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test // (enabled=false) + public void createProductAdminRoleNotAllowed() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + User wrongRole = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, wrongRole); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, wrongRole); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, wrongRole, ActionStatus.RESTRICTED_OPERATION, Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, + null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test // (enabled=false) + public void createProductProductStrategistRoleNotAllowed() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + User wrongRole = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST3); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, wrongRole); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, createProduct.getErrorCode().intValue()); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, wrongRole); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, wrongRole, ActionStatus.RESTRICTED_OPERATION, Constants.EMPTY_STRING, Constants.EMPTY_STRING, null, + null, Constants.EMPTY_STRING); + constructFieldsForAuditValidation.setCURR_VERSION(""); + constructFieldsForAuditValidation.setCURR_STATE(""); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + @Test // (enabled=false) + public void getProductSuccessFlow() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after getting created Product", BaseRestUtils.STATUS_CODE_SUCCESS, getProductRes.getErrorCode().intValue()); + + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.GET_COMPONENT); + } + + @Test // (enabled=false) + public void getNonExistedProduct() throws Exception { + + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after getting created Product", BaseRestUtils.STATUS_CODE_SUCCESS, getProductRes.getErrorCode().intValue()); + + Product product = ResponseParser.parseToObjectUsingMapper(getProductRes.getResponse(), Product.class); + assertEquals("Assert on product icon", "Product1", product.getName()); + + RestResponse deleteProductRes = ProductRestUtils.deleteProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code for deletign Product", BaseRestUtils.STATUS_CODE_SUCCESS, deleteProductRes.getErrorCode().intValue()); + + RestResponse getProductAfterDeleteRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after getting deleted Product", BaseRestUtils.STATUS_CODE_NOT_FOUND, getProductAfterDeleteRes.getErrorCode().intValue()); + } + + @Test // (enabled=false) + public void getProductMissingHeader() throws Exception { + + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + + productManager1.setUserId(null); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after getting created Producuct with userId extracted from header", BaseRestUtils.STATUS_CODE_MISSING_INFORMATION, getProductRes.getErrorCode().intValue()); + + } + + @Test // (enabled=false) + public void getProductNonExistingUser() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + + productManager1.setUserId("bt1111"); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after getting created Producuct with non exsisting user", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, getProductRes.getErrorCode().intValue()); + } + + @Test // (enabled=false) + public void createProductAndGetProductWithDifferentUser() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + User sdncProductStrategistUserAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), sdncProductStrategistUserAdminDetails.getUserId()); + assertEquals("Check response code after getting created Product different user role", BaseRestUtils.STATUS_CODE_SUCCESS, getProductRes.getErrorCode().intValue()); + } + + // US594753 - Update Product metadata + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductAllFieldsByPM() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + // Update product + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("NewProductName"); + List addSecondGroupingToDefaultCategory = addSecondGroupingToDefaultCategory(); + productReqDetails.setFullName("New Full name"); + productReqDetails.setActive("false"); + productReqDetails.setContacts(Arrays.asList(productManager2.getUserId().toLowerCase(), productManager1.getUserId().toLowerCase())); + productReqDetails.setDescription("New Product Description"); + productReqDetails.setIcon("asdfghjklqwertyuiozxcvbfv"); + productReqDetails.setProjectCode("98765"); + productReqDetails.setCategories(addSecondGroupingToDefaultCategory); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), + // productOldName)); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductByPS() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("New discription"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productStrategistUser1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void updateProductByAdmin() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("New discription"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, designerUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void updateProductByNonPmUser() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + // Update product name + productReqDetails.setDescription("New discription"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, designerUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void updateProductByNonAsdcUser() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + // Update product name + productReqDetails.setDescription("New discription"); + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + nonAsdcUser.setUserId("bt789k"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, nonAsdcUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void updateProductUserIdIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + // Update product name + productReqDetails.setDescription("New discription"); + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + nonAsdcUser.setUserId(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, nonAsdcUser); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_MISSING_INFORMATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void updateProductByNonProductOwner() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(defaultCategories); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + Product product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("New discription"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager2); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.GET_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNotInCheckoutState() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(defaultCategories); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + Product product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + // Update product name + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + String valueFromJsonResponse = ResponseParser.getValueFromJsonResponse(changeProductLifeCycle.getResponse(), "lastUpdateDate"); + expectedProduct.setLastUpdateDate(Long.parseLong(valueFromJsonResponse)); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("abbreviated"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager2, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + // List tags = productReqDetails.getTags(); + // tags.removeAll(tags); + productReqDetails.setTags(new ArrayList<>()); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName(null); // no update will be performed + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager2); + ProductRestUtils.checkSuccess(updateProduct); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager2); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(product.getName().toLowerCase()); + expectedProduct.setName(product.getName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameLessThanMinLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("ABC"); // no update will be performed + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("abbreviated"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameHasMinLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager2, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("NewP"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager2); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + productReqDetails.setLastUpdaterUserId(productManager2.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager2.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager2); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + // DE193857 - Normalized Name is not removing special characters + @Test(enabled = false) + public void updateProductNameMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + // Update product name + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("Ac_2B3U4k mSKnob-u.j-uGgP"); + String newNormalizedName = "ac2b3u4kmsknobujuggp"; + String newName = "Ac_2B3U4k MSKnob-u.j-uGgP"; + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setTags(Arrays.asList(newName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(newName); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("Ac_2B3U4k mSKnob-u.j-uGgPx"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("abbreviated"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameAlreadyExist() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(defaultCategories); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager2); + ProductRestUtils.checkCreateResponse(createProduct); + Product product1 = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product1, productManager2, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setName("CiProduct2000"); + // productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + createProduct = ProductRestUtils.createProduct(productReqDetails, productManager2); + ProductRestUtils.checkCreateResponse(createProduct); + Product product2 = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product2, productManager2, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product2, productManager2, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product2.getUniqueId()); + productReqDetails.setUUID(product2.getUUID()); + productReqDetails.setName(product1.getName()); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager2); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_ALREADY_EXISTS, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add(product1.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager2.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product2.getUniqueId()); + expectedProduct.setVersion(product2.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // DE193857 - Normalized Name is not removing special characters + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameAllowedCharacters() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + // Update product name + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("A_BU4k m&K=o#b-u.j-uG'g+P"); // Allowed + // characters + // [a-z,A-Z,0-9] + // , ‘ ‘ + // (space), + // ampersand + // dash + // “-“, plus + // "+", period + // ".", + // apostrophe + // "'", hashtag + // "#", equal + // "=", period + // ":", at "@", + // and + // underscore + // + String newNormalizedName = "abu4km&kobujuggp"; + String newName = "A_BU4k M&K=o#b-u.j-uG'g+P"; + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setTags(Arrays.asList(newName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(newName); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameRemoveSpaceFromBeginning() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName(" asdfg"); + String newNormalizedName = "asdfg"; + String newName = "Asdfg"; + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // productReqDetails.setTags(Arrays.asList(newName, productOldName)); + productReqDetails.setTags(Arrays.asList(newName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(newName); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameRemoveSpaceFromEnd() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("asdfg fc "); + String newNormalizedName = "asdfgfc"; + String newName = "Asdfg Fc"; + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // productReqDetails.setTags(Arrays.asList(newName, productOldName)); + productReqDetails.setTags(Arrays.asList(newName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(newName); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + //// DE193857 - Normalized Name is not removing special characters + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameRemoveExtraNonAlphanumericChars() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("A__k &&==##---u..hG'''+++"); + String newNormalizedName = "akhg"; + String newName = "A_k &=#-u.hG'+"; + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // productReqDetails.setTags(Arrays.asList(newName, productOldName)); + productReqDetails.setTags(Arrays.asList(newName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(newName); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // If user update Product Name we need to remove the old product name from + // Tags and add the new product name instead - will be handled in new US + @Test(enabled = false) + public void updateProductNameValidationStartWithNumber() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("1000Ab"); + String newNormalizedName = productReqDetails.getName().toLowerCase(); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName())); + // productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), + // productOldName)); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setNormalizedName(newNormalizedName); + expectedProduct.setName(productReqDetails.getName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductNameValidationStartWithNonAlphaNumeric() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setName("_1000Ab"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("abbreviated"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("full"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setNormalizedName(product.getNormalizedName()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setFullName(product.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameHasMinLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("asdc"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setNormalizedName(product.getNormalizedName()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setFullName(productReqDetails.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameHasMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setNormalizedName(product.getNormalizedName()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setFullName(productReqDetails.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNamelessThanMinLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("123"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("full"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjkx"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("full"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + // DE193947 + @Test + public void updateProductFullNameWithSpecialCharacters() throws Exception { + char invalidChars[] = { '~', '!', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', '|', '\\', ',', '$', '#', '@', '+' }; + String fullName = "avbng"; + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + for (int i = 0; i < invalidChars.length; i++) { + productReqDetails.setFullName(fullName + invalidChars[i]); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, updateProduct.getErrorCode().intValue()); + } + } + + @Test // (enabled=false) + public void updateProductFullNameValidCharactersCharacters01() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setNormalizedName(product.getNormalizedName()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setFullName("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductFullNameRemoveExtraSpaces() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setFullName("Abbaaa a1"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setNormalizedName(product.getNormalizedName()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setFullName("Abbaaa a1"); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test(enabled = false) + public void updateProductDescriptionValidCharacters01() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("~!@#$%^&*()_+<>?qwertyuiopasdfghjklzxcvbnm1234567890#"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setDescription("~!@#$%^&*()_+<>?qwertyuiopasdfghjklzxcvbnm1234567890#"); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionValidCharacters02() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setDescription("qwertyuiopasdfghjklzxcvbnm1234567890Bold<"); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionInValidCharacters() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("מה"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_DESCRIPTION.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionRemoveSpacesFromBeginning() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription(" abcd12345 g"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setDescription("abcd12345 g"); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionRemoveSpacesFromTheEnd() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setDescription("abcd12345 gdf "); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setDescription("abcd12345 gdf"); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + String description = "1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfg"; + productReqDetails.setDescription(description); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setDescription(description); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductDescriptionExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + String description = "01234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjk aa1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfghjklzxcvbnm1234567890qwertyuiopasdfg"; + productReqDetails.setDescription(description); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("1024"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductTagIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList("")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + varibales.add("tag"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductTagIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setTags(product.getTags()); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductTagsNameValidationProductNameIsNotInTag() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList("Abc")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME.name(), new ArrayList(), updateProduct.getResponse()); + } + + @Test // (enabled=false) + public void createProductSingleTagMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345678")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setTags(productReqDetails.getTags()); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductSingleTagExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh123456788")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("50"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductAllTagsMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345601", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345602", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345603", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345604", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345605", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345606", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345607", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345608", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh1234569", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345610", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345611", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345612", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345613", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345614", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345615", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345616", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345617", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345618", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345619", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setTags(productReqDetails.getTags()); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductAllTagsExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345601", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345602", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345603", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345604", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345605", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345606", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345607", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345608", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh1234569", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345610", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345611", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345612", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345613", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345614", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345615", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345616", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345617", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345618", "Abba1234567890asdfghjkl123zxcvbnm432asdfgh12345619", + "Abba1234567890asdfghjkl123zxcvbnm432asdfgh123456")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add("1024"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductTagsDuplicateTagRemoved() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setTags(Arrays.asList(productReqDetails.getName(), "KoKo", "KoKo")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata updated + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setTags(Arrays.asList(productReqDetails.getName(), "KoKo")); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductContactsIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setContacts(Arrays.asList("")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductContactsIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setContacts(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductContactsInvalidFormat() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setContacts(Arrays.asList("bt750345")); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductConvertContactsToLowerCase() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setContacts(Arrays.asList(productManager2.getUserId().toUpperCase())); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setContacts(Arrays.asList(productManager2.getUserId().toLowerCase(), productManager1.getUserId())); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductContactsNotAllowedAsdcUsers() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setContacts(Arrays.asList(productStrategistUser1.getUserId())); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(productStrategistUser1.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PRODUCT_CONTACT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductContactsNotAsdcUser() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + String nonAsdcUserUserId = "bt567h"; + productReqDetails.setContacts(Arrays.asList(nonAsdcUserUserId)); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(nonAsdcUserUserId); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PRODUCT_CONTACT.name(), varibales, updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_PROJECT_CODE.name(), new ArrayList(), updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setProjectCode(product.getProjectCode()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeLessThanMinCharacters() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode("9870"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROJECT_CODE.name(), new ArrayList(), updateProduct.getResponse()); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeHasnMinCharacters() throws Exception { // min + // =5 + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode("98700"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setProjectCode(productReqDetails.getProjectCode()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeHasnMaxCharacters() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode("1234567890"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setProjectCode(productReqDetails.getProjectCode()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeExceedMaxCharacters() throws Exception {// Max + // =10 + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode("12345678901"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROJECT_CODE.name(), new ArrayList(), updateProduct.getResponse()); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setProjectCode(product.getProjectCode()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductProjectCodeIsNotNumeric() throws Exception { + // Max =10 + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setProjectCode("1234a"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROJECT_CODE.name(), new ArrayList(), updateProduct.getResponse()); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setProjectCode(product.getProjectCode()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIconIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setIcon(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList variables = new ArrayList(); + variables.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_ICON.name(), variables, updateProduct.getResponse()); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIcon(product.getIcon()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIconIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setIcon(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + // Get Product and verify that metadata didn't change + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIcon(product.getIcon()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIconMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setIcon("A_a-1-2--b__BB1234567890A"); // Max length = + // 25 + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIcon(productReqDetails.getIcon()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIconExceedMaxLength() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setIcon("A_a-1-2--b__BB1234567890A_"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList variables = new ArrayList(); + variables.add(COMPONENT_TYPE); + variables.add("25"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT.name(), variables, updateProduct.getResponse()); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIcon(product.getIcon()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIconInValidCharacters() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + String icon = "asdfg"; // Allowed characters [a-zA-Z0-9], dash (‘-‘), + // underscore (‘_’). + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', '|', '\\', ',' }; + RestResponse updateProduct; + for (int i = 0; i < invalidChars.length; i++) { + productReqDetails.setIcon(icon + invalidChars[i]); + updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ArrayList variables = new ArrayList(); + variables.add(COMPONENT_TYPE); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_ICON.name(), variables, updateProduct.getResponse()); + } + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIcon(product.getIcon()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIsActiveIsEmpty() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setActive(""); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIsActive(false); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIsActiveIsTrue() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setActive("true"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIsActive(true); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIsActiveIsNull() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(defaultCategories); + productReqDetails.setActive("true"); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + Product product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setActive(null); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIsActive(true); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIsActiveIsFalse() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setActive("false"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + expectedProduct.setIsActive(false); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductIsActiveHasInvalidValue() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setActive("eeeee"); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), updateProduct.getResponse()); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_INVALID_CONTENT, updateProduct.getErrorCode().intValue()); + RestResponse getProduct = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + ProductRestUtils.checkSuccess(getProduct); + Product expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + expectedProduct.setUniqueId(product.getUniqueId()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(getProduct.getResponse(), Product.class); + expectedProduct.setVersion(product.getVersion()); + expectedProduct.setLastUpdaterUserId(productManager1.getUserId()); + expectedProduct.setLastUpdaterFullName(productManager1.getFullName()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductAssociations() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + List addSecondGroupingToDefaultCategory = addSecondGroupingToDefaultCategory(); + productReqDetails.setCategories(addSecondGroupingToDefaultCategory); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setCategories(productReqDetails.getCategories()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductAssociations02() throws Exception { + List addSecondGroupingToDefaultCategory = addSecondGroupingToDefaultCategory(); // Category1->Subcategory1->[Grouping1, + // Grouping11] + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(addSecondGroupingToDefaultCategory); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + Product product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + List defaultCategory = addSubcategoryAndGroupingToDefaultCategory(); // Category1->[Subcategory1->[Grouping1, + // Grouping11],Subcategory2->[Grouping12]] + productReqDetails.setCategories(defaultCategory); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setCategories(productReqDetails.getCategories()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductRemoveAllAssociations() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + List defaultCategory = new ArrayList(); + productReqDetails.setCategories(defaultCategory); + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setCategories(productReqDetails.getCategories()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + @Test // (enabled=false) + public void updateProductAssociationsCategotyIsNull() throws Exception { + createProducrByPSAndCheckIn(); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + productReqDetails.setUniqueId(product.getUniqueId()); + productReqDetails.setUUID(product.getUUID()); + productReqDetails.setCategories(null);// product categories will not be + // updated + RestResponse updateProduct = ProductRestUtils.updateProduct(productReqDetails, productManager1); + ProductRestUtils.checkSuccess(updateProduct); + productReqDetails.setLastUpdaterUserId(productManager1.getUserId()); + productReqDetails.setLastUpdaterFullName(productManager1.getFullName()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(updateProduct.getResponse(), Product.class); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, "0.2", productManager1); + expectedProduct.setUUID(product.getUUID()); + expectedProduct.setInvariantUUID(product.getInvariantUUID()); + expectedProduct.setCategories(product.getCategories()); + expectedProduct.setNormalizedName(productReqDetails.getName().toLowerCase()); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.UPDATE_COMPONENT); + } + + //////////////////////////////////////////////////////////////////////// + + private void createProductWithCategories(List categoryDefinitions) throws Exception { + ProductReqDetails productReqDetails = (categoryDefinitions != null ? ElementFactory.getDefaultProduct(categoryDefinitions) : ElementFactory.getDefaultProduct()); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + String actualUuid = ResponseParser.getUuidFromResponse(createProduct); + Product expectedProduct = Convertor.constructFieldsForRespValidation(productReqDetails, INITIAL_PRODUCT_VERSION, productManager1); + String normalizedNameFomJsonResponse = ResponseParser.getValueFromJsonResponse(createProduct.getResponse(), "normalizedName"); + expectedProduct.setNormalizedName(normalizedNameFomJsonResponse); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, ComponentOperationEnum.CREATE_COMPONENT); + ExpectedProductAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(expectedProduct, CREATE_AUDIT_ACTION, productManager1, ActionStatus.CREATED, Constants.EMPTY_STRING, "0.1", null, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, actualUuid); + AuditValidationUtils.validateAuditProduct(constructFieldsForAuditValidation, CREATE_AUDIT_ACTION); + } + + private void createProducrByPSAndCheckIn() throws Exception { + productReqDetails = ElementFactory.getDefaultProduct(defaultCategories); + createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + ProductRestUtils.checkCreateResponse(createProduct); + product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + RestResponse changeProductLifeCycle = ProductRestUtils.changeProductLifeCycle(product, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.checkSuccess(changeProductLifeCycle); + } + + @Test + public void checkInvariantUuidIsImmutable() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + String invariantUuidDefinedByUser = "!!!!!!!!!!!!!!!!!!!!!!!!"; + productReqDetails.setInvariantUUID(invariantUuidDefinedByUser); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + BaseRestUtils.checkStatusCode(createProduct, "create request failed", false, 201); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + Product ProductCreation = ResponseParser.convertProductResponseToJavaObject(createProduct.getResponse()); + String invariantUUIDcreation = ProductCreation.getInvariantUUID(); + + // validate get response + RestResponse getProductRes = ProductRestUtils.getProduct(productReqDetails.getUniqueId(), productManager1.getUserId()); + BaseRestUtils.checkSuccess(getProductRes); + Product productGetting = ResponseParser.convertProductResponseToJavaObject(getProductRes.getResponse()); + String invariantUUIDgetting = productGetting.getInvariantUUID(); + assertEquals(invariantUUIDcreation, invariantUUIDgetting); + + // Update Product with new invariant UUID + RestResponse restResponseUpdate = ProductRestUtils.updateProduct(productReqDetails, productManager1); + BaseRestUtils.checkSuccess(restResponseUpdate); + Product updatedProduct = ResponseParser.convertProductResponseToJavaObject(restResponseUpdate.getResponse()); + String invariantUUIDupdating = updatedProduct.getInvariantUUID(); + assertEquals(invariantUUIDcreation, invariantUUIDupdating); + + // Do checkin + RestResponse restResponseCheckin = LifecycleRestUtils.changeProductState(productReqDetails, productManager1, LifeCycleStatesEnum.CHECKIN); + BaseRestUtils.checkSuccess(restResponseCheckin); + Product checkinProduct = ResponseParser.convertProductResponseToJavaObject(restResponseCheckin.getResponse()); + String invariantUUIDcheckin = checkinProduct.getInvariantUUID(); + String version = checkinProduct.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckin); + assertEquals(version, "0.1"); + + // Do checkout + RestResponse restResponseCheckout = LifecycleRestUtils.changeProductState(productReqDetails, productManager1, LifeCycleStatesEnum.CHECKOUT); + BaseRestUtils.checkSuccess(restResponseCheckout); + Product checkoutProduct = ResponseParser.convertProductResponseToJavaObject(restResponseCheckout.getResponse()); + String invariantUUIDcheckout = checkoutProduct.getInvariantUUID(); + version = checkoutProduct.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckout); + assertEquals(version, "0.2"); + + } + + // US672129 Benny + private void getProductValidateInvariantUuid(String productUniqueId, String invariantUUIDcreation) throws Exception { + RestResponse getProduct = ProductRestUtils.getProduct(productUniqueId, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, getProduct.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(getProduct)); + } + + @Test // invariantUUID generated when the component is created and never + // changed + public void productInvariantUuid() throws Exception { + ProductReqDetails productReqDetails = ElementFactory.getDefaultProduct(); + String invariantUuidDefinedByUser = "12345"; + productReqDetails.setInvariantUUID(invariantUuidDefinedByUser); + RestResponse createProduct = ProductRestUtils.createProduct(productReqDetails, productManager1); + assertEquals("Check response code after create resource", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + // invariantUUID generated when the component is created and never + // changed + String invariantUUIDcreation = ResponseParser.getInvariantUuid(createProduct); + getProductValidateInvariantUuid(productReqDetails.getUniqueId(), invariantUUIDcreation); + // Update Product with new invariant UUID + RestResponse restResponse = ProductRestUtils.updateProduct(productReqDetails, productManager1); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getProductValidateInvariantUuid(productReqDetails.getUniqueId(), invariantUUIDcreation); + // Checkin + restResponse = LifecycleRestUtils.changeProductState(productReqDetails, productManager1, LifeCycleStatesEnum.CHECKIN); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getProductValidateInvariantUuid(productReqDetails.getUniqueId(), invariantUUIDcreation); + // Checkout + restResponse = LifecycleRestUtils.changeProductState(productReqDetails, productManager1, LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getProductValidateInvariantUuid(productReqDetails.getUniqueId(), invariantUUIDcreation); + + // UnDo-CheckOut + restResponse = LifecycleRestUtils.changeProductState(productReqDetails, productManager1, LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getProductValidateInvariantUuid(productReqDetails.getUniqueId(), invariantUUIDcreation); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductGetFollowedTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductGetFollowedTest.java new file mode 100644 index 0000000000..aebea697b2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductGetFollowedTest.java @@ -0,0 +1,164 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ProductGetFollowedTest extends ProductBaseTest { + + protected Product product200; + protected Product product400; + + private ProductReqDetails productDetails200; + private ProductReqDetails productDetails400; + + @Rule + public static TestName name = new TestName(); + + public ProductGetFollowedTest() { + super(name, ProductGetFollowedTest.class.getName()); + } + + @BeforeMethod + public void init() throws Exception { + createProducts(); + } + + @Test + public void followedPageTest() throws Exception { // Actions + RestResponse changeLifeCycleResponse; + changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product200, productManager1, LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + // Expected users Followed page + ProductValidationUtils.checkUserFollowedPage(productManager1, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager1, product400); + ProductValidationUtils.checkUserFollowedPage(productManager2, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager2, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + @Test + public void followedPagePmCheckedOutProductWasCheckInByOtherPm() throws Exception { + ProductRestUtils.changeProductLifeCycle(product200, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product400, productManager1, LifeCycleStatesEnum.CHECKOUT); + RestResponse changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product200, productManager2, LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + + ProductValidationUtils.checkUserFollowedPage(productManager1, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager2, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + @Test + public void followedPagePmCheckInProduct02() throws Exception { + ProductRestUtils.changeProductLifeCycle(product200, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + + ProductValidationUtils.checkUserFollowedPage(productManager1, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager1, product400); + ProductValidationUtils.checkUserFollowedPage(productManager2, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager2, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + @Test + public void followedPageAdminCheckoutProductWasCheckedinByPm() throws Exception { + ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + RestResponse changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product400, adminUser, LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + + ProductValidationUtils.checkUserFollowedPage(productManager1, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager1, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager2, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + @Test + public void followedPageAdminCheckInProduct() throws Exception { + ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product400, adminUser, LifeCycleStatesEnum.CHECKOUT); + RestResponse changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product400, adminUser, LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + + ProductValidationUtils.checkUserFollowedPage(productManager1, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager1, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager2, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + @Test + public void followedPagePmCheckoutProductWasCheckedinByAdmin() throws Exception { + ProductRestUtils.changeProductLifeCycle(product200, productManager1, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product400, productManager2, LifeCycleStatesEnum.CHECKIN); + ProductRestUtils.changeProductLifeCycle(product200, adminUser, LifeCycleStatesEnum.CHECKOUT); + ProductRestUtils.changeProductLifeCycle(product200, adminUser, LifeCycleStatesEnum.CHECKIN); + RestResponse changeLifeCycleResponse = ProductRestUtils.changeProductLifeCycle(product200, productManager2, LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(changeLifeCycleResponse); + + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productManager1, product200); + ProductValidationUtils.checkUserFollowedPage(productManager2, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(adminUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(designerUser, product200, product400); + ProductValidationUtils.verifyProductsNotExistInUserFollowedPage(productStrategistUser1, product200, product400); + } + + private void createProducts() throws Exception { + // PM1 (Product manager) create :PR200 (check In State) + // PM2 (Product manager) create :PR400 (check In State) + + productDetails200 = ElementFactory.getDefaultProduct("CiProd200", defaultCategories); + productDetails400 = ElementFactory.getDefaultProduct("CiProd400", defaultCategories); + + RestResponse createProduct = ProductRestUtils.createProduct(productDetails200, productManager1); + ResourceRestUtils.checkCreateResponse(createProduct); + product200 = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + + createProduct = ProductRestUtils.createProduct(productDetails400, productManager2); + ResourceRestUtils.checkCreateResponse(createProduct); + product400 = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductLifecycleTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductLifecycleTest.java new file mode 100644 index 0000000000..8c3409342b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductLifecycleTest.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; + +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.BeforeMethod; + +public abstract class ProductLifecycleTest extends ProductBaseTest { + + protected static final String CHECKIN_ACTION = "Checkin"; + protected static final String CHECKOUT_ACTION = "Checkout"; + protected static final String UNDO_CHECKOUT_ACTION = "UndoCheckout"; + + protected Product expectedProduct; + + public ProductLifecycleTest(TestName testName, String className) { + super(testName, className); + } + + @BeforeMethod + public void init() throws Exception { + ProductReqDetails defaultProduct = ElementFactory.getDefaultProduct(defaultCategories); + RestResponse createProduct = ProductRestUtils.createProduct(defaultProduct, productManager1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, createProduct.getErrorCode().intValue()); + expectedProduct = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductTestBase.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductTestBase.java new file mode 100644 index 0000000000..479dbb9436 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductTestBase.java @@ -0,0 +1,148 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.io.IOException; + +import org.apache.log4j.lf5.util.ResourceUtils; +import org.junit.Before; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.ArtifactUtils; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; + +public class ProductTestBase extends ProductBaseTest { + + public ProductTestBase(TestName testName, String className) { + super(testName, className); + } + + protected ResourceReqDetails downloadResourceDetails; + protected ServiceReqDetails serviceDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected User sdncUserDetails; + protected ArtifactReqDetails heatArtifactDetails; + protected ArtifactReqDetails defaultArtifactDetails; + protected ResourceUtils resourceUtils; + protected ArtifactUtils artifactUtils; + protected Resource resource; + protected Service service; + protected Product product; + + // protected static ServiceUtils serviceUtils = new ServiceUtils(); + + @Before + public void before() throws Exception { + + initializeMembers(); + createComponents(); + + } + + public void initializeMembers() throws IOException, Exception { + + downloadResourceDetails = ElementFactory.getDefaultResource(); + serviceDetails = ElementFactory.getDefaultService(); + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + resourceInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + + } + + protected void createComponents() throws Exception { + + RestResponse response = ResourceRestUtils.createResource(downloadResourceDetails, sdncUserDetails); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", downloadResourceDetails.getUniqueId()); + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncUserDetails, + downloadResourceDetails.getUniqueId()); + assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + // certified resource + response = LifecycleRestUtils.certifyResource(downloadResourceDetails); + assertTrue("certify resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + response = ResourceRestUtils.getResource(downloadResourceDetails.getUniqueId()); + assertTrue("response code is not 200, returned: " + response.getErrorCode(), response.getErrorCode() == 200); + resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + + response = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetails.getUniqueId()); + + // add resource instance with HEAT deployment artifact to the service + resourceInstanceReqDetails.setComponentUid(downloadResourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncUserDetails, + serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + assertTrue("response code is not 201, returned: " + response.getErrorCode(), response.getErrorCode() == 201); + + // certified service + response = LifecycleRestUtils.certifyService(serviceDetails); + assertTrue("certify service request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + response = ServiceRestUtils.getService(serviceDetails, sdncUserDetails); + assertTrue("response code is not 200, returned: " + response.getErrorCode(), response.getErrorCode() == 200); + service = ResponseParser.convertServiceResponseToJavaObject(response.getResponse()); + + DbUtils.cleanAllAudits(); + + ProductReqDetails defaultProduct = ElementFactory.getDefaultProduct(defaultCategories); + RestResponse createProduct = ProductRestUtils.createProduct(defaultProduct, productStrategistUser1); + assertEquals("Check response code after create Product", BaseRestUtils.STATUS_CODE_CREATED, + createProduct.getErrorCode().intValue()); + product = ResponseParser.parseToObjectUsingMapper(createProduct.getResponse(), Product.class); + + // add service instance to product + // + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductToscaYamlGenerationTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductToscaYamlGenerationTest.java new file mode 100644 index 0000000000..412e6fd92d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductToscaYamlGenerationTest.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ProductToscaYamlGenerationTest extends ProductTestBase { + + @Rule + public static TestName name = new TestName(); + + public ProductToscaYamlGenerationTest() { + super(name, ProductToscaYamlGenerationTest.class.getName()); + } + + @Test + public void productToscaYamlFormat() throws IOException { + + String heatEnvArtifactHeader = (String) Utils.parseYamlConfig("heatEnvArtifactHeader"); + // System.out.println("heatEnvArtifactHeader = \n" + + // heatEnvArtifactHeader); + + String heatEnvArtifactFooter = (String) Utils.parseYamlConfig("heatEnvArtifactFooter"); + // System.out.println("heatEnvArtifactFooter = \n" + + // heatEnvArtifactFooter); + + // temporary commented + // RestResponse downloadResourceInstanceHeatArtifact = + // ArtifactRestUtils.downloadResourceInstanceArtifact(service.getUniqueId(), + // resourceInstanceId, sdncUserDetails, + // heatArtifactDefinition.getUniqueId()); + // assertTrue("expected request returned status:" + 200 + ", actual: " + + // downloadResourceInstanceHeatArtifact.getErrorCode(), + // downloadResourceInstanceHeatArtifact.getErrorCode()==200); + + // InputStream stream = + // getDecodedSteramFromString(downloadResourceInstanceHeatArtifact.getResponse()); + // System.out.println(Utils.getParamValueFromYamlByKey(stream, + // "description", String.class)); + + // node_types + + } + + private InputStream getDecodedSteramFromString(String encoded64Payload) throws IOException { + + Gson gson = new Gson(); + ArtifactUiDownloadData artifactUiDownloadData = gson.fromJson(encoded64Payload, ArtifactUiDownloadData.class); + String decodedPayload = Decoder.decode(artifactUiDownloadData.getBase64Contents()); + return new ByteArrayInputStream(decodedPayload.getBytes()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductUndoCheckoutTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductUndoCheckoutTest.java new file mode 100644 index 0000000000..d4bfb62377 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/product/ProductUndoCheckoutTest.java @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.product; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNull; + +import java.io.FileNotFoundException; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ProductValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +public class ProductUndoCheckoutTest extends ProductLifecycleTest { + + @Rule + public static TestName name = new TestName(); + + @BeforeClass + public static void staticInit() { + auditAction = UNDO_CHECKOUT_ACTION; + operation = ComponentOperationEnum.CHANGE_STATE_UNDO_CHECKOUT; + } + + public ProductUndoCheckoutTest() { + super(name, ProductUndoCheckoutTest.class.getName()); + } + + @Test + public void undoCheckOutProductByPm() throws Exception { + undoCheckOutProductSuccess(productManager1, false); + } + + @Test + public void undoCheckOutProductByAdmin() throws Exception { + undoCheckOutProductSuccess(adminUser, true); + } + + @Test + public void undoCheckOutAfterCreate() throws Exception { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undo checkout product", 200, lcsResponse.getErrorCode().intValue()); + + // Verify version was removed + lcsResponse = ProductRestUtils.getProduct(expectedProduct.getUniqueId(), productManager1.getUserId()); + assertEquals("Check response code after get undone product", 404, lcsResponse.getErrorCode().intValue()); + + Product emptyProduct = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + assertNull(emptyProduct); + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(emptyProduct, + auditAction, productManager1, ActionStatus.OK, "0.1", Constants.EMPTY_STRING, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, null, Constants.EMPTY_STRING); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + + } + + @Test + public void undoCheckOutNotExist() throws Exception { + String notExistId = "1234"; + expectedProduct.setUniqueId(notExistId); + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undo checkout product", 404, lcsResponse.getErrorCode().intValue()); + expectedProduct.setName(notExistId); + String[] auditParameters = new String[] { Constants.EMPTY_STRING }; + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productManager1, ActionStatus.PRODUCT_NOT_FOUND, Constants.EMPTY_STRING, + Constants.EMPTY_STRING, null, null, Constants.EMPTY_STRING, auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + + } + + @Test + public void undoCheckOutNotInCheckout() throws Exception { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin product", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undo checkout product", 409, lcsResponse.getErrorCode().intValue()); + + String[] auditParameters = new String[] { expectedProduct.getName(), "product", productManager1.getFirstName(), + productManager1.getLastName(), productManager1.getUserId() }; + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, productManager1, ActionStatus.COMPONENT_ALREADY_CHECKED_IN, "0.1", "0.1", + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + expectedProduct.getUUID(), auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + + } + + @Test + public void undoCheckOutProductByPsRoleNotAllowed() throws Exception { + undoCheckOutProductRestricted(productStrategistUser1); + } + + @Test + public void undoCheckOutProductByPmNotStateOwner() throws Exception { + undoCheckOutProductForbidden(productManager2); + } + + private void undoCheckOutProductSuccess(User user, boolean isAdmin) throws Exception, FileNotFoundException { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin product", 200, lcsResponse.getErrorCode().intValue()); + + // Checking undo checkout of admin even if not state owner + User checkoutUser = isAdmin ? productManager1 : user; + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, checkoutUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout product", 200, lcsResponse.getErrorCode().intValue()); + Product productToBeUndone = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + lcsResponse = LifecycleRestUtils.changeProductState(productToBeUndone, user, LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undo checkout product", 200, lcsResponse.getErrorCode().intValue()); + + // Verify version was removed + lcsResponse = ProductRestUtils.getProduct(productToBeUndone.getUniqueId(), user.getUserId()); + assertEquals("Check response code after get undone product", 404, lcsResponse.getErrorCode().intValue()); + + lcsResponse = ProductRestUtils.getProduct(expectedProduct.getUniqueId(), user.getUserId()); + assertEquals("Check response code after get latest version", 200, lcsResponse.getErrorCode().intValue()); + + Product latestProduct = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + expectedProduct.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, latestProduct, operation); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(latestProduct, + auditAction, user, ActionStatus.OK, "0.2", "0.1", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, latestProduct.getUUID()); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + private void undoCheckOutProductRestricted(User undoCheckoutUser) throws Exception, FileNotFoundException { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin product", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout product", 200, lcsResponse.getErrorCode().intValue()); + Product productToBeUndone = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + lcsResponse = LifecycleRestUtils.changeProductState(productToBeUndone, undoCheckoutUser, + LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undocheckout product", 409, lcsResponse.getErrorCode().intValue()); + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(productToBeUndone, + auditAction, undoCheckoutUser, ActionStatus.RESTRICTED_OPERATION, "0.2", "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + productToBeUndone.getUUID()); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + + private void undoCheckOutProductForbidden(User undoCheckoutUser) throws Exception, FileNotFoundException { + RestResponse lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkin product", 200, lcsResponse.getErrorCode().intValue()); + + lcsResponse = LifecycleRestUtils.changeProductState(expectedProduct, productManager1, + LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout product", 200, lcsResponse.getErrorCode().intValue()); + Product productToBeUndone = ResponseParser.parseToObjectUsingMapper(lcsResponse.getResponse(), Product.class); + + lcsResponse = LifecycleRestUtils.changeProductState(productToBeUndone, undoCheckoutUser, + LifeCycleStatesEnum.UNDOCHECKOUT); + assertEquals("Check response code after undocheckout product", 403, lcsResponse.getErrorCode().intValue()); + String[] auditParameters = new String[] { productToBeUndone.getName(), "product", + productManager1.getFirstName(), productManager1.getLastName(), productManager1.getUserId() }; + + ExpectedProductAudit expectedProductAudit = Convertor.constructFieldsForAuditValidation(expectedProduct, + auditAction, undoCheckoutUser, ActionStatus.COMPONENT_CHECKOUT_BY_ANOTHER_USER, "0.2", "0.2", + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + productToBeUndone.getUUID(), auditParameters); + AuditValidationUtils.validateAuditProduct(expectedProductAudit, auditAction); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/AdditionalInformationServletTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/AdditionalInformationServletTest.java new file mode 100644 index 0000000000..303be77f92 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/AdditionalInformationServletTest.java @@ -0,0 +1,2021 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.property; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.simple.parser.JSONParser; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.resource.ResourceApiTest; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.Test; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; + +public class AdditionalInformationServletTest extends ComponentBaseTest { + + protected Type constraintType = new TypeToken() { + }.getType(); + + protected Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + + @Rule + public static TestName name = new TestName(); + + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + + protected JSONParser jsonParser = new JSONParser(); + + public AdditionalInformationServletTest() { + super(name, AdditionalInformationServletTest.class.getName()); + } + + // @Before + // public void deleteResources() { + // //TODO Evg : will be new API added for delete by name and version + // + // ResourceReqDetails resource = getResource(); + // User user = getUser(); + // + // try { + // String resourceName = resource.getResourceName(); + // ResourceRestUtils.deleteResourceByNameAndVersion(user, resourceName, + // "0.1"); + // ResourceRestUtils.deleteResourceByNameAndVersion(user, resourceName, + // "0.2"); + // ResourceRestUtils.deleteResourceByNameAndVersion(user, resourceName, + // "1.0"); + // ResourceRestUtils.deleteResourceByNameAndVersion(user, resourceName, + // "1.1"); + // ResourceRestUtils.deleteResourceByNameAndVersion(user, resourceName + + // "aa", "0.1"); + // resourceUtils.deleteResource_allVersions(resource, user); + // + // } catch (IOException e) { + // assertTrue(false); + // } + // + // try { + // ServiceReqDetails serviceDetails = getServiceDetails(); + // + // RestResponse deleteServiceResponse = + // serviceUtils.deleteServiceByNameAndVersion(UserUtils.getAdminDetails(), + // serviceDetails.getServiceName(), "0.1"); + // + // assertNotNull("check response object is not null after delete + // service",deleteServiceResponse); + // assertNotNull("check error code exists in response after delete + // service",deleteServiceResponse.getErrorCode()); + // assertTrue("delete service failed status:" + + // deleteServiceResponse.getErrorCode(), + // deleteServiceResponse.getErrorCode() != 500); + // + // deleteServiceResponse = + // serviceUtils.deleteServiceByNameAndVersion(UserUtils.getAdminDetails(), + // serviceDetails.getServiceName(), "1.0"); + // + // assertNotNull("check response object is not null after delete + // service",deleteServiceResponse); + // assertNotNull("check error code exists in response after delete + // service",deleteServiceResponse.getErrorCode()); + // assertTrue("delete service failed status:" + + // deleteServiceResponse.getErrorCode(), + // deleteServiceResponse.getErrorCode() != 500); + // + // serviceUtils.deleteService_allVersions(serviceDetails, user); + // + // } catch (IOException e) { + // assertTrue(false); + // } + // } + + @Test + public void updateResourceAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + AssertJUnit.assertNotNull("check response object is not null after create resource", createResourceResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + String updatedKey = "ZZZ ZZZ"; + String updatedValue = "JJJJ"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + AssertJUnit.assertNotNull("check response object is not null after create property", createProperty); + AssertJUnit.assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + AssertJUnit.assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + AssertJUnit.assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + fromJson.setKey(updatedKey); + fromJson.setValue(updatedValue); + + RestResponse updatedProperty = updateAdditionalInformation(resourceId, fromJson, user, fromJson.getUniqueId()); + AssertJUnit.assertNotNull("check response object is not null after update additional information", updatedProperty); + AssertJUnit.assertNotNull("check error code exists in response after additional information", updatedProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after additional information", 200, updatedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(updatedProperty.getResponse(), AdditionalInfoParameterInfo.class); + AssertJUnit.assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + AssertJUnit.assertEquals("check returned key", "ZZZ ZZZ", updatedJson.getKey()); + AssertJUnit.assertEquals("check returned value", updatedValue, updatedJson.getValue()); + AssertJUnit.assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + } + + @Test + public void deleteResourceAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + AssertJUnit.assertNotNull("check response object is not null after create resource", createResourceResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + AssertJUnit.assertNotNull("check response object is not null after create property", createProperty); + AssertJUnit.assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + AssertJUnit.assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + AssertJUnit.assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = deleteAdditionalInformation(resourceId, fromJson.getUniqueId(), user); + AssertJUnit.assertNotNull("check response object is not null after update additional information", deletedProperty); + AssertJUnit.assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInfoParameterInfo.class); + AssertJUnit.assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + AssertJUnit.assertEquals("check returned key", "AAA AAA", updatedJson.getKey()); + AssertJUnit.assertEquals("check returned value", value, updatedJson.getValue()); + AssertJUnit.assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + deletedProperty = deleteAdditionalInformation(resourceId, fromJson.getUniqueId(), user); + AssertJUnit.assertNotNull("check response object is not null after update additional information", deletedProperty); + AssertJUnit.assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after additional information", 409, deletedProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceAdditionalInformationTestDuringLifecycle() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + AssertJUnit.assertNotNull("check response object is not null after create resource", createResourceResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + AssertJUnit.assertNotNull("check response object is not null after create property", createProperty); + AssertJUnit.assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + AssertJUnit.assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + AssertJUnit.assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + resource.setUniqueId(resourceId); + + // resourceUtils.addResourceMandatoryArtifacts(user, + // createResourceResponse); + + certifyResource(user, resource, null, 1); + + } + + public RestResponse createService() { + + User user = getUser(); + ServiceReqDetails serviceDetails = getServiceDetails(); + + RestResponse createServiceResponse = null; + try { + createServiceResponse = ServiceRestUtils.createService(serviceDetails, user); + AssertJUnit.assertNotNull("check response object is not null after create user", createServiceResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", createServiceResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after checkout resource", 201, createServiceResponse.getErrorCode().intValue()); + } catch (Exception e) { + AssertJUnit.assertTrue(false); + } + + return createServiceResponse; + + } + + protected User getUser() { + String adminFirstName = "Jimmy"; + String adminLastName = "Hendrix"; + String adminUserId = "jh0003"; + return new User(adminFirstName, adminLastName, adminUserId, null, null, null); + } + + protected ResourceReqDetails getResource() { + String resourceName = "ciResourceforproperty4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "pe0123"; + String icon = "myICON"; + ResourceReqDetails resource = new ResourceReqDetails(resourceName, description, resourceTags, null, derivedFrom, vendorName, vendorRelease, contactId, icon); + resource.addCategoryChain(ResourceCategoryEnum.GENERIC_DATABASE.getCategory(), ResourceCategoryEnum.GENERIC_DATABASE.getSubCategory()); + return resource; + } + + protected RestResponse createResource(ResourceReqDetails resourceDetails, User sdncModifierDetails) throws IOException { + + ResourceApiTest rat = new ResourceApiTest(); + ResourceReqDetails resourceObj = rat.getResourceObj(); + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + RestResponse createResourceResponse = http.httpSendPost(url, userBodyJson, headersMap); + + return createResourceResponse; + + } + + protected RestResponse getResource(User sdncModifierDetails, String resourceUid) throws IOException { + + ResourceApiTest rat = new ResourceApiTest(); + ResourceReqDetails resourceObj = rat.getResourceObj(); + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid); + RestResponse createResourceResponse = http.httpSendGet(url, headersMap); + + return createResourceResponse; + + } + + protected RestResponse deleteResource(String resourceName, String resourceVersion, User sdncModifierDetails) throws IOException { + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceName, resourceVersion); + + return deleteResourceResponse; + + } + + protected RestResponse updateAdditionalInformation(String resourceId, AdditionalInfoParameterInfo additionalInfo, User sdncModifierDetails, String id) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String body = gson.toJson(additionalInfo); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_ADDITIONAL_INFORMATION_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendPut(url, body, headersMap); + + } + + protected RestResponse updateServiceAdditionalInformation(String resourceId, AdditionalInfoParameterInfo additionalInfo, User sdncModifierDetails, String id) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String body = gson.toJson(additionalInfo); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_ADDITIONAL_INFORMATION_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendPut(url, body, headersMap); + + } + + protected RestResponse deleteAdditionalInformation(String resourceId, String id, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.DELETE_ADDITIONAL_INFORMATION_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendDelete(url, headersMap); + + } + + protected RestResponse deleteServiceAdditionalInformation(String resourceId, String id, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.DELETE_ADDITIONAL_INFORMATION_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendDelete(url, headersMap); + + } + + protected RestResponse getAdditionalInformation(String resourceId, String id, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ADDITIONAL_INFORMATION_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendGet(url, headersMap); + + } + + protected RestResponse getServiceAdditionalInformation(String resourceId, String id, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ADDITIONAL_INFORMATION_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, id); + return http.httpSendGet(url, headersMap); + + } + + protected RestResponse getResourceAllAdditionalInformation(String resourceId, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ALL_ADDITIONAL_INFORMATION_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + return http.httpSendGet(url, headersMap); + + } + + protected RestResponse getServiceAllAdditionalInformation(String resourceId, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ALL_ADDITIONAL_INFORMATION_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + return http.httpSendGet(url, headersMap); + + } + + protected RestResponse createResourceAdditionalInformation(String resourceId, AdditionalInfoParameterInfo additionalInfo, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String body = gson.toJson(additionalInfo); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_ADDITIONAL_INFORMATION_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + return http.httpSendPost(url, body, headersMap); + + } + + protected RestResponse createServiceAdditionalInformation(String serviceId, AdditionalInfoParameterInfo additionalInfo, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String body = gson.toJson(additionalInfo); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_ADDITIONAL_INFORMATION_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId); + return http.httpSendPost(url, body, headersMap); + + } + + protected ServiceReqDetails getServiceDetails() { + String serviceName = "ciNewTestService21"; + String category = ServiceCategoriesEnum.MOBILITY.getValue(); + ArrayList tags = new ArrayList(); + tags.add("serviceTag"); + tags.add(serviceName); + String description = "service Description"; + String vendorName = "Oracle"; + String vendorRelease = "0.1"; + String contactId = "al1976"; + String icon = "myIcon"; + + return new ServiceReqDetails(serviceName, category, tags, description, contactId, icon); + } + + // TODO Tal: Since Cashing change partial resource returned that causes null + // pointer exception in line: + // commented out till fixing + protected Resource certifyResource(User user, ResourceReqDetails resource, String resourceVersion, int numberOfAI) throws IOException { + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKIN); + + AssertJUnit.assertNotNull("check response object is not null after create user", checkInResponse); + AssertJUnit.assertNotNull("check error code exists in response after create user", checkInResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create user", 200, checkInResponse.getErrorCode().intValue()); + + Resource resourceAfterOperation = gson.fromJson(checkInResponse.getResponse(), Resource.class); + // TODO Tal: Since Cashing change partial resource returned that causes + // null pointer exception + /* + * AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + */ + /* + * AssertJUnit.assertEquals("check size of additional information", numberOfAI, resourceAfterOperation.getAdditionalInformation().get(0). getParameters().size()); + */ + + RestResponse req4certResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + AssertJUnit.assertNotNull("check response object is not null after create user", req4certResponse); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, req4certResponse.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(req4certResponse.getResponse(), Resource.class); + // TODO Tal: Since Cashing change partial resource returned that causes + // null pointer exception + /* + * AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + */ + /* + * AssertJUnit.assertEquals("check size of additional information", numberOfAI, resourceAfterOperation.getAdditionalInformation().get(0). getParameters().size()); + */ + + // change modifier + user.setUserId(UserRoleEnum.TESTER.getUserId()); + // start certification + + RestResponse startCertResourceResponse3 = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + AssertJUnit.assertNotNull("check response object is not null after create user", startCertResourceResponse3); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, startCertResourceResponse3.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(startCertResourceResponse3.getResponse(), Resource.class); + // TODO Tal: Since Cashing change partial resource returned that causes + // null pointer exception + /* + * AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + */ + /* + * AssertJUnit.assertEquals("check size of additional information", numberOfAI, resourceAfterOperation.getAdditionalInformation().get(0). getParameters().size()); + */ + + // certify + + RestResponse certifyResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CERTIFY); + AssertJUnit.assertNotNull("check response object is not null after create user", certifyResponse); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, certifyResponse.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(certifyResponse.getResponse(), Resource.class); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + AssertJUnit.assertEquals("check size of additional information", numberOfAI, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + Resource certifyResource = gson.fromJson(certifyResponse.getResponse(), Resource.class); + return certifyResource; + } + + protected Resource certifyService(User user, ServiceReqDetails service, String resourceVersion) throws Exception { + RestResponse checkInResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CHECKIN); + + AssertJUnit.assertNotNull("check response object is not null after create user", checkInResponse); + AssertJUnit.assertNotNull("check error code exists in response after create user", checkInResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create user", 200, checkInResponse.getErrorCode().intValue()); + + Resource resourceAfterOperation = gson.fromJson(checkInResponse.getResponse(), Resource.class); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + RestResponse req4certResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + AssertJUnit.assertNotNull("check response object is not null after create user", req4certResponse); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, req4certResponse.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(req4certResponse.getResponse(), Resource.class); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + // change modifier + user.setUserId(UserRoleEnum.TESTER.getUserId()); + // start certification + + RestResponse startCertResourceResponse3 = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + AssertJUnit.assertNotNull("check response object is not null after create user", startCertResourceResponse3); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, startCertResourceResponse3.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(startCertResourceResponse3.getResponse(), Resource.class); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + // certify + + RestResponse certifyResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CERTIFY); + AssertJUnit.assertNotNull("check response object is not null after create user", certifyResponse); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, certifyResponse.getErrorCode().intValue()); + + resourceAfterOperation = gson.fromJson(certifyResponse.getResponse(), Resource.class); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + AssertJUnit.assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + Resource certifyResource = gson.fromJson(certifyResponse.getResponse(), Resource.class); + return certifyResource; + } + + @Test + public void createResourceAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceAdditionalInfoFormatWithTags() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "Bold<"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertEquals("check returned key", "Bold&lt;", fromJson.getValue()); + + } + + @Test + public void createServiceAdditionalInfoFormatWithTags() throws Exception { + User user = getUser(); + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + assertNotNull("check response object is not null after create resource", createServiceResponse); + assertNotNull("check error code exists in response after create resource", createServiceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createServiceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "Bold<"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertEquals("check returned key", "Bold&lt;", fromJson.getValue()); + + } + + @Test + public void createResourceAdditionalInfoFormatWithWhiteSpaces() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = " "; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + key = " "; + value = "AAA AAA"; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceAdditionalInfoFormatWithWhiteSpaces() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + assertNotNull("check response object is not null after create resource", createServiceResponse); + assertNotNull("check error code exists in response after create resource", createServiceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createServiceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = " "; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + key = " "; + value = "AAA AAA"; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceAndUpdateAdditionalInfo() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + key = "BBB BBB"; + value = "BBBB"; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "BBB BBB", fromJson.getKey()); + + String updatedKey = "AAA AAA"; + String updatedValue = "JJJJ"; + + fromJson.setKey(updatedKey); + fromJson.setValue(updatedValue); + + RestResponse updatedProperty = updateAdditionalInformation(resourceId, fromJson, user, fromJson.getUniqueId()); + assertNotNull("check response object is not null after update additional information", updatedProperty); + assertNotNull("check error code exists in response after additional information", updatedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 409, updatedProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceEmptyAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = ""; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + key = "BBBB"; + value = ""; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceEmptyAdditionalInformationTest() throws Exception { + + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = ""; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceAllSpacesAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = " "; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceAllSpacesAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = " "; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceInvalidKeyAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "abc?"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceInvalidKeyAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "abc?"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceAdditionalInformationNullKeyTest() throws Exception { + + User user = getUser(); + ResourceReqDetails resource = getResource(); + + RestResponse createResourceResponse = createResource(resource, user); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + String key = null; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceAdditionalInformationNullKeyTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = null; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceMaximumInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + for (int i = 0; i < 50; i++) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + i, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceLifeCycleAndMaximumInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + resource.setUniqueId(resourceId); + + String key = "AAA AAA"; + String value = "BBBB"; + + for (int i = 0; i < 49; i++) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + i, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } + + String resourceVersion = "0.1"; + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + + assertNotNull("check response object is not null after create property", checkInResponse); + assertNotNull("check error code exists in response after create property", checkInResponse.getErrorCode()); + assertEquals("Check response code after create property", 200, checkInResponse.getErrorCode().intValue()); + + resourceVersion = "0.2"; + + RestResponse checkOutResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT, null); + + resourceId = ResponseParser.getUniqueIdFromResponse(checkOutResponse); + resource.setUniqueId(resourceId); + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 50, value); + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 51, value); + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + RestResponse checkUndoOutResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.UNDOCHECKOUT, null); + + resourceVersion = "0.1"; + + checkOutResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT, null); + resourceId = ResponseParser.getUniqueIdFromResponse(checkOutResponse); + resource.setUniqueId(resourceId); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 50, value); + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 51, value); + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createResourceLifeCycleCertifyAndMaximumInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + resource.setUniqueId(resourceId); + + String key = "AAA AAA"; + String value = "BBBB"; + + for (int i = 0; i < 49; i++) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + i, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } + + String resourceVersion = "0.1"; + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + + // resourceUtils.addResourceMandatoryArtifacts(user, + // createResourceResponse); + + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + + assertNotNull("check response object is not null after create property", checkInResponse); + assertNotNull("check error code exists in response after create property", checkInResponse.getErrorCode()); + assertEquals("Check response code after create property", 200, checkInResponse.getErrorCode().intValue()); + + RestResponse changeStateResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST, null); + changeStateResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.STARTCERTIFICATION, null); + changeStateResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CERTIFY, null); + + assertNotNull("check response object is not null after create property", checkInResponse); + assertNotNull("check error code exists in response after create property", checkInResponse.getErrorCode()); + assertEquals("Check response code after create property", 200, checkInResponse.getErrorCode().intValue()); + + resourceId = ResponseParser.getUniqueIdFromResponse(changeStateResponse); + resource.setUniqueId(resourceId); + + resourceVersion = "1.0"; + + changeStateResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT, null); + resourceId = ResponseParser.getUniqueIdFromResponse(changeStateResponse); + resource.setUniqueId(resourceId); + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 50, value); + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 51, value); + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceCycleAndMaximumInformationTest() throws Exception { + + User user = getUser(); + + ServiceReqDetails service = getServiceDetails(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + assertNotNull("check response object is not null after create resource", createServiceResponse); + assertNotNull("check error code exists in response after create resource", createServiceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createServiceResponse.getErrorCode().intValue()); + + service.setUniqueId(serviceId); + + String key = "AAA AAA"; + String value = "BBBB"; + + for (int i = 0; i < 49; i++) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + i, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } + + String resourceVersion = "0.1"; + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + RestResponse checkInResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CHECKIN, checkinComentJson); + + assertNotNull("check response object is not null after create property", checkInResponse); + assertNotNull("check error code exists in response after create property", checkInResponse.getErrorCode()); + assertEquals("Check response code after create property", 200, checkInResponse.getErrorCode().intValue()); + + resourceVersion = "0.2"; + + RestResponse checkOutResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT, null); + + serviceId = ResponseParser.convertServiceResponseToJavaObject(checkOutResponse.getResponse()).getUniqueId(); + service.setUniqueId(serviceId); + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 50, value); + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 51, value); + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + RestResponse checkUndoOutResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.UNDOCHECKOUT, null); + + resourceVersion = "0.1"; + + checkOutResponse = LifecycleRestUtils.changeServiceState(service, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT, null); + serviceId = ResponseParser.convertServiceResponseToJavaObject(checkOutResponse.getResponse()).getUniqueId(); + service.setUniqueId(serviceId); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 50, value); + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + 51, value); + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + } + + @Test + public void createServiceMaximumInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + String lastCreatedProperty = null; + + for (int i = 0; i < 50; i++) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key + i, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + lastCreatedProperty = fromJson.getUniqueId(); + + } + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 409, createProperty.getErrorCode().intValue()); + + RestResponse deletedProperty = deleteServiceAdditionalInformation(serviceId, lastCreatedProperty, user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } + + @Test + public void updateServiceAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + String updatedKey = "ZZZ ZZZ"; + String updatedValue = "JJJJ"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + fromJson.setKey(updatedKey); + fromJson.setValue(updatedValue); + + RestResponse updatedProperty = updateServiceAdditionalInformation(serviceId, fromJson, user, fromJson.getUniqueId()); + assertNotNull("check response object is not null after update additional information", updatedProperty); + assertNotNull("check error code exists in response after additional information", updatedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, updatedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(updatedProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + assertEquals("check returned key", "ZZZ ZZZ", updatedJson.getKey()); + assertEquals("check returned value", updatedValue, updatedJson.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + fromJson.setKey(updatedKey); + fromJson.setValue(""); + + updatedProperty = updateServiceAdditionalInformation(serviceId, fromJson, user, fromJson.getUniqueId()); + assertNotNull("check response object is not null after update additional information", updatedProperty); + assertNotNull("check error code exists in response after additional information", updatedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 400, updatedProperty.getErrorCode().intValue()); + + } + + @Test + public void deleteServiceAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = deleteServiceAdditionalInformation(serviceId, fromJson.getUniqueId(), user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", updatedJson.getKey()); + assertEquals("check returned value", value, updatedJson.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + deletedProperty = deleteServiceAdditionalInformation(serviceId, fromJson.getUniqueId(), user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 409, deletedProperty.getErrorCode().intValue()); + + } + + @Test + public void getResourceAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = getAdditionalInformation(resourceId, fromJson.getUniqueId(), user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", updatedJson.getKey()); + assertEquals("check returned value", value, updatedJson.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + } + + @Test + public void getServiceAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = getServiceAdditionalInformation(serviceId, fromJson.getUniqueId(), user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", updatedJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", updatedJson.getKey()); + assertEquals("check returned value", value, updatedJson.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), updatedJson.getUniqueId()); + + } + + @Test + public void getResourceAllAdditionalInformationTest() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = getResourceAllAdditionalInformation(resourceId, user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInformationDefinition updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInformationDefinition.class); + assertEquals("check number of parameters", 1, updatedJson.getParameters().size()); + AdditionalInfoParameterInfo info = updatedJson.getParameters().iterator().next(); + + assertFalse("check number of spaces", info.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", info.getKey()); + assertEquals("check returned value", value, info.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), info.getUniqueId()); + + } + + @Test + public void getServiceAllAdditionalInformationTest() throws Exception { + User user = getUser(); + + RestResponse createServiceResponse = createService(); + + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + RestResponse deletedProperty = getServiceAllAdditionalInformation(serviceId, user); + assertNotNull("check response object is not null after update additional information", deletedProperty); + assertNotNull("check error code exists in response after additional information", deletedProperty.getErrorCode()); + assertEquals("Check response code after additional information", 200, deletedProperty.getErrorCode().intValue()); + + AdditionalInformationDefinition updatedJson = gson.fromJson(deletedProperty.getResponse(), AdditionalInformationDefinition.class); + assertEquals("check number of parameters", 1, updatedJson.getParameters().size()); + AdditionalInfoParameterInfo info = updatedJson.getParameters().iterator().next(); + + assertFalse("check number of spaces", info.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", info.getKey()); + assertEquals("check returned value", value, info.getValue()); + assertEquals("check returned id", fromJson.getUniqueId(), info.getUniqueId()); + + } + + @Test + public void createServiceAdditionalInformationTestDuringLifecycle() throws Exception { + + User user = getUser(); + RestResponse createServiceResponse = createService(); + String serviceId = ResponseParser.convertServiceResponseToJavaObject(createServiceResponse.getResponse()).getUniqueId(); + String key = "AAA AAA"; + String value = "BBBB"; + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createServiceAdditionalInformation(serviceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + AdditionalInfoParameterInfo fromJson = gson.fromJson(createProperty.getResponse(), AdditionalInfoParameterInfo.class); + assertFalse("check number of spaces", fromJson.getKey().contains(" ")); + assertEquals("check returned key", "AAA AAA", fromJson.getKey()); + + ServiceReqDetails serviceDetails = getServiceDetails(); + + serviceDetails.setUniqueId(serviceId); + + // serviceUtils.addServiceMandatoryArtifacts(user, + // createServiceResponse); + + certifyService(user, serviceDetails, null); + + } + + @Test + public void createCascadeResource() { + + // TODO: to check after rebase + + User user = getUser(); + ResourceReqDetails resource = getResource(); + String newResourceNameSuffix = "aa"; + + RestResponse createResourceResponse = null; + try { + + createResourceResponse = createResource(resource, user); + assertEquals("check invalid type", 201, createResourceResponse.getErrorCode().intValue()); + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + String resourceVersion = "0.1"; + // resourceUtils.addResourceMandatoryArtifacts(user, + // createResourceResponse); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + resource.setUniqueId(resourceId); + Resource certifiedResource = certifyResource(user, resource, resourceVersion, 1); + + ResourceReqDetails newResourceDetails = getResource(); + String newResourceName = newResourceDetails.getName() + newResourceNameSuffix; + newResourceDetails.setName(newResourceName); + List derivedFrom = new ArrayList<>(); + derivedFrom.add(certifiedResource.getName()); + newResourceDetails.setDerivedFrom(derivedFrom); + newResourceDetails.getTags().add(newResourceName); + + user.setUserId(UserRoleEnum.ADMIN.getUserId()); + RestResponse newCreateResourceResponse = createResource(newResourceDetails, user); + assertEquals("Check response code after creating resource", 201, newCreateResourceResponse.getErrorCode().intValue()); + Resource newResource = gson.fromJson(newCreateResourceResponse.getResponse(), Resource.class); + + RestResponse allAdditionalInformation = getResourceAllAdditionalInformation(newResource.getUniqueId(), user); + + assertNotNull("check response object is not null after update additional information", allAdditionalInformation); + assertNotNull("check error code exists in response after additional information", allAdditionalInformation.getErrorCode()); + assertEquals("Check response code after additional information", 200, allAdditionalInformation.getErrorCode().intValue()); + + AdditionalInformationDefinition updatedJson = gson.fromJson(allAdditionalInformation.getResponse(), AdditionalInformationDefinition.class); + assertEquals("check number of parameters", 0, updatedJson.getParameters().size()); + // AdditionalInfoParameterInfo info = + // updatedJson.getParameters().iterator().next(); + + String newResourceId = newResource.getUniqueId(); + createProperty = createResourceAdditionalInformation(newResourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + allAdditionalInformation = getResourceAllAdditionalInformation(newResourceId, user); + + assertNotNull("check response object is not null after update additional information", allAdditionalInformation); + assertNotNull("check error code exists in response after additional information", allAdditionalInformation.getErrorCode()); + assertEquals("Check response code after additional information", 200, allAdditionalInformation.getErrorCode().intValue()); + + updatedJson = gson.fromJson(allAdditionalInformation.getResponse(), AdditionalInformationDefinition.class); + assertEquals("check number of parameters", 1, updatedJson.getParameters().size()); + + } catch (IOException e) { + assertTrue(false); + } + + } + + @Test + public void createSamePropertyAfterCiCOResource() { + + User user = getUser(); + ResourceReqDetails resource = getResource(); + + RestResponse createResourceResponse = null; + try { + + createResourceResponse = createResource(resource, user); + assertEquals("check invalid type", 201, createResourceResponse.getErrorCode().intValue()); + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + String resourceVersion = "0.1"; + // resourceUtils.addResourceMandatoryArtifacts(user, + // createResourceResponse); + + String key = "AAA AAA"; + String value = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + resource.setUniqueId(resourceId); + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKIN); + + assertNotNull("check response object is not null after create user", checkInResponse); + assertNotNull("check error code exists in response after create user", checkInResponse.getErrorCode()); + assertEquals("Check response code after create user", 200, checkInResponse.getErrorCode().intValue()); + + Resource resourceAfterOperation = gson.fromJson(checkInResponse.getResponse(), Resource.class); + assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().size()); + assertEquals("check size of additional information", 1, resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + + RestResponse checkOutResponse = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT); + + assertNotNull("check response object is not null after create user", checkOutResponse); + assertNotNull("check error code exists in response after create user", checkOutResponse.getErrorCode()); + assertEquals("Check response code after create user", 200, checkOutResponse.getErrorCode().intValue()); + + Resource resourceAfterCoOperation = gson.fromJson(checkOutResponse.getResponse(), Resource.class); + assertEquals("check size of additional information", 1, resourceAfterCoOperation.getAdditionalInformation().size()); + assertEquals("check size of additional information", 1, resourceAfterCoOperation.getAdditionalInformation().get(0).getParameters().size()); + + String newResourceId = ResponseParser.getUniqueIdFromResponse(checkOutResponse); + + String key2 = "ZZZ"; + String value2 = "BBBB"; + + AdditionalInfoParameterInfo additionalInfoParameterInfo2 = new AdditionalInfoParameterInfo(null, key2, value2); + + RestResponse createProperty2 = createResourceAdditionalInformation(newResourceId, additionalInfoParameterInfo2, user); + assertNotNull("check response object is not null after create property", createProperty2); + assertNotNull("check error code exists in response after create property", createProperty2.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty2.getErrorCode().intValue()); + + RestResponse afterCreateAI = ResourceRestUtils.getResource(user, newResourceId); + Resource resourceNew = gson.fromJson(afterCreateAI.getResponse(), Resource.class); + assertEquals("check size of additional information", 1, resourceNew.getAdditionalInformation().size()); + assertEquals("check size of additional information", 2, resourceNew.getAdditionalInformation().get(0).getParameters().size()); + + resource.setUniqueId(newResourceId); + Resource certifiedResource = certifyResource(user, resource, resourceVersion, 2); + assertEquals("check size of additional information", 1, certifiedResource.getAdditionalInformation().size()); + assertEquals("check size of additional information", 2, certifiedResource.getAdditionalInformation().get(0).getParameters().size()); + + user.setUserId(UserRoleEnum.DESIGNER.getUserId()); + resource.setUniqueId(certifiedResource.getUniqueId()); + RestResponse checkOutResponseAfterCertify = LifecycleRestUtils.changeResourceState(resource, user, resourceVersion, LifeCycleStatesEnum.CHECKOUT); + + assertNotNull("check response object is not null after create user", checkOutResponseAfterCertify); + assertNotNull("check error code exists in response after create user", checkOutResponseAfterCertify.getErrorCode()); + assertEquals("Check response code after create user", 200, checkOutResponseAfterCertify.getErrorCode().intValue()); + + Resource resourceAfterCertifyCoOperation = gson.fromJson(checkOutResponseAfterCertify.getResponse(), Resource.class); + assertEquals("check size of additional information", 1, resourceAfterCertifyCoOperation.getAdditionalInformation().size()); + assertEquals("check size of additional information", 2, resourceAfterCertifyCoOperation.getAdditionalInformation().get(0).getParameters().size()); + + } catch (IOException e) { + assertTrue(false); + } + + } + + // public Resource certifyService(User user, ServiceReqDetails service, + // String resourceVersion) throws Exception { + // + // RestResponse checkInResponse = + // LifecycleRestUtils.changeServiceState(service, user, resourceVersion, + // LifeCycleStates.CHECKIN); + // + // assertNotNull("check response object is not null after create user", + // checkInResponse); + // assertNotNull("check error code exists in response after create user", + // checkInResponse.getErrorCode()); + // assertEquals("Check response code after create user", 200, + // checkInResponse.getErrorCode().intValue()); + // + // Resource resourceAfterOperation = + // gson.fromJson(checkInResponse.getResponse(), Resource.class); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().size()); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + // + //// TODO Andrey + // createAndAddCertResourceToService(service, user); + // + // RestResponse req4certResponse = + // LifecycleRestUtils.changeServiceState(service, user, resourceVersion, + // LifeCycleStates.CERTIFICATIONREQUEST); + // + // assertNotNull("check response object is not null after create user", + // req4certResponse); + // assertEquals("Check response code after checkout resource", 200, + // req4certResponse.getErrorCode().intValue()); + // + // resourceAfterOperation = gson.fromJson(req4certResponse.getResponse(), + // Resource.class); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().size()); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + // + // //change modifier + // user.setUserId(UserRoleEnum.TESTER.getUserId()); + // + // //start certification + // RestResponse startCertResourceResponse3 = + // LifecycleRestUtils.changeServiceState(service, user, resourceVersion, + // LifeCycleStates.STARTCERTIFICATION); + // assertNotNull("check response object is not null after create user", + // startCertResourceResponse3); + // assertEquals("Check response code after checkout resource", 200, + // startCertResourceResponse3.getErrorCode().intValue()); + // + // resourceAfterOperation = + // gson.fromJson(startCertResourceResponse3.getResponse(), Resource.class); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().size()); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + // + // //certify + // + // RestResponse certifyResponse = + // LifecycleRestUtils.changeServiceState(service, user, resourceVersion, + // LifeCycleStates.CERTIFY); + // assertNotNull("check response object is not null after create user", + // certifyResponse); + // assertEquals("Check response code after checkout resource", 200, + // certifyResponse.getErrorCode().intValue()); + // + // resourceAfterOperation = gson.fromJson(certifyResponse.getResponse(), + // Resource.class); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().size()); + // assertEquals("check size of additional information", 1, + // resourceAfterOperation.getAdditionalInformation().get(0).getParameters().size()); + // + // Resource certifyResource = gson.fromJson(certifyResponse.getResponse(), + // Resource.class); + // return certifyResource; + // } + + private void createAndAddCertResourceToService(ServiceReqDetails serviceDetails, User user) throws Exception { + + User sdncTesterUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + + RestResponse response = ResourceRestUtils.createResource(resourceDetails, user); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetails.getUniqueId()); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, user, resourceDetails.getUniqueId()); + assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), response.getErrorCode() == 200); + + // certified resource + // response = LCSbaseTest.certifyResource(resourceDetails); + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user, LifeCycleStatesEnum.CHECKIN); + assertTrue("certify resource request returned status:" + restResponseResource.getErrorCode(), response.getErrorCode() == 200); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, user, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertTrue("certify resource request returned status:" + restResponseResource.getErrorCode(), response.getErrorCode() == 200); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterUser, LifeCycleStatesEnum.STARTCERTIFICATION); + assertTrue("certify resource request returned status:" + restResponseResource.getErrorCode(), response.getErrorCode() == 200); + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterUser, LifeCycleStatesEnum.CERTIFY); + assertTrue("certify resource request returned status:" + restResponseResource.getErrorCode(), response.getErrorCode() == 200); + + // add resource instance with HEAT deployment artifact to the service + restResponseResource = LifecycleRestUtils.changeServiceState(serviceDetails, user, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertTrue("certify resource request returned status:" + restResponseResource.getErrorCode(), response.getErrorCode() == 200); + resourceInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, user, serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + assertTrue("response code is not 201, returned: " + response.getErrorCode(), response.getErrorCode() == 201); + } + + @Test + public void createResourceAdditionalInformationTestAddValue() throws Exception { + User user = getUser(); + ResourceReqDetails resource = getResource(); + + // deleteResource(resourceId, user); + RestResponse createResourceResponse = createResource(resource, user); + + String resourceId = ResponseParser.getUniqueIdFromResponse(createResourceResponse); + + assertNotNull("check response object is not null after create resource", createResourceResponse); + assertNotNull("check error code exists in response after create resource", createResourceResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResourceResponse.getErrorCode().intValue()); + + String key = "AAA AAA"; + String value = ""; + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + RestResponse createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + value = ""; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 400, createProperty.getErrorCode().intValue()); + + value = "----<>;"; + + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(null, key, value); + + createProperty = createResourceAdditionalInformation(resourceId, additionalInfoParameterInfo, user); + assertNotNull("check response object is not null after create property", createProperty); + assertNotNull("check error code exists in response after create property", createProperty.getErrorCode()); + assertEquals("Check response code after create property", 201, createProperty.getErrorCode().intValue()); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentInstancePropertyTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentInstancePropertyTest.java new file mode 100644 index 0000000000..6ba1b2ccca --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentInstancePropertyTest.java @@ -0,0 +1,1263 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.property; + +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.PropertyTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.PropertyRestUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import fj.data.Either; + +// open bug for this class: DE199108 - closed, DE199741 +public class ComponentInstancePropertyTest extends ComponentBaseTest { + + protected Resource basicVFC; + protected Resource vfc1FromBasicVFC; + protected Resource vfc2FromVfc1; + protected Resource vfResource; + + private List expectedPropertyList; + private List actualPropertyList; + // protected String updatedStringValue = "{Not Default String Value}"; + protected String updatedStringValue = "Not Default String Value"; + protected String updatedIntegerValue = "666"; + protected String updatedBooleanValue = "false"; + protected String newStringPropName = "stringProp2"; + protected String newIntegerPropName = "integerProp2"; + protected String newBooleanPropName = "booleanProp2"; + // bug DE199741 protected String newStringPropValue = ""; + protected String newStringPropValue = "second string value"; + protected String newIntegerPropValue = "888"; + protected String newBooleanPropValue = "false"; + + @BeforeMethod + public void init() { + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + } + + @Rule + public static TestName name = new TestName(); + + public ComponentInstancePropertyTest() { + super(name, ComponentInstancePropertyTest.class.getName()); + } + + // --------------Regular + // resource------------------------------------------------------------------------------- + + @Test + public void nestedResourceProperty3Levels() throws Exception { + + // first res + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + // second resource + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + // third resource + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + // verify property + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, actualPropertyList); + assertTrue("check list size failed, expected 3", actualPropertyList.size() == 3); + + } + + // --------------VF + // resource----------------------------------------------------------- + + @Test + public void nestedVfResourceProperty3Levels() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + // verify property + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + } + + @Test + public void nestedVfResourceProperty3LevelsAndCpWithProp() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // four resource + Resource cp = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, + NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails cpStringProperty = ElementFactory.getDefaultStringProperty(); + cpStringProperty.setName("Different Name"); + cpStringProperty.setPropertyDefaultValue("Different value from default"); + AtomicOperationUtils.addCustomPropertyToResource(cpStringProperty, cp, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + cp = AtomicOperationUtils.getResourceObject(cp, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(cp, expectedPropertyList); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, vfResource, UserRoleEnum.DESIGNER, true).left().value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, cp, expectedPropertyList, + vfResource); + // verify property + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + } + + @Test + public void nestedCertifiedVfResourceProperty3Levels() throws Exception { + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CERTIFY, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + // verify property + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + } + + @Test + public void nestedVfResourceProperty3Levels2SameResInstances() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + // verify property + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + } + + // ------------------update resource + // property----------------------------------- + + @Test + public void nestedVfResourceProperty3LevelsUpdateFirstLevelProperty() throws Exception { + // first res + basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addDefaultPropertyToResource(PropertyTypeEnum.STRING, basicVFC, UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + + // verify property + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedStringValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(vfResource, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + @Test + public void nestedVfResourceProperty3LevelsUpdateSecondLevelProperty() throws Exception { + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + + // second resource + vfc1FromBasicVFC = AtomicOperationUtils.createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, + basicVFC, ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true).left().value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addCustomPropertyToResource(ElementFactory.getDefaultIntegerProperty(), vfc1FromBasicVFC, + UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(vfc1FromBasicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, + true); + + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + + // verify property + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedIntegerValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(vfResource, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue( + "expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS + + " ,but was " + updatePropertyValueOnResourceInstance.getErrorCode(), + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated properly", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + @Test + public void nestedVfResourceProperty3LevelsUpdateThirdLevelProperty() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + + // third resource + vfc2FromVfc1 = AtomicOperationUtils.createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, + vfc1FromBasicVFC, ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true).left().value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addCustomPropertyToResource(ElementFactory.getDefaultBooleanProperty(), vfc2FromVfc1, + UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(vfc2FromVfc1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, + true); + + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + + // verify property + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedBooleanValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(vfResource, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + // ---------------------Service------------------------------------------------------------------------ + + /** + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p3) (p2) (p1) + */ + @Test + public void serviceWithNestedResourceProperty3Levels() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + /** + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) + */ + @Test + public void serviceWithNestedResourceProperty3LevelsAndVfProperty() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + PropertyReqDetails propDetails = ElementFactory.getDefaultBooleanProperty(); + propDetails.setName(newBooleanPropName); + propDetails.setPropertyDefaultValue(newBooleanPropValue); + AtomicOperationUtils.addCustomPropertyToResource(propDetails, vfResource, UserRoleEnum.DESIGNER, true); + propDetails = ElementFactory.getDefaultStringProperty(); + propDetails.setName(newStringPropName); + propDetails.setPropertyDefaultValue(newStringPropValue); + AtomicOperationUtils.addCustomPropertyToResource(propDetails, vfResource, UserRoleEnum.DESIGNER, true); + propDetails = ElementFactory.getDefaultIntegerProperty(); + propDetails.setName(newIntegerPropName); + propDetails.setPropertyDefaultValue(newIntegerPropValue); + AtomicOperationUtils.addCustomPropertyToResource(propDetails, vfResource, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfResource, expectedPropertyList); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + /** + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) CP(VF inst) (p5) + */ + @Test + public void serviceWithNestedResourceProperty3LevelsAndCp() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // four resource + Resource cp = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, + NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails cpStringProperty = ElementFactory.getDefaultStringProperty(); + cpStringProperty.setName("Different Name"); + cpStringProperty.setPropertyDefaultValue("Different value from default"); + AtomicOperationUtils.addCustomPropertyToResource(cpStringProperty, cp, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + cp = AtomicOperationUtils.getResourceObject(cp, UserRoleEnum.DESIGNER); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(cp, expectedPropertyList); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, vfResource, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, cp, expectedPropertyList, + vfResource); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + /** + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) CP(inst) (p5) + */ + @Test + public void serviceWithNestedResourceProperty3LevelsAndCpResInst() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + // expectedPropertyList = + // PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, + // expectedPropertyList); + + // four resource + Resource cp = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, + NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails cpStringProperty = ElementFactory.getDefaultStringProperty(); + cpStringProperty.setName("Different Name"); + cpStringProperty.setPropertyDefaultValue("Different value from default"); + AtomicOperationUtils.addCustomPropertyToResource(cpStringProperty, cp, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(cp, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + cp = AtomicOperationUtils.getResourceObject(cp, UserRoleEnum.DESIGNER); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(cp, expectedPropertyList); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, service, UserRoleEnum.DESIGNER, true).left().value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + /** + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) | (p3) (p2) (p1) + * | (VFC(inst)-->VFC-->VFC-->VFC) (p3) (p2) (p1) + * + * VF2(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) | (p3') (p2') (p1') | + * (VFC(inst)-->VFC-->VFC-->VFC) (p3) (p2) (p1) + */ + @Test + public void serviceNestedVfResourceProperty3Levels2SameResInstances() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, expectedPropertyList); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + // verify property + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnResource(componentInstDetails, vfc2FromVfc1, expectedPropertyList, + vfResource); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + // service test template + /** + * Service-->VF(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) + */ + @Test + public void serviceNestedVfResourceProperty3LevelsAndSelfVfProperty() throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + PropertyReqDetails newProp = ElementFactory.getDefaultStringProperty(); + newProp.setName(newStringPropName); + newProp.setPropertyDefaultValue(newStringPropValue); + AtomicOperationUtils.addCustomPropertyToResource(newProp, vfResource, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + } + + /** + * update property(p4) + * + * + * VFC(p1) ^ | VFC(p2) ^ | Service-->VF(inst)-->VF-->(VFC(inst)-->VFC(p3) + * (p4) + */ + @Test + public void serviceNestedVfResourceProperty3LevelsAndSelfVfProperty_UpdateVfproperty() throws Exception { + // Create VFC(check-in state) derived from another resource + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + + // add property to VF + PropertyReqDetails newProp = ElementFactory.getDefaultStringProperty(); + newProp.setName(newStringPropName); + newProp.setPropertyDefaultValue(newStringPropValue); + Either propDetailsToUpdate = AtomicOperationUtils + .addCustomPropertyToResource(newProp, vfResource, UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update VF instance property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedStringValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + /** + * update property(p1) + * Service-->VF(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) + */ + @Test + public void serviceNestedVfResourceProperty3LevelsAndSelfVfPropertyUpdateVfInheritance1LevelProperty() + throws Exception { + + basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addDefaultPropertyToResource(PropertyTypeEnum.STRING, basicVFC, UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + // verify property + PropertyReqDetails newProp = ElementFactory.getDefaultStringProperty(); + newProp.setName(newStringPropName); + newProp.setPropertyDefaultValue(newStringPropValue); + AtomicOperationUtils.addCustomPropertyToResource(newProp, vfResource, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update VF property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedStringValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + /** + * update property(p2) + * Service-->VF(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) + */ + @Test + public void serviceNestedVfResourceProperty3LevelsAndSelfVfPropertyUpdateVfInheritance2LevelProperty() + throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = AtomicOperationUtils.createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, + basicVFC, ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true).left().value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addCustomPropertyToResource(ElementFactory.getDefaultIntegerProperty(), vfc1FromBasicVFC, + UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(vfc1FromBasicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, + true); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + + // verify property + PropertyReqDetails newProp = ElementFactory.getDefaultStringProperty(); + newProp.setName(newStringPropName); + newProp.setPropertyDefaultValue(newStringPropValue); + AtomicOperationUtils.addCustomPropertyToResource(newProp, vfResource, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update VF property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedIntegerValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + /** + * update property(p3) + * Service-->VF(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) + */ + @Test + public void serviceNestedVfResourceProperty3LevelsAndSelfVfPropertyUpdateVfInheritance3LevelProperty() + throws Exception { + + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = AtomicOperationUtils.createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, + vfc1FromBasicVFC, ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true).left().value(); + Either propDetailsToUpdate = AtomicOperationUtils + .addCustomPropertyToResource(ElementFactory.getDefaultBooleanProperty(), vfc2FromVfc1, + UserRoleEnum.DESIGNER, true); + String propNameToUpdate = propDetailsToUpdate.left().value().getName(); + String propTypeToUpdate = propDetailsToUpdate.left().value().getType(); + AtomicOperationUtils.changeComponentState(vfc2FromVfc1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, + true); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + // verify property + PropertyReqDetails newProp = ElementFactory.getDefaultStringProperty(); + newProp.setName(newStringPropName); + newProp.setPropertyDefaultValue(newStringPropValue); + AtomicOperationUtils.addCustomPropertyToResource(newProp, vfResource, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + // update VF property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils + .getPropFromListByPropNameAndType(actualPropertyList, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedBooleanValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, null); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + + } + + /** + * update property p5' + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) CP(inst on VF) (p5) CP(inst) (p5') + */ + @Test + public void serviceWithNestedResourceProperty3LevelsAndCpOnVfUpdateCpInstanceOfService() throws Exception { + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CHECKIN, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + // expectedPropertyList = + // PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, + // expectedPropertyList); + + // four resource + Resource cp = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, + NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails cpStringProperty = ElementFactory.getDefaultStringProperty(); + cpStringProperty.setName("Different Name"); + cpStringProperty.setPropertyDefaultValue("Different value from default"); + AtomicOperationUtils.addCustomPropertyToResource(cpStringProperty, cp, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(cp, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + cp = AtomicOperationUtils.getResourceObject(cp, UserRoleEnum.DESIGNER); + // create VF + add RI + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, vfResource, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(cp, expectedPropertyList); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, service, UserRoleEnum.DESIGNER, true).left().value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + // service = AtomicOperationUtils.getServiceObject(service, + // UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + String propNameToUpdate = "cidr"; + String propTypeToUpdate = "string"; + + // update CP property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils.getCompPropInstListByInstIdAndPropName( + service, componentInstDetails, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedStringValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + List path = expectedUpdatePropDetails.getPath(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, path); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + } + + /** + * update property p5 + * Service-->VF1(inst)-->VF-->(VFC(inst)-->VFC-->VFC-->VFC) (p4) (p3) (p2) + * (p1) CP(inst on VF) (p5) CP(inst) (p5') + */ + @Test + public void serviceWithNestedResourceProperty3LevelsAndCpOnVfUpdateCpInstanceOfVf() throws Exception { + basicVFC = createResourceWithProperty(ElementFactory.getDefaultStringProperty(), LifeCycleStatesEnum.CERTIFY); + vfc1FromBasicVFC = createResourceWithPropertyDerivedFromOtherResource( + ElementFactory.getDefaultIntegerProperty(), LifeCycleStatesEnum.CERTIFY, basicVFC); + vfc2FromVfc1 = createResourceWithPropertyDerivedFromOtherResource(ElementFactory.getDefaultBooleanProperty(), + LifeCycleStatesEnum.CERTIFY, vfc1FromBasicVFC); + vfc2FromVfc1 = AtomicOperationUtils.getResourceObject(vfc2FromVfc1, UserRoleEnum.DESIGNER); + // expectedPropertyList = + // PropertyRestUtils.addResourcePropertiesToList(vfc2FromVfc1, + // expectedPropertyList); + + // four resource + Resource cp = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, + NormativeTypesEnum.NETWORK, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails cpStringProperty = ElementFactory.getDefaultStringProperty(); + cpStringProperty.setName("Different Name"); + cpStringProperty.setPropertyDefaultValue("Different value from default"); + AtomicOperationUtils.addCustomPropertyToResource(cpStringProperty, cp, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(cp, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + // create VF + add RI + cp = AtomicOperationUtils.getResourceObject(cp, UserRoleEnum.DESIGNER); + vfResource = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left() + .value(); + ComponentInstance componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfc2FromVfc1, vfResource, UserRoleEnum.DESIGNER, true).left() + .value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, vfResource, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.changeComponentState(vfResource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + vfResource = AtomicOperationUtils.getResourceObject(vfResource, UserRoleEnum.DESIGNER); + + // Service + expectedPropertyList = new ArrayList(); + actualPropertyList = new ArrayList(); + expectedPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(vfResource, expectedPropertyList, + null); + expectedPropertyList = PropertyRestUtils.addResourcePropertiesToList(cp, expectedPropertyList); + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vfResource, service, UserRoleEnum.DESIGNER, true).left() + .value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + componentInstDetails = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp, service, UserRoleEnum.DESIGNER, true).left().value(); + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + PropertyRestUtils.updatePropertyListWithPathOnComponentInstance(componentInstDetails, service, + expectedPropertyList); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + PropertyRestUtils.comparePropertyLists(expectedPropertyList, actualPropertyList, false); + + String propNameToUpdate = "cidr"; + String propTypeToUpdate = "string"; + + // update CP property + ComponentInstanceProperty expectedUpdatePropDetails = PropertyRestUtils.getCompPropInstListByInstIdAndPropName( + service, componentInstDetails, propNameToUpdate, propTypeToUpdate); + expectedUpdatePropDetails.setValue(updatedStringValue); + String propUniqeId = expectedUpdatePropDetails.getUniqueId(); + List path = expectedUpdatePropDetails.getPath(); + RestResponse updatePropertyValueOnResourceInstance = ComponentInstanceRestUtils + .updatePropertyValueOnResourceInstance(service, componentInstDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), expectedUpdatePropDetails); + assertTrue("expected updatePropertyValueOnResourceInstance response code: " + BaseRestUtils.STATUS_CODE_SUCCESS, + updatePropertyValueOnResourceInstance.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + service = AtomicOperationUtils.getServiceObject(service, UserRoleEnum.DESIGNER); + + actualPropertyList = new ArrayList<>(); + actualPropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, actualPropertyList, null); + + ComponentInstanceProperty actualUpdatedPropDetails = PropertyRestUtils + .getPropFromListByPropIdAndPath(actualPropertyList, propUniqeId, path); + assertTrue("property was not updated propely", + PropertyRestUtils.comparePropertyObjects(expectedUpdatePropDetails, actualUpdatedPropDetails, true)); + } + + // -------------------Methods-------------------------- + public static PropertyDataDefinition convertToPropertyDataDefinitionObject(PropertyReqDetails prop) { + PropertyDataDefinition propDataDef = new PropertyDataDefinition(); + propDataDef.setDefaultValue(prop.getPropertyDefaultValue()); + propDataDef.setType(prop.getPropertyType()); + propDataDef.setPassword(prop.getPropertyPassword()); + propDataDef.setDescription(prop.getPropertyDescription()); + return propDataDef; + } + + protected Resource createResourceWithPropertyDerivedFromOtherResource(PropertyReqDetails propertyReqDetails, + LifeCycleStatesEnum state, Resource derivedFromResource) throws Exception { + Resource resource = AtomicOperationUtils.createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, + derivedFromResource, ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true).left() + .value(); + if (propertyReqDetails != null) { + AtomicOperationUtils.addCustomPropertyToResource(propertyReqDetails, resource, UserRoleEnum.DESIGNER, true); + } + AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, state, true); + return AtomicOperationUtils.getResourceObject(resource, UserRoleEnum.DESIGNER); + // return resource; + } + + protected Resource createResourceWithProperty(PropertyReqDetails propertyReqDetails, LifeCycleStatesEnum state) + throws Exception { + Resource resource = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + if (propertyReqDetails != null) { + AtomicOperationUtils.addCustomPropertyToResource(propertyReqDetails, resource, UserRoleEnum.DESIGNER, true); + } + AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, state, true); + return AtomicOperationUtils.getResourceObject(resource, UserRoleEnum.DESIGNER); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentProperty.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentProperty.java new file mode 100644 index 0000000000..e1c4c18270 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/ComponentProperty.java @@ -0,0 +1,1796 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.property; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.PropertyTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +public class ComponentProperty extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public ComponentProperty() { + super(name, ComponentProperty.class.getName()); + } + + @DataProvider + private static final Object[][] propertiesListDefaultValueSuccessFlow() throws IOException, Exception { + return new Object[][] { + // integer + { "integer", "[1,2]", "[1,2]" }, + { "tosca.datatypes.Credential", + "[{\"protocol\":\"protocol1\",\"token\":\"token1\"},{\"protocol\":\"protocol2\",\"token\":\"token2\"}]", + "[{\"protocol\":\"protocol1\",\"token\":\"token1\"},{\"protocol\":\"protocol2\",\"token\":\"token2\"}]" }, + { "tosca.datatypes.Credential", + "[{\"protocol\":\"protocol1\",\"token\":\"token1\"},{\"protocol\":\"protocol
2\",\"token\":\"token2 2\"}]", + "[{\"protocol\":\"protocol1\",\"token\":\"token1\"},{\"protocol\":\"protocol2\",\"token\":\"token2 2\"}]" }, + { "tosca.datatypes.Credential", null, null }, { "tosca.datatypes.Credential", "[]", "[]" }, + { "integer", "[1,2,1,2]", "[1,2,1,2]" }, { "integer", "[1,,2]", "[1,2]" }, + { "integer", "[1,null,2]", "[1,2]" }, { "integer", "[1,2,null]", "[1,2]" }, + { "integer", "[null,1,2]", "[1,2]" }, { "integer", "[1,,2]", "[1,2]" }, + { "integer", "[,1,2]", "[1,2]" }, + // {"integer", + // "[1000000000000000000000000000000000000000000000000000,2]" , + // "[1000000000000000000000000000000000000000000000000000,2]"}, + { "integer", "[100000000,2]", "[100000000,2]" }, // Andrey, in + // success + // flow + // integer + // max value + // is + // 2147483647 + { "integer", null, null }, // no default value + { "integer", + "[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2]", + "[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2]" }, + // boolean + { "boolean", "[true,false]", "[true,false]" }, + { "boolean", "[true,false,false]", "[true,false,false]" }, + { "boolean", "[null,true,false]", "[true,false]" }, { "boolean", "[true,false,null]", "[true,false]" }, + { "boolean", "[true,,false]", "[true,false]" }, { "boolean", "[true,false,]", "[true,false]" }, + { "boolean", "[,true,false]", "[true,false]" }, { "boolean", null, null }, + // DE199713 - Default value for property type Boolean should + // support also the following values: true, t , one , 1 , + // false, f , off , 0 + { "boolean", "[on,off]", "[true,false]" }, { "boolean", "[ON,OFF]", "[true,false]" }, + { "boolean", "[On,Off]", "[true,false]" }, { "boolean", "[yes,no]", "[true,false]" }, + { "boolean", "[YES,NO]", "[true,false]" }, { "boolean", "[Yes,No]", "[true,false]" }, + { "boolean", "[y,n]", "[true,false]" }, { "boolean", "[Y,N]", "[true,false]" }, + // float + { "float", "[10.0,0.0]", "[10.0,0.0]" }, { "float", "[10,0]", "[10,0]" }, // contain + // integer + { "float", "[-10,-5.30]", "[-10,-5.30]" }, // Negative numbers + { "float", "[10,null,0]", "[10,0]" }, { "float", "[null,10,0]", "[10,0]" }, + { "float", "[10,0,null]", "[10,0]" }, + { "float", "[10,0.1111111111111111111111111111111111111111]", + "[10,0.1111111111111111111111111111111111111111]" }, + { "float", "[10, ,7.3 ]", "[10,7.3]" }, { "float", "[10 , 7.3 , ]", "[10,7.3]" }, + { "float", "[, , 10 , 7.3 , ]", "[10,7.3]" }, { "float", "[4.7f, -5.5f ]", "[4.7,-5.5]" }, + { "float", "[4.7f, 6.3 ,6.3, 4.7f]", "[4.7,6.3,6.3,4.7]" }, // duplicate + // value + { "float", null, null }, { "string", "[aaaa , AAAA ]", "[\"aaaa\",\"AAAA\"]" }, + + { "string", + "[1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2,1,2]", + "[\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\",\"1\",\"2\"]" }, + { "string", "[aaaa , AAAA, 1, off , true, false ]", + "[\"aaaa\",\"AAAA\",\"1\",\"off\",\"true\",\"false\"]" }, + { "string", "[aaaa , AAAA, aaaa, Aaaa , aaaa ]", "[\"aaaa\",\"AAAA\",\"aaaa\",\"Aaaa\",\"aaaa\"]" }, + { "string", "[aaaa , AAAA, , ]", "[\"aaaa\",\"AAAA\"]" }, + { "string", "[ , aaaa , AAAA ]", "[\"aaaa\",\"AAAA\"]" }, + { "string", "[ aaaa , , AAAA ]", "[\"aaaa\",\"AAAA\"]" }, + { "string", "[ aaaa , AAAA, null ]", "[\"aaaa\",\"AAAA\"]" }, + { "string", "[ null, aaaa , AAAA ]", "[\"aaaa\",\"AAAA\"]" }, + { "string", "[ aaaa , null , AAAA ]", "[\"aaaa\",\"AAAA\"]" }, { "string", null, null }, // without + // default + // values + // - + // Property + // will + // be + // without + // default + // parameter + { "string", "[ AAA ]", "[\"AAA\"]" }, // BUG DE199715 - + // Error 400 + // response + // received + // while adding + // property with + // default value + // contain HTML + // tags. + // Need to check + // whether / is + // legal in yaml + + }; + } + + @DataProvider + private static final Object[][] invalidListProperties() throws IOException, Exception { + return new Object[][] { + + { "integer", "[1,aaa]" }, + { "tosca.datatypes.Credential", + "[{\"protocol\":\"protocol1\",\"token\":\"token1\"},{\"protocol\":\"protocol2\",\"token1\":\"token2\"}]" }, + { "integer", "[1,false]" }, { "integer", "[1,3.5]" }, { "integer", "[1,3#]" }, + { "boolean", "[true,3.5]" }, { "boolean", "[true,1000]" }, { "boolean", "[false,trueee]" }, + { "boolean", "[true,false!]" }, { "float", "[5.0000001,true]" }, { "float", "[0.0001,koko]" }, + { "float", "[0.0001,6.3@]" }, { "float", "[0.0001f,6.3x]" }, }; + } + + @DataProvider + private static final Object[][] updatePropertiesListDefaultValueSuccessFlow() throws IOException, Exception { + return new Object[][] { + // integer + // Setting --- update properties + // ----------------------------------------------------------------------- + { "integer", "[1,2]", "[1,2]", "integer", "[200,100]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[200,100,null]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[null, 200,100]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[200,null,100]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[200,100, ]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[ , 200,100 ]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[200 , ,100 ]", "[200,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", null, null }, + { "integer", "[1,2]", "[1,2]", "integer", "[200 , 100 , 200, 100]", "[200,100,200,100]" }, + // + // ////DE199829 update resource property schema_type is not + // updated + { "integer", "[1,2]", "[1,2]", "string", "[aaaa , bbbb ]", "[\"aaaa\",\"bbbb\"]" }, + { "integer", "[1,2]", "[1,2]", "boolean", "[true , false ]", "[true,false]" }, + { "integer", "[1,2]", "[1,2]", "float", "[3.5,4.8f ]", "[3.5,4.8]" }, + // {"string", "[aaa,bbb]" , "[\"aaa\",\"bbb\"]","integer","[100, + // 200]" , "[\"100\",\"200\"]"}, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "integer", "[100, 200]", "[100,200]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "float", "[0.1f, 3.01]", "[0.1,3.01]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "boolean", "[true, false]", "[true,false]" }, + { "float", "[1.2,2.3]", "[1.2,2.3]", "boolean", "[true, false]", "[true,false]" }, + { "float", "[1.2,2.3]", "[1.2,2.3]", "integer", "[100, 200]", "[100,200]" }, + { "float", "[1.2,2.3]", "[1.2,2.3]", "string", "[koko, moko]", "[\"koko\",\"moko\"]" }, + { "boolean", "[true,false]", "[true,false]", "string", "[koko, moko]", "[\"koko\",\"moko\"]" }, + // {"boolean", "[true,false]" , + // "[\"true\",\"false\"]","integer","[100, 300000000000000]" , + // "[\"100\",\"300000000000000\"]"},// Andrey, value not valid + // for integer success flow + { "boolean", "[true,false]", "[true,false]", "integer", "[100,2147483647]", "[100,2147483647]" }, // Andrey, + // in + // success + // flow + // integer + // max + // value + // is + // 2147483647 + { "boolean", "[true,false]", "[true,false]", "float", "[3.000000000000002, 5.67f]", + "[3.000000000000002,5.67]" }, + // ////DE199829 + // + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx, yyy]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx , yyy ,null]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[null, xxx, yyy]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx ,null,yyy]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx ,yyy, ]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[ , xxx,yyy ]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx , ,yyy ]", "[\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[ xxx , yyy , xxx , yyy]", + "[\"xxx\",\"yyy\",\"xxx\",\"yyy\"]" }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", null, null }, + { "string", "[aaa,bbb]", "[\"aaa\",\"bbb\"]", "string", "[xxx_-x, y__y--y]", + "[\"xxx_-x\",\"y__y--y\"]" }, + // DE199715 + // {"string", "[aaa,bbb]" , "[\"aaa\",\"bbb\"]", "string" , + // "[\"xxx\", \"yyy\"]" , "[\"xxx\",\"yyy\"]"}, + // + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1 , -0.1]", "[2.1,-0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1, 0.1 ,null]", "[2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[null , 2.1, 0.1]", "[2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1,null,0.1]", "[2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1,0.1, ]", "[2.1,0.1]" }, + // {"float", "[1.00,0.02]" , "[1.00,0.02]","float","[ , + // 2.00000000000001,0.00000000000000100 ]" , + // "[2.00000000000001,0.00000000000000100]"}, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1 , ,0.1 ]", "[2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", null, null }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1f , ,0.1f ]", "[2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[2.1 , 0.1 , 2.1, 0.1]", "[2.1,0.1,2.1,0.1]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[200 , 100.11]", "[200,100.11]" }, + { "float", "[1.00,0.02]", "[1.00,0.02]", "float", "[-2.35 , 100.11]", "[-2.35,100.11]" }, + // + { "boolean", "[true,false]", "[true,false]", "boolean", "[false , false]", "[false,false]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[false, true ,null]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[null , false, true]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[false,null,true]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[false ,true , ]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[ , false, true ]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", "[false , ,true ]", "[false,true]" }, + { "boolean", "[true,false]", "[true,false]", "boolean", null, null }, { "boolean", "[true,false]", + "[true,false]", "boolean", "[false , true , false, true]", "[false,true,false,true]" }, }; + } + + @DataProvider + private static final Object[][] updatePropertiesListDefaultValueFailureFlow() throws IOException, Exception { + return new Object[][] { + // integer + // Setting --- update properties + // ----------------------------------------------------------------------- + { "integer", "[1,2]", "[1,2]", "integer", "[aaa,bbb]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[true,false]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[1.0,100]" }, + { "integer", "[1,2]", "[1,2]", "integer", "[@12,100]" }, + { "float", "[0.11,0.22]", "[0.11,0.22]", "float", "[aaa, bbb]" }, + { "float", "[0.11,0.22]", "[0.11,0.22]", "float", "[0.88, false]" }, + { "float", "[0.11,0.22]", "[0.11,0.22]", "float", "[0.88g, 0.3]" }, + { "float", "[0.11,0.22]", "[0.11,0.22]", "float", "[@0.88, 0.3]" }, + { "boolean", "[true, false]", "[true,false]", "boolean", "[true, 100]" }, + { "boolean", "[true, false]", "[true,false]", "boolean", "[false, 0.01]" }, + { "boolean", "[true, false]", "[true,false]", "boolean", "[koko, true]" }, + { "boolean", "[true, false]", "[true,false]", "boolean", "[@false, true]" }, + + }; + } + + // Map properties + @DataProvider + private static final Object[][] updatePropertiesMapDefaultValueSuccessFlow() throws IOException, Exception { + return new Object[][] { + // entrySchemaType , propertyDefaultValues , + // expectedDefaultValue , newEntrySchemaType , + // newPropertyDefaultValue , newExpectedDefaultValue + // integer + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":200,\"key2\":null , \"key3\":300}", "{\"key1\":200,\"key2\":null,\"key3\":300}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":null,\"key2\":200 , \"key3\":100}", "{\"key1\":null,\"key2\":200,\"key3\":100}" }, + // string + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "string", + "{\"key1\":\"aaaa\" , \"key2\":\"aaaa\"}", "{\"key1\":\"aaaa\",\"key2\":\"aaaa\"}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "boolean", + "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "float", + "{\"key1\":3.5 , \"key2\":4.8f}", "{\"key1\":3.5,\"key2\":4.8}" }, + // string + { "string", "{\"key1\":aaa , \"key2\":bbb}", "{\"key1\":\"aaa\",\"key2\":\"bbb\"}", "string", + "{\"key1\":xxx , \"key2\":yyy}", "{\"key1\":\"xxx\",\"key2\":\"yyy\"}" }, + // float + { "float", "{\"key1\":1.00 , \"key2\":0.02}", "{\"key1\":1.00,\"key2\":0.02}", "float", + "{\"key1\":2.1, \"key2\":-0.1}", "{\"key1\":2.1,\"key2\":-0.1}" }, + { "float", "{\"key1\":1.00 , \"key2\":0.02}", "{\"key1\":1.00,\"key2\":0.02}", "float", + "{\"key1\":2.1 , \"key2\":0.1 , \"key3\":null}", "{\"key1\":2.1,\"key2\":0.1,\"key3\":null}" }, + // boolean + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":false , \"key2\":false}", "{\"key1\":false,\"key2\":false}" }, + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":false , \"key2\":true , \"key3\":null}", + "{\"key1\":false,\"key2\":true,\"key3\":null}" }, + // null + { "boolean", "{\"key1\":null , \"key2\":false}", "{\"key1\":null,\"key2\":false}", "boolean", + "{\"key1\":false , \"key2\":true , \"key3\":null}", + "{\"key1\":false,\"key2\":true,\"key3\":null}" }, + // tosca.datatypes.Credential + { "tosca.datatypes.Credential", + "{\"key1\":{\"protocol\":\"protocol
1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "{\"key1\":{\"protocol\":\"protocol1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "tosca.datatypes.Credential", + "{\"key1\":{\"protocol\":\"protocol
1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "{\"key1\":{\"protocol\":\"protocol1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}" }, + + }; + } + + @DataProvider + private static final Object[][] propertiesMapDefaultValueSuccessFlow() throws IOException, Exception { + return new Object[][] { + + // entrySchemaType , propertyDefaultValues , + // expectedDefaultValue + // + // {"string", + // "{\"vf_module_id\":{\"get_input\":\"vf_module_id\"}, + // \"vnf_idw\": 2}", + // "{\"vf_module_id\":{\"get_input\":\"vf_module_id\"}, + // \"vnf_idw\": 2}"}, + + // tosca.datatypes.Credential + { "tosca.datatypes.Credential", + "{\"key1\":{\"protocol\":\"protocol
1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "{\"key1\":{\"protocol\":\"protocol1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}" }, + // integer + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}" }, + { "integer", "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":2}", + "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":2}" }, + { "integer", "{\"key1\":1,\"key2\":null,\"key3\":1,\"key4\":2}", + "{\"key1\":1,\"key2\":null,\"key3\":1,\"key4\":2}" }, + { "integer", "{\"key1\":null,\"key2\":1,\"key3\":1,\"key4\":2}", + "{\"key1\":null,\"key2\":1,\"key3\":1,\"key4\":2}" }, + { "integer", "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":null}", + "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":null}" }, + { "integer", "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":NULL}", + "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":null}" }, + { "integer", "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":Null}", + "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":null}" }, + { "integer", "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":nuLL}", + "{\"key1\":1,\"key2\":2,\"key3\":1,\"key4\":null}" }, + { "integer", null, null }, // no default value + // //BUG + //// {"integer", + // "{\"key1\":1000000000000000000000000000000000000000000000000000,\"key2\":2}" + // ,"{\"key1\":1000000000000000000000000000000000000000000000000000,\"key2\":2}"}, + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":true , \"key2\":false, \"key3\":false }", + "{\"key1\":true,\"key2\":false,\"key3\":false}" }, + { "boolean", "{\"key1\":null , \"key2\":true, \"key3\":false }", + "{\"key1\":null,\"key2\":true,\"key3\":false}" }, + { "boolean", "{\"key1\":true , \"key2\":Null, \"key3\":false }", + "{\"key1\":true,\"key2\":null,\"key3\":false}" }, + { "boolean", "{\"key1\":true , \"key2\":false, \"key3\":nULL }", + "{\"key1\":true,\"key2\":false,\"key3\":null}" }, + { "boolean", null, null }, + { "boolean", "{\"key1\":on , \"key2\":off}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":ON , \"key2\":OFF}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":On , \"key2\":Off}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":yes , \"key2\":no}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":YES , \"key2\":NO}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":Yes , \"key2\":No}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":y , \"key2\":n}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{\"key1\":Y , \"key2\":N}", "{\"key1\":true,\"key2\":false}" }, + { "boolean", "{null:false}", "{\"null\":false}" }, + // float + { "float", "{\"key1\":10.0 , \"key2\":0.0}", "{\"key1\":10.0,\"key2\":0.0}" }, + { "float", "{\"key1\":10 , \"key2\":0}", "{\"key1\":10,\"key2\":0}" }, // contain + // integer + { "float", "{\"key1\":null , \"key2\":Null}", "{\"key1\":null,\"key2\":null}" }, // contain + // null + { "float", "{\"key1\":3.5 , \"key2\":nULL}", "{\"key1\":3.5,\"key2\":null}" }, + // BUG + { "float", "{\"key1\":3.5 , \"key2\":0.1111111111111111111111111111111111111111}", + "{\"key1\":3.5,\"key2\":0.1111111111111111111111111111111111111111}" }, + { "float", "{\"key1\":4.7f , \"key2\":-5.5f}", "{\"key1\":4.7,\"key2\":-5.5}" }, + { "float", "{\"key1\":4.7f , \"key2\":-5.5f, \"key3\":-5.5f}", + "{\"key1\":4.7,\"key2\":-5.5,\"key3\":-5.5}" }, + { "boolean", null, null }, + { "string", "{\"key1\":aaaa , \"key2\":AAAA}", "{\"key1\":\"aaaa\",\"key2\":\"AAAA\"}" }, + { "string", "{\"key1\":off , \"key2\":true , \"key3\":1}", + "{\"key1\":\"off\",\"key2\":\"true\",\"key3\":\"1\"}" }, + { "string", "{\"key1\":aaaa , \"key2\":Aaaa , \"key3\":aaaa}", + "{\"key1\":\"aaaa\",\"key2\":\"Aaaa\",\"key3\":\"aaaa\"}" }, + { "string", "{\"key1\":aaaa , \"key2\":bbbb , \"key3\":null}", + "{\"key1\":\"aaaa\",\"key2\":\"bbbb\",\"key3\":null}" }, + { "string", "{\"key1\":NULL , \"key2\":bbbb , \"key3\":aaaa}", + "{\"key1\":null,\"key2\":\"bbbb\",\"key3\":\"aaaa\"}" }, + { "string", "{\"key1\":aaaa , \"key2\":Null , \"key3\":bbbb}", + "{\"key1\":\"aaaa\",\"key2\":null,\"key3\":\"bbbb\"}" }, + { "string", null, null }, // without default values - Property + // will be without default parameter + { "string", "{\"key1\":\"AAAA\" }", "{\"key1\":\"AAAA\"}" }, + + }; + } + + @DataProvider + private static final Object[][] updatePropertiesMapDefaultValueFailureFlow() throws IOException, Exception { + return new Object[][] { + + // integer + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":aaa , \"key2\":bbb}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":true , \"key2\":false}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":1.0 , \"key2\":100}" }, + { "integer", "{\"key1\":1 , \"key2\":2}", "{\"key1\":1,\"key2\":2}", "integer", + "{\"key1\":12@ , \"key2\":100}" }, + // float + { "float", "{\"key1\":0.11 , \"key2\":0.22}", "{\"key1\":0.11,\"key2\":0.22}", "float", + "{\"key1\":aaa , \"key2\":bbb}" }, + { "float", "{\"key1\":0.11 , \"key2\":0.22}", "{\"key1\":0.11,\"key2\":0.22}", "float", + "{\"key1\":0.88 , \"key2\":false}" }, + { "float", "{\"key1\":0.11 , \"key2\":0.22}", "{\"key1\":0.11,\"key2\":0.22}", "float", + "{\"key1\":0.88g , \"key2\":0.3}" }, + { "float", "{\"key1\":0.11 , \"key2\":0.22}", "{\"key1\":0.11,\"key2\":0.22}", "float", + "{\"key1\":@0.88g , \"key2\":0.3}" }, + // boolean + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":true , \"key2\":100}" }, + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":false , \"key2\":0.01}" }, + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":koko , \"key2\":true}" }, + { "boolean", "{\"key1\":true , \"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":@false , \"key2\":true}" }, + { "boolean", "{\"key1\":true,\"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{:false , \"key2\":true}" }, + { "boolean", "{\"key1\":true,\"key2\":false}", "{\"key1\":true,\"key2\":false}", "boolean", + "{\"key1\":true , , \"key2\":false}" }, + // tosca.datatypes.Credential + { "tosca.datatypes.Credential", + "{\"key1\":{\"protocol\":\"protocol
1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "{\"key1\":{\"protocol\":\"protocol1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token\":\"token2\"}}", + "tosca.datatypes.Credential", + "{\"key1\":{\"protocol\":\"protocol
1\",\"token\":\"token1\"},\"key2\":{\"protocol\":\"protocol2\",\"token2\":\"token2\"}}" }, + + }; + } + + // US594938 - UPDATE PROPERTY + // DE199718 + @Test(dataProvider = "updatePropertiesListDefaultValueFailureFlow") + public void updateDefaultValueOfResourcePropertyListFailureFlow(String entrySchemaType, String propertyDefaltValues, + String expecteddefaultValues, String newEntrySchemaType, String newPropertyDefaltValues) throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.setPropertyDefaultValue(propertyDefaltValues); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // verify properties return from response + assertEquals("list", resourcePropertiesFromResponse.getType()); + assertEquals(expecteddefaultValues, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + // Update resource property type = "list" + propertyDetails.setPropertyDefaultValue(newPropertyDefaltValues); + propertyDetails.getSchema().getProperty().setType(newEntrySchemaType); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(propertyDetails.getName()); + variables.add(propertyDetails.getPropertyType()); + variables.add(propertyDetails.getSchema().getProperty().getType()); + variables.add(newPropertyDefaltValues); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, + updatePropertyResponse.getResponse()); + } + + @Test + public void updatePropertyOfDerivedResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String derivedResourcePropertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + // second resource derived from basicVFC + Resource vfc1FromBasicVFC = AtomicOperationUtils + .createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, basicVFC, + ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true) + .left().value(); + // add property Type list to second resource + PropertyReqDetails defaultListProperty = ElementFactory.getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(defaultListProperty, vfc1FromBasicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + // Update property (list) of derived resource + RestResponse updatePropertyResponse = AtomicOperationUtils.updatePropertyOfResource(propertyDetails, basicVFC, + derivedResourcePropertyUniqueId, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + verifyResourcePropertyList(basicVFC, propertyDetails, "[\"a\",\"b\"]"); + } + + @Test + public void updatePropertyOfNonDerivedResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + // second resource derived from basicVFC + Resource vfc1FromBasicVFC = AtomicOperationUtils + .createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, basicVFC, + ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true) + .left().value(); + // add property Type list to second resource + PropertyReqDetails defaultListProperty = ElementFactory.getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(defaultListProperty, vfc1FromBasicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // Update property (list) of derived resource + defaultListProperty.setPropertyDefaultValue("[1,2,3,4]"); + String expectedDefaultValue = "[1,2,3,4]"; + ComponentInstanceProperty resourcePropertyAfterUpdate = AtomicOperationUtils + .updatePropertyOfResource(defaultListProperty, vfc1FromBasicVFC, propertyUniqueId, + UserRoleEnum.DESIGNER, true) + .left().value(); + assertEquals(resourcePropertyAfterUpdate.getType(), "list"); + assertEquals(resourcePropertyAfterUpdate.getDefaultValue(), expectedDefaultValue); + assertEquals(resourcePropertyAfterUpdate.getSchema().getProperty().getType(), + defaultListProperty.getSchema().getProperty().getType()); // string/integer/boolean/float + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(vfc1FromBasicVFC.getUniqueId()); + String expectedDefaultValueFromDerivedResource = "[\"a\",\"b\"]"; + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + resource.getProperties().get(0).getDefaultValue().equals(expectedDefaultValue); + resource.getProperties().get(1).getDefaultValue().equals(expectedDefaultValueFromDerivedResource); + } + + @Test + public void updateListPropertyToNonCheckedOutResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + // Update resource property type = "list" + propertyDetails.setPropertyDefaultValue("[3,4]"); + propertyDetails.getSchema().getProperty().setType("integer"); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + @Test + public void updateListPropertyResourceByNonResouceOwner() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // AtomicOperationUtils.changeComponentState(basicVFC, + // UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + // Update resource property type = "list" + propertyDetails.setPropertyDefaultValue("[3,4]"); + propertyDetails.getSchema().getProperty().setType("integer"); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER2, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + @Test + public void updateListPropertyResourceByTester() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // AtomicOperationUtils.changeComponentState(basicVFC, + // UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + // Update resource property type = "list" + propertyDetails.setPropertyDefaultValue("[3,4]"); + propertyDetails.getSchema().getProperty().setType("integer"); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.TESTER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + // DE199964 + @Test(enabled = false) + public void updateListPropertyToNonExistingResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + String resourceUniqueId = basicVFC.getUniqueId(); + basicVFC.setUniqueId("1111111"); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_NOT_FOUND)); + ArrayList variables = new ArrayList<>(); + variables.add(basicVFC.getUniqueId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), variables, + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + basicVFC.setUniqueId(resourceUniqueId); + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + // DE199725 + @Test + public void updateResourcePropertyListNonSupportedPropertyType() throws Exception { // Not + // "list" + // type + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // update resource property + String propertyType = "listttttttt"; + propertyDetails.setPropertyType(propertyType); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + ArrayList variables = new ArrayList<>(); + variables.add(propertyDetails.getPropertyType()); // property data type + // (koko instead + // list) + variables.add(propertyDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_TYPE.name(), variables, + updatePropertyResponse.getResponse()); + // Verify resource's priority list did not changed + propertyDetails.setPropertyType("list"); + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + @Test(enabled = false) // DE199732 + public void updateResourcePropertyListNonSupportedEntrySchemaType() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String PropertyDefaultValue = "[2,3]"; + propertyDetails.setPropertyDefaultValue(PropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType("integer"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // update resource property + String EntrySchemaType = "integerrrrrr"; + propertyDetails.getSchema().getProperty().setType(EntrySchemaType); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(EntrySchemaType); + variables.add(propertyDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_INNER_TYPE.name(), variables, + updatePropertyResponse.getResponse()); + propertyDetails.getSchema().getProperty().setType("integer"); + verifyResourcePropertyList(basicVFC, propertyDetails, "[2,3]"); + } + + @Test(dataProvider = "updatePropertiesListDefaultValueSuccessFlow") + public void updateResourcePropertyListSuccessFlow(String entrySchemaType, String propertyDefaltValues, + String expecteddefaultValues, String newEntrySchemaType, String newPropertyDefaltValues, + String newExpecteddefaultValues) throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.setPropertyDefaultValue(propertyDefaltValues); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // verify properties return from response + assertEquals("list", resourcePropertiesFromResponse.getType()); + assertEquals(expecteddefaultValues, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + // Update resource property type = "list" + propertyDetails.setPropertyDefaultValue(newPropertyDefaltValues); + propertyDetails.getSchema().getProperty().setType(newEntrySchemaType); + ComponentInstanceProperty resourcePropertyAfterUpdate = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, true) + .left().value(); + assertEquals("list", resourcePropertyAfterUpdate.getType()); + assertEquals(newExpecteddefaultValues, resourcePropertyAfterUpdate.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertyAfterUpdate.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, newExpecteddefaultValues); + } + + // Add property type list to resource + // DE199718 + @Test(dataProvider = "invalidListProperties") // invalid default values + public void addListPropertyToResourceFailureFlow(String entrySchemaType, String propertyDefaltValues) + throws Exception { + // String propertyType = "list"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + propertyDetails.setPropertyDefaultValue(propertyDefaltValues); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(propertyDetails.getName()); + variables.add(propertyDetails.getPropertyType()); + variables.add(propertyDetails.getSchema().getProperty().getType()); + variables.add(propertyDefaltValues); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, + addPropertyToResourceResponse.getResponse()); + + } + + // DE199964 + @Test + public void addListPropertyToNonExistingResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType("integer"); + propertyDetails.setPropertyDefaultValue("[1,2]"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to non existing resource + basicVFC.setUniqueId("1111111"); + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_NOT_FOUND)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), variables, + addPropertyToResourceResponse.getResponse()); + } + + @Test + public void addListPropertyToNonCheckedOutResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType("integer"); + propertyDetails.setPropertyDefaultValue("[1,2]"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + // Add property type list to non Checked-Out resource + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + addPropertyToResourceResponse.getResponse()); + } + + @Test + public void addListPropertyToResourceByNonResourceOwner() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType("integer"); + propertyDetails.setPropertyDefaultValue("[1,2]"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to non Checked-Out resource + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER2, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + addPropertyToResourceResponse.getResponse()); + } + + @Test + public void addListPropertyToResourcePropertyAlreadyExists01() throws Exception { + String propertyType = "list"; + String propertySchemaType = "integer"; + String defaultValues = "[1,2]"; + String expecteddefaultValues = "[1,2]"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType(propertySchemaType); + propertyDetails.setPropertyDefaultValue(defaultValues); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // check-in and check-out resource + RestResponse changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKOUT); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + // verify properties return from response + assertEquals(resourcePropertiesFromResponse.getType(), propertyType); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expecteddefaultValues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), propertySchemaType); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + // Add same property again to resource + RestResponse addPropertyRestResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyRestResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_ALREADY_EXISTS)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_ALREADY_EXIST.name(), variables, + addPropertyRestResponse.getResponse()); + // verify property not deleted + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + } + + @Test + public void addListPropertyToResourcePropertyAlreadyExists02() throws Exception { + String propertyType = "list"; + String propertySchemaType = "integer"; + String defaultValues = "[1,2]"; + String expecteddefaultValues = "[1,2]"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType(propertySchemaType); + propertyDetails.setPropertyDefaultValue(defaultValues); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + // verify properties return from response + assertEquals(resourcePropertiesFromResponse.getType(), propertyType); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expecteddefaultValues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), propertySchemaType); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + // check-in and check-out resource + RestResponse changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKOUT); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + // Add same property again to resource + RestResponse addPropertyRestResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyRestResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_ALREADY_EXISTS)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_ALREADY_EXIST.name(), variables, + addPropertyRestResponse.getResponse()); + // verify property not deleted + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + } + + @Test // DE199725 + public void addListPropertyToResourceNonSupportedPropertyType() throws Exception { // Not + // "list" + // type + String propertyType = "listttttttt"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.setPropertyType(propertyType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + RestResponse addPropertyRestResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyRestResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(propertyDetails.getPropertyType()); // property data type + // (koko instead + // list) + variables.add(propertyDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_TYPE.name(), variables, + addPropertyRestResponse.getResponse()); + } + + @Test // DE199732 + public void addListPropertyToResourceNonSupportedEntrySchemaType() throws Exception { + String EntrySchemaType = "stringggg"; // instead "string" + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType(EntrySchemaType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + RestResponse addPropertyRestResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyRestResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(EntrySchemaType); + variables.add(propertyDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_PROPERTY_INNER_TYPE.name(), variables, + addPropertyRestResponse.getResponse()); + } + + @Test + public void addHundredPropertyListToResourceSuccessFlow() throws Exception { + String propertyType = "list"; + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + String propertyName = propertyDetails.getName(); + int numberOfPropertiesToAddToResource = 100; + ComponentInstanceProperty resourcePropertiesFromResponse; + for (int x = 0; x < numberOfPropertiesToAddToResource; x++) { + propertyDetails.setName(propertyName + x); + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + // verify properties return from response + assertEquals(resourcePropertiesFromResponse.getName(), propertyName + x); + assertEquals(resourcePropertiesFromResponse.getType(), propertyType); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[\"a\",\"b\"]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetails.getSchema().getProperty().getType()); // string/integer/boolean/float + } + // get resource and verify that 100 properties exist + Resource resourceObject = AtomicOperationUtils.getResourceObject(basicVFC, UserRoleEnum.DESIGNER); + assertEquals(numberOfPropertiesToAddToResource, resourceObject.getProperties().size()); + + } + + @Test(dataProvider = "propertiesListDefaultValueSuccessFlow") + public void addListPropertyToResourceSuccessFlow(String entrySchemaType, String propertyDefaltValues, + String expecteddefaultValues) throws Exception { + String propertyType = "list"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + propertyDetails.setPropertyDefaultValue(propertyDefaltValues); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + // verify properties return from response + assertEquals(propertyType, resourcePropertiesFromResponse.getType()); + assertEquals(expecteddefaultValues, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(entrySchemaType, resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + + assertEquals(resourcePropertiesFromResponse.getType(), propertyType); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expecteddefaultValues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), entrySchemaType); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + } + + // Delete property type list + @Test + public void deleteOneOfTheListPropertiesFromResourceAndAddItAgain() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + PropertyReqDetails propertyDetailsInteger = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[\"a\",\"b\"]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, "[\"a\",\"b\"]"); + // Add deleted property again to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + } + + @Test + public void deletePropertyListTypeInteger() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + PropertyReqDetails propertyDetailsInteger = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[\"a\",\"b\"]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "[1,2]"); + } + + @Test + public void deletePropertyListTypeBoolean() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.BOOLEAN_LIST); + PropertyReqDetails propertyDetailsInteger = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[true,false]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one property + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "[1,2]"); + } + + @Test + public void deletePropertyListTypeFloat() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.FLOAT_LIST); + PropertyReqDetails propertyDetailsInteger = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1.0,2.0]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one property + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "[1,2]"); + } + + @Test + public void deletePropertyListAlreadyDeleted() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.FLOAT_LIST); + PropertyReqDetails propertyDetailsInteger = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1.0,2.0]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), "[1,2]"); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one property + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "[1,2]"); + // delete again the same property + deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_NOT_FOUND == deletePropertyOfResource.getErrorCode()); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_NOT_FOUND.name(), variables, + deletePropertyOfResource.getResponse()); + } + + @Test + public void deletePropertyListResourceIsNotCheckedOutState() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.FLOAT_LIST); + String expectedDefaultvalues = "[1.0,2.0]"; + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expectedDefaultvalues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + // Get resource and verify updated default value + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + // Check-in resource + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + // Delete property + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION == deletePropertyOfResource.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deletePropertyOfResource.getResponse()); + // Get resource and verify property is not deleted + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + } + + @Test + public void deletePropertyListResourceByNotIsNonResouceOwner() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.FLOAT_LIST); + String expectedDefaultvalues = "[1.0,2.0]"; + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expectedDefaultvalues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + // Get resource and verify updated default value + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + // Delete property by non resource owner + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER2); + assertTrue(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION == deletePropertyOfResource.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + deletePropertyOfResource.getResponse()); + // Get resource and verify property is not deleted + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + } + + @Test + public void deletePropertyListFromNonExistingResource() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.FLOAT_LIST); + String expectedDefaultvalues = "[1.0,2.0]"; + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + String actualResourceUniqueId = basicVFC.getUniqueId(); + // Add property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals(resourcePropertiesFromResponse.getDefaultValue(), expectedDefaultvalues); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + // Get resource and verify updated default value + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + // Delete property from non existing resource + basicVFC.setUniqueId("1111111"); + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(deletePropertyOfResource.getErrorCode().equals(BaseRestUtils.STATUS_CODE_NOT_FOUND)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), variables, + deletePropertyOfResource.getResponse()); + // Get resource and verify property is not deleted + basicVFC.setUniqueId(actualResourceUniqueId); + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, expectedDefaultvalues); + } + + @Test + public void deletePropertyOfDerivedResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String derivedResourcePropertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + // second resource derived from basicVFC + Resource vfc1FromBasicVFC = AtomicOperationUtils + .createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, basicVFC, + ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true) + .left().value(); + // Delete property (list) of derived resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource( + vfc1FromBasicVFC.getUniqueId(), derivedResourcePropertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(deletePropertyOfResource.getErrorCode().equals(BaseRestUtils.STATUS_CODE_NOT_FOUND)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_NOT_FOUND.name(), variables, + deletePropertyOfResource.getResponse()); + // Verify resource's priority list did not changed + verifyResourcePropertyList(vfc1FromBasicVFC, propertyDetails, "[\"a\",\"b\"]"); + } + + @Test + public void deletePropertyOfNonDerivedResource() throws Exception { + PropertyReqDetails propertyListString = ElementFactory.getDefaultListProperty(PropertyTypeEnum.STRING_LIST); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyListString, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.changeComponentState(basicVFC, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + // second resource derived from basicVFC + Resource vfc1FromBasicVFC = AtomicOperationUtils + .createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum.VFC, basicVFC, + ResourceCategoryEnum.APPLICATION_L4_BORDER, UserRoleEnum.DESIGNER, true) + .left().value(); + // add property Type list to second resource + PropertyReqDetails propertyListInteger = ElementFactory.getDefaultListProperty(PropertyTypeEnum.INTEGER_LIST); + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyListInteger, vfc1FromBasicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // Delete property (list) of derived resource + RestResponse deletePropertyOfResource = AtomicOperationUtils + .deletePropertyOfResource(vfc1FromBasicVFC.getUniqueId(), propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyListString, "[\"a\",\"b\"]"); + } + + private void verifyResourcePropertyList(Resource resource, PropertyReqDetails expectedProperty, + String expecteddefaultValues) throws Exception { + // get resource and verify property from type list + Resource getResource = AtomicOperationUtils.getResourceObject(resource, UserRoleEnum.DESIGNER); + List actualResourceProperties = getResource.getProperties(); + boolean isPropertyAppear = false; + for (PropertyDefinition pro : actualResourceProperties) { + if (expectedProperty.getName().equals(pro.getName())) { + assertTrue("Check Property Type ", pro.getType().equals(expectedProperty.getPropertyType())); + assertEquals("Check Property default values ", expecteddefaultValues, pro.getDefaultValue()); + // assertTrue("Check Property default values ", + // pro.getDefaultValue().equals(expecteddefaultValues)); + assertTrue("Check entrySchema Property Type ", pro.getSchema().getProperty().getType() + .equals(expectedProperty.getSchema().getProperty().getType())); + isPropertyAppear = true; + } + } + assertTrue(isPropertyAppear); + } + + // US656905 + // --------------------- Map Property + // ---------------------------------------------------------------- + @Test(dataProvider = "updatePropertiesMapDefaultValueFailureFlow") + public void updateDefaultValueOfResourcePropertyMapFailureFlow(String entrySchemaType, String propertyDefaultValues, + String expectedDefaultValue, String newEntrySchemaType, String newPropertyDefaultValue) throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultMapProperty(); + propertyDetails.setPropertyDefaultValue(propertyDefaultValues); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // verify properties return from response + assertEquals("map", resourcePropertiesFromResponse.getType()); + assertEquals(expectedDefaultValue, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expectedDefaultValue); + // Update resource property type = "map" + propertyDetails.setPropertyDefaultValue(newPropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType(newEntrySchemaType); + RestResponse updatePropertyResponse = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, false) + .right().value(); + assertTrue(updatePropertyResponse.getErrorCode().equals(STATUS_CODE_INVALID_CONTENT)); + ArrayList variables = new ArrayList<>(); + variables.add(propertyDetails.getName()); + variables.add(propertyDetails.getPropertyType()); + variables.add(propertyDetails.getSchema().getProperty().getType()); + variables.add(newPropertyDefaultValue); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE.name(), variables, + updatePropertyResponse.getResponse()); + } + + @Test(dataProvider = "updatePropertiesMapDefaultValueSuccessFlow") + public void updateResourcePropertyMapSuccessFlow(String entrySchemaType, String propertyDefaultValues, + String expectedDefaultValue, String newEntrySchemaType, String newPropertyDefaultValue, + String newExpectedDefaultValue) throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultMapProperty(); + propertyDetails.setPropertyDefaultValue(propertyDefaultValues); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + // verify properties return from response + assertEquals("map", resourcePropertiesFromResponse.getType()); + assertEquals(expectedDefaultValue, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expectedDefaultValue); + // Update resource property type = "map" + propertyDetails.setPropertyDefaultValue(newPropertyDefaultValue); + propertyDetails.getSchema().getProperty().setType(newEntrySchemaType); + ComponentInstanceProperty resourcePropertyAfterUpdate = AtomicOperationUtils + .updatePropertyOfResource(propertyDetails, basicVFC, propertyUniqueId, UserRoleEnum.DESIGNER, true) + .left().value(); + assertEquals("map", resourcePropertyAfterUpdate.getType()); + assertEquals(newExpectedDefaultValue, resourcePropertyAfterUpdate.getDefaultValue()); + assertEquals(propertyDetails.getSchema().getProperty().getType(), + resourcePropertyAfterUpdate.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, newExpectedDefaultValue); + } + + @Test + public void deletePropertyMapTypeString() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultMapProperty(PropertyTypeEnum.STRING_MAP); + PropertyReqDetails propertyDetailsInteger = ElementFactory.getDefaultMapProperty(PropertyTypeEnum.INTEGER_MAP); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals("{\"key1\":\"val1\",\"key2\":\"val2\"}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals("{\"key1\":123,\"key2\":-456}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "{\"key1\":123,\"key2\":-456}"); + } + + @Test + public void deletePropertyMapTypeFloat() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeFloat = ElementFactory.getDefaultMapProperty(PropertyTypeEnum.FLOAT_MAP); + PropertyReqDetails propertyDetailsInteger = ElementFactory.getDefaultMapProperty(PropertyTypeEnum.INTEGER_MAP); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeFloat, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeFloat.getPropertyType()); + assertEquals("{\"key1\":0.2123,\"key2\":43.545}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeFloat.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals("{\"key1\":123,\"key2\":-456}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "{\"key1\":123,\"key2\":-456}"); + } + + @Test + public void deletePropertyMapTypeBoolean() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeBoolean = ElementFactory + .getDefaultMapProperty(PropertyTypeEnum.BOOLEAN_MAP); + PropertyReqDetails propertyDetailsInteger = ElementFactory.getDefaultMapProperty(PropertyTypeEnum.INTEGER_MAP); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeBoolean, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeBoolean.getPropertyType()); + assertEquals("{\"key1\":true,\"key2\":false}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeBoolean.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsInteger.getPropertyType()); + assertEquals("{\"key1\":123,\"key2\":-456}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsInteger.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsInteger, "{\"key1\":123,\"key2\":-456}"); + } + + @Test + public void deletePropertyMapTypeInteger() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeInteger = ElementFactory + .getDefaultMapProperty(PropertyTypeEnum.INTEGER_MAP); + PropertyReqDetails propertyDetailsBoolean = ElementFactory.getDefaultMapProperty(PropertyTypeEnum.BOOLEAN_MAP); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeInteger, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + String propertyUniqueId = resourcePropertiesFromResponse.getUniqueId(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeInteger.getPropertyType()); + assertEquals("{\"key1\":123,\"key2\":-456}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeInteger.getSchema().getProperty().getType()); // string/integer/boolean/float + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsBoolean, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsBoolean.getPropertyType()); + assertEquals("{\"key1\":true,\"key2\":false}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsBoolean.getSchema().getProperty().getType()); + // Get resource and verify updated default value + RestResponse restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + Resource resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(2, resource.getProperties().size()); + // Delete one resource + RestResponse deletePropertyOfResource = AtomicOperationUtils.deletePropertyOfResource(basicVFC.getUniqueId(), + propertyUniqueId, UserRoleEnum.DESIGNER); + assertTrue(BaseRestUtils.STATUS_CODE_DELETE == deletePropertyOfResource.getErrorCode()); + // Get resource and verify updated default value + restResponse = ResourceRestUtils.getResource(basicVFC.getUniqueId()); + resource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + assertEquals(1, resource.getProperties().size()); + verifyResourcePropertyList(basicVFC, propertyDetailsBoolean, "{\"key1\":true,\"key2\":false}"); + } + + @Test(dataProvider = "propertiesMapDefaultValueSuccessFlow") + public void addMapPropertyToResourceSuccessFlow(String entrySchemaType, String propertyDefaltValues, + String expecteddefaultValues) throws Exception { + String propertyType = "map"; + PropertyReqDetails propertyDetails = ElementFactory.getDefaultMapProperty(); + propertyDetails.getSchema().getProperty().setType(entrySchemaType); + propertyDetails.setPropertyDefaultValue(propertyDefaltValues); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to resource + ComponentInstanceProperty resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, true).left().value(); + // verify properties return from response + assertEquals(propertyType, resourcePropertiesFromResponse.getType()); + assertEquals(expecteddefaultValues, resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(entrySchemaType, resourcePropertiesFromResponse.getSchema().getProperty().getType()); // string/integer/boolean/float + verifyResourcePropertyList(basicVFC, propertyDetails, expecteddefaultValues); + } + + @Test + public void addMapPropertyToNonExistingResource() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType("integer"); + propertyDetails.setPropertyDefaultValue("{\"key1\":1 , \"key2\":2}"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to non existing resource + basicVFC.setUniqueId("1111111"); + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_NOT_FOUND)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), variables, + addPropertyToResourceResponse.getResponse()); + } + + @Test + public void addMaptPropertyToResourceByNonResourceOwner() throws Exception { + PropertyReqDetails propertyDetails = ElementFactory.getDefaultListProperty(); + propertyDetails.getSchema().getProperty().setType("integer"); + propertyDetails.setPropertyDefaultValue("{\"key1\":1 , \"key2\":2}"); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add property type list to non Checked-Out resource + RestResponse addPropertyToResourceResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetails, basicVFC, UserRoleEnum.DESIGNER2, false).right().value(); + assertTrue(addPropertyToResourceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION)); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + addPropertyToResourceResponse.getResponse()); + } + + @Test + public void addMapPropertyToResourcePropertyAlreadyExists() throws Exception { + ComponentInstanceProperty resourcePropertiesFromResponse; + PropertyReqDetails propertyDetailsTypeString = ElementFactory + .getDefaultListProperty(PropertyTypeEnum.STRING_MAP); + // create resource + Resource basicVFC = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left() + .value(); + // Add 2 property type list to resource + resourcePropertiesFromResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, true).left() + .value(); + assertEquals(resourcePropertiesFromResponse.getType(), propertyDetailsTypeString.getPropertyType()); + assertEquals("{\"key1\":\"val1\",\"key2\":\"val2\"}", resourcePropertiesFromResponse.getDefaultValue()); + assertEquals(resourcePropertiesFromResponse.getSchema().getProperty().getType(), + propertyDetailsTypeString.getSchema().getProperty().getType()); // string/integer/boolean/float + // check-in and check-out resource + RestResponse changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + changeComponentState = LifecycleRestUtils.changeComponentState(basicVFC, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKOUT); + assertTrue(changeComponentState.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS)); + // Add same property again to resource + RestResponse addPropertyRestResponse = AtomicOperationUtils + .addCustomPropertyToResource(propertyDetailsTypeString, basicVFC, UserRoleEnum.DESIGNER, false).right() + .value(); + assertTrue(addPropertyRestResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_ALREADY_EXISTS)); + ArrayList variables = new ArrayList<>(); + variables.add(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_ALREADY_EXIST.name(), variables, + addPropertyRestResponse.getResponse()); + // verify property not deleted + verifyResourcePropertyList(basicVFC, propertyDetailsTypeString, "{\"key1\":\"val1\",\"key2\":\"val2\"}"); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/PropertyApisTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/PropertyApisTest.java new file mode 100644 index 0000000000..d1302c8d8c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/property/PropertyApisTest.java @@ -0,0 +1,383 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.property; + +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.preRequisites.SimpleOneRsrcOneServiceTest; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.PropertyRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.UserRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class PropertyApisTest extends SimpleOneRsrcOneServiceTest { + + protected static final String RESOURCE_CATEGORY = "Generic/Databases"; + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json";; + + // protected User sdncDesignerDetails; + // protected ResourceReqDetails resourceDetails; + protected PropertyReqDetails property; + protected String body; + + protected HttpRequest httpRequest = new HttpRequest(); + protected Map headersMap = new HashMap(); + + @Rule + public static TestName testName = new TestName(); + + public PropertyApisTest() { + super(testName, PropertyApisTest.class.getName()); + } + + @BeforeMethod + public void init() throws Exception { + // //Create user + // sdncDesignerDetails = createUser("tu1234", "Test", "User", + // "tu1234@intl.sdc.com", "DESIGNER"); + // + // //Delete resource + // + // resourceDetails = new ResourceReqDetails(); + // resourceDetails.setResourceName("testresourceDetails"); + // + // resourceUtils.deleteResource_allVersions(resourceDetails, + // sdncDesignerDetails); + // + // //Create resource + // resourceDetails = createResource(sdncDesignerDetails, + // "testresourceDetails"); + + // Create property + // property.setPropertyName("test"); + // property.setPropertyType("integer"); + // property.setPropertySource("A&AI"); + // property.setPropertyDescription("test property"); + + // body = gson.toJson(property); + property = ElementFactory.getDefaultProperty(); + body = property.propertyToJsonString(); + // System.out.println(body); + // HTTP (for negative tests) + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncDesignerDetails.getUserId()); + + } + + @Test + public void testPropertyApis() throws Exception { + // Create property + // System.out.println ("---- Create Property (POST) ----"); + + String propertyId = UniqueIdBuilder.buildPropertyUniqueId(getResourceId(resourceDetails), property.getName()); + + PropertyRestUtils.deleteProperty(getResourceId(resourceDetails), propertyId, sdncDesignerDetails); + RestResponse createPropertyResponse = PropertyRestUtils.createProperty(getResourceId(resourceDetails), body, + sdncDesignerDetails); + AssertJUnit.assertTrue("Expected result code - 201, received - " + createPropertyResponse.getErrorCode(), + createPropertyResponse.getErrorCode() == 201); + + // Get property + // System.out.println ("---- Get Property (GET) ----"); + RestResponse getPropertyResponse = PropertyRestUtils.getProperty(getResourceId(resourceDetails), propertyId, + sdncDesignerDetails); + AssertJUnit.assertTrue("Expected result code - 200, received - " + getPropertyResponse.getErrorCode(), + getPropertyResponse.getErrorCode() == 200); + + JSONObject jsonResp = (JSONObject) JSONValue.parse(getPropertyResponse.getResponse()); + + // assertTrue("Wrong 'type' in the + // response",jsonResp.get("type").equals(property.getPropertyType())); + // assertTrue("Wrong 'source' in the + // response",jsonResp.get("name").equals(property.getPropertyName())); + // assertTrue("Wrong 'name' in the + // response",jsonResp.get("source").equals(property.getPropertySource())); + // assertTrue("Wrong 'description' in the + // response",jsonResp.get("description").equals(property.getPropertyDescription())); + + // Update property + // System.out.println ("---- Update Property (UPDATE) ----"); + property.setPropertyDescription("Updated description"); + // body = gson.toJson(property); + body = property.propertyToJsonString(); + + RestResponse updatePropertyResponse = PropertyRestUtils.updateProperty(getResourceId(resourceDetails), + propertyId, body, sdncDesignerDetails); + AssertJUnit.assertTrue("Expected result code - 200, received - " + updatePropertyResponse.getErrorCode(), + updatePropertyResponse.getErrorCode() == 200); + + // Get property + // System.out.println ("---- Get Property (GET) ----"); + getPropertyResponse = PropertyRestUtils.getProperty(getResourceId(resourceDetails), propertyId, + sdncDesignerDetails); + AssertJUnit.assertTrue("Expected result code - 200, received - " + getPropertyResponse.getErrorCode(), + getPropertyResponse.getErrorCode() == 200); + + jsonResp = (JSONObject) JSONValue.parse(getPropertyResponse.getResponse()); + + // assertTrue("Wrong 'type' in the + // response",jsonResp.get("type").equals(property.getPropertyType())); + // assertTrue("Wrong 'source' in the + // response",jsonResp.get("name").equals(property.getPropertyName())); + // assertTrue("Wrong 'name' in the + // response",jsonResp.get("source").equals(property.getPropertySource())); + // assertTrue("Wrong 'description' in the + // response",jsonResp.get("description").equals(property.getPropertyDescription())); + + // Delete property + // System.out.println ("---- Delete Property (DELETE) ----"); + RestResponse deletePropertyResponse = PropertyRestUtils.deleteProperty(getResourceId(resourceDetails), + propertyId, sdncDesignerDetails); + AssertJUnit.assertTrue("Expected result code - 204, received - " + deletePropertyResponse.getErrorCode(), + deletePropertyResponse.getErrorCode() == 204); + + // Get property - verify that the property doesn't exist. + // System.out.println("---- GET - Property Not Found ----"); + getPropertyResponse = PropertyRestUtils.getProperty(getResourceId(resourceDetails), propertyId, + sdncDesignerDetails); + List variables = Arrays.asList(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_NOT_FOUND.name(), variables, + getPropertyResponse.getResponse()); + + } + + // -------------------------------------------------------------------------------------- + + protected String getPropertyId(ResourceReqDetails resource, PropertyReqDetails property) { + // return + // resource.getResourceName().toLowerCase()+".0.1."+property.getPropertyName(); + return UniqueIdBuilder.buildPropertyUniqueId(resource.getUniqueId(), property.getName()); + } + + protected String getResourceId(ResourceReqDetails resource) { + // String resourceUid = + // UniqueIdBuilder.buildResourceUniqueId(resource.getResourceName(), + // "0.1"); + + return resource.getUniqueId(); + } + + protected User createUser(String cspUserId, String firstName, String lastName, String email, String role) + throws Exception { + User sdncUserDetails = new User(firstName, lastName, cspUserId, email, role, null); + + User adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + UserRestUtils.createUser(sdncUserDetails, adminUser); + + return sdncUserDetails; + } + + protected ResourceReqDetails createResource(User sdncUserDetails, String resourceName) throws Exception { + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + // String category = ResourceCategoryEnum.DATABASE.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.0"; + String contactId = sdncUserDetails.getUserId(); + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, + derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_DATABASE.getCategory(), + ResourceCategoryEnum.GENERIC_DATABASE.getSubCategory()); + // deleteResource(resourceName.toLowerCase()+".0.1",sdncUserDetails.getUserId()); + // TODO delete by name + // deleteResource(UniqueIdBuilder.buildResourceUniqueId(resourceName, + // "0.1"), sdncUserDetails.getUserId()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + AssertJUnit.assertTrue(createResource.getErrorCode().intValue() == 201); + String resourceId = ResponseParser.getUniqueIdFromResponse(createResource); + resourceDetails.setUniqueId(resourceId); + + return resourceDetails; + + } + + @Test + public void putReqToCreateUriNotAllowed() throws Exception { + // System.out.println("---- PUT request to Create uri - Not Allowed + // ----"); + String url = String.format(Urls.CREATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails)); + RestResponse propertyErrorResponse = httpRequest.httpSendByMethod(url, "PUT", body, headersMap); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void getReqToCreateUriNotAllowed() throws Exception { + // System.out.println("---- GET request to Create uri - Not Allowed + // ----"); + String url = String.format(Urls.CREATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails)); + RestResponse propertyErrorResponse = httpRequest.httpSendGet(url, headersMap); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void deleteReqToCreateUriNotAllowed() throws Exception { + // System.out.println("---- DELETE request to Create uri - Not Allowed + // ----"); + String url = String.format(Urls.CREATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails)); + RestResponse propertyErrorResponse = httpRequest.httpSendDelete(url, headersMap); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void postReqToUpdateUriNotAllowed() throws Exception { + // System.out.println("---- POST request to Update uri - Not Allowed + // ----"); + String url = String.format(Urls.UPDATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), getPropertyId(resourceDetails, property)); + RestResponse propertyErrorResponse = httpRequest.httpSendPost(url, body, headersMap); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void deleteReqPropertyNotFound() throws Exception { + // System.out.println("---- DELETE - Property Not Found ----"); + String unknownPropertyId = getPropertyId(resourceDetails, property) + "111"; + String url = String.format(Urls.DELETE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), unknownPropertyId); + RestResponse propertyErrorResponse = httpRequest.httpSendDelete(url, headersMap); + List variables = Arrays.asList(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_NOT_FOUND.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void updateReqPropertyNotFound() throws Exception { + // System.out.println("---- PUT - Property Not Found ----"); + String unknownPropertyId = getPropertyId(resourceDetails, property) + "111"; + String url = String.format(Urls.UPDATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), unknownPropertyId); + RestResponse propertyErrorResponse = httpRequest.httpSendByMethod(url, "PUT", body, headersMap); + List variables = Arrays.asList(""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.PROPERTY_NOT_FOUND.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void modifierNotTheStateOwner() throws Exception { + // System.out.println("---- The modifier is not the state owner - + // Operation Not Allowed ----"); + User sdncUserDetails2 = createUser("tu5555", "Test", "User", "tu5555@intl.sdc.com", "DESIGNER"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails2.getUserId()); + property.setPropertyDescription("new description"); + // body = gson.toJson(property); + body = property.propertyToJsonString(); + String url = String.format(Urls.UPDATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), getPropertyId(resourceDetails, property)); + RestResponse propertyErrorResponse = httpRequest.httpSendByMethod(url, "PUT", body, headersMap); + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, + propertyErrorResponse.getResponse()); + + } + + @Test + public void postReqInvalidContent() throws Exception { + // System.out.println("---- POST - Invalid Content ----"); + body = "invalid"; + String url = String.format(Urls.CREATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), getPropertyId(resourceDetails, property)); + RestResponse propertyErrorResponse = httpRequest.httpSendPost(url, body, headersMap); + + // System.out.println(propertyErrorResponse.getResponse()+" "+ + // propertyErrorResponse.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), variables, + propertyErrorResponse.getResponse()); + } + + @Test + public void putReqInvalidContent() throws Exception { + + // Create property + // System.out.println ("---- Create Property (POST) ----"); + RestResponse createPropertyResponse = PropertyRestUtils.createProperty(getResourceId(resourceDetails), body, + sdncDesignerDetails); + assertTrue("Expected result code - 201, received - " + createPropertyResponse.getErrorCode(), + createPropertyResponse.getErrorCode() == 201); + + // System.out.println("---- PUT - Invalid Content ----"); + body = "invalid"; + + String url = String.format(Urls.UPDATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + getResourceId(resourceDetails), getPropertyId(resourceDetails, property)); + + // System.out.println(url + "\n" + body); + + RestResponse propertyErrorResponse = httpRequest.httpSendByMethod(url, "PUT", body, headersMap); + + // System.out.println(propertyErrorResponse.getResponse()+" "+ + // propertyErrorResponse.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), variables, + propertyErrorResponse.getResponse()); + } + + // -------------------------------------------------------------------------------------- + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CheckGetResource.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CheckGetResource.java new file mode 100644 index 0000000000..85dfe4e13a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CheckGetResource.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.common.util.SerializationUtils; + +import fj.data.Either; + +public class CheckGetResource { + + public void checkGetVmmsc6() throws Exception { + + try { + + System.out.println("dddd"); + RestResponse getResource = ResourceRestUtils.getResource("96eb6583-2822-448b-a284-bfc144fa627e"); + + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + + Either serialize = SerializationUtils.serializeExt(resource); + + SerializationUtils.deserializeExt(serialize.left().value(), Resource.class, "ffff"); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ComponentRelationshipInVfTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ComponentRelationshipInVfTest.java new file mode 100644 index 0000000000..d05dd1039a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ComponentRelationshipInVfTest.java @@ -0,0 +1,1408 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ComponentRelationshipInVfTest extends ComponentBaseTest { + + public ComponentRelationshipInVfTest() { + super(new TestName(), ComponentRelationshipInVfTest.class.getName()); + } + + private ResourceReqDetails resourceDetailsVF; + private User designerUser; + private User adminUser; + private User testerUser; + private ResourceReqDetails resourceDetailsReq; + private ResourceReqDetails resourceDetailsCap; + + @BeforeMethod + public void before() throws Exception { + designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + testerUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + + resourceDetailsVF = ElementFactory.getDefaultResourceByType("VF100", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, designerUser.getUserId(), ResourceTypeEnum.VF.toString()); + createResource(resourceDetailsVF, designerUser); + + resourceDetailsReq = ElementFactory.getDefaultResourceByType("SoftCompRouter", + NormativeTypesEnum.SOFTWARE_COMPONENT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + designerUser.getUserId(), ResourceTypeEnum.CP.toString()); // resourceType + // = + // VFC + resourceDetailsCap = ElementFactory.getDefaultResourceByType("MyCompute", NormativeTypesEnum.COMPUTE, + ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, designerUser.getUserId(), ResourceTypeEnum.CP.toString()); // resourceType + // = + // VFC + + } + + private void createResource(ResourceReqDetails resourceDetails, User user) throws Exception, IOException { + RestResponse createResourceResponse = ResourceRestUtils.createResource(resourceDetails, user); + ResourceRestUtils.checkCreateResponse(createResourceResponse); + if (!resourceDetails.getResourceType().equals("VF")) + LifecycleRestUtils.changeResourceState(resourceDetails, user, "0.1", LifeCycleStatesEnum.CHECKIN); + } + + private void createAtomicResource(ResourceReqDetails resourceDetails, User user) throws Exception { + createResource(resourceDetails, user); + } + + private RequirementCapabilityRelDef setRelationshipBetweenInstances(ComponentInstance riReq, + ComponentInstance riCap, CapReqDef capReqDef) throws Exception { + + String capbilityUid = capReqDef.getCapabilities().get("tosca.capabilities.Container").get(0).getUniqueId(); + String requirementUid = capReqDef.getRequirements().get("tosca.capabilities.Container").get(0).getUniqueId(); + + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(riReq.getUniqueId()); + requirementDef.setToNode(riCap.getUniqueId()); + + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(riReq.getUniqueId()); + pair.setCapabilityOwnerId(riCap.getUniqueId()); + pair.setRequirement("host"); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType("tosca.capabilities.Container"); + pair.setRelationships(relationship); + pair.setCapabilityUid(capbilityUid); + pair.setRequirementUid(requirementUid); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + return requirementDef; + } + + private ComponentInstance createComponentInstance(ResourceReqDetails res) throws Exception { + return createComponentInstance(res, designerUser); + } + + private ComponentInstance createComponentInstance(ResourceReqDetails res, User user, ResourceReqDetails vf) + throws Exception { + RestResponse response = ResourceRestUtils.createResourceInstance(res, user, vf.getUniqueId()); + ResourceRestUtils.checkCreateResponse(response); + ComponentInstance compInstance = ResponseParser.parseToObject(response.getResponse(), ComponentInstance.class); + return compInstance; + } + + private ComponentInstance createComponentInstance(ResourceReqDetails res, User user) throws Exception { + return createComponentInstance(res, user, resourceDetailsVF); + } + + private void createTwoAtomicResourcesByType(String reqType, String capType, User user1, User user2) + throws Exception { + resourceDetailsReq.setResourceType(reqType); + createAtomicResource(resourceDetailsReq, user1); + resourceDetailsCap.setResourceType(capType); + createAtomicResource(resourceDetailsCap, user2); + } + + private void createTwoAtomicResourcesByType(String reqType, String capType) throws Exception { + createTwoAtomicResourcesByType(reqType, capType, designerUser, designerUser); + } + + @Test + public void associateInVF() throws Exception { + + createTwoAtomicResourcesByType(ResourceTypeEnum.VFC.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDef = getResourceReqCap(); + + List capList = capReqDef.getCapabilities().get("tosca.capabilities.Container"); + List reqList = capReqDef.getRequirements().get("tosca.capabilities.Container"); + + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(riReq.getUniqueId()); + requirementDef.setToNode(riCap.getUniqueId()); + + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(riReq.getUniqueId()); + pair.setCapabilityOwnerId(riCap.getUniqueId()); + pair.setRequirement("host"); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType("tosca.capabilities.Container"); + pair.setRelationships(relationship); + pair.setCapabilityUid(capList.get(0).getUniqueId()); + pair.setRequirementUid(reqList.get(0).getUniqueId()); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(designerUser, + resourceDetailsVF); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + + List list = capReqDef.getRequirements().get("tosca.capabilities.Container"); + assertEquals("Check requirement", null, list); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(designerUser, resourceDetailsVF); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + + list = capReqDef.getRequirements().get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, list.size()); + } + + //////////////////////////////// Q A ////////////////////////////// + private boolean checkRealtionship(String fromNode, String toNode, String resourceUniqueId) throws Exception { + List componentInstancesRelations = getComponentInstancesRelations( + resourceUniqueId); + RequirementCapabilityRelDef requirementCapabilityRelDef = componentInstancesRelations.get(0); + boolean fromNodeCheck = requirementCapabilityRelDef.getFromNode().equals(fromNode); + boolean toNodeCheck = requirementCapabilityRelDef.getToNode().equals(toNode); + + return fromNodeCheck && toNodeCheck; + } + + private List getComponentInstancesRelations(String resourceUniqueId) + throws ClientProtocolException, IOException { + Resource resource = getVfAsResourceObject(resourceUniqueId); + List componenRelationInstances = resource.getComponentInstancesRelations(); + + return componenRelationInstances; + } + + private Resource getVfAsResourceObject(String resourceUniqueId) throws ClientProtocolException, IOException { + RestResponse getResource = ResourceRestUtils.getResource(resourceUniqueId); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + return resource; + } + + private List getComponentInstancesList(String resourceUniqueId) throws Exception { + Resource resource = getVfAsResourceObject(resourceUniqueId); + List componentInstances = resource.getComponentInstances(); + return componentInstances; + } + + @Test + public void associateCpToCpTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.CP.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDef = getResourceReqCap(); + + requirementsBeforeAssociate.remove("tosca.capabilities.Container"); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + + List list = capabilitiesBeforeAssociate.get("tosca.capabilities.Container"); + for (CapabilityDefinition cap : list) { + cap.setMinOccurrences("0"); + } + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + } + + private CapReqDef getResourceReqCap(ResourceReqDetails res) throws IOException { + RestResponse getResourceBeforeAssociate = ComponentRestUtils.getComponentRequirmentsCapabilities(designerUser, + resourceDetailsVF); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceBeforeAssociate.getResponse(), CapReqDef.class); + return capReqDef; + } + + private CapReqDef getResourceReqCap() throws IOException { + return getResourceReqCap(resourceDetailsVF); + } + + @Test + public void associateCpToVLTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDef = getResourceReqCap(); + + requirementsBeforeAssociate.remove("tosca.capabilities.Container"); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + + List list = capabilitiesBeforeAssociate.get("tosca.capabilities.Container"); + for (CapabilityDefinition cap : list) { + cap.setMinOccurrences("0"); + } + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + + } + + // Error handling + // ELLA - more informative error + @Test + public void associateCpToVlInVFCTest() throws Exception { + ResourceReqDetails vfcDetails = ElementFactory.getDefaultResourceByType("VFC100", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, designerUser.getUserId(), ResourceTypeEnum.VFC.toString()); + RestResponse createVfcResponse = ResourceRestUtils.createResource(vfcDetails, designerUser); + ResourceRestUtils.checkCreateResponse(createVfcResponse); + + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + vfcDetails.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 400, associateInstances.getErrorCode().intValue()); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "SoftCompRouter 1", + // "MyCompute 2", + // "host" + // ] + } + + // Error handling + @Test + public void associateCpToVfTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riCapInVfInstance = createComponentInstance(resourceDetailsCap, designerUser, + resourceDetailsVF); + ComponentInstance riReqInVfInstance = createComponentInstance(resourceDetailsReq, designerUser, + resourceDetailsVF); + + ResourceReqDetails vfHigh = new ResourceReqDetails(resourceDetailsVF, "0.1"); + vfHigh.setName("vfHigh"); + vfHigh.setTags(new ArrayList(Arrays.asList(vfHigh.getName()))); + vfHigh.setResourceType(ResourceTypeEnum.VF.toString()); + createResource(vfHigh, designerUser); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq, designerUser, vfHigh); + LifecycleRestUtils.changeResourceState(resourceDetailsVF, designerUser, "0.1", LifeCycleStatesEnum.CHECKIN); + ComponentInstance riCap = createComponentInstance(resourceDetailsVF, designerUser, vfHigh); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + associateInstances.getResponse()); + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "SoftCompRouter 1", + // "VF100 2", + // "host" + // ] + } + + // Error handling + @Test + public void associateVfcToVfcNotFoundTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.VFC.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + riCap.setUniqueId("123"); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 400, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_BAD_REQUEST.name(), + new ArrayList(), associateInstances.getResponse()); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "SoftCompRouter 1", + // "012f6dcd-bcdf-4d9b-87be-ff1442b95831.5d265453-0b6a-4453-8f3d-57a253b88432.softcomprouter1", + // "host" + } + + @Test + public void associateCpToDeletedVfcTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResource(resourceDetailsCap.getUniqueId(), + designerUser.getUserId()); + ResourceRestUtils.checkDeleteResponse(deleteResourceResponse); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + } + + @Test + public void associateCpToDeletedVlTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResource(resourceDetailsCap.getUniqueId(), + designerUser.getUserId()); + ResourceRestUtils.checkDeleteResponse(deleteResourceResponse); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + } + + @Test + public void associateCpToDeletedCpTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.CP.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResource(resourceDetailsCap.getUniqueId(), + designerUser.getUserId()); + ResourceRestUtils.checkDeleteResponse(deleteResourceResponse); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + } + + // Error handling + @Test + public void associateCpToDeletedCpInstanceTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.CP.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse deleteComponentInstance = ComponentInstanceRestUtils.deleteComponentInstance(designerUser, + resourceDetailsVF.getUniqueId(), riReq.getUniqueId(), ComponentTypeEnum.RESOURCE); + ComponentInstanceRestUtils.checkDeleteResponse(deleteComponentInstance); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 400, associateInstances.getErrorCode().intValue()); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "7d6aca08-9321-4ea1-a781-c52c8214a30e.c0e63466-5283-44d8-adff-365c0885a6ba.softcomprouter1", + // "MyCompute 2", + // "host" + // ] + } + + // Error handling + @Test + public void associateVfcToDeletedVFCInstanceTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.VFC.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse deleteComponentInstance = ComponentInstanceRestUtils.deleteComponentInstance(designerUser, + resourceDetailsVF.getUniqueId(), riReq.getUniqueId(), ComponentTypeEnum.RESOURCE); + ComponentInstanceRestUtils.checkDeleteResponse(deleteComponentInstance); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 400, associateInstances.getErrorCode().intValue()); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "7d6aca08-9321-4ea1-a781-c52c8214a30e.c0e63466-5283-44d8-adff-365c0885a6ba.softcomprouter1", + // "MyCompute 2", + // "host" + // ] + } + + @Test + public void associateWithDifferentOwnerOfVf() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), resourceDetailsVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + associateInstances.getResponse()); + + CapReqDef capReqDef = getResourceReqCap(); + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + Map> requirementsAfterAssociate = capReqDef.getRequirements(); + + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + assertTrue(requirementsAfterAssociate.equals(requirementsBeforeAssociate)); + } + + @Test + public void associateWithTester() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + ElementFactory.getDefaultUser(UserRoleEnum.TESTER), resourceDetailsVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + associateInstances.getResponse()); + + CapReqDef capReqDef = getResourceReqCap(); + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + Map> requirementsAfterAssociate = capReqDef.getRequirements(); + + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + assertTrue(requirementsAfterAssociate.equals(requirementsBeforeAssociate)); + } + + // Error handling + @Test + public void associateCpToVLIntoVFNotFound() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + String uidNotFound = "123"; + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + uidNotFound, ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 404, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), + new ArrayList(Arrays.asList("")), associateInstances.getResponse()); + + // {"serviceException":{"messageId":"SVC4063","text":"Error: Requested + // '%1' resource was not found.","variables":[""]}}} + } + + // Error Handling + @Test + public void associateCpToVlWithMissingUid() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + requirementDef.setToNode(""); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 400, associateInstances.getErrorCode().intValue()); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), + // new ArrayList(), associateInstances.getResponse()); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "SoftCompRouter 1", + // "fd3a689b-fa1c-4105-933d-d1310e642f05.95bce626-ce73-413b-8c14-2388d1589d5c.softcomprouter1", + // "host" + // ] + } + + @Test + public void associateInServiceWithUidOfVf() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", 404, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), + new ArrayList(Arrays.asList("")), associateInstances.getResponse()); + } + + @Test + public void associateCpToVl_DifferentOwners() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString(), designerUser, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2)); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDef = getResourceReqCap(); + + requirementsBeforeAssociate.remove("tosca.capabilities.Container"); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + + List list = capabilitiesBeforeAssociate.get("tosca.capabilities.Container"); + for (CapabilityDefinition cap : list) { + cap.setMinOccurrences("0"); + } + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + } + + @Test(enabled = false) + public void associateToNotCheckedoutVf() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse changeResourceStateToCheckin = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckin); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + associateInstances.getResponse()); + + CapReqDef capReqDef = getResourceReqCap(); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDef.getCapabilities().equals(capabilitiesBeforeAssociate)); + + String firstUniqueId = resourceDetailsVF.getUniqueId(); + + // checkout + + RestResponse changeResourceStateToCheckout = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckout); + String secondUniqueId = resourceDetailsVF.getUniqueId(); + + CapReqDef capReqDefAfterFirstCheckout = getResourceReqCap(); + Map> capabilitiesAfterFirstCheckout = capReqDefAfterFirstCheckout + .getCapabilities(); + Map> requirementsAfterFirstCheckout = capReqDefAfterFirstCheckout + .getRequirements(); + + requirementDef = setUidsOfInstancesAfterLifecycleStateChange(riReq, riCap, capReqDefBeforeAssociate); + + RestResponse firstAssociateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + designerUser, resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, firstAssociateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDefAfterFirstAssociate = getResourceReqCap(); + Map> capabilitiesAfterFirstAssociate = capReqDefAfterFirstAssociate + .getCapabilities(); + Map> requirementsAfterFirstAssociate = capReqDefAfterFirstAssociate + .getRequirements(); + + requirementsAfterFirstCheckout.remove("tosca.capabilities.Container"); + assertTrue(requirementsAfterFirstAssociate.equals(requirementsAfterFirstCheckout)); + assertTrue(capabilitiesAfterFirstAssociate.equals(capabilitiesAfterFirstCheckout)); + + resourceDetailsVF.setUniqueId(firstUniqueId); + CapReqDef capReqDefOfFirstVersion = getResourceReqCap(); + Map> capabilitiesOfFirstVersion = capReqDefOfFirstVersion.getCapabilities(); + Map> requirementsOfFirstVersion = capReqDefOfFirstVersion.getRequirements(); + + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + assertTrue(requirementsBeforeAssociate.equals(requirementsOfFirstVersion)); + assertTrue(capabilitiesBeforeAssociate.equals(capabilitiesOfFirstVersion)); + + // checkin-checkout + resourceDetailsVF.setUniqueId(secondUniqueId); + RestResponse changeResourceStateToCheckin2 = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckin2); + RestResponse changeResourceStateToCheckout2 = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckout2); + + List componentInstancesRelations = getComponentInstancesRelations( + resourceDetailsVF.getUniqueId()); + assertFalse(componentInstancesRelations.isEmpty()); + assertEquals(1, componentInstancesRelations.size()); + List componentInstancesList = getComponentInstancesList(resourceDetailsVF.getUniqueId()); + for (ComponentInstance comp : componentInstancesList) { + String instanceUid = comp.getUniqueId(); + assertTrue(checkNodesInRelations(instanceUid, componentInstancesRelations.get(0))); + } + assertEquals(2, componentInstancesList.size()); + + } + + private RequirementCapabilityRelDef setUidsOfInstancesAfterLifecycleStateChange(ComponentInstance riReq, + ComponentInstance riCap, CapReqDef capReqDefBeforeAssociate) + throws ClientProtocolException, IOException, Exception { + RequirementCapabilityRelDef requirementDef; + // RestResponse getResourceResponse = + // ResourceRestUtils.getResource(resourceDetailsVF.getUniqueId()); + // Resource resource_0_2 = + // ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), + // Resource.class); + // List componentInstances = + // resource_0_2.getComponentInstances(); + List componentInstances = getComponentInstancesList(resourceDetailsVF.getUniqueId()); + + for (ComponentInstance comp : componentInstances) { + if (comp.getName().equals(riReq.getName())) { + riReq.setUniqueId(comp.getUniqueId()); + } else if (comp.getName().equals(riCap.getName())) { + riCap.setUniqueId(comp.getUniqueId()); + } + } + requirementDef = setRelationshipBetweenInstances(riReq, riCap, capReqDefBeforeAssociate); + return requirementDef; + } + + private boolean checkNodesInRelations(String instanceUid, RequirementCapabilityRelDef relation) { + if (relation.getToNode().equals(instanceUid)) { + return true; + } else if (relation.getFromNode().equals(instanceUid)) { + return true; + } else { + return false; + } + } + + @Test + public void associateOneOfTwoCPsToVl_ThenDiscocciate() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + ResourceReqDetails secondResourceDetailsReq = new ResourceReqDetails(resourceDetailsReq, "0.1"); + secondResourceDetailsReq.setName("secondCP"); + secondResourceDetailsReq.setTags(Arrays.asList(secondResourceDetailsReq.getName())); + createAtomicResource(secondResourceDetailsReq, designerUser); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riReq2 = createComponentInstance(secondResourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDef = getResourceReqCap(); + + List expectedList = requirementsBeforeAssociate.get("tosca.capabilities.Container"); + for (RequirementDefinition req : expectedList) { + if (req.getOwnerName().equals(riReq2.getName())) { + expectedList = new ArrayList(Arrays.asList(req)); + break; + } + } + requirementsBeforeAssociate.put("tosca.capabilities.Container", expectedList); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + + List list = capabilitiesBeforeAssociate.get("tosca.capabilities.Container"); + for (CapabilityDefinition cap : list) { + cap.setMinOccurrences("0"); + } + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + + // second relationship + + RequirementCapabilityRelDef secondRequirementDef = setRelationshipBetweenInstances(riReq2, riCap, + capReqDefBeforeAssociate); + RestResponse secondAssociateInstances = ComponentInstanceRestUtils.associateInstances(secondRequirementDef, + designerUser, resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, secondAssociateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(secondRequirementDef.getFromNode(), secondRequirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + CapReqDef capReqDefAfterSecondAssociation = getResourceReqCap(); + + requirementsBeforeAssociate.remove("tosca.capabilities.Container"); + assertTrue(capReqDefAfterSecondAssociation.getRequirements().equals(requirementsBeforeAssociate)); + + Map> capabilitiesAfterSecondAssociate = capReqDefAfterSecondAssociation + .getCapabilities(); + assertTrue(capabilitiesAfterSecondAssociate.equals(capabilitiesBeforeAssociate)); + + // dissociate + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(secondRequirementDef, + designerUser, resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + CapReqDef capReqDefAfterDissociation = getResourceReqCap(); + Map> capabilitiesAfterDissociate = capReqDefAfterDissociation + .getCapabilities(); + Map> requirementsAfterDissociate = capReqDefAfterDissociation + .getRequirements(); + + assertTrue(capabilitiesAfterDissociate.equals(capReqDef.getCapabilities())); + requirementsBeforeAssociate.put("tosca.capabilities.Container", expectedList); + assertTrue(requirementsAfterDissociate.equals(requirementsBeforeAssociate)); + } + + @Test + public void associateNotCompitableCapAndReq() throws Exception { + resourceDetailsReq = ElementFactory.getDefaultResourceByType("Database", NormativeTypesEnum.DATABASE, + ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, designerUser.getUserId(), ResourceTypeEnum.CP.toString()); // resourceType + // = + // VFC + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + assertTrue(requirementDef.getRelationships().size() == 1); + String requirement = requirementDef.getRelationships().get(0).getRequirement(); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 404, associateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND.name(), + new ArrayList(Arrays.asList(riReq.getName(), riCap.getName(), requirement)), + associateInstances.getResponse()); + + CapReqDef capReqDef = getResourceReqCap(); + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + Map> requirementsAfterAssociate = capReqDef.getRequirements(); + + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + assertTrue(requirementsAfterAssociate.equals(requirementsBeforeAssociate)); + + } + + @Test + public void disassociateCpAndCpTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.CP.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + @Test + public void disassociateCpAndVfcTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + @Test + public void disassociateCpAndVLTest() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + // Error handliing + // in the error should we get the unique id of instances instead of names + @Test + public void disassociateNotFoundAssociation() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + String requirementName = requirementDef.getRelationships().get(0).getRequirement(); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 404, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND.name(), + new ArrayList(Arrays.asList(riReq.getName(), riCap.getName(), requirementName)), + dissociateInstances.getResponse()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + // Error handliing + @Test + public void disassociateRelationInVfNotFound() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + String uidNotFound = "123"; + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + uidNotFound, ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 404, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), + new ArrayList(Arrays.asList(uidNotFound)), dissociateInstances.getResponse()); + + // "serviceException": { + // "messageId": "SVC4063", + // "text": "Error: Requested \u0027%1\u0027 resource was not found.", + // "variables": [ + // "" + // ] + } + + @Test + public void disassociateWithDifferentDesigner() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), resourceDetailsVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + dissociateInstances.getResponse()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + + } + + @Test + public void disassociateWithTester() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + ElementFactory.getDefaultUser(UserRoleEnum.TESTER), resourceDetailsVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + dissociateInstances.getResponse()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertNotNull("Requierment is null after disassociate with tester", listOfRequierments); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + @Test + public void disassociateServiceWithUidOfVF() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VFC.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", 404, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), + new ArrayList(Arrays.asList("")), dissociateInstances.getResponse()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertTrue(listOfRequierments == null); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).size() != 0); + } + + @Test + public void disassociateWithEmptyVfUid() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + "", ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 404, dissociateInstances.getErrorCode().intValue()); + + CapReqDef capReqDef = getResourceReqCap(); + + requirementsBeforeAssociate.remove("tosca.capabilities.Container"); + assertTrue(capReqDef.getRequirements().equals(requirementsBeforeAssociate)); + + List list = capabilitiesBeforeAssociate.get("tosca.capabilities.Container"); + for (CapabilityDefinition cap : list) { + cap.setMinOccurrences("0"); + } + + Map> capabilitiesAfterAssociate = capReqDef.getCapabilities(); + assertTrue(capabilitiesAfterAssociate.equals(capabilitiesBeforeAssociate)); + } + + @Test + public void disassociateOneComponentDeleted() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + + RestResponse deleteResourceResponse = ResourceRestUtils.deleteResource(resourceDetailsCap.getUniqueId(), + designerUser.getUserId()); + ResourceRestUtils.checkDeleteResponse(deleteResourceResponse); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + + List listOfRequierments = capReqDefAfterDissociate.getRequirements() + .get("tosca.capabilities.Container"); + assertEquals("Check requirement", 1, listOfRequierments.size()); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + } + + @Test + public void disassociateNotCheckedoutVf() throws Exception { + createTwoAtomicResourcesByType(ResourceTypeEnum.CP.toString(), ResourceTypeEnum.VL.toString()); + + ComponentInstance riReq = createComponentInstance(resourceDetailsReq); + ComponentInstance riCap = createComponentInstance(resourceDetailsCap); + + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(); + Map> capabilitiesBeforeAssociate = capReqDefBeforeAssociate + .getCapabilities(); + Map> requirementsBeforeAssociate = capReqDefBeforeAssociate + .getRequirements(); + + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(riReq, riCap, + capReqDefBeforeAssociate); + + RestResponse changeResourceStateToCheckin = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckin); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", 409, dissociateInstances.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + dissociateInstances.getResponse()); + + CapReqDef capReqDefAfterDissociate = getResourceReqCap(); + assertTrue(capReqDefAfterDissociate.getRequirements().equals(requirementsBeforeAssociate)); + assertTrue(capReqDefAfterDissociate.getCapabilities().equals(capabilitiesBeforeAssociate)); + + RestResponse changeResourceStateToCheckout = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckout); + + requirementDef = setUidsOfInstancesAfterLifecycleStateChange(riReq, riCap, capReqDefBeforeAssociate); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, designerUser, + resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF.getUniqueId())); + + RestResponse secondDisociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + designerUser, resourceDetailsVF.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, secondDisociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + RestResponse changeResourceStateToCheckout2 = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckout2); + RestResponse changeResourceStateToCheckout3 = LifecycleRestUtils.changeResourceState(resourceDetailsVF, + designerUser, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.checkSuccess(changeResourceStateToCheckout3); + + assertTrue(getComponentInstancesRelations(resourceDetailsVF.getUniqueId()).isEmpty()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CreateResourceApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CreateResourceApiTest.java new file mode 100644 index 0000000000..a9ed54ef15 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/CreateResourceApiTest.java @@ -0,0 +1,2199 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +/** + * @author yshlosberg + * + */ +public class CreateResourceApiTest extends ComponentBaseTest { + + private static Logger log = LoggerFactory.getLogger(CreateResourceApiTest.class.getName()); + + String contentTypeHeaderData = "application/json"; + String acceptHeaderDate = "application/json"; + String resourceVersion = "0.1"; + + @Rule + public static TestName name = new TestName(); + + public CreateResourceApiTest() { + super(name, CreateResourceApiTest.class.getName()); + } + + @Test + public void createResourceTest() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // ResourceReqDetails resourceDetails = new + // ResourceReqDetails(resourceName, description, resourceTags, category, + // derivedFrom, vendorName, vendorRelease, contactId, icon); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + String resourceName = resourceDetails.getName(); + resourceDetails.setTags(Arrays.asList(resourceName, resourceName, resourceName, resourceName, "tag2", "tag2")); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void createResourceNonDefaultResourceTypeTest() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + String resourceType = ResourceTypeEnum.CP.toString(); + resourceDetails.setResourceType(resourceType); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + resourceRespJavaObject.setResourceType(resourceType); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void createResourceTest_costAndLicenseType() throws Exception { + + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + + } + + // ////Benny + @Test + public void createResourceTest_CostIsMissing() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + // resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + } + + @Test + public void createResourceTest_LicenseTypeMissing() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + // resourceDetails.setLicenseType("User"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + } + + @Test + public void createResourceTest_LicenseType_Installation() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("99999.999"); + resourceDetails.setLicenseType("Installation"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + } + + @Test + public void createResourceTest_LicenseType_CPU() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("0.0"); + resourceDetails.setLicenseType("CPU"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + // validate response + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, + resourceDetails.getUniqueId()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + } + + @Test + public void createResourceTest_LicenseType_Uppercase() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("0.0"); + resourceDetails.setLicenseType("INSTALLATION"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", createResponse.getResponseMessage()); + } + + @Test + public void createResourceTest_LicenseType_Invalid() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("0.0"); + resourceDetails.setLicenseType("CPUUU"); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", createResponse.getResponseMessage()); + } + + @Test + public void createResourceTest_CostValidation_noNumeric() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + resourceDetails.setCost("12355.34b"); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + } + + @Test + public void createResourceTest_CostValidation_valueLength() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + + // Adding invalid cost + resourceDetails.setCost("12355.3434"); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + } + + @Test + public void createResourceTest_CostValidation_PriceLimitations() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + + // Adding invalid cost + RestResponse createResponse; + // create resource + + resourceDetails.setCost("000000.000"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + /* + * resourceDetails.setCost("0550.457"); createResponse = + * resourceUtils.createResource(resourceDetails, sdncModifierDetails); + * assertNotNull("check response object is not null after create resource" + * , createResponse); + * assertNotNull("check error code exists in response after create resource" + * , createResponse.getErrorCode()); + * assertEquals("Check response code after create resource", 400, + * createResponse.getErrorCode().intValue()); + * assertEquals("Check response code after create resource", + * "Bad Request", createResponse.getResponseMessage().toString()); + */ + + resourceDetails.setCost("1"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + resourceDetails.setCost("123555.340"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + resourceDetails.setCost("123.4570"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + resourceDetails.setCost("123555.30"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + resourceDetails.setCost("123.5550"); + createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", + createResponse.getResponseMessage().toString()); + + } + + @Test + public void createResourceTest_CostIsNull() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + resourceDetails.setCost(""); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", createResponse.getResponseMessage()); + + } + + @Test + public void createResourceTest_LicenseIsNull() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // set resource details + String resourceName = "CISCO4572"; + String description = "description"; + // Duplicate tags are allowed and should be de-duplicated by the server + // side + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add(resourceName); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + // Adding cost and licenseType + resourceDetails.setCost("12355.345"); + resourceDetails.setLicenseType("User"); + resourceDetails.setLicenseType(""); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 400, createResponse.getErrorCode().intValue()); + assertEquals("Check response code after create resource", "Bad Request", createResponse.getResponseMessage()); + + } + + @Test + public void createResourceTest_uri_methods() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + ResourceReqDetails resourceDetails = createRandomResource(); + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + log.debug(userBodyJson); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + + RestResponse createResourceResponse2 = http.httpSendByMethod(url, "PUT", userBodyJson, headersMap); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.NOT_ALLOWED.name()); + + assertNotNull("check response object is not null after create resource", createResourceResponse2); + assertNotNull("check error code exists in response after create resource", + createResourceResponse2.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), + createResourceResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + createResourceResponse2.getResponse()); + + } + + private ResourceReqDetails createRandomResource() { + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + return resourceDetails; + } + + @Test + public void createResource_role_tester() throws Exception { + + // init TESTER user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + + ResourceReqDetails resourceDetails2 = createRandomResource(); + + // create resource + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, + restResponse2.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.TESTER.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.TESTER.getUserName()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + // TODO DE171450(to check) + @Test + public void createResource_role_DESIGNER() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ResourceReqDetails resourceDetails = createRandomResource(); + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + // validate response + assertNotNull("check response object is not null after create resource", restResponse); + assertNotNull("check error code exists in response after create resource", restResponse.getErrorCode()); + assertEquals( + "Check response code after create resource, response message is: " + restResponse.getResponseMessage(), + 201, restResponse.getErrorCode().intValue()); + + } + + @Test + public void createResource_missing_header() throws Exception { + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + ResourceReqDetails resourceDetails = createRandomResource(); + + // set null in userId header + sdncModifierDetails.setUserId(null); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_INFORMATION.name(), variables, + restResponse2.getResponse()); + + // //validate audit + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // resourceUtils.constructFieldsForAuditValidation(resourceDetails,resourceVersion); + // + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setModifierUid("null null"); + // expectedResourceAuditJavaObject.setModifierName("null null"); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setCurrState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrVersion(""); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // + // String auditDesc = + // AuditValidationUtils.buildAuditDescription(errorInfo, variables); + // expectedResourceAuditJavaObject.setDesc(auditDesc); + // + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction); + // TODO: yshlosberg enable back + + } + + @Test + public void createResource_existing_resource() throws Exception { + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // ResourceReqDetails resourceDetails = createRandomResource(); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", restResponse); + assertNotNull("check error code exists in response after create resource", restResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + + // set resource details + ResourceReqDetails resourceDetails2 = ElementFactory.getDefaultResource(); + + // clean ES DB + DbUtils.cleanAllAudits(); + + // create resource + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource", resourceDetails2.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_category() throws Exception { + + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + ; + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + category = null; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_CATEGORY.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CATEGORY.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_empty_category() throws Exception { + + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + category = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_CATEGORY.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CATEGORY.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_tags() throws Exception { + + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + ; + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_TAGS.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_TAGS.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + // TODO DE171450(to check) + @Test + public void createResourceTest_with_multiple_tags() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setTags(Arrays.asList(resourceDetails.getName(), "tag2")); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", restResponse); + assertNotNull("check error code exists in response after create resource", restResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + + } + + @Test + public void createResourceTest_empty_tag() throws Exception { + + // init ADMIN user + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(""); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_FIELD_FORMAT.name()); + + assertNotNull("check response object is not null after create resouce", restResponse); + assertNotNull("check error code exists in response after create resource", restResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), restResponse.getErrorCode()); + + List variables = Arrays.asList("Resource", "tag"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), variables, + restResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_with_empty_vendorName() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + vendorName = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_VENDOR_NAME.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_NAME.name(), variables, + restResponse2.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_vendorName() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + vendorName = null; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + assertNotNull("check response object is not null after create resource", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create resource", 400, restResponse2.getErrorCode().intValue()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_NAME.name(), variables, + restResponse2.getResponse()); + + } + + @Test + public void createResourceTest_with_empty_vendorRelease() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + vendorRelease = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_VENDOR_RELEASE.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_RELEASE.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_vendorRelease() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + vendorRelease = null; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_VENDOR_RELEASE.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_RELEASE.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_with_empty_contactId() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + contactId = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_CONTACT.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CONTACT.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_contactId() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + contactId = null; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_CONTACT.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CONTACT.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_with_empty_icon() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + icon = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_ICON.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_ICON.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_icon() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + icon = null; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_ICON.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_ICON.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_with_empty_description() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + description = ""; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createResourceTest_without_description() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // set resource details + String resourceName = "CISCO4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + // set resource details + description = null; + + ResourceReqDetails resourceDetails2 = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + // create resource + + RestResponse restResponse2 = ResourceRestUtils.createResource(resourceDetails2, sdncModifierDetails); + + // validate response + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name()); + + assertNotNull("check response object is not null after create resouce", restResponse2); + assertNotNull("check error code exists in response after create resource", restResponse2.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse2.getErrorCode()); + + List variables = Arrays.asList("Resource"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), variables, + restResponse2.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails2, resourceVersion); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createAndGetResourceByNameAndVersion() throws Exception { + + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + ResourceReqDetails resourceDetailsComp = ElementFactory.getDefaultResource("testresourceComp", + NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, sdncModifierDetails.getUserId()); + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetailsComp, sdncModifierDetails); + // validate response + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + String resourceVersion = "0.1"; + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetailsComp, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResourceByNameAndVersion( + sdncModifierDetails.getUserId(), resourceDetailsComp.getName(), resourceDetailsComp.getVersion()); + assertEquals("Check response code after delete resource", 200, resourceGetResponse.getErrorCode().intValue()); + // Resource resource = + // ResourceRestUtils.parseResourceFromListResp(resourceGetResponse); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + // resourceDetailsComp.setUniqueId(resource.getUniqueId()); + + } + + @Test + public void createResourceResourceTypeNotExistsTest() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + String resourceType = "NOT EXISTS"; + resourceDetails.setResourceType(resourceType); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_CONTENT.name()); + + assertNotNull("check response object is not null after create resouce", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), createResponse.getErrorCode()); + + List variables = new ArrayList<>(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), variables, + createResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor + .constructFieldsForAuditValidation(resourceDetails, resourceVersion); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @Test + public void createResourceResourceTypeEmptyTest() throws Exception { + + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + // String resourceType = ""; + // resourceDetails.setResourceType(resourceType); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // ErrorInfo errorInfo = + // ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_CONTENT.name()); + // + // assertNotNull("check response object is not null after create + // resouce", createResponse); + // assertNotNull("check error code exists in response after create + // resource", createResponse.getErrorCode()); + // assertEquals("Check response code after create service", + // errorInfo.getCode(), createResponse.getErrorCode()); + // + // List variables = new ArrayList<>(); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), + // variables, createResponse.getResponse()); + // + // // validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // Convertor.constructFieldsForAuditValidation(resourceDetails, + // resourceVersion); + // String auditAction = "Create"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState(""); + // expectedResourceAuditJavaObject.setCurrVersion(""); + // expectedResourceAuditJavaObject.setResourceName(""); + // expectedResourceAuditJavaObject.setModifierUid(ElementFactory.getDefaultUser(UserRoleEnum.ADMIN).getUserId()); + // expectedResourceAuditJavaObject.setModifierName(ElementFactory.getDefaultUser(UserRoleEnum.ADMIN).getFullName()); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // + // String auditDesc = + // AuditValidationUtils.buildAuditDescription(errorInfo, variables); + // expectedResourceAuditJavaObject.setDesc(auditDesc); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + } + + @Test + public void checkInvariantUuidIsImmutable() throws Exception { + // choose the user to create resource + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + String invariantUuidDefinedByUser = "!!!!!!!!!!!!!!!!!!!!!!!!"; + resourceDetails.setInvariantUUID(invariantUuidDefinedByUser); + String resourceName = resourceDetails.getName(); + resourceDetails.setTags(Arrays.asList(resourceName, resourceName, resourceName, resourceName, "tag2", "tag2")); + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + BaseRestUtils.checkStatusCode(createResponse, "create request failed", false, 201); + // validate response + assertNotNull("check response object is not null after create resource", createResponse); + assertNotNull("check error code exists in response after create resource", createResponse.getErrorCode()); + assertEquals("Check response code after create resource", 201, createResponse.getErrorCode().intValue()); + + Resource resourceCreation = ResponseParser.convertResourceResponseToJavaObject(createResponse.getResponse()); + String invariantUUIDcreation = resourceCreation.getInvariantUUID(); + // validate response + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + ResourceValidationUtils.validateResp(createResponse, resourceRespJavaObject); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncUserDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(resourceGetResponse); + Resource resourceGetting = ResponseParser + .convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + String invariantUUIDgetting = resourceGetting.getInvariantUUID(); + assertEquals(invariantUUIDcreation, invariantUUIDgetting); + + // Update resource with new invariant UUID + RestResponse restResponseUpdate = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncUserDetails, + resourceDetails.getUniqueId()); + BaseRestUtils.checkSuccess(restResponseUpdate); + Resource updatedResource = ResponseParser.convertResourceResponseToJavaObject(restResponseUpdate.getResponse()); + String invariantUUIDupdating = updatedResource.getInvariantUUID(); + assertEquals(invariantUUIDcreation, invariantUUIDupdating); + + // Do checkin + RestResponse restResponseCheckin = LifecycleRestUtils.changeResourceState(resourceDetails, sdncUserDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + BaseRestUtils.checkSuccess(restResponseCheckin); + Resource checkinResource = ResponseParser + .convertResourceResponseToJavaObject(restResponseCheckin.getResponse()); + String invariantUUIDcheckin = checkinResource.getInvariantUUID(); + String version = checkinResource.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckin); + assertEquals(version, "0.1"); + + // Do checkout + RestResponse restResponseCheckout = LifecycleRestUtils.changeResourceState(resourceDetails, sdncUserDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + BaseRestUtils.checkSuccess(restResponseCheckout); + Resource ResourceResource = ResponseParser + .convertResourceResponseToJavaObject(restResponseCheckout.getResponse()); + String invariantUUIDcheckout = ResourceResource.getInvariantUUID(); + version = ResourceResource.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckout); + assertEquals(version, "0.2"); + + // do certification request + RestResponse restResponseCertificationRequest = LifecycleRestUtils.changeResourceState(resourceDetails, + sdncUserDetails, resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + BaseRestUtils.checkSuccess(restResponseCertificationRequest); + Resource certificationRequestResource = ResponseParser + .convertResourceResponseToJavaObject(restResponseCertificationRequest.getResponse()); + String invariantUUIDcertificationRequest = certificationRequestResource.getInvariantUUID(); + version = certificationRequestResource.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcertificationRequest); + assertEquals(version, "0.2"); + + // start certification + RestResponse restResponseStartCertification = LifecycleRestUtils.changeResourceState(resourceDetails, + sdncUserDetails, resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + BaseRestUtils.checkSuccess(restResponseStartCertification); + Resource startCertificationRequestResource = ResponseParser + .convertResourceResponseToJavaObject(restResponseStartCertification.getResponse()); + String invariantUUIDStartCertification = startCertificationRequestResource.getInvariantUUID(); + version = startCertificationRequestResource.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDStartCertification); + assertEquals(version, "0.2"); + + // certify + RestResponse restResponseCertify = LifecycleRestUtils.changeResourceState(resourceDetails, sdncUserDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + BaseRestUtils.checkSuccess(restResponseCertify); + Resource certifyResource = ResponseParser + .convertResourceResponseToJavaObject(restResponseCertify.getResponse()); + String invariantUUIDcertify = certifyResource.getInvariantUUID(); + version = certifyResource.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcertify); + assertEquals(version, "1.0"); + + } + + // US672129 BENNY + + private void getResourceValidateInvariantUuid(String resourceUniqueId, String invariantUUIDcreation) + throws Exception { + RestResponse getResource = ResourceRestUtils.getResource(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), + resourceUniqueId); + BaseRestUtils.checkSuccess(getResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + assertEquals(invariantUUIDcreation, resource.getInvariantUUID()); + } + + @Test + public void resourceInvariantUuid() throws Exception { + + User designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + User testerUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResourceByType("VF200", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, designerUser.getUserId(), ResourceTypeEnum.VF.toString()); + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService("newtestservice1", + ServiceCategoriesEnum.MOBILITY, designerUser.getUserId()); + + // ResourceReqDetails resourceDetails = + // ElementFactory.getDefaultResource(); + resourceDetails.setInvariantUUID("kokomoko"); + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, designerUser); + assertEquals("Check response code after create resource", BaseRestUtils.STATUS_CODE_CREATED, + createResponse.getErrorCode().intValue()); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResponse.getResponse(), Resource.class); + String invariantUUIDcreation = resource.getInvariantUUID(); // generated + // when the + // component + // is + // created + // and never + // changed + // get resource and verify InvariantUuid is not changed + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + + // Update resource with new invariant UUID + resourceDetails.setInvariantUUID("1234567890"); + RestResponse updateResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, designerUser, + resourceDetails.getUniqueId()); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, + updateResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + + // checkIn resource + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + + // checkIn resource + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + // certification request + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + // start certification + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + // certify + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getResourceValidateInvariantUuid(resource.getUniqueId(), invariantUUIDcreation); + // update resource + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + resourceDetails.setDescription("updatedDescription"); + resourceDetails.setVendorRelease("1.2.3.4"); + updateResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, designerUser, + resourceDetails.getUniqueId()); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, updateResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // certification request + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // checkout resource + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // certification request + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + // start certification + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // cancel certification + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, + LifeCycleStatesEnum.CANCELCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // start certification + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // failure + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, testerUser, + LifeCycleStatesEnum.FAILCERTIFICATION); + assertEquals(STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // upload artifact + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + ArtifactReqDetails artifactDetails = ElementFactory.getDefaultArtifact(); + ArtifactRestUtils.addInformationalArtifactToResource(artifactDetails, designerUser, + resourceDetails.getUniqueId()); + assertEquals(STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + // checkIn resource + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, designerUser, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + // create instance + RestResponse createServiceResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + ResourceRestUtils.checkCreateResponse(createServiceResponse); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, designerUser, serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_CREATED, + createResourceInstanceResponse.getErrorCode().intValue()); + getResourceValidateInvariantUuid(resourceDetails.getUniqueId(), invariantUUIDcreation); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetAllResourceVersions.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetAllResourceVersions.java new file mode 100644 index 0000000000..a3372098a0 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetAllResourceVersions.java @@ -0,0 +1,580 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GetAllResourceVersions extends ComponentBaseTest { + + private static Logger logger = LoggerFactory.getLogger(GetAllResourceVersions.class.getName()); + protected User designerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + protected ResourceReqDetails resourceDetails; + + public static TestName name = new TestName(); + + public GetAllResourceVersions() { + super(name, GetAllResourceVersions.class.getName()); + + } + + //// NEW + + protected void deleteAllVersionOfResource() throws Exception { + RestResponse response = null; + + String[] versions = { "0.1", "0.2", "0.3", "0.4", "0.5", "0.6", "1.0", "1.1", "1.2", "1.3", "1.4", "1.5", "2.0", + "2.1", "2.2", "2.3", "2.4", "2.5", "3.0", "4.0", "4.1" }; + + for (String version : versions) { + + response = ResourceRestUtils.deleteResourceByNameAndVersion(designerDetails, + resourceDetails.getName().toUpperCase(), version); + AssertJUnit.assertTrue("delete request returned status:" + response.getErrorCode(), + response.getErrorCode() == 204 || response.getErrorCode() == 404); + + response = ResourceRestUtils.deleteResourceByNameAndVersion(designerDetails, resourceDetails.getName(), + version); + AssertJUnit.assertTrue("delete request returned status:" + response.getErrorCode(), + response.getErrorCode() == 204 || response.getErrorCode() == 404); + + } + } + + @BeforeMethod + public void init() throws Exception { + resourceDetails = defineResourse(); + deleteAllVersionOfResource(); + + } + + @AfterMethod + public void endOfTests() throws Exception { + deleteAllVersionOfResource(); + } + + protected ResourceReqDetails defineResourse() { + String resourceName = "cisco4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + // String category = ServiceCategoriesEnum.MOBILITY.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, + derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getCategory(), + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getSubCategory()); + + return resourceDetails; + } + + @Test + public void getResourceAllVersions_version15() throws Exception { + // create resource + Map origVersionsMap = new HashMap(); + RestResponse restResponse = createResource(designerDetails, resourceDetails); + AssertJUnit.assertTrue("create request returned status:" + restResponse.getErrorCode(), + restResponse.getErrorCode() == 201); + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + // change resource version to 1.5 + for (int x = 0; x < 5; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + AssertJUnit.assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + protected RestResponse createResource(User sdncModifierDetails, ResourceReqDetails resourceDetails) + throws Exception { + // clean ES DB + DbUtils.cleanAllAudits(); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + AssertJUnit.assertNotNull("check response object is not null after create resource", restResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", + restResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create resource", 201, + restResponse.getErrorCode().intValue()); + + return restResponse; + } + + @Test + public void getResourceAllVersions_version05() throws Exception { + + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + Map origVersionsMap = new HashMap(); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + // change resource version to 0.5 + RestResponse checkoutResource; + + logger.debug("Changing resource life cycle "); + for (int x = 0; x < 4; x++) { + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + } + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_version01() throws Exception { + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + Map origVersionsMap = new HashMap(); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_version25() throws Exception { + + Map origVersionsMap = new HashMap(); + + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + assertTrue("create request returned status:" + restResponse.getErrorCode(), restResponse.getErrorCode() == 201); + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // resource version 1.0 + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + // change resource version to 1.5 + for (int x = 0; x < 5; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // resource version 2.0 + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + // change resource version to 2.5 + for (int x = 0; x < 5; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_ReadyForCertification_version05() throws Exception { + Map origVersionsMap = new HashMap(); + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + assertTrue("create request returned status:" + restResponse.getErrorCode(), restResponse.getErrorCode() == 201); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + } + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_CertifactionInProgress_version05() throws Exception { + Map origVersionsMap = new HashMap(); + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + assertTrue("create request returned status:" + restResponse.getErrorCode(), restResponse.getErrorCode() == 201); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + } + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_Certified_version10() throws Exception { + + Map origVersionsMap = new HashMap(); + + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + assertTrue("create request returned status:" + restResponse.getErrorCode(), restResponse.getErrorCode() == 201); + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + + } + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_Certified_version20() throws Exception { + + Map origVersionsMap = new HashMap(); + + // create resource + RestResponse restResponse = createResource(designerDetails, resourceDetails); + assertTrue("create request returned status:" + restResponse.getErrorCode(), restResponse.getErrorCode() == 201); + String resourceName = resourceDetails.getName(); + // resourceUtils.addResourceMandatoryArtifacts(designerDetails, + // restResponse); + + // change resource version to 0.5 + RestResponse checkoutResource; + for (int x = 0; x < 4; x++) { + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // get to version 1.0 + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + // change resource version to 1.5 + for (int x = 0; x < 4; x++) { + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, designerDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, + checkoutResource.getErrorCode().intValue()); + } + + // get to version 1.0 + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, + resourceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + origVersionsMap.put(resourceDetails.getVersion(), resourceDetails.getUniqueId()); + + // validate get response + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, + resourceDetails.getUniqueId()); + Resource res = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void getResourceAllVersions_ResourceNotFound() throws Exception { + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(designerDetails, "123456789"); + assertEquals("Check response code after checkout resource", 404, resourceGetResponse.getErrorCode().intValue()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetResourceNotAbstractApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetResourceNotAbstractApiTest.java new file mode 100644 index 0000000000..ccf6142538 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/GetResourceNotAbstractApiTest.java @@ -0,0 +1,326 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +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.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.imports.ImportGenericResourceCITest; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class GetResourceNotAbstractApiTest extends ComponentBaseTest { + + private static Logger logger = LoggerFactory.getLogger(ComponentBaseTest.class.getName()); + protected static final int STATUS_CODE_GET_SUCCESS = 200; + + protected Config config = Config.instance(); + protected String contentTypeHeaderData = "application/json"; + protected String acceptHeaderDate = "application/json"; + + @Rule + public static TestName name = new TestName(); + + public GetResourceNotAbstractApiTest() { + super(name, GetResourceNotAbstractApiTest.class.getName()); + } + + @Test + public void getNotAbstractResourceList() throws Exception { + + // remove all the not abstract resources + // Map originalState = + // ImportResourceCITest.removeAllNormativeTypeResources(); + + // import all the default not abstract resources + // ImportGenericResourceCITest.importAllNormativeTypesResources(UserRoleEnum.ADMIN); + + // Get not abstract resources + RestResponse getResourceNotAbstarctResponse = getNotAbstractResources(); + // Check that received 200. + assertEquals("Check response code after get abstract resources", STATUS_CODE_GET_SUCCESS, + getResourceNotAbstarctResponse.getErrorCode().intValue()); + // Verify that all the resources not abstract + assertTrue("One or more resources are abstract", isAllResourcesNotAbstract(getResourceNotAbstarctResponse)); + // Verify that all the resources are certified + assertTrue("Not all the resources are certified", isAllResourcesCertified(getResourceNotAbstarctResponse)); + + String objectStorageUid = "ObjectStorage"; + String computeUid = "Compute"; + String blockStorageUid = "BlockStorage"; + String loadBalancerUid = "LoadBalancer"; + // String portUid = "tosca.nodes.Network.Port"; + String portUid = "Port"; + String networkUid = "Network"; + String databaseUid = "Database"; + + // Compare expected list of abstract resources to actual list of + // abstract resources. + List expectedNotAbstractResourcesUniqueIdArray = new ArrayList(Arrays.asList(computeUid, + databaseUid, objectStorageUid, blockStorageUid, loadBalancerUid, portUid, networkUid)); + + List actualNotAbstarctResourcesUniqueIdArray = restResponseToListByHeader( + getResourceNotAbstarctResponse, "name"); + + // Collections.sort(actualNotAbstarctResourcesUniqueIdArray); + // Collections.sort(expectedNotAbstractResourcesUniqueIdArray); + + List toFind = new ArrayList<>(); + toFind.add(objectStorageUid); + toFind.add(computeUid); + toFind.add(blockStorageUid); + toFind.add(loadBalancerUid); + toFind.add(portUid); + + boolean removeAll = toFind.removeAll(actualNotAbstarctResourcesUniqueIdArray); + logger.debug("Cannot find resources {}", toFind.toString()); + + for (String expectedResource : expectedNotAbstractResourcesUniqueIdArray) { + if (false == actualNotAbstarctResourcesUniqueIdArray.contains(expectedResource)) { + // System.out.println("Not found abstract resource " + + // expectedResource); + } + } + + assertTrue( + "Expected abstract resources list: " + expectedNotAbstractResourcesUniqueIdArray.toString() + + " Actual: " + actualNotAbstarctResourcesUniqueIdArray.toString(), + actualNotAbstarctResourcesUniqueIdArray.containsAll(expectedNotAbstractResourcesUniqueIdArray)); + + /* + * java.lang.AssertionError: Expected abstract resources list: + * [tosca.nodes.Compute, tosca.nodes.ObjectStorage, + * tosca.nodes.BlockStorage, tosca.nodes.LoadBalancer, + * tosca.nodes.Network.Port] Actual: [resourceforproperty216, + * tosca.nodes.Compute, tosca.nodes.Database, resourceforproperty217, + * resourceforproperty217, tosca.nodes.ObjectStorage, + * tosca.nodes.BlockStorage, tosca.nodes.LoadBalancer, + * tosca.nodes.network.Port, tosca.nodes.network.Network, + * resourceforproperty217, resourceforproperty217, + * resourceforproperty217, resourceforproperty217, + * resourceforproperty217, resourceforproperty217, + * resourceforproperty217, resourceforproperty217, + * resourceforproperty217, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317, + * resourceforproperty317, resourceforproperty317] + */ + + // Create resource (not certified) + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + String resourceName = "TestResource"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + String category = ServiceCategoriesEnum.MOBILITY.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.root"); + String vendorName = "Oracle"; + String vendorRelease = "1.0"; + String contactId = "Peter"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + // assertEquals("Check response code after create user", 201, + // restResponse.getErrorCode().intValue()); + + // Get not abstract resources + getResourceNotAbstarctResponse = getNotAbstractResources(); + // Check that received 200. + assertEquals("Check response code after get abstract resources", STATUS_CODE_GET_SUCCESS, + getResourceNotAbstarctResponse.getErrorCode().intValue()); + // Verify that all the resources not abstract + assertTrue("One or more resources are abstract", isAllResourcesNotAbstract(getResourceNotAbstarctResponse)); + // Verify that all the resources are certified + assertTrue("Not all the resources are certified", isAllResourcesCertified(getResourceNotAbstarctResponse)); + + // Compare expected list of abstract resources to actual list of + // abstract resources. + // expectedNotAbstractResourcesUniqueIdArray = new + // ArrayList(Arrays.asList("tosca.nodes.compute.1.0", + // "tosca.nodes.objectstorage.1.0", "tosca.nodes.blockstorage.1.0", + // "tosca.nodes.loadbalancer.1.0", "tosca.nodes.network.port.1.0")); + + // actualNotAbstarctResourcesUniqueIdArray = + // restResponseToListByHeader(getResourceNotAbstarctResponse, + // "uniqueId"); + + actualNotAbstarctResourcesUniqueIdArray = restResponseToListByHeader(getResourceNotAbstarctResponse, "name"); + + Collections.sort(actualNotAbstarctResourcesUniqueIdArray); + Collections.sort(expectedNotAbstractResourcesUniqueIdArray); + + for (String expectedResource : expectedNotAbstractResourcesUniqueIdArray) { + if (false == actualNotAbstarctResourcesUniqueIdArray.contains(expectedResource)) { + // System.out.println("Not found abstract resource " + + // expectedResource); + } + } + assertTrue( + "Expected abstract resources list: " + expectedNotAbstractResourcesUniqueIdArray.toString() + + " Actual: " + actualNotAbstarctResourcesUniqueIdArray.toString(), + actualNotAbstarctResourcesUniqueIdArray.containsAll(expectedNotAbstractResourcesUniqueIdArray)); + // assertTrue("Expected abstract resources list: "+ + // expectedNotAbstractResourcesUniqueIdArray.toString()+ " Actual: + // "+actualNotAbstarctResourcesUniqueIdArray.toString(),expectedNotAbstractResourcesUniqueIdArray.equals(actualNotAbstarctResourcesUniqueIdArray)); + + // restore the resources + // ImportResourceCITest.restoreToOriginalState(originalState); + + } + + protected RestResponse getNotAbstractResources() throws Exception { + HttpRequest httpRequest = new HttpRequest(); + + String url = String.format(Urls.GET_ALL_NOT_ABSTRACT_RESOURCES, config.getCatalogBeHost(), + config.getCatalogBePort()); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), "cs0008"); + + RestResponse getResourceNotAbstarctResponse = httpRequest.httpSendGet(url, headersMap); + + return getResourceNotAbstarctResponse; + } + + protected List restResponseToListByHeader(RestResponse restResponse, String restResponseHeader) { + JsonElement jelement = new JsonParser().parse(restResponse.getResponse()); + JsonArray jsonArray = jelement.getAsJsonArray(); + + List restResponseArray = new ArrayList<>(); + + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject jobject = (JsonObject) jsonArray.get(i); + String header = jobject.get(restResponseHeader).toString(); + header = header.replace("\"", ""); + restResponseArray.add(header); + } + + return restResponseArray; + + } + + protected boolean isAllResourcesNotAbstract(RestResponse restResponse) { + JsonElement jelement = new JsonParser().parse(restResponse.getResponse()); + JsonArray jsonArray = jelement.getAsJsonArray(); + + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject jobject = (JsonObject) jsonArray.get(i); + + if (jobject.get("abstract").getAsBoolean()) { + return false; + } + + } + return true; + + } + + protected boolean isEmptyList(RestResponse restResponse) { + JsonElement jelement = new JsonParser().parse(restResponse.getResponse()); + JsonArray jsonArray = jelement.getAsJsonArray(); + + if (jsonArray.size() == 0) { + return true; + } + return false; + } + + protected boolean isAllResourcesCertified(RestResponse restResponse) { + JsonElement jelement = new JsonParser().parse(restResponse.getResponse()); + JsonArray jsonArray = jelement.getAsJsonArray(); + + String certified = "CERTIFIED"; + String lifecycleState; + + for (int i = 0; i < jsonArray.size(); i++) { + JsonObject jobject = (JsonObject) jsonArray.get(i); + lifecycleState = jobject.get("lifecycleState").getAsString(); + if (!lifecycleState.equals(certified)) { + return false; + } + + } + return true; + } + + @Test(enabled = false) + public void getEmptyNonAbstractResourcesList() throws Exception { + // remove all the not abstract resources + Map originalState = ImportGenericResourceCITest.removeAllNormativeTypeResources(); + + // Get not abstract resources + RestResponse getResourceNotAbstarctResponse = getNotAbstractResources(); + // Check that received 200. + assertEquals("Check response code after get abstract resources", STATUS_CODE_GET_SUCCESS, + getResourceNotAbstarctResponse.getErrorCode().intValue()); + // Verify empty list + assertTrue("Received list is not empty", isEmptyList(getResourceNotAbstarctResponse)); + + // restore the resources + // ImportResourceCITest.restoreToOriginalState(originalState); + // import the resources + ImportGenericResourceCITest.importAllNormativeTypesResources(UserRoleEnum.ADMIN); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ResourceApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ResourceApiTest.java new file mode 100644 index 0000000000..eac33242ed --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ResourceApiTest.java @@ -0,0 +1,366 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class ResourceApiTest extends ComponentBaseTest { + + protected final String contentTypeHeaderData = "application/json"; + protected final String acceptHeaderDate = "application/json"; + + @Rule + public static TestName name = new TestName(); + + public ResourceApiTest() { + super(name, ResourceApiTest.class.getName()); + } + + // Keep + @Test + public void updateResourceMetadataSuccess() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncModifierDetails.setUserId("jh0003"); + RestResponse restResponse = createResourceForUpdate(sdncModifierDetails); + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(restResponse.getResponse()); + + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + // set resource details + ResourceReqDetails resourceDetails = new ResourceReqDetails(); + resourceDetails.setDescription("updatedDescription"); + ArrayList resourceTags = new ArrayList(); + // Duplicate tags are allowed and should be de-duplicated by the server + // side + resourceTags.add(resourceRespJavaObject.getName()); + resourceTags.add("tag1"); + resourceTags.add("tag1"); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + resourceDetails.setTags(resourceTags); + resourceDetails.addCategoryChain(ResourceCategoryEnum.NETWORK_L2_3_ROUTERS.getCategory(), + ResourceCategoryEnum.NETWORK_L2_3_ROUTERS.getSubCategory()); + resourceDetails.setVendorName("OracleUp"); + resourceDetails.setVendorRelease("1.5Up"); + resourceDetails.setContactId("pe1116"); + + resourceDetails.setIcon(resourceRespJavaObject.getIcon()); + resourceDetails.setName(resourceRespJavaObject.getName()); + resourceDetails.setDerivedFrom(resourceRespJavaObject.getDerivedFrom()); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceRespJavaObject.getUniqueId()); + RestResponse updateResourceResponse = http.httpSendByMethod(url, "PUT", userBodyJson, headersMap); + + // resourceDetails.setResourceName(resourceRespJavaObject.getResourceName()); + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, + ResponseParser.convertResourceResponseToJavaObject(updateResourceResponse.getResponse())); + + // Delete resource + deleteResource(resourceRespJavaObject.getUniqueId(), sdncModifierDetails.getUserId()); + + } + + protected void deleteResource(String resourceUniqueId, String httpCspUserId) throws Exception { + RestResponse res = ResourceRestUtils.deleteResource(resourceUniqueId, httpCspUserId); + + // System.out.println("Delete resource was finished with response: " + + // res.getErrorCode()); + } + + protected RestResponse createResourceForUpdate(User sdncModifierDetails) throws Exception { + + ResourceReqDetails resourceDetails = getResourceObj(); + + // create resource + return ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + } + + public ResourceReqDetails getResourceObj() { + // set resource details + String resourceName = "ResourceForUpdate" + (int) (Math.random() * 100); + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + // String category = ResourceCategoriesEnum.MOBILITY.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "pe1116"; + String icon = "myICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, + derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getCategory(), + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getSubCategory()); + return resourceDetails; + } + + // ------------------------------------------------------------------- + + protected ResourceReqDetails defineResourse_Benny(int n) { + String resourceName = "cisco" + String.valueOf(n); + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add("tag1"); + String category = ServiceCategoriesEnum.MOBILITY.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "borderElement"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + return resourceDetails; + } + + @Test + public void getAllAbstractResources() throws Exception { + RestResponse abstractResources = CatalogRestUtils.getAbstractResources(); + + int status = abstractResources.getErrorCode(); + assertTrue(status == 200); + String json = abstractResources.getResponse(); + JSONArray array = (JSONArray) JSONValue.parse(json); + for (Object o : array) { + JSONObject value = (JSONObject) o; + Boolean element = (Boolean) value.get("abstract"); + assertTrue(element); + } + + } + + @Test + public void getAllNotAbstractResources() throws Exception { + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + String url = String.format(Urls.GET_ALL_NOT_ABSTRACT_RESOURCES, config.getCatalogBeHost(), + config.getCatalogBePort()); + HttpGet httpget = new HttpGet(url); + + httpget.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + + httpget.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + + httpget.addHeader(HttpHeaderEnum.USER_ID.getValue(), ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + + // System.out.println("Executing request " + + // httpget.getRequestLine()); + CloseableHttpResponse response = httpclient.execute(httpget); + int status = response.getStatusLine().getStatusCode(); + assertTrue(status == 200); + try { + String json = EntityUtils.toString(response.getEntity()); + JSONArray array = (JSONArray) JSONValue.parse(json); + for (Object o : array) { + JSONObject value = (JSONObject) o; + Boolean element = (Boolean) value.get("abstract"); + assertTrue(!element); + } + + } finally { + response.close(); + } + } finally { + httpclient.close(); + } + } + + @Test + public void updateResourceMetadata_methodNotAllowed() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + // set resource details + String resourceName = "ResForUpdate"; + String description = "updatedDescription"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add("tag1"); + resourceTags.add("tag2"); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add("tosca.nodes.root"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + String vendorName = "OracleUp"; + String vendorRelease = "1.5Up"; + String contactId = "pe1117"; + String icon = "myICON.jpgUp"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, + derivedFrom, vendorName, vendorRelease, contactId, icon); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), + "NotExistsId"); + + RestResponse updateResourceResponse = http.httpSendByMethod(url, "POST", userBodyJson, headersMap); + + assertNotNull("Check error code exists in response after wrong update resource", + updateResourceResponse.getErrorCode()); + assertEquals("Check error code after update resource", 405, updateResourceResponse.getErrorCode().intValue()); + } + + @Test + public void validateResourceNameTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncModifierDetails.setUserId("jh0003"); + + ResourceReqDetails resourceDetails = getResourceObj(); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + Resource resourceRespJavaObject = ResponseParser + .convertResourceResponseToJavaObject(restResponse.getResponse()); + CloseableHttpClient httpclient = HttpClients.createDefault(); + try { + + // check invalid + String url = String.format(Urls.VALIDATE_RESOURCE_NAME, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetails.getName()); + + HttpGet httpget = new HttpGet(url); + + httpget.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + + httpget.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + + httpget.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + // System.out.println("Executing request " + + // httpget.getRequestLine()); + CloseableHttpResponse response = httpclient.execute(httpget); + int status = response.getStatusLine().getStatusCode(); + assertTrue(status == 200); + try { + String json = EntityUtils.toString(response.getEntity()); + JSONObject object = (JSONObject) JSONValue.parse(json); + Boolean element = (Boolean) object.get("isValid"); + assertTrue(!element); + + } finally { + response.close(); + } + // check valid + url = String.format(Urls.VALIDATE_RESOURCE_NAME, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceDetails.getName() + "temp"); + + httpget = new HttpGet(url); + + httpget.addHeader(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + + httpget.addHeader(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + + httpget.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + // System.out.println("Executing request " + + // httpget.getRequestLine()); + response = httpclient.execute(httpget); + status = response.getStatusLine().getStatusCode(); + assertTrue(status == 200); + try { + String json = EntityUtils.toString(response.getEntity()); + JSONObject object = (JSONObject) JSONValue.parse(json); + Boolean element = (Boolean) object.get("isValid"); + assertTrue(element); + + } finally { + response.close(); + } + } finally { + httpclient.close(); + } + + // Delete resource + ResourceRestUtils.deleteResource(resourceDetails, sdncModifierDetails, "0.1"); + + } + + // ------------------------------------------------------------------- + // //Benny Tal + // @Test + // public void createResource_Benny() throws Exception { + // for (int i = 0; i < 100; i++) { + // ResourceReqDetails resourceDetails = defineResourse_Benny(i); + // + // ResourceRestUtils.createResource(resourceDetails, + // UserUtils.getDesignerDetails()); + // // resourceUtils.deleteResource(resourceDetails, + // UserUtils.getDesignerDetails(), "0.1"); + // } + // } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SampleDataProvider.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SampleDataProvider.java new file mode 100644 index 0000000000..f4a4fa108a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SampleDataProvider.java @@ -0,0 +1,41 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import java.io.IOException; + +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.testng.ITestContext; +import org.testng.annotations.DataProvider; + +public class SampleDataProvider { + + @DataProvider + public static Object[][] getResourceByType(ITestContext context) throws IOException, Exception { + return new Object[][] { + { AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true) }, + { AtomicOperationUtils.createResourceByType(ResourceTypeEnum.CP, UserRoleEnum.DESIGNER, true) }, + { AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VL, UserRoleEnum.DESIGNER, true) } }; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SimultaneousApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SimultaneousApiTest.java new file mode 100644 index 0000000000..de83385029 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/SimultaneousApiTest.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.Test; + +public class SimultaneousApiTest extends ComponentBaseTest { + + protected static ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + + @Rule + public static TestName name = new TestName(); + + static String httpCspUserId = "km2000"; + static String userFirstName = "Kot"; + static String userLastName = "Matroskin"; + static String email = "km2000@intl.sdc.com"; + static String role = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN).getRole(); + + public SimultaneousApiTest() { + super(name, SimultaneousApiTest.class.getName()); + + } + + public static class WorkerThread implements Runnable { + CountDownLatch countDownLatch; + int threadIndex; + + public WorkerThread(int threadIndex, CountDownLatch countDownLatch) { + this.threadIndex = threadIndex; + this.countDownLatch = countDownLatch; + } + + @Override + public void run() { + System.out.println("**** Thread started " + threadIndex); + try { + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + String id = ResponseParser.getUniqueIdFromResponse(createResource); + // System.out.println("**** Thread " + threadIndex + " create + // resource status " + createResource.getErrorCode() + " id = " + // + id + " error " + createResource.getResponse()); + // assertEquals("**** create resource: " + + // createResource.getErrorCode() + " thread " + threadIndex, + // 201, status); + } catch (Exception e) { + // System.out.println("**** Thread " + threadIndex + " exception + // " + e); + } + countDownLatch.countDown(); + // System.out.println("**** Thread finished " + threadIndex); + + } + + } + + @Test + public void create2Resources() throws InterruptedException { + int threadCount = 5; + CountDownLatch countDownLatch = new CountDownLatch(threadCount); + ExecutorService executor = Executors.newFixedThreadPool(threadCount); + for (int i = 0; i < threadCount; i++) { + Runnable worker = new WorkerThread(i + 1, countDownLatch); + executor.execute(worker); + } + countDownLatch.await(); + // System.out.println(" finished "); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/UpdateResourceMetadataTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/UpdateResourceMetadataTest.java new file mode 100644 index 0000000000..b61489d12d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/UpdateResourceMetadataTest.java @@ -0,0 +1,2254 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.json.JSONException; +import org.json.JSONObject; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class UpdateResourceMetadataTest extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(UpdateResourceMetadataTest.class.getName()); + protected List Empty_List = new ArrayList(); + protected String extendedChars; + + protected final String contentTypeHeaderData = "application/json"; + protected final String acceptHeaderDate = "application/json"; + protected final String CHARSET_ISO_8859 = "charset=ISO-8859-1"; + + public static TestName name = new TestName(); + protected User sdncModifierDetails; + protected ResourceReqDetails resourceDetails; + + public UpdateResourceMetadataTest() { + super(name, UpdateResourceMetadataTest.class.getName()); + + } + + public String extendedCharsStringBuilder() throws Exception { + char[] extendedCharsArray = new char[128]; + char ch = 128; + for (int i = 0; i < extendedCharsArray.length - 1; i++) { + extendedCharsArray[i] = ch; + ch++; + } + extendedChars = new String(extendedCharsArray); + return extendedChars; + + } + + @BeforeMethod + public void setup() throws Exception { + sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + resourceDetails = defineResourse(); + + } + + // Keep + @Test + public void UpdateDerivedFromSuccess() throws Exception { + + String oldDerivedFromName = NormativeTypesEnum.ROOT.getNormativeName(); + String newDerivedFromName = NormativeTypesEnum.SOFTWARE_COMPONENT.getNormativeName(); + + // Getting both derived from resources for validation + /* + * RestResponse resourceByNameAndVersion = resourceUtils.getResourceByNameAndVersion(sdncModifierDetails, oldDerivedFromName, "1.0"); assertEquals("Check response code after get database normative", 200, + * resourceByNameAndVersion.getErrorCode().intValue()); Resource databaseNormative = resourceUtils.parseResourceResp(resourceByNameAndVersion); + * + * resourceByNameAndVersion = resourceUtils.getResourceByNameAndVersion(sdncModifierDetails, newDerivedFromName, "1.0"); assertEquals("Check response code after get database normative", 200, + * resourceByNameAndVersion.getErrorCode().intValue()); Resource lbNormative = resourceUtils.parseResourceResp(resourceByNameAndVersion); + */ + + // Derived from set to Database + List derivedFrom = new ArrayList<>(); + derivedFrom.add(oldDerivedFromName); + resourceDetails.setDerivedFrom(derivedFrom); + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + AssertJUnit.assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResource = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + derivedFrom.clear(); + derivedFrom.add(newDerivedFromName); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResource.getUniqueId(), ""); + AssertJUnit.assertEquals("Check response code after create resource", 200, updatedRestResponse.getErrorCode().intValue()); + + } + + protected ResourceReqDetails defineUpdateResourceWithNonUpdatableFields(Resource resourceBeforeUpdate) { + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceBeforeUpdate.getName()); + + updatedResourceDetails.setVersion("mumu"); + updatedResourceDetails.setIsAbstract(true); + updatedResourceDetails.setIsHighestVersion(true); + updatedResourceDetails.setCreatorUserId("df4444"); + updatedResourceDetails.setCreatorFullName("John Doe"); + updatedResourceDetails.setLastUpdaterUserId("gf5646"); + updatedResourceDetails.setLastUpdaterFullName("Viktor Tzoy"); + updatedResourceDetails.setCreationDate(new Long(4444)); + updatedResourceDetails.setLastUpdateDate(new Long("534535")); + updatedResourceDetails.setLifecycleState(LifecycleStateEnum.READY_FOR_CERTIFICATION); + updatedResourceDetails.setCost("6.1"); + updatedResourceDetails.setLicenseType("Installation"); + updatedResourceDetails.setUUID("dfsfsdf"); + return updatedResourceDetails; + } + + public void UpdateResourceNotFoundTest() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + String resourceName = "cisco4"; + // update resource + String description = "updatedDescription"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.MOBILITY.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "newOracle"; + String vendorRelease = "2.5"; + String contactId = "jh0003"; + String icon = "myICON"; + + ResourceReqDetails updatedResourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, derivedFrom, vendorName, vendorRelease, contactId, icon); + updatedResourceDetails.setUniqueId("dummyId"); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, "0.1"); + + // validate response + AssertJUnit.assertNotNull("check response object is not null after update resource", updatedRestResponse); + AssertJUnit.assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after update resource", 404, updatedRestResponse.getErrorCode().intValue()); + // String resourceId = + // UniqueIdBuilder.buildResourceUniqueId(resourceName, "0.1"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), Arrays.asList("dummyId"), updatedRestResponse.getResponse()); + + resourceName = ""; + // resourceId = UniqueIdBuilder.buildResourceUniqueId(resourceName, + // "0.1"); + updatedResourceDetails = defineUpdatedResourse(resourceName); + updatedResourceDetails.setUniqueId("dummyId"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, "0.1"); + AssertJUnit.assertNotNull("check response object is not null after update resource", updatedRestResponse); + AssertJUnit.assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), Arrays.asList("dummyId"), updatedRestResponse.getResponse()); + + } + + public char[] getInValidChars() throws Exception { + + char[] extendedCharsArray = new char[59]; + char ch = 1; + for (int i = 0; i < 44; i++) { + extendedCharsArray[i] = ch; + ch++; + } + ch = 58; + for (int i = 44; i < 51; i++) { + extendedCharsArray[i] = ch; + ch++; + } + ch = 91; + for (int i = 51; i < 55; i++) { + extendedCharsArray[i] = ch; + ch++; + } + ch = 123; + for (int i = 55; i < 59; i++) { + extendedCharsArray[i] = ch; + ch++; + } + return extendedCharsArray; + } + + public char[] getTagInValidFormatChars() throws Exception { + // Tag format is the same as defined for Resource Name : + // Allowed characters: Alphanumeric (a-zA-Z0-9), space (' '), underscore + // ('_'), dash ('-'), dot ('.') + char[] notValidCharsArray = new char[30]; + char ch = 33; + for (int i = 0; i < 12; i++) { + notValidCharsArray[i] = ch; + ch++; + } + notValidCharsArray[13] = 47; + ch = 58; + for (int i = 14; i < 21; i++) { + notValidCharsArray[i] = ch; + ch++; + } + ch = 91; + for (int i = 21; i < 24; i++) { + notValidCharsArray[i] = ch; + ch++; + } + notValidCharsArray[24] = 96; + ch = 123; + for (int i = 25; i < 30; i++) { + notValidCharsArray[i] = ch; + ch++; + } + return notValidCharsArray; + } + + public void Validation_UpdateWithIncompleteJsonBodyTest() throws Exception { + // init ADMIN user + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // define and create resource + ResourceReqDetails resourceDetails = defineResourse(); + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "0.1"); + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "1.0"); + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "1.1"); + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceId = resourceDetails.getUniqueId(); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(restResponse)); + + // build Json Object + JSONObject jsonObject = JsonObjectBuilder(resourceDetails); + + List resource = new ArrayList<>(); + resource.add("Resource"); + + // remove Description + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "description", ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), resource); + // remove Tags + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "tags", ActionStatus.COMPONENT_MISSING_TAGS.name(), Empty_List); + // remove Category + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "category", ActionStatus.COMPONENT_MISSING_CATEGORY.name(), resource); + // remove VendorName + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "vendorName", ActionStatus.MISSING_VENDOR_NAME.name(), Empty_List); + // remove VendorRelease + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "vendorRelease", ActionStatus.MISSING_VENDOR_RELEASE.name(), Empty_List); + // remove AT&T Contact + UpdateAndValidateWithIncompletedJsonBody(sdncModifierDetails, jsonObject, resourceId, "contactId", ActionStatus.COMPONENT_MISSING_CONTACT.name(), resource); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, "0.1"); + // validate response + AssertJUnit.assertNotNull("check response object is not null after get resource", getRestResponse); + AssertJUnit.assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "0.1"); + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "1.0"); + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, resourceDetails.getName(), "1.1"); + } + + // End of validation tests + // /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + + protected ResourceReqDetails defineUpdatedResourse(String resourceName) { + String description = "updatedDescription"; + ArrayList resourceTags = new ArrayList(); + // Duplicate tags are allowed and should be de-duplicated by server side + resourceTags.add(resourceName); + resourceTags.add("tag1"); + resourceTags.add("tag1"); + resourceTags.add("tag2"); + resourceTags.add("tag2"); + String category = ServiceCategoriesEnum.VOIP.getValue(); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName()); + String vendorName = "updatedOracle"; + String vendorRelease = "3.5"; + String contactId = "jh0001"; + String icon = "myUpdatedICON"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, category, derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getCategory(), ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getSubCategory()); + + return resourceDetails; + } + + protected ResourceReqDetails defineResourse() { + String resourceName = "cisco4"; + String description = "description"; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(NormativeTypesEnum.ROOT.getNormativeName());// "tosca.nodes.Root"); + String vendorName = "Oracle"; + String vendorRelease = "1.5"; + String contactId = "jh0003"; + String icon = "objectStorage"; + + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getCategory(), ResourceCategoryEnum.GENERIC_INFRASTRUCTURE.getSubCategory()); + + return resourceDetails; + } + + protected RestResponse createResource(User sdncModifierDetails, ResourceReqDetails resourceDetails) throws Exception { + // clean ES DB + DbUtils.cleanAllAudits(); + + // create resource + RestResponse restResponse = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + + // validate response + AssertJUnit.assertNotNull("check response object is not null after create resource", restResponse); + AssertJUnit.assertNotNull("check error code exists in response after create resource", restResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + + return restResponse; + } + + protected RestResponse TryUpdateByAnotherVerb(ResourceReqDetails updatedResourceDetails, User sdncModifierDetails, String uri) throws Exception { + // delete resource + Config config; + RestResponse ResourceResponse; + try { + config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), updatedResourceDetails.getName() + ".0.1"); + + if (uri == "GET") { + ResourceResponse = http.httpSendGet(url, headersMap); + } else if (uri == "POST") { + Gson gson = new Gson(); + String userBodyJson = gson.toJson(updatedResourceDetails); + ResourceResponse = http.httpSendPost(url, userBodyJson, headersMap); + } else if (uri == "DELETE") { + ResourceResponse = http.httpSendDelete(url, headersMap); + } else + return null; + + return ResourceResponse; + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return null; + + } + + protected JSONObject JsonObjectBuilder(ResourceReqDetails resourceDetails) throws JSONException { + // json object: resourceName and icon are must + JSONObject jObject = new JSONObject(); + + List tagsList = Arrays.asList(resourceDetails.getName()); + List derivedFromList = Arrays.asList("[tosca.nodes.Root]"); + + jObject.put("name", resourceDetails.getName()); + jObject.put("description", "updatedDescription"); + jObject.put("tags", tagsList); + jObject.put("category", ServiceCategoriesEnum.VOIP.getValue()); + jObject.put("derivedFrom", derivedFromList); + jObject.put("vendorName", "newOracle"); + jObject.put("vendorRelease", "1.5"); + jObject.put("contactId", "jh0003"); + jObject.put("icon", resourceDetails.getIcon()); + + return jObject; + } + + protected JSONObject RemoveFromJsonObject(JSONObject jObject, String removedPropery) { + jObject.remove(removedPropery); + + return jObject; + } + + // purpose: function for controlling json body fields and validating + // response + protected void UpdateAndValidateWithIncompletedJsonBody(User sdncModifierDetails, JSONObject jsonObject, String resourceId, String removedField, String errorMessage, List variables) throws Exception { + + JSONObject jObject = new JSONObject(jsonObject, JSONObject.getNames(jsonObject)); + // remove description from jsonObject + jObject = RemoveFromJsonObject(jObject, removedField); + // update with incomplete body. + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(jObject.toString(), sdncModifierDetails, resourceId); + // validate response + AssertJUnit.assertNotNull("check response object is not null after update resource", updatedRestResponse); + AssertJUnit.assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(errorMessage, variables, updatedRestResponse.getResponse()); + + } + + // purpose: function for validating error response + protected void UpdateAndValidate(User sdncModifierDetails, ResourceReqDetails resourceDetails, String recievedMessage, List variables) throws Exception { + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, "0.1"); + // validate response + AssertJUnit.assertNotNull("check response object is not null after update resource", updatedRestResponse); + AssertJUnit.assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(recievedMessage, variables, updatedRestResponse.getResponse()); + + } + + protected void parseResponseAndValidateNonUpdatable(ResourceReqDetails resourceDetails, RestResponse restResponse) throws Exception { + // parse response to javaObject + Resource updatedResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + AssertJUnit.assertTrue(!resourceDetails.getIsHighestVersion().equals(updatedResourceRespJavaObject.isHighestVersion())); + AssertJUnit.assertTrue(!resourceDetails.getVersion().equals(updatedResourceRespJavaObject.getName())); + AssertJUnit.assertTrue(!resourceDetails.getIsAbstract().equals(updatedResourceRespJavaObject.isAbstract())); + AssertJUnit.assertTrue(!resourceDetails.getCreatorUserId().equals(updatedResourceRespJavaObject.getCreatorUserId())); + AssertJUnit.assertTrue(!resourceDetails.getCreatorFullName().equals(updatedResourceRespJavaObject.getCreatorFullName())); + AssertJUnit.assertTrue(!resourceDetails.getLastUpdateDate().equals(updatedResourceRespJavaObject.getLastUpdateDate())); + AssertJUnit.assertTrue(!resourceDetails.getCreationDate().equals(updatedResourceRespJavaObject.getCreationDate())); + AssertJUnit.assertTrue(!resourceDetails.getLastUpdaterUserId().equals(updatedResourceRespJavaObject.getLastUpdaterUserId())); + AssertJUnit.assertTrue(!resourceDetails.getLastUpdaterFullName().equals(updatedResourceRespJavaObject.getLastUpdaterFullName())); + AssertJUnit.assertTrue(!resourceDetails.getLifecycleState().equals(updatedResourceRespJavaObject.getLifecycleState())); + AssertJUnit.assertTrue(!resourceDetails.getCost().equals(updatedResourceRespJavaObject.getCost())); + AssertJUnit.assertTrue(!resourceDetails.getLicenseType().equals(updatedResourceRespJavaObject.getLicenseType())); + AssertJUnit.assertTrue(!resourceDetails.getUUID().equals(updatedResourceRespJavaObject.getUUID())); + } + + protected void parseResponseAndValidate(ResourceReqDetails ResourceDetails, RestResponse restResponse) throws Exception { + // parse response to javaObject + Resource updatedResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + // validate request vs response + ResourceValidationUtils.validateResourceReqVsResp(ResourceDetails, updatedResourceRespJavaObject); + } + + public ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ResourceReqDetails resourceDetails, String resourceVersion) { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + + expectedResourceAuditJavaObject.setAction("Checkout"); + expectedResourceAuditJavaObject.setModifierUid(UserRoleEnum.ADMIN.getUserId()); + expectedResourceAuditJavaObject.setModifierName(UserRoleEnum.ADMIN.getUserName()); + expectedResourceAuditJavaObject.setStatus("200.0"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setResourceName(resourceDetails.getName().toLowerCase()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(String.valueOf(Float.parseFloat(resourceVersion) - 0.1f)); + expectedResourceAuditJavaObject.setCurrVersion(resourceVersion); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + + return expectedResourceAuditJavaObject; + + } + + public enum FieldToValidate { + ContactId, Tags, VendorName, VendorRelease, Description + } + + @Test + public void UpdateBy_postTest() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // update resource - without changing resourceName + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + + RestResponse updatedRestResponse = TryUpdateByAnotherVerb(updatedResourceDetails, sdncModifierDetails, "POST"); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), Empty_List, updatedRestResponse.getResponse()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(resourceDetails, getRestResponse); + + } + + @Test + public void UpdateBy_getTest() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // update resource - without changing resourceName + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + RestResponse updatedRestResponse = TryUpdateByAnotherVerb(updatedResourceDetails, sdncModifierDetails, "GET"); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), Empty_List, updatedRestResponse.getResponse()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(resourceDetails, getRestResponse); + + } + + @Test + public void UpdateBy_deleteTest() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // update resource - without changing resourceName + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + RestResponse updatedRestResponse = TryUpdateByAnotherVerb(updatedResourceDetails, sdncModifierDetails, "DELETE"); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), Empty_List, updatedRestResponse.getResponse()); + + RestResponse getRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(resourceDetails, getRestResponse); + + } + + // TODO DE + // @Ignore("") + @Test + public void UpdateWithInvaldJsonBodyTest() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(restResponse)); + String resourceId = resourceDetails.getUniqueId(); + + // update Descirption value + String description = "updatedDescription"; + + // send update with incompleted json, only description string + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(description, sdncModifierDetails, resourceId); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("check error code after update resource", 400, updatedRestResponse.getErrorCode().intValue()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(resourceDetails, getRestResponse); + + } + + @Test + public void UpdateResourceNameSensitiveTest() throws Exception { + User sdncModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + String resourceName = "Ab"; + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + // Delete resources + RestResponse response = null; + response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.1"); + BaseRestUtils.checkDeleteResponse(response); + response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.2"); + BaseRestUtils.checkDeleteResponse(response); + + RestResponse restResponse = createResource(sdncModifierDetails, updatedResourceDetails); + assertEquals("create resource failed", 201, restResponse.getErrorCode().intValue()); + + // check-in Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(updatedResourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // String resourceCertifyVersion = "0.1"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(updatedResourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + updatedResourceDetails.setName("ABC_-bt.aT"); + ArrayList resourceTag = new ArrayList(); + resourceTag.add(0, "ABC_-bt.aT"); + updatedResourceDetails.setTags(resourceTag); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, updatedResourceDetails.getUniqueId(), ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(updatedResourceDetails, updatedRestResponse); + + // Delete resources + response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.1"); + BaseRestUtils.checkDeleteResponse(response); + response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.2"); + BaseRestUtils.checkDeleteResponse(response); + + } + + @Test + public void UpdateIcon_InegativeFlow() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + List resourceList = new ArrayList(); + resourceList.add(0, "Resource"); + // check InValid Characters + char[] notValidCharsArray = new char[59]; + notValidCharsArray = getInValidChars(); + // update metadata details + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + RestResponse updatedRestResponse; + + for (int i = 0; i < notValidCharsArray.length; i++) { + // change icon of metadata + updatedResourceDetails.setIcon("MyIcon" + notValidCharsArray[i]); + // PUT request + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_ICON.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource icon", 400, updatedRestResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating resource icon", "Bad Request", updatedRestResponse.getResponseMessage().toString()); + + } + + // empty icon + String updateIcon = ""; + updatedResourceDetails.setIcon(updateIcon); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_ICON.name(), resourceList, updatedRestResponse.getResponse()); + + // Icon length more then 25 characters + resourceList.add(1, "25"); + updatedResourceDetails.setIcon("1234567890_-qwertyuiopASDNNN"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after create resource", 400, updatedRestResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating resource icon", "Bad Request", updatedRestResponse.getResponseMessage().toString()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResource_NoTagsEqualToResourceName() throws Exception { + + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + ResourceReqDetails updatedResourceDetails = defineResourse(); + updatedResourceDetails.setName("updatedResourceName"); + List tags = updatedResourceDetails.getTags(); + + for (Iterator iter = tags.listIterator(); iter.hasNext();) { + String a = iter.next(); + if (a.equals("updatedResourceName")) { + iter.remove(); + } + } + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource icon", 400, updatedRestResponse.getErrorCode().intValue()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResourceName_negativeFlow() throws Exception { + // The validation are done in Tag's validation + User sdncAdminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + RestResponse updatedRestResponse; + RestResponse restResponse = createResource(sdncAdminModifierDetails, resourceDetails); + assertEquals("create resource failed", 201, restResponse.getErrorCode().intValue()); + String uniqueId = resourceDetails.getUniqueId(); + String resourceName = resourceDetails.getName(); + // check InValid Characters + char[] notValidCharsArray = new char[59]; + notValidCharsArray = getInValidChars(); + ArrayList resource_Name = new ArrayList(); + List resourceList = new ArrayList(); + + ArrayList resourceTags = new ArrayList(); + resourceList.add(0, "Resource"); + + // update metadata details + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + for (int i = 0; i < notValidCharsArray.length; i++, resource_Name.clear()) { + if (i != 1 && i != 46 && /* + * i != 8 && i != 9 && i != 10 && i != 11 && i != 12 && + */ i != 31) // space ("") and dot(.) + { + // change resourceName parameter + updatedResourceDetails.setName("UpdatedResourceName" + notValidCharsArray[i]); + resource_Name.add("UpdatedResourceName" + notValidCharsArray[i]); + updatedResourceDetails.setTags(resource_Name); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncAdminModifierDetails, uniqueId, ""); + // validate response + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_TAG.name(), + // Empty_List, updatedRestResponse.getResponse()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPONENT_NAME.name(), resourceList, updatedRestResponse.getResponse()); + + } + } + + // resourceName length more then 50 characters + // Duplicate tags are allowed and should be de-duplicated by server side + resource_Name.add(resourceName); + resource_Name.add("tag1"); + resource_Name.add("tag1"); + resource_Name.add("tag2"); + resource_Name.add("tag2"); + + resourceList.add(1, "1024"); + // updatedResourceDetails.setName("123456789012345678901234567890123456789012345678901"); + updatedResourceDetails.setName(new String(new char[1025]).replace("\0", "a")); + // resource_Name.add("123456789012345678901234567890123456789012345678901"); + updatedResourceDetails.setTags(resource_Name); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncAdminModifierDetails, uniqueId, ""); + // validate response + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT.name(), resourceList, updatedRestResponse.getResponse()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncAdminModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + // delete resource + RestResponse response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncAdminModifierDetails, updatedResourceDetails.getName(), "0.1"); + BaseRestUtils.checkDeleteResponse(response); + } + + @Test + public void UpdateResourceInformation_NotCheckedOut() throws Exception { + + String resourceBaseVersion = "0.1"; + List resourceList = new ArrayList(); + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // CheckIn Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); // NOT_CERTIFIED_CHECKIN + assertNotNull("check response object is not null after checkout resource", checkoutResource); + assertNotNull("check error code exists in response after checkIn resource", checkoutResource.getErrorCode()); + assertEquals("Check response code after checkin resource", 200, checkoutResource.getErrorCode().intValue()); + + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource icon", 409, updatedRestResponse.getErrorCode().intValue()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResourceInformation_resourceVersion_11() throws Exception { + + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), resourceList, updatedRestResponse.getResponse()); + // assertEquals("Check response code after updating resource icon", 409, + // updatedRestResponse.getErrorCode().intValue()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResourceInformation_resourceVersion_02() throws Exception { + + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // String resourceCertifyVersion = "0.1"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after updating resource icon", 200, updatedRestResponse.getErrorCode().intValue()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(updatedResourceDetails, getResourceRespJavaObject); + + // delete resource + RestResponse response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.1"); + BaseRestUtils.checkDeleteResponse(response); + response = ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.2"); + BaseRestUtils.checkDeleteResponse(response); + + } + + @Test + public void UpdateResourceIcon_resourceVersion_11() throws Exception { + // Can be changed only if major version is 0. + + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // ResourceReqDetails updatedResourceDetails = + // defineUpdatedResourse(resourceName); + ResourceReqDetails updatedResourceDetails = defineResourse(); + // updatedResourceDetails.setVendorName("updatedVandorName"); + updatedResourceDetails.setIcon("updatedIcon"); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED.name(), resourceList, updatedRestResponse.getResponse()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResourceVandorName_resourceVersion_11() throws Exception { + // Can be changed only if the major resource version is 0. + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // ResourceReqDetails updatedResourceDetails = + // defineUpdatedResourse(resourceName); + ResourceReqDetails updatedResourceDetails = defineResourse(); + + updatedResourceDetails.setVendorName("updatedVandorName"); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource icon", 400, updatedRestResponse.getErrorCode().intValue()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResourceName_resourceVersion_11() throws Exception { + // Can be changed only if the major resource version is 0. + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("create resource failed", 201, restResponse.getErrorCode().intValue()); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + /* + * //ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); ResourceReqDetails updatedResourceDetails = defineResourse(); + * + * updatedResourceDetails.setResourceName("updatedResourceName"); updatedResourceDetails.setIcon("updatedResourceName"); + */ + resourceDetails.setName("updatedResourceName"); + List tagList = new ArrayList(); + tagList.add(0, "updatedResourceName"); + resourceDetails.setTags(tagList); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED.name(), resourceList, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResourceTag_resourceVersion_11() throws Exception { + // Tag Can be updated when major version is 0. + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // ResourceReqDetails updatedResourceDetails = + // defineUpdatedResourse(resourceName); + ResourceReqDetails updatedResourceDetails = defineResourse(); + // updatedResourceDetails.setVendorName("updatedVandorName"); + + ArrayList resourceTags = new ArrayList(); + resourceTags.add("NewTag"); + resourceTags.add(resourceDetails.getName()); + + updatedResourceDetails.setTags(resourceTags); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(updatedResourceDetails, getRestResponse); + + } + + @Test + public void UpdateAllowedParames_resourceVersion_11() throws Exception { + + // Tag, contactId, vendorRelease,tags And description - Can be also + // updated when major version is NOT 0. + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // ResourceReqDetails updatedResourceDetails = + // defineUpdatedResourse(resourceName); + ResourceReqDetails updatedResourceDetails = defineResourse(); + // updatedResourceDetails.setVendorName("updatedVandorName"); + + // updated allowed parameters when major resource version is NOT "0" + ArrayList resourceTags = new ArrayList(); + resourceTags.add("NewTag"); + resourceTags.add(resourceDetails.getName()); + updatedResourceDetails.setTags(resourceTags); + updatedResourceDetails.setDescription("UpdatedDescription"); + updatedResourceDetails.setVendorRelease("5.1"); + updatedResourceDetails.setContactId("bt750h"); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(updatedResourceDetails, getRestResponse); + + } + + @Test + public void UpdateResourceDerivedFrom_resourceVersion_11() throws Exception { + // DerivedFrom parameter - Can be updated when major version is 0. + User adminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + String resourceBaseVersion = "0.1"; + + // create resource + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String resourceName = resourceDetails.getName(); + + // resourceUtils.addResourceMandatoryArtifacts(sdncModifierDetails, + // restResponse); + + // Certify Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, adminModifierDetails, resourceBaseVersion, LifeCycleStatesEnum.CERTIFY); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + String resourceCertifyVersion = "1.0"; + logger.debug("Changing resource life cycle "); + checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceCertifyVersion, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after checkout resource", 200, checkoutResource.getErrorCode().intValue()); + + // ResourceReqDetails updatedResourceDetails = + // defineUpdatedResourse(resourceName); + ResourceReqDetails updatedResourceDetails = defineResourse(); + ArrayList drivenFrom = new ArrayList(); + drivenFrom.add(0, "tosca.nodes.Container.Application"); + updatedResourceDetails.setDerivedFrom(drivenFrom); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + List resourceList = new ArrayList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_DERIVED_FROM_CANNOT_BE_CHANGED.name(), resourceList, updatedRestResponse.getResponse()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + } + + @Test + public void UpdateResource_vendorNameValidation() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + String updatedVendorName = ""; + String uniqueId = resourceDetails.getUniqueId(); + resourceDetails.setVendorName(updatedVendorName); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + // update resource vendorName metadata: 1 characters + updatedVendorName = " "; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + // update resource vendorName metadata: 25 characters + updatedVendorName = "Verification and validati"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // update resource vendorName metadata: 26 characters + updatedVendorName = "Verification and validatii"; + // set vendorName + List myList = new ArrayList(); + myList.add(0, "25"); + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT.name(), myList, updatedRestResponse.getResponse()); + + // update resource VendorRelease metadata: forbidden characters + updatedVendorName = "A1<"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1>"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1:"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1\""; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1/"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1\\"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1|"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1?"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorName = "A1*"; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + // update resource vendorName metadata: null + updatedVendorName = null; + // set vendorName + resourceDetails.setVendorName(updatedVendorName); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_NAME.name(), Empty_List, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResource_vendorReleaseValidation() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + RestResponse updatedRestResponse; + String uniqueId = resourceDetails.getUniqueId(); + String updatedVendorRelease; + // set VendorRelease + + // update resource VendorRelease metadata: 1 characters + updatedVendorRelease = "1"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // update resource VendorRelease metadata: 25 characters + updatedVendorRelease = "(!#1.00000000000000000000"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // update resource VendorRelease metadata: 26 characters + updatedVendorRelease = "(!#1.000000000000000000005";// set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT.name(), Arrays.asList("" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH), updatedRestResponse.getResponse()); + + // UpdateAndValidate(sdncModifierDetails, resourceDetails, + // ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT.name(), + // Arrays.asList(""+ValidationUtils.VENDOR_RELEASE_MAX_LENGTH)); + + // update resource VendorRelease metadata: forbidden characters + updatedVendorRelease = "A1<"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1>"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1:"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1\""; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1/"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1\\"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1|"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1?"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + updatedVendorRelease = "A1*"; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + // update resource VendorRelease metadata: null + updatedVendorRelease = null; + // set VendorRelease + resourceDetails.setVendorRelease(updatedVendorRelease); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_VENDOR_RELEASE.name(), Empty_List, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResource_contactIdValidation() throws Exception { // [a-zA-Z]{2}[0-9]{3}[a-zA-Z0-9]{1} + // (6 + // characters + // now, + // may + // be + // expanded + // up + // to + // 8 + // characters + // in + // the + // future). + // Convert + // Upper + // case + // character + // to + // lower + // case + RestResponse updatedRestResponse; + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + String uniqueId = resourceDetails.getUniqueId(); + + List myList = new ArrayList(); + myList.add(0, "Resource"); + String updatedContactId = ""; + resourceDetails.setContactId(updatedContactId); + + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "ab12345"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = " "; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "ab 50h"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "ab123c"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + updatedContactId = "cd789E"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + // contactId norm + resourceDetails.setContactId(updatedContactId.toLowerCase()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + updatedContactId = "ef4567"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + updatedContactId = "AA012A"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + // contactId norm + resourceDetails.setContactId(updatedContactId.toLowerCase()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + updatedContactId = "CD012c"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + // contactId norm + resourceDetails.setContactId(updatedContactId.toLowerCase()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + updatedContactId = "EF0123"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + // contactId norm + resourceDetails.setContactId(updatedContactId.toLowerCase()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + ////////////////////////////// **************////////////////////////////// + List resource = Arrays.asList("Resource"); + updatedContactId = "01345a"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "0y000B"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "Y1000b"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "abxyzC"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "cdXYZc"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "efXY1D"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "EFabcD"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "EFABCD"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "EFABC1"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "efui1D"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "efui1!"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "ef555!"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = ",f555"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + updatedContactId = "EF55.5"; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + // update resource contactId metadata: extended character set (128–255) + resourceDetails.setContactId(extendedCharsStringBuilder()); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + // update resource contactId metadata: null + updatedContactId = null; + resourceDetails.setContactId(updatedContactId); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CONTACT.name(), myList, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResource_TagsFieldValidation() throws Exception { + RestResponse updatedRestResponse; + // define and create resource + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + String uniqueId = resourceDetails.getUniqueId(); + + String updatedTagField = ""; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(updatedTagField); + // set description + resourceDetails.setTags(resourceTags); + List variables = Arrays.asList("Resource", "tag"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), variables, updatedRestResponse.getResponse()); + + // update resource tags metadata: empty + resourceTags = new ArrayList(); + // set Tags + resourceDetails.setTags(resourceTags); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_TAGS.name(), Empty_List, updatedRestResponse.getResponse()); + + // update resource description metadata: 1 characters + updatedTagField = "A"; + resourceTags = new ArrayList(); + resourceTags.add(updatedTagField); + resourceTags.add(resourceDetails.getName()); + // set description + resourceDetails.setTags(resourceTags); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // OK - tag up to 50 chars + updatedTagField = "The Indian-crested.porcupine_The Indian cresteddds"; + resourceTags.add(updatedTagField); + resourceDetails.setTags(resourceTags); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // OK - sum is 1024, 50x20+48+20(commas)+6(cisco4 - resource name) + String updatedTagField1 = "The Indian-crested.porcupine_The Indian crestedd01"; + String updatedTagField2 = "The Indian-crested.porcupine_The Indian crestedd02"; + String updatedTagField3 = "The Indian-crested.porcupine_The Indian crestedd03"; + String updatedTagField4 = "The Indian-crested.porcupine_The Indian crestedd04"; + String updatedTagField5 = "The Indian-crested.porcupine_The Indian crestedd05"; + String updatedTagField6 = "The Indian-crested.porcupine_The Indian crestedd06"; + String updatedTagField7 = "The Indian-crested.porcupine_The Indian crestedd07"; + String updatedTagField8 = "The Indian-crested.porcupine_The Indian crestedd08"; + String updatedTagField9 = "The Indian-crested.porcupine_The Indian crestedd09"; + String updatedTagField10 = "The Indian-crested.porcupine_The Indian crestedd10"; + String updatedTagField11 = "The Indian-crested.porcupine_The Indian crestedd11"; + String updatedTagField12 = "The Indian-crested.porcupine_The Indian crestedd12"; + String updatedTagField13 = "The Indian-crested.porcupine_The Indian crestedd13"; + String updatedTagField14 = "The Indian-crested.porcupine_The Indian crestedd14"; + String updatedTagField15 = "The Indian-crested.porcupine_The Indian crestedd15"; + String updatedTagField16 = "The Indian-crested.porcupine_The Indian crestedd16"; + String updatedTagField17 = "The Indian-crested.porcupine_The Indian crestedd17"; + String updatedTagField18 = "The Indian-crested.porcupine_The Indian crestedd18"; + String updatedTagField19 = "The Indian-crested.porcupine_The Indian crestaa"; + + resourceTags = new ArrayList(); + resourceTags.add(updatedTagField); + resourceTags.add(updatedTagField1); + resourceTags.add(updatedTagField2); + resourceTags.add(updatedTagField3); + resourceTags.add(updatedTagField4); + resourceTags.add(updatedTagField5); + resourceTags.add(updatedTagField6); + resourceTags.add(updatedTagField7); + resourceTags.add(updatedTagField8); + resourceTags.add(updatedTagField9); + resourceTags.add(updatedTagField10); + resourceTags.add(updatedTagField11); + resourceTags.add(updatedTagField12); + resourceTags.add(updatedTagField13); + resourceTags.add(updatedTagField14); + resourceTags.add(updatedTagField15); + resourceTags.add(updatedTagField16); + resourceTags.add(updatedTagField17); + resourceTags.add(updatedTagField18); + resourceTags.add(updatedTagField19); + resourceTags.add(resourceDetails.getName()); + // set description + resourceDetails.setTags(resourceTags); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // Add another tag-exceeds limit + resourceTags.add("d"); + resourceDetails.setTags(resourceTags); + ArrayList myArray = new ArrayList(); + myArray.add(0, "1024"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT.name(), myArray, updatedRestResponse.getResponse()); + + // Tag exceeds limit - 51 + resourceTags = new ArrayList(); + updatedTagField = "The Indian-crested.porcupine_The Indian crestedddsw"; + resourceTags.add(updatedTagField); + resourceTags.add(resourceDetails.getName()); + // set description + resourceDetails.setTags(resourceTags); + myArray.remove(0); + myArray.add(0, "50"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT.name(), myArray, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResource_DesriptionFieldValidation() throws Exception { + // define and create resource + RestResponse updatedRestResponse; + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + String uniqueId = resourceDetails.getUniqueId(); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + List resource = new ArrayList<>(); + resource.add("Resource"); + // update resource description metadata: 0 characters + String updatedDescription = ""; + // set description + resourceDetails.setDescription(updatedDescription); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), resource, updatedRestResponse.getResponse()); + + // update resource description metadata: null + updatedDescription = null; + // set description + resourceDetails.setDescription(updatedDescription); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), resource, updatedRestResponse.getResponse()); + + // update resource description metadata: 1 characters + updatedDescription = "A"; + // set description + resourceDetails.setDescription(updatedDescription); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // update resource description metadata: 1024 characters + updatedDescription = "The Indian crested porcupine *{Hystrix indica}*, or Indian porcupine is a member of the Old World porcupines." + "It is quite an adaptable rodent, found throughout southern Asia and the Middle East." + + "It is tolerant of several different habitats: mountains, tropical and subtropical grasslands, scrublands, and forests." + + "It is a large rodent, growing more than 0.9 m = (3 ft) long and weighing 14.5 kg = (32 lb)! [citation needed] It is covered in multiple layers of quills." + + "The longest quills grow from its shoulders to about a third of the animal's length." + "Its tail is covered in short, hollow quills that can rattle when threatened." + + "It has broad feet and long claws for digging. When attacked, the Indian crested porcupine raises its quills and rattles the hollow quills on its tail." + + "If the predator persists past these threats, the porcupine launches a backwards assault, hoping to stab its attacker with its quills." + + "It does this so effectively that most brushes between predators and the Indian porcupine end in death or severe injury"; + // set description + resourceDetails.setDescription(updatedDescription); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + parseResponseAndValidate(resourceDetails, updatedRestResponse); + + // update resource description metadata: 1025 characters + updatedDescription = "The Indian crested porcupine *{Hystrix indica}*, or Indian porcupine is a member of the Old World porcupines." + "It is quite an adaptable rodent, found throughout southern Asia and the Middle East." + + "It is tolerant of several different habitats: mountains, tropical and subtropical grasslands, scrublands, and forests." + + "It is a large rodent, growing more than 0.9 m = (3 ft) long and weighing 14.5 kg = (32 lb)! [citation needed] It is covered in multiple layers of quills." + + "The longest quills grow from its shoulders to about a third of the animal's length." + "Its tail is covered in short, hollow quills that can rattle when threatened." + + "It has broad feet and long claws for digging. When attacked, the Indian crested porcupine raises its quills and rattles the hollow quills on its tail." + + "If the predator persists past these threats, the porcupine launches a backwards assault, hoping to stab its attacker with its quills." + + "It does this so effectively that most brushes between predators and the Indian porcupine end in death or severe injury."; + // set description + resourceDetails.setDescription(updatedDescription); + resource.add(1, "1024"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, uniqueId, ""); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT.name(), resource, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResource_TagsFormatValidation() throws Exception { + char[] notValidCharsArray = getTagInValidFormatChars(); + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check recourse created ", 201, restResponse.getErrorCode().intValue()); + String resourceName = resourceDetails.getName(); + + // update tag details + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + ArrayList resourceTags = new ArrayList(); + + String updatedTagField; + RestResponse updatedRestResponse; + List variables = Arrays.asList("Resource", "tag"); + + for (int i = 0; i < notValidCharsArray.length; i++) { + updatedTagField = "UpdatedTag" + notValidCharsArray[i]; + resourceTags = new ArrayList(); + resourceTags.add(updatedTagField); + resourceTags.add(resourceDetails.getName()); + // set description + updatedResourceDetails.setTags(resourceTags); + + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), variables, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource icon", 400, updatedRestResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating resource icon", "Bad Request", updatedRestResponse.getResponseMessage().toString()); + + } + + } + + @Test + public void UpdateResourceCategory_negativeFlow() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after update resource", 201, restResponse.getErrorCode().intValue()); + Resource resourceBeforeUpdate = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + String uniqueID = resourceDetails.getUniqueId(); + + // Update resource Category Successfully + ResourceReqDetails updatedResourceDetails = resourceDetails; + + updatedResourceDetails.removeAllCategories(); + updatedResourceDetails.addCategoryChain(ServiceCategoriesEnum.MOBILITY.getValue(), ResourceCategoryEnum.APPLICATION_L4_DATABASE.getSubCategory()); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + + // validate response + List resourceList = new ArrayList(); + resourceList.add(0, "Resource"); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CATEGORY.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource", 400, updatedRestResponse.getErrorCode().intValue()); + + // Updating resource category + updatedResourceDetails = defineUpdateResourceWithNonUpdatableFields(resourceBeforeUpdate); + updatedResourceDetails.addCategory(""); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + resourceList = new ArrayList(); + resourceList.add(0, "Resource"); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CATEGORY.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource", 400, updatedRestResponse.getErrorCode().intValue()); + + // Updating resource category + updatedResourceDetails = defineUpdateResourceWithNonUpdatableFields(resourceBeforeUpdate); + updatedResourceDetails.addCategory("XXXXXX"); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // validate response + resourceList = new ArrayList(); + resourceList.add(0, "Resource"); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_CATEGORY.name(), resourceList, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource", 400, updatedRestResponse.getErrorCode().intValue()); + + // CheckIn Resource + logger.debug("Changing resource life cycle "); + RestResponse checkoutResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); // NOT_CERTIFIED_CHECKIN + assertEquals("Check response code after checkin resource", 200, checkoutResource.getErrorCode().intValue()); + + // Update resource Category + updatedResourceDetails = defineUpdateResourceWithNonUpdatableFields(resourceBeforeUpdate); + updatedResourceDetails.addCategory(ServiceCategoriesEnum.VOIP.getValue()); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + // verify response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), Empty_List, updatedRestResponse.getResponse()); + assertEquals("Check response code after updating resource", 409, updatedRestResponse.getErrorCode().intValue()); + + // CheckIn Resource + logger.debug("Changing resource life cycle "); + RestResponse checkinResource = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); // NOT_CERTIFIED_CHECKIN + assertNotNull("check response object is not null after checkout resource", checkoutResource); + assertNotNull("check error code exists in response after checkIn resource", checkoutResource.getErrorCode()); + assertEquals("Check response code after checkin resource", 200, checkoutResource.getErrorCode().intValue()); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, uniqueID); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(resourceDetails, getRestResponse); + + } + + @Test + public void UpdateResourceCategorySuccessfully() throws Exception { + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after update resource", 201, restResponse.getErrorCode().intValue()); + Resource resourceBeforeUpdate = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + // Update resource Category Successfully + ResourceReqDetails updatedResourceDetails = resourceDetails; + + updatedResourceDetails.removeAllCategories(); + updatedResourceDetails.addCategoryChain(ResourceCategoryEnum.APPLICATION_L4_DATABASE.getCategory(), ResourceCategoryEnum.APPLICATION_L4_DATABASE.getSubCategory()); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, resourceDetails.getUniqueId(), ""); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, updatedRestResponse.getErrorCode().intValue()); + // parseResponseAndValidateNonUpdatable(updatedResourceDetails, + // updatedRestResponse); + parseResponseAndValidate(updatedResourceDetails, updatedRestResponse); + + // validate category updated + assertTrue(updatedResourceDetails.getCategories().get(0).getName().equals(ResourceCategoryEnum.APPLICATION_L4_DATABASE.getCategory())); + + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceDetails.getUniqueId()); + assertNotNull("check response object is not null after update resource", getRestResponse); + parseResponseAndValidate(updatedResourceDetails, getRestResponse); + + ResourceRestUtils.deleteResourceByNameAndVersion(sdncModifierDetails, updatedResourceDetails.getName(), "0.1"); + } + + // Benny + + @Test + public void Validation_UpdateIcon() throws Exception { + // Fields to update (Forbidden) + String _updatedIcon = "mySecondIcon.Jpg"; + + // administrator permissions + User sdncAdminModifierDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // define and create resource + ResourceRestUtils.deleteResourceByNameAndVersion(sdncAdminModifierDetails, resourceDetails.getName(), "0.1"); + + RestResponse restResponse = createResource(sdncAdminModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + String resourceName = resourceDetails.getName(); + + // update metadata details + ResourceReqDetails updatedResourceDetails = defineUpdatedResourse(resourceName); + // change icon of metadata + updatedResourceDetails.setIcon(_updatedIcon); + // PUT request + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncAdminModifierDetails, resourceDetails.getUniqueId(), ""); + + // validate response + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_INVALID_ICON.name(), Arrays.asList("Resource"), updatedRestResponse.getResponse()); + + // empty icon + _updatedIcon = ""; + updatedResourceDetails.setIcon(_updatedIcon); + updatedRestResponse = ResourceRestUtils.updateResourceMetadata(updatedResourceDetails, sdncAdminModifierDetails, resourceDetails.getUniqueId(), ""); + assertNotNull("check response object is not null after update resource", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_ICON.name(), Arrays.asList("Resource"), updatedRestResponse.getResponse()); + + // get resource with original name. original metadata should be returned + RestResponse getRestResponse = ResourceRestUtils.getResource(sdncAdminModifierDetails, resourceDetails.getUniqueId()); + // validate response + assertNotNull("check response object is not null after get resource", getRestResponse); + assertNotNull("check error code exists in response after get resource", getRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", 200, getRestResponse.getErrorCode().intValue()); + + // parse updated response to javaObject + Resource getResourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(getRestResponse.getResponse()); + // validate that metadata was not changed + ResourceValidationUtils.validateResourceReqVsResp(resourceDetails, getResourceRespJavaObject); + + ResourceRestUtils.deleteResourceByNameAndVersion(sdncAdminModifierDetails, updatedResourceDetails.getName(), "0.1"); + + } + + @Test + public void UpdateResourceTypeSuccess() throws Exception { + // LCS is CheckOut + String newResourceType = ResourceTypeEnum.VL.toString(); + String currentResourceType = resourceDetails.getResourceType(); + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + resourceDetails.setResourceType(newResourceType); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + assertEquals("Check response code after create resource", 200, updatedRestResponse.getErrorCode().intValue()); + Resource updatedResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(updatedRestResponse.getResponse()); + // assertTrue("Check resource type after update resource", + // updatedResourceJavaObject.getResourceType().toString().equals(resourceType)); + assertTrue("Check resource type after update resource", updatedResourceJavaObject.getResourceType().toString().equals(currentResourceType)); + + } + + @Test + public void UpdateResourceTypeAndNameSuccess() throws Exception { + // LCS is CheckOut + String newResourceType = ResourceTypeEnum.VL.toString(); + String currentResourceType = resourceDetails.getResourceType(); + String newResourceName = "new Name"; + + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + resourceDetails.setResourceType(newResourceType); + resourceDetails.setName(newResourceName); + List tags = resourceDetails.getTags(); + tags.add(newResourceName); + resourceDetails.setTags(tags); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + assertEquals("Check response code after create resource", 200, updatedRestResponse.getErrorCode().intValue()); + Resource updatedResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(updatedRestResponse.getResponse()); + assertTrue("Check resource type after update resource", updatedResourceJavaObject.getResourceType().toString().equals(currentResourceType)); + assertTrue("Check resource name after update resource", updatedResourceJavaObject.getName().equals(newResourceName)); + + } + + @Test + public void UpdateResourceTypeAfterResourceCertification() throws Exception { + + String newResourceType = ResourceTypeEnum.VF.toString(); + String currentResourceType = resourceDetails.getResourceType(); + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + resourceDetails.setResourceType(newResourceType); + restResponse = LifecycleRestUtils.certifyResource(resourceDetails); + assertEquals("Check response code after resource CheckIn", 200, restResponse.getErrorCode().intValue()); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after resource CheckIn", 200, restResponse.getErrorCode().intValue()); + currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + assertEquals("Check response code after create resource", 200, updatedRestResponse.getErrorCode().intValue()); + Resource updatedResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(updatedRestResponse.getResponse()); + // assertTrue("Check resource type after update resource", + // updatedResourceJavaObject.getResourceType().toString().equals(newResourceType)); + assertTrue("Check resource type after update resource", updatedResourceJavaObject.getResourceType().toString().equals(currentResourceType)); + + } + + @Test + public void UpdateResourceTypeCheckInLCS() throws Exception { + + String resourceType = ResourceTypeEnum.VL.toString(); + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + resourceDetails.setResourceType(resourceType); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum.CHECKIN); + assertEquals("Check response code after resource CheckIn", 200, restResponse.getErrorCode().intValue()); + + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + + assertNotNull("check response object is not null after create resouce", updatedRestResponse); + assertNotNull("check error code exists in response after create resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), updatedRestResponse.getErrorCode()); + + List variables = new ArrayList<>(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResourceTypeCertifiedLCS() throws Exception { + + String resourceType = ResourceTypeEnum.VL.toString(); + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + restResponse = LifecycleRestUtils.certifyResource(resourceDetails); + assertEquals("Check response code after resource CheckIn", 200, restResponse.getErrorCode().intValue()); + + resourceDetails.setResourceType(resourceType); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + + assertNotNull("check response object is not null after create resouce", updatedRestResponse); + assertNotNull("check error code exists in response after create resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), updatedRestResponse.getErrorCode()); + + List variables = new ArrayList<>(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, updatedRestResponse.getResponse()); + + } + + @Test + public void UpdateResourceTypeInvalidType() throws Exception { + + String resourceType = "INVALID TYPE"; + RestResponse restResponse = createResource(sdncModifierDetails, resourceDetails); + assertEquals("Check response code after create resource", 201, restResponse.getErrorCode().intValue()); + Resource currentResourceJavaObject = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + resourceDetails.setResourceType(resourceType); + RestResponse updatedRestResponse = ResourceRestUtils.updateResourceMetadata(resourceDetails, sdncModifierDetails, currentResourceJavaObject.getUniqueId(), ""); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_CONTENT.name()); + + assertNotNull("check response object is not null after update resouce", updatedRestResponse); + assertNotNull("check error code exists in response after update resource", updatedRestResponse.getErrorCode()); + assertEquals("Check response code after update resource", errorInfo.getCode(), updatedRestResponse.getErrorCode()); + + List variables = new ArrayList<>(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), variables, updatedRestResponse.getResponse()); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VFResourceInstanceNameCRUD.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VFResourceInstanceNameCRUD.java new file mode 100644 index 0000000000..895390f764 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VFResourceInstanceNameCRUD.java @@ -0,0 +1,480 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +import fj.data.Either; + +public class VFResourceInstanceNameCRUD extends ComponentBaseTest { + + protected static ServiceReqDetails serviceDetails; + protected static ResourceReqDetails resourceDetailsVFC; + protected static ResourceReqDetails resourceDetailsVL; + protected static ResourceReqDetails resourceDetailsVF; + protected static ResourceReqDetails resourceDetailsCP; + protected static ComponentInstanceReqDetails resourceInstanceReqDetailsVF; + protected static ComponentInstanceReqDetails resourceInstanceReqDetailsVFC; + protected static ComponentInstanceReqDetails resourceInstanceReqDetailsVL; + protected static ComponentInstanceReqDetails resourceInstanceReqDetailsCP; + protected static User sdncDesignerDetails1; + protected static User sdncTesterDeatails1; + protected static User sdncAdminDetails1; + protected static ArtifactReqDetails heatArtifactDetails; + protected static ArtifactReqDetails defaultArtifactDetails; + protected static int maxLength = 50; + protected static Resource resourceVF = null; + + @Rule + public static TestName name = new TestName(); + + public VFResourceInstanceNameCRUD() { + super(name, VFResourceInstanceNameCRUD.class.getName()); + } + + @BeforeMethod + + public void init() throws Exception { + + // serviceDetails = ElementFactory.getDefaultService(); + // resourceDetailsVFC = + // ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VFC.toString(), + // "resourceVFC"); + // resourceDetailsVF = + // ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VF.toString(), + // "resourceVF3"); + // resourceDetailsVL = + // ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VL.toString(), + // "resourceVL"); + // resourceDetailsCP = + // ElementFactory.getDefaultResourceByType(ResourceTypeEnum.CP.toString(), + // "resourceCP"); + sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncAdminDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // heatArtifactDetails = + // ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + + Either resourceDetailsCP_01e = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.CP, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(resourceDetailsCP_01e.left().value(), UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CHECKIN, true); + resourceDetailsCP = new ResourceReqDetails(resourceDetailsCP_01e.left().value()); + Either resourceDetailsVL_01e = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VL, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVL_01e.left().value(), UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CHECKIN, true); + resourceDetailsVL = new ResourceReqDetails(resourceDetailsVL_01e.left().value()); + Either resourceDetailsVF_01e = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true); + resourceDetailsVF = new ResourceReqDetails(resourceDetailsVF_01e.left().value()); + Either resourceDetailsVFC_01e = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVFC_01e.left().value(), UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CHECKIN, true); + resourceDetailsVFC = new ResourceReqDetails(resourceDetailsVFC_01e.left().value()); + + resourceInstanceReqDetailsVFC = ElementFactory.getDefaultComponentInstance("VFC", resourceDetailsVFC); + resourceInstanceReqDetailsVF = ElementFactory.getDefaultComponentInstance("VF", resourceDetailsVF); + resourceInstanceReqDetailsVL = ElementFactory.getDefaultComponentInstance("VL", resourceDetailsVL); + resourceInstanceReqDetailsCP = ElementFactory.getDefaultComponentInstance("CP", resourceDetailsCP); + sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncAdminDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + } + + @Test + public void addResourceInstanceToVF() throws Exception { + + createVFWithCertifiedResourceInstance(resourceDetailsCP, resourceInstanceReqDetailsCP); + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsCP.getName() + " 1"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void updateResourceInstanceName() throws Exception { + + // update resource instance name + String resourceInstanceUpdatedName = "resource New 2"; + + ResourceReqDetails updatedResourceDetailsVLC = changeResouceName(resourceDetailsVFC, + resourceInstanceUpdatedName); + createVFWithCertifiedResourceInstance(updatedResourceDetailsVLC, resourceInstanceReqDetailsVFC); + + resourceInstanceReqDetailsVFC.setName(resourceInstanceUpdatedName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetailsVFC, sdncDesignerDetails1, resourceVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertTrue(updateResourceInstanceResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceUpdatedName); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void updateResourceInstanceNameToNextGeneratedName() throws Exception { + + // update resource instance name + String resourceInstanceUpdatedName = resourceInstanceReqDetailsCP.getName() + " 2"; + + ResourceReqDetails updatedResourceDetailsVL = changeResouceName(resourceDetailsVL, resourceInstanceUpdatedName); + createVFWithCertifiedResourceInstance(updatedResourceDetailsVL, resourceInstanceReqDetailsVL); + resourceInstanceReqDetailsCP.setName(resourceInstanceUpdatedName); + + // add second resource instance + RestResponse response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetailsCP, + sdncDesignerDetails1, resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsVL.getName() + " 1"); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsCP.getName() + " 2"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void normolizeUpdatedResourceInstanceName() throws Exception { + + String resourceInstanceUpdatedName = "resource new - .2"; + String normalizedName = "resourcenew2"; + + ResourceReqDetails updatedResourceDetailsVL = changeResouceName(resourceDetailsVL, resourceInstanceUpdatedName); + + createVFWithCertifiedResourceInstance(updatedResourceDetailsVL, resourceInstanceReqDetailsVL); + // update resource instance name + resourceInstanceReqDetailsCP.setName(resourceInstanceUpdatedName); + + // add second resource instance + RestResponse response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetailsCP, + sdncDesignerDetails1, resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsVL.getName() + " 1"); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsCP.getName() + " 2"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void updatedResourceInstanceNameToEmpty() throws Exception { + + createVFWithCertifiedResourceInstance(resourceDetailsVL, resourceInstanceReqDetailsVL); + String resourceInstanceUpdatedName = ""; + String resourceInstancePreviousName = resourceDetailsCP.getName(); + + // add second resource instance + RestResponse response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetailsCP, + sdncDesignerDetails1, resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + resourceInstanceReqDetailsCP.setName(resourceInstanceUpdatedName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails1, resourceVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + assertEquals("Check response code after RI update request", 200, + updateResourceInstanceResponse.getErrorCode().intValue()); + // change request + // ErrorInfo errorInfo = + // Utils.parseYaml(ActionStatus.MISSING_COMPONENT_NAME.name()); + // utils.validateResponseCode(updateResourceInstanceResponse, + // errorInfo.getCode(), "update resource instance"); + // + // List variables = Arrays.asList("Resource Instance"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_COMPONENT_NAME.name(), + // variables, updateResourceInstanceResponse.getResponse()); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsVL.getName() + " 1"); + resourceInstanceExpectedListName.add(resourceInstancePreviousName + " 3"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void updatedResourceNameLengthExceedMaximumCharacters() throws Exception { + + String resourceInstancePreviousName = resourceDetailsCP.getName(); + // update resource instance name + String resourceInstanceUpdatedName = "a"; + for (int i = 0; i < maxLength; i++) { + resourceInstanceUpdatedName += "b"; + } + // ResourceReqDetails updatedResourceDetailsVL = + // changeResouceName(resourceDetailsVL, resourceInstanceUpdatedName); + + createVFWithCertifiedResourceInstance(resourceDetailsVL, resourceInstanceReqDetailsVL); + // add second resource instance + RestResponse response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetailsCP, + sdncDesignerDetails1, resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + String prevName = resourceInstanceReqDetailsCP.getName(); + resourceInstanceReqDetailsCP.setName(resourceInstanceUpdatedName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails1, resourceVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT.name()); + // utils.validateResponseCode(updateResourceInstanceResponse, + // errorInfo.getCode(), "update resource instance"); + + List variables = Arrays.asList("Resource Instance", "50"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT.name(), variables, + updateResourceInstanceResponse.getResponse()); + + resourceInstanceReqDetailsCP.setName(prevName); + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsVL.getName() + " 1"); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsCP.getName() + " 2"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + @Test + public void updatedResourceNameWithUnSupportedCharacters() throws Exception { + + createVFWithCertifiedResourceInstance(resourceDetailsVL, resourceInstanceReqDetailsVL); + String resourceInstancePreviousName = resourceDetailsCP.getName(); + // update resource instance name + String resourceInstanceUpdatedName = "a???<>"; + + // add second resource instance + RestResponse response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetailsCP, + sdncDesignerDetails1, resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + String prevValue = resourceInstanceReqDetailsCP.getName(); + resourceInstanceReqDetailsCP.setName(resourceInstanceUpdatedName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails1, resourceVF.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_COMPONENT_NAME.name()); + // ResourceRestUtils.validateResponseCode(updateResourceInstanceResponse, + // errorInfo.getCode(), "update resource instance"); + + List variables = Arrays.asList("Resource Instance"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_COMPONENT_NAME.name(), variables, + updateResourceInstanceResponse.getResponse()); + + resourceInstanceReqDetailsCP.setName(prevValue); + + // validate RI name + List resourceInstances = resourceVF.getComponentInstances(); + List resourceInstanceListName = new ArrayList(); + for (int i = 0; i < resourceInstances.size(); i++) { + resourceInstanceListName.add(resourceInstances.get(i).getName()); + } + List resourceInstanceExpectedListName = new ArrayList(); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsVL.getName() + " 1"); + resourceInstanceExpectedListName.add(resourceInstanceReqDetailsCP.getName() + " 2"); + String message = "resource instance name"; + Utils.compareArrayLists(resourceInstanceListName, resourceInstanceExpectedListName, message); + + } + + private static ResourceReqDetails changeResouceName(ResourceReqDetails resourceDet, + String resourceInstanceUpdatedName) throws Exception { + + ResourceReqDetails updatedResourceDetails = new ResourceReqDetails(); + updatedResourceDetails = resourceDet; + updatedResourceDetails.setName(resourceInstanceUpdatedName); + List tags = new ArrayList(); + tags.add(resourceInstanceUpdatedName); + updatedResourceDetails.setTags(tags); + Gson gson = new Gson(); + String updatedResourceBodyJson = gson.toJson(updatedResourceDetails); + RestResponse response = LifecycleRestUtils.changeResourceState(resourceDet, sdncDesignerDetails1, + resourceDet.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertTrue("change LS state to CHECKOUT, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + response = ResourceRestUtils.updateResourceMetadata(updatedResourceBodyJson, sdncDesignerDetails1, + updatedResourceDetails.getUniqueId()); + assertEquals("Check response code after updateresource name", 200, response.getErrorCode().intValue()); + response = LifecycleRestUtils.changeResourceState(updatedResourceDetails, sdncDesignerDetails1, + resourceDet.getVersion(), LifeCycleStatesEnum.CHECKIN); + + return updatedResourceDetails; + + } + + // private Component changeResouceName(Resource resourceDet, String + // resourceInstanceUpdatedName) throws Exception{ + // + // User defaultUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // Resource updatedResourceDetails = resourceDet; + // RestResponse response = + // LifecycleRestUtils.changeComponentState(updatedResourceDetails, + // defaultUser, LifeCycleStatesEnum.CHECKOUT, "state changed"); + // assertTrue("change LS state to CHECKOUT, returned status:" + + // response.getErrorCode(),response.getErrorCode() == 200); + // updatedResourceDetails.setName(resourceInstanceUpdatedName); + // List tags = new ArrayList(); + // tags.add(resourceInstanceUpdatedName); + // updatedResourceDetails.setTags(tags); + // Gson gson = new Gson(); + // ResourceReqDetails resourceReqDetails = new + // ResourceReqDetails(updatedResourceDetails); + // String updatedResourceBodyJson = gson.toJson(resourceReqDetails); + // response = ResourceRestUtils.updateResource(updatedResourceBodyJson, + // defaultUser, updatedResourceDetails.getUniqueId()); + // assertEquals("Check response code after updateresource name", 200, + // response.getErrorCode().intValue()); + // response = + // LifecycleRestUtils.changeComponentState(updatedResourceDetails, + // defaultUser, LifeCycleStatesEnum.CHECKIN, "state changed"); + // assertEquals("Check response code after updateresource name", 200, + // response.getErrorCode().intValue()); + // + // return updatedResourceDetails; + // + // } + + private void createVFWithCertifiedResourceInstance(ResourceReqDetails resourceDetails, + ComponentInstanceReqDetails resourceInstanceReqDetails) throws Exception { + + RestResponse response = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails1, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after CHECKOUT", 200, response.getErrorCode().intValue()); + + // add heat artifact to resource and certify + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, + resourceDetails.getUniqueId()); + assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + response = LifecycleRestUtils.certifyResource(resourceDetails); + assertEquals("Check response code after CERTIFY request", 200, response.getErrorCode().intValue()); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + resourceInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncDesignerDetails1, + resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + } + + protected Resource convertResourceGetResponseToJavaObject(ResourceReqDetails resourceDetails) throws IOException { + RestResponse response = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails1); + assertEquals("Check response code after get resource", 200, response.getErrorCode().intValue()); + return ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ValidateExtendedVfData.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ValidateExtendedVfData.java new file mode 100644 index 0000000000..37e7539fd9 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/ValidateExtendedVfData.java @@ -0,0 +1,315 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.AssocType; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import fj.data.Either; + +public class ValidateExtendedVfData extends ComponentBaseTest { + + protected Resource resourceDetailsVF; + protected Resource resourceDetailsCP_01; + protected Resource resourceDetailsVL_01; + protected Resource resourceDetailsVFCcomp; + + protected User sdncUserDetails; + + @Rule + public static TestName name = new TestName(); + + public ValidateExtendedVfData() { + super(name, ValidateExtendedVfData.class.getName()); + } + + @BeforeMethod + public void create() throws Exception { + + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + Either resourceDetailsVFe = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true); + resourceDetailsVF = resourceDetailsVFe.left().value(); + Either resourceDetailsCP_01e = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, NormativeTypesEnum.PORT, + ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true); + resourceDetailsCP_01 = resourceDetailsCP_01e.left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsCP_01, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_VOL, resourceDetailsCP_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_VOL, resourceDetailsCP_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_NET, resourceDetailsCP_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsCP_01, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.changeComponentState(resourceDetailsCP_01, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + Either resourceDetailsVL_01e = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VL, NormativeTypesEnum.NETWORK, + ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, UserRoleEnum.DESIGNER, true); + resourceDetailsVL_01 = resourceDetailsVL_01e.left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVL_01, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_VOL, resourceDetailsVL_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_VOL, resourceDetailsVL_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_NET, resourceDetailsVL_01, + UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsVL_01, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVL_01, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + + Either resourceDetailsVFCcompE = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, NormativeTypesEnum.COMPUTE, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, UserRoleEnum.DESIGNER, true); + resourceDetailsVFCcomp = resourceDetailsVFCcompE.left().value(); + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + + ComponentInstance resourceDetailsCP_01ins = AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceDetailsCP_01, resourceDetailsVF, + UserRoleEnum.DESIGNER, true) + .left().value(); + ComponentInstance resourceDetailsVL_01ins = AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceDetailsVL_01, resourceDetailsVF, + UserRoleEnum.DESIGNER, true) + .left().value(); + ComponentInstance resourceDetailsVFCcomp_ins = AtomicOperationUtils + .addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, resourceDetailsVF, + UserRoleEnum.DESIGNER, true) + .left().value(); + + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF, resourceDetailsCP_01ins, + resourceDetailsVL_01ins, AssocType.LINKABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF, resourceDetailsCP_01ins, + resourceDetailsVFCcomp_ins, AssocType.BINDABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + + } + + @Test + public void getResourceLatestVersion() throws Exception { + + RestResponse response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKIN); + assertTrue("change LC state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + // resourceDetailsVF = + // AtomicOperationUtils.getResourceObject(resourceDetailsVF, + // UserRoleEnum.DESIGNER); + RestResponse getResourceLatestVersionResponse = ResourceRestUtils.getResourceLatestVersionList(sdncUserDetails); + assertTrue("response code is not 200, returned :" + getResourceLatestVersionResponse.getErrorCode(), + getResourceLatestVersionResponse.getErrorCode() == 200); + + List resourceList = ResourceRestUtils + .restResponseToResourceObjectList(getResourceLatestVersionResponse.getResponse()); + Resource resource = ResourceRestUtils.getResourceObjectFromResourceListByUid(resourceList, + resourceDetailsVF.getUniqueId()); + + callAllCheckMethods(resource); + } + + @Test + public void getFollowedResources() throws Exception { + + RestResponse response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKIN); + assertTrue("change LC state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + // resourceDetailsVF = + // AtomicOperationUtils.getResourceObject(resourceDetailsVF, + // UserRoleEnum.DESIGNER); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + RestResponse getFollowedResourcesResponse = ResourceRestUtils.getFollowedList(sdncUserDetails); + String json = getFollowedResourcesResponse.getResponse(); + JSONObject jsonResp = (JSONObject) JSONValue.parse(json); + JSONArray resources = (JSONArray) jsonResp.get("resources"); + + List resourceList = ResourceRestUtils.restResponseToResourceObjectList(resources.toString()); + Resource resource = ResourceRestUtils.getResourceObjectFromResourceListByUid(resourceList, + resourceDetailsVF.getUniqueId()); + // TODO if get followed list Api should return full object data? + // callAllCheckMethods(resource); + } + + @Test + public void lifeCycleChekInRequest() throws Exception { + + RestResponse response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKIN); + assertTrue("change LC state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + // resourceDetailsVF = + // AtomicOperationUtils.getResourceObject(resourceDetailsVF, + // UserRoleEnum.DESIGNER); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + callAllCheckMethods(resource); + } + + @Test + public void lifeCycleChekOutRequest() throws Exception { + + RestResponse response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKIN); + assertTrue("change LC state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKOUT); + assertTrue("change LC state to CHECKOUT, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + callAllCheckMethods(resource); + } + + @Test + public void lifeCycleRequestForCertification() throws Exception { + + RestResponse response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CHECKIN); + assertTrue("change LC state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + response = LifecycleRestUtils.changeComponentState(resourceDetailsVF, sdncUserDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertTrue("change LC state to CERTIFICATIONREQUEST, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + callAllCheckMethods(resource); + } + + @Test + public void lifeCycleCertificationRequest() throws Exception { + + RestResponse response = AtomicOperationUtils + .changeComponentState(resourceDetailsVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, false) + .getRight(); + assertTrue("change LC state to CERTIFY, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + callAllCheckMethods(resource); + } + + @Test + public void checkGetResourceAfterCertificationRequest() throws Exception { + + RestResponse response = AtomicOperationUtils + .changeComponentState(resourceDetailsVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, false) + .getRight(); + assertTrue("change LC state to CERTIFY, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + resourceDetailsVF = AtomicOperationUtils.getResourceObject(resourceDetailsVF, UserRoleEnum.DESIGNER); + + callAllCheckMethods(resourceDetailsVF); + } + + @Test + public void updateResourceMetadata() throws Exception { + + resourceDetailsVF.setDescription("stamStam"); + ResourceReqDetails resourceDetailsVFreqD = new ResourceReqDetails(resourceDetailsVF); + RestResponse updateResourceResponse = ResourceRestUtils.updateResourceMetadata(resourceDetailsVFreqD, + sdncUserDetails, resourceDetailsVF.getUniqueId()); + assertTrue("response code is not 200, returned :" + updateResourceResponse.getErrorCode(), + updateResourceResponse.getErrorCode() == 200); + + Resource resource = ResponseParser.convertResourceResponseToJavaObject(updateResourceResponse.getResponse()); + + callAllCheckMethods(resource); + } + + private void checkResourceInstances(Resource resource) { + assertNotNull("resource component Instances list is null ", resource.getComponentInstances()); + assertTrue("resource component Instances list is empty ", !resource.getComponentInstances().equals("")); + } + + private void checkResourceInstancesProperties(Resource resource) { + assertNotNull("component Instances properies list is null ", resource.getComponentInstancesProperties()); + assertTrue("component Instances properies list is empty ", + !resource.getComponentInstancesProperties().equals("")); + } + + private void checkResourceInstancesRelations(Resource resource) { + assertNotNull("component Instances Relations list is null ", resource.getComponentInstancesRelations()); + assertTrue("component Instances Relations list is empty ", + !resource.getComponentInstancesRelations().equals("")); + } + + private void checkResourceCapabilities(Resource resource) { + assertNotNull("component Instances Capabilities list is null ", resource.getCapabilities()); + assertTrue("component Instances Capabilities list is empty ", !resource.getCapabilities().equals("")); + } + + private void checkResourceRequirements(Resource resource) { + assertNotNull("component Instances Requirements list is null ", resource.getRequirements()); + assertTrue("component Instances Requirements list is empty ", !resource.getRequirements().equals("")); + } + + private void callAllCheckMethods(Resource resource) { + + checkResourceInstances(resource); + checkResourceInstancesProperties(resource); + checkResourceInstancesRelations(resource); + checkResourceCapabilities(resource); + checkResourceRequirements(resource); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VfComponentInstanceCRUDTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VfComponentInstanceCRUDTest.java new file mode 100644 index 0000000000..ea8b89200e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/resource/VfComponentInstanceCRUDTest.java @@ -0,0 +1,1792 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.resource; + +import static org.junit.Assert.assertTrue; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_ALREADY_EXISTS; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_DELETE; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_INVALID_CONTENT; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_NOT_FOUND; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.BaseValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class VfComponentInstanceCRUDTest extends ComponentInstanceBaseTest { + + @Rule + public static TestName name = new TestName(); + + public VfComponentInstanceCRUDTest() { + super(name, VfComponentInstanceCRUDTest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + init(); + createComponents(); + } + + // CREATE Resource + private void createComponents() throws Exception { + createAtomicResource(resourceDetailsVFC_01); + LifecycleRestUtils.changeResourceState(resourceDetailsVFC_01, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsVFC_02); + LifecycleRestUtils.changeResourceState(resourceDetailsVFC_02, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsCP_01); + LifecycleRestUtils.changeResourceState(resourceDetailsCP_01, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsCP_02); + LifecycleRestUtils.changeResourceState(resourceDetailsCP_02, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsVL_01); + LifecycleRestUtils.changeResourceState(resourceDetailsVL_01, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsVL_02); + LifecycleRestUtils.changeResourceState(resourceDetailsVL_02, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createVF(resourceDetailsVF_02); + } + + @Test + public void createVfcInstanceByDesigner() throws Exception { + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVFC_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test(enabled = false) // DE189419 + public void createInstanceOfVfToItself() throws Exception { + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVF_02); + createAtomicResourceInstance = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertTrue(createAtomicResourceInstance.getErrorCode() == STATUS_CODE_NOT_FOUND); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createVfcInstanceByAdmin() throws Exception { + User user = sdncAdminDetails; + createVF(resourceDetailsVF_01, user); + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_01, + resourceDetailsVFC_01, user); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_01, 1, 0); + } + + @Test + public void createCpInstance() throws Exception { + // Create CP instance + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createVlInstance() throws Exception { + // Create VL instance + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void updateResourceInstanceNameLessMaxLegth() throws Exception { + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("xxxxXthisXstringxisx49XcharcatersXlengthXxxxxxxxx"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + + } + + @Test + public void updateInstanceNameExceedMaxLegth() throws Exception { + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("xxxxXthisXstringxisx51XcharcatersXlengthXxxxxxxxxxx"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT, + updateResourceInstanceResponse.getErrorCode().intValue()); + } + + @Test + public void updateResourceInstanceNameHasMaxLegth() throws Exception { + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("xxxxXthisXstringxisx50XcharcatersXlengthXxxxxxxxxx"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + } + + @Test + public void resourceInstanceNameIsEmpty() throws Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + resourceInstanceReqDetails.setName(""); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "name"); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "1").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 1"), + instanceName); + } + + @Test + public void resourceInstanceNameIsNull() throws Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + resourceInstanceReqDetails.setName(null); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "name"); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "1").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 1"), + instanceName); + } + + @Test + public void resourceInstanceNameValidation01() throws Exception { + // 2 Instances + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "name"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "1").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 1"), + instanceName); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "normalizedName"); + instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "name"); + componentInstance = ResponseParser.parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), + ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "2").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", (resourceDetailsVFC_01.getName() + " 2"), + instanceName); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void resourceInstanceNameValidation02() throws Exception { + + // 2 Instances + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "name"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "1").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 1"), + instanceName); + resourceInstanceReqDetails = ElementFactory.getComponentResourceInstance(resourceDetailsCP_01); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "normalizedName"); + instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "name"); + componentInstance = ResponseParser.parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), + ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsCP_01.getName() + "2").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", (resourceDetailsCP_01.getName() + " 2"), + instanceName); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createVfcInstanceByTester() throws Exception { // Response 409 + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncTesterDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void createVfcInstance_UserIdIsEmpty() throws Exception { + + User sdncUserDetails = new User(); + sdncUserDetails.setUserId(""); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncUserDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void createVfcInstance_UserIdIsNonAsdcUser() throws Exception { + + User sdncUserDetails = new User(); + sdncUserDetails.setUserId("bt4567"); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncUserDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void createAllAtomicInstances() throws Exception { + + // Add to VF resource VFC, CP and VL instances + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 3, 0); + } + + @Test + public void createDefferentVfcInstances() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVFC_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createDefferentCpInstances() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCP_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createDefferentVLInstances() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVL_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createSeveralInstanceOfSameVFC() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVFC_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createSeveralInstanceOfSameVL() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVL_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createSeveralInstanceOfSameCP() throws Exception { + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void createInstanceOfCpToVfc() throws Exception { // Add to CP to VFC + // (not allowed) + + ComponentInstanceReqDetails resourceInstanceReqDetailsCP = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + ComponentInstanceReqDetails resourceInstanceReqDetailsVFC = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails, resourceInstanceReqDetailsVFC.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createInstanceVfcToCp() throws Exception { // (not allowed) + + ComponentInstanceReqDetails resourceInstanceReqDetailsCP = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + ComponentInstanceReqDetails resourceInstanceReqDetailsVFC = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsVFC, sdncDesignerDetails, resourceInstanceReqDetailsCP.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createInstanceVlToVfc() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetailsVL = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + ComponentInstanceReqDetails resourceInstanceReqDetailsVFC = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsVFC, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsVL, sdncDesignerDetails, resourceInstanceReqDetailsVFC.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createInstanceToNonSupportedComponentType() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetailsCP = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetailsCP, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE_INSTANCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_INVALID_CONTENT, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + // ("Create instance without position is allowed") + @Test + public void createInstanceOfVlWithoutPosXAndPosY() throws Exception { // instance + // does + // not + // have + // position + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + resourceInstanceReqDetails.setPosX(""); + resourceInstanceReqDetails.setPosY(""); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + // Create instance without position is allowed") + @Test + public void createInstanceOfVlWithPositionNull() throws Exception { // instance + // does + // not + // have + // position + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + resourceInstanceReqDetails.setPosX(null); + resourceInstanceReqDetails.setPosY(null); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void createResourceInstanceForNonCheckedOutVF() throws Exception { + + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncAdminDetails, + "0.1", LifeCycleStatesEnum.CHECKIN); + resourceDetailsVF_02.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + AssertJUnit.assertEquals("Check response code after create user", STATUS_CODE_SUCCESS, + checkInResponse.getErrorCode().intValue()); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + createResourceInstanceResponse.getErrorCode().intValue()); + } + + @Test + public void createResourceInstanceVfCheckedOutByOtherUser() throws Exception { + + // Admin try to add RI to VF which is checked-Out By Designer + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncAdminDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void createResourceInstanceForNonExistingVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, "blablabla", ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + createResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + // Delete + @Test + public void deleteVfcInstanceByDesigner() throws Exception { + + // Create RI + RestResponse createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVFC_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String compInstId = ResponseParser.getUniqueIdFromResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = deleteAtomicInstanceForVF(compInstId, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(deleteResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void deleteVfcInstanceByAdmin() throws Exception { + createVF(resourceDetailsVF_01, sdncAdminDetails); + RestResponse createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_01, + resourceDetailsVL_01, sdncAdminDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String compInstId = ResponseParser.getUniqueIdFromResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_01, 1, 0); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = deleteAtomicInstanceForVF(compInstId, resourceDetailsVF_01, + sdncAdminDetails); + ResourceRestUtils.checkDeleteResponse(deleteResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_01, 0, 0); + } + + @Test + public void deleteCpInstance() throws Exception { + + RestResponse createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String compInstId = ResponseParser.getUniqueIdFromResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = deleteAtomicInstanceForVF(compInstId, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(deleteResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void deleteVlInstance() throws Exception { + + RestResponse createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String compInstId = ResponseParser.getUniqueIdFromResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = deleteAtomicInstanceForVF(compInstId, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(deleteResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + } + + @Test + public void deleteOneVlInstance() throws Exception { + + // RI-1 + RestResponse createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String compInstId = ResponseParser.getUniqueIdFromResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // RI-2 + createResourceInstanceResponse = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVL_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + // Delete Resource instance RI-1 + RestResponse deleteResourceInstanceResponse = deleteAtomicInstanceForVF(compInstId, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(deleteResourceInstanceResponse); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteVfcInstanceCheckedByOtherUser() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncTesterDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteInstanceNonSupportedComponentType() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE_INSTANCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_INVALID_CONTENT, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteInstanceFromNonVF() throws Exception { + // RI-1 + + ComponentInstanceReqDetails resourceInstanceVlReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceVlReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + // RI-2 + ComponentInstanceReqDetails resourceInstanceCplReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceCplReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance2 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance2, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + // Delete VL instance from CP instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceInstanceCplReqDetails.getUniqueId(), + resourceInstanceVlReqDetails.getUniqueId(), ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + } + + @Test + public void deleteNonExistingInstanceFromVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceVlReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceVlReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + resourceInstanceVlReqDetails.setUniqueId("1234567890"); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceVlReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteCpInstanceFromNonCheckOutVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceCpReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceCpReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncDesignerDetails, + "0.1", LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + checkInResponse.getErrorCode().intValue()); + resourceDetailsVF_02.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceCpReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteVlInstanceFromNonCheckOutVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceVlReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceVlReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncDesignerDetails, + "0.1", LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + checkInResponse.getErrorCode().intValue()); + resourceDetailsVF_02.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceVlReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteVfcInstanceFromNonCheckOutVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceVfcReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceVfcReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + RestResponse checkInResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncDesignerDetails, + "0.1", LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + checkInResponse.getErrorCode().intValue()); + resourceDetailsVF_02.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + // Delete Resource instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceVfcReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteVlInstance_UserIdIsNonAsdcUser() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + // Delete Resource instance by non-ASDC User + User sdncUserDetails = new User(); + sdncUserDetails.setUserId("bt4567"); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncUserDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + deleteResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void deleteAlreadyDeletedInstance() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_DELETE, + deleteResourceInstanceResponse.getErrorCode().intValue()); + deleteCompInstReqCapFromExpected(componentInstance.getUniqueId()); + getComponentAndValidateRIs(resourceDetailsVF_02, 0, 0); + deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncDesignerDetails, + resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + deleteResourceInstanceResponse.getErrorCode().intValue()); + } + + @Test + public void reCreateDeletedInstance() throws Exception { + + // 2 Instances + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "name"); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "1").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 1"), + instanceName); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "normalizedName"); + instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "name"); + componentInstance = ResponseParser.parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), + ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "2").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", (resourceDetailsVFC_01.getName() + " 2"), + instanceName); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + // Delete one instance + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance( + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), resourceInstanceReqDetails.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_DELETE, + deleteResourceInstanceResponse.getErrorCode().intValue()); + deleteCompInstReqCapFromExpected(componentInstance.getUniqueId()); + // Create same instance again + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + instanceNormalizedName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), + "normalizedName"); + instanceName = ResponseParser.getValueFromJsonResponse(createResourceInstanceResponse.getResponse(), "name"); + componentInstance = ResponseParser.parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), + ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "3").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance Name ", (resourceDetailsVFC_01.getName() + " 3"), + instanceName); + + } + + // Update + @Test + public void updateVfcInstanceNameByDesigner() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("abcd"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, "abcd"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, "abcd"); + } + + @Test + public void updateVfcInstanceNameByAdmin() throws Exception { + User user = sdncAdminDetails; + createVF(resourceDetailsVF_01, user); + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncAdminDetails, resourceDetailsVF_01.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_01, 1, 0); + vfcResourceInstanceReqDetails.setName("ABCD E"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncAdminDetails, resourceDetailsVF_01.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, "abcde"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, "ABCD E"); + } + + @Test + public void updateInstanceNameAllowedCharacters() throws Exception { + // Allowed characters: Alphanumeric (a-zA-Z0-9), space (' '), underscore + // ('_'), dash ('-'), dot ('.')) + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("Abcd_1234567890-qwert-yuiop.zxcvb"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + // assertEquals("Check if RI normalizedName is correct ", + // riNormalizedName, "abcd_1234567890-qwert-yuiop.zxcv" ); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, "Abcd_1234567890-qwert-yuiop.zxcvb"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, + "abcd1234567890qwertyuiopzxcvb"); + + } + + @Test + public void updateVfcInstanceNameEmpty() throws Exception { + // see US534663 In case a designer removes the current resource instance + // name then BE has to generate again the "default" resource instance + // name + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = ""; + vfcResourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String instanceNormalizedName = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "name"); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "2").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", (resourceDetailsVFC_01.getName() + " 2"), + instanceName); + } + + @Test + public void updateVfcInstanceNameNull() throws Exception { + // see US534663 In case a designer removes the current resource instance + // name then BE has to generate again the "default" resource instance + // name + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = null; + vfcResourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + final String updateResponse = updateResourceInstanceResponse.getResponse(); + String instanceNormalizedName = ResponseParser.getValueFromJsonResponse(updateResponse, "normalizedName"); + String instanceName = ResponseParser.getValueFromJsonResponse(updateResponse, "name"); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", + (resourceDetailsVFC_01.getName() + "2").toLowerCase(), instanceNormalizedName); + AssertJUnit.assertEquals("check Resource Instance normalizedName ", (resourceDetailsVFC_01.getName() + " 2"), + instanceName); + } + + @Test + public void updateCpInstanceName() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("AbcD"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, "abcd"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, "AbcD"); + } + + @Test + public void updateVlInstanceName() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName("ABCD"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, "abcd"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, "ABCD"); + } + + @Test + public void updateInstanceNameToArleadyExistInstanceName02() throws Exception { + + // Create VFC instance + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance vfcComponentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(vfcComponentInstance, ComponentTypeEnum.RESOURCE); + // Create CP instance + ComponentInstanceReqDetails cpResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance cpComponentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(cpComponentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 2, 0); + cpResourceInstanceReqDetails.setName(vfcComponentInstance.getName()); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_ALREADY_EXISTS, + updateResourceInstanceResponse.getErrorCode().intValue()); + } + + @Test + public void updateInstanceNameMaxLength() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = "Qwertyuiop1234567890asdfAhjklzxcvbnmasdfghjkl12345"; + vfcResourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, newName.toLowerCase()); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, newName); + } + + @Test + public void updateInstanceNameExceedMaxLength() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = "Qwertyuiop1234567890asdfAhjklzxcvbnmasdfghjkl123456"; + vfcResourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT, + updateResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void updateCpInstanceCheckedByOtherUser() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = "Qwertyuiop1234567890"; + resourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetails, sdncAdminDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + updateResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void UpdateVfcInstance_UserIdIsNonAsdcUser() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = "Qwertyuiop1234567890"; + resourceInstanceReqDetails.setName(newName); + User nonSdncUserDetails = new User(); + nonSdncUserDetails.setUserId("bt4567"); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetails, nonSdncUserDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_RESTRICTED_OPERATION, + updateResourceInstanceResponse.getErrorCode().intValue()); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + } + + @Test + public void UpdateResourceInstanceFormNonExistingVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + // LifecycleRestUtils.changeResourceState(resourceDetailsVL_01, + // sdncAdminDetails, "0.1", LifeCycleStatesEnum.CHECKIN); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String newName = "Qwertyuiop1234567890"; + resourceInstanceReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, "blablabla", ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + updateResourceInstanceResponse.getErrorCode().intValue()); + } + + @Test + public void updateNonExistingInstanceFromVF() throws Exception { + + ComponentInstanceReqDetails resourceInstanceVlReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceVlReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance1 = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance1, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + resourceInstanceVlReqDetails.setUniqueId("1234567890"); + // String newName= "Qwertyuiop1234567890"; + // resourceInstanceVlReqDetails.setName(newName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + resourceInstanceVlReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + updateResourceInstanceResponse.getErrorCode().intValue()); + } + + // Update + @Test + public void updateVfcInstanceNameAsVfName() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + vfcResourceInstanceReqDetails.setName(resourceDetailsVF_02.getName()); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String resourceNameFromJsonResponse = ResponseParser.getNameFromResponse(updateResourceInstanceResponse); + AssertJUnit.assertEquals(resourceNameFromJsonResponse, vfcResourceInstanceReqDetails.getName()); + String riNormalizedName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "normalizedName"); + String riName = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "name"); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riNormalizedName, + resourceDetailsVF_02.getName().toLowerCase()); + AssertJUnit.assertEquals("Check if RI normalizedName is correct ", riName, resourceDetailsVF_02.getName()); + } + + @Test + public void updateInstanceNameInvalidCharacters() throws Exception { + char invalidChars[] = { '~', '!', '$', '%', '^', '*', '(', ')', '"', '{', '}', '[', ']', '?', '>', '<', '/', + '|', '\\', ',' }; + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String newName = "Abcd1"; + String updateName; + for (int i = 0; i < invalidChars.length; i++) { + updateName = newName + invalidChars[i]; + vfcResourceInstanceReqDetails.setName(updateName); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_INVALID_CONTENT, + updateResourceInstanceResponse.getErrorCode().intValue()); + } + } + + // Update Position + @Test + public void updateVfcInstancePosition() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String updatePosX = "130"; + String updatePosY = "180"; + vfcResourceInstanceReqDetails.setPosX(updatePosX); + vfcResourceInstanceReqDetails.setPosY(updatePosY); + vfcResourceInstanceReqDetails.setName(null); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String posXFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posX"); + String posYFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + } + + @Test + public void updateVlInstancePosition() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVL_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String updatePosX = "130"; + String updatePosY = "180"; + vfcResourceInstanceReqDetails.setPosX(updatePosX); + vfcResourceInstanceReqDetails.setPosY(updatePosY); + vfcResourceInstanceReqDetails.setName(null); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String posXFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posX"); + String posYFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + } + + @Test + public void updateCpInstancePosition() throws Exception { + + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String updatePosX = "130"; + String updatePosY = "180"; + vfcResourceInstanceReqDetails.setPosX(updatePosX); + vfcResourceInstanceReqDetails.setPosY(updatePosY); + vfcResourceInstanceReqDetails.setName(null); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String posXFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posX"); + String posYFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + } + + @Test + public void updateInstancePositionNegativePosition() throws Exception { + + ComponentInstanceReqDetails cpResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, ComponentTypeEnum.RESOURCE); + getComponentAndValidateRIs(resourceDetailsVF_02, 1, 0); + String updatePosX = "-100"; + String updatePosY = "-100"; + cpResourceInstanceReqDetails.setPosX(updatePosX); + cpResourceInstanceReqDetails.setPosY(updatePosY); + cpResourceInstanceReqDetails.setName(null); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String posXFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posX"); + String posYFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + } + + @Test + public void updateInstancesPositionSameLocationForBothInstances() throws Exception { + + ComponentInstanceReqDetails cpResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + ComponentInstanceReqDetails vfcResourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsVFC_01); + createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + String updatePosX = "100"; + String updatePosY = "500"; + vfcResourceInstanceReqDetails.setPosX(updatePosX); + vfcResourceInstanceReqDetails.setPosY(updatePosY); + vfcResourceInstanceReqDetails.setName(null); + cpResourceInstanceReqDetails.setPosX(updatePosX); + cpResourceInstanceReqDetails.setPosY(updatePosY); + cpResourceInstanceReqDetails.setName(null); + RestResponse updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + vfcResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + String posXFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posX"); + String posYFromJsonResponse = ResponseParser + .getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + updateResourceInstanceResponse = ComponentInstanceRestUtils.updateComponentInstance( + cpResourceInstanceReqDetails, sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), + ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(updateResourceInstanceResponse); + posXFromJsonResponse = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "posX"); + posYFromJsonResponse = ResponseParser.getValueFromJsonResponse(updateResourceInstanceResponse.getResponse(), + "posY"); + AssertJUnit.assertEquals(posXFromJsonResponse, updatePosX); + AssertJUnit.assertEquals(posYFromJsonResponse, updatePosY); + } + + @Test + public void createAllAtomicInstancesTestGetReqCapAPI_suc() throws Exception { + + // Add to VF resource VFC, CP and VL instances + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + + getVfResourceReqCapUsingAPI(3, 0, sdncDesignerDetails); + + } + + // END of Update + + @Test + public void createAllAtomicInstancesTestGetReqCapAPIfailed() throws Exception { + + // Add to VF resource VFC, CP and VL instances + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsVL_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + resourceDetailsVF_02.setUniqueId("dummy"); + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncAdminDetails, + resourceDetailsVF_02); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, + getResourceResponse.getErrorCode().intValue()); + + } + + @Test + public void associateInVF() throws Exception { + + ResourceReqDetails resourceDetailsReq = ElementFactory.getDefaultResourceByType("SoftCompRouter", + NormativeTypesEnum.SOFTWARE_COMPONENT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, + sdncDesignerDetails.getUserId(), ResourceTypeEnum.VFC); // resourceType + // = VFC + ResourceReqDetails resourceDetailsCap = ElementFactory.getDefaultResourceByType("MyComput", + NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VFC); // resourceType = VFC + createAtomicResource(resourceDetailsReq); + LifecycleRestUtils.changeResourceState(resourceDetailsReq, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createAtomicResource(resourceDetailsCap); + LifecycleRestUtils.changeResourceState(resourceDetailsCap, sdncAdminDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + + RestResponse riReqR = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsReq, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(riReqR); + RestResponse riCapR = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsCap, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(riCapR); + + ComponentInstance riReq = ResponseParser.parseToObject(riReqR.getResponse(), ComponentInstance.class); + ComponentInstance riCap = ResponseParser.parseToObject(riCapR.getResponse(), ComponentInstance.class); + + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + resourceDetailsVF_02); + + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + + List capList = capReqDef.getCapabilities().get("tosca.capabilities.Container"); + List reqList = capReqDef.getRequirements().get("tosca.capabilities.Container"); + + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(riReq.getUniqueId()); + requirementDef.setToNode(riCap.getUniqueId()); + + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(riReq.getUniqueId()); + pair.setCapabilityOwnerId(riCap.getUniqueId()); + pair.setRequirement("host"); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType("tosca.capabilities.Container"); + pair.setRelationships(relationship); + pair.setCapabilityUid(capList.get(0).getUniqueId()); + pair.setRequirementUid(reqList.get(0).getUniqueId()); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + associateInstances.getErrorCode().intValue()); + + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + resourceDetailsVF_02); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + + List list = capReqDef.getRequirements().get("tosca.capabilities.Container"); + AssertJUnit.assertEquals("Check requirement", null, list); + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF_02.getUniqueId(), ComponentTypeEnum.RESOURCE); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + dissociateInstances.getErrorCode().intValue()); + + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + resourceDetailsVF_02); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + + list = capReqDef.getRequirements().get("tosca.capabilities.Container"); + AssertJUnit.assertEquals("Check requirement", 1, list.size()); + + } + + @Test + public void testUnsatisfiedCpReqInVF() throws Exception { + + // Certify all the needed atomic resources + RestResponse response = LifecycleRestUtils.certifyResource(resourceDetailsVFC_02); + ResourceRestUtils.checkSuccess(response); + response = LifecycleRestUtils.certifyResource(resourceDetailsCP_01); + ResourceRestUtils.checkSuccess(response); + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails, + resourceDetailsVF_02.getUniqueId()); + ResourceRestUtils.checkSuccess(response); + + RestResponse createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String compInstName = ResponseParser.getNameFromResponse(createAtomicResourceInstance); + String cpCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + RestResponse submitForTesting = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, + sdncDesignerDetails, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + String[] variables = new String[] { resourceDetailsVF_02.getName(), "VF", "CP (Connection Point)", compInstName, + "requirement", "tosca.capabilities.network.Bindable", "fulfilled" }; + BaseValidationUtils.checkErrorResponse(submitForTesting, + ActionStatus.REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION, variables); + + createAtomicResourceInstance = createAtomicInstanceForVF(resourceDetailsVF_02, resourceDetailsVFC_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String computeCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + fulfillCpRequirement(resourceDetailsVF_02, cpCompInstId, computeCompInstId, computeCompInstId, + sdncDesignerDetails, ComponentTypeEnum.RESOURCE); + + submitForTesting = LifecycleRestUtils.changeResourceState(resourceDetailsVF_02, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + BaseValidationUtils.checkSuccess(submitForTesting); + } + + private void getVfResourceReqCapUsingAPI(int numberOfRIs, int numberOfRelations, User user) + throws IOException, Exception { + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncAdminDetails, + resourceDetailsVF_02); + AssertJUnit.assertEquals("Check response code ", STATUS_CODE_SUCCESS, + getResourceResponse.getErrorCode().intValue()); + // ResourceValidationUtils.validateResp(getResourceResponse, + // resourceRespJavaObject); + // int numberOfActualRIs = resource.getComponentInstances()!=null ? + // resource.getComponentInstances().size() : 0; + // int numberOfActualRelations = + // resource.getComponentInstancesRelations()!=null ? + // resource.getComponentInstancesRelations().size() : 0; + // assertEquals("Check number of RIs meet the expected number", + // numberOfRIs ,numberOfActualRIs); + // assertEquals("Check number of RI relations meet the expected number", + // numberOfRelations ,numberOfActualRelations); + + //// get VF actual Capabilities and Requirements and validate according + //// to expected + Resource vfResource = ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), + Resource.class); + verifyReqCap(vfResource); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ChangeServiceDistributionStatusApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ChangeServiceDistributionStatusApiTest.java new file mode 100644 index 0000000000..c8a20cf44a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ChangeServiceDistributionStatusApiTest.java @@ -0,0 +1,1008 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ServiceValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ChangeServiceDistributionStatusApiTest extends ComponentBaseTest { + + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected User sdncDesignerDetails; + protected User sdncAdminDetails; + protected User sdncGovernorDeatails; + protected User sdncTesterDetails; + protected User sdncOpsDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected Component resourceDetailsVFCcomp; + protected Component serviceDetailsCompp; + + private String userRemarks = "commentTest"; + + private List variablesAsList; + + @Rule + public static TestName name = new TestName(); + + public ChangeServiceDistributionStatusApiTest() throws Exception { + super(name, ChangeServiceDistributionStatusApiTest.class.getName()); + + } + + @BeforeMethod + public void init() throws Exception { + + variablesAsList = new ArrayList(); + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncGovernorDeatails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + sdncTesterDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncOpsDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + resourceDetailsVFCcomp = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + true, true); + + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + Service serviceServ = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, serviceServ, + UserRoleEnum.DESIGNER, true); + + serviceDetails = new ServiceReqDetails(serviceServ); + + } + + // -----------------------------------------------T E S T + // S--------------------------------------------// + + @Test + public void approveNotCertifiedService_checkout() throws Exception { + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void approveNotCertifiedService_checkedin() throws Exception { + RestResponse checkinResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals(200, checkinResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void approveNotCertifiedService_inProgress() throws Exception { + RestResponse certReqResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(200, certReqResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DApprove"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.READY_FOR_CERTIFICATION.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DApprove", LifecycleStateEnum.READY_FOR_CERTIFICATION, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + + } + + @Test + public void approveNotCertifiedService_readyForCer() throws Exception { + approveNotCertifiedService_inProgress(); + DbUtils.deleteFromEsDbByPattern("_all"); + + RestResponse startCertResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(200, startCertResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DApprove"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setDprevStatus(""); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void rejectNotCertifiedService_checkeout() throws Exception { + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setDprevStatus(""); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void rejectNotCertifiedService_checkedin() throws Exception { + RestResponse startCertResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertEquals(200, startCertResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN.name()); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setDprevStatus(""); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.NOT_CERTIFIED_CHECKIN, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void rejectNotCertifiedService_inProgress() throws Exception { + RestResponse startCertResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(200, startCertResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.READY_FOR_CERTIFICATION.name()); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setDprevStatus(""); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.READY_FOR_CERTIFICATION, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + } + + @Test + public void rejectNotCertifiedService_readyForCer() throws Exception { + rejectNotCertifiedService_inProgress(); + DbUtils.deleteFromEsDbByPattern("_all"); + + RestResponse startCertResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(200, startCertResp.getErrorCode().intValue()); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 403, serviceDetails.getVersion()); + + variablesAsList = Arrays.asList(serviceDetails.getVersion(), serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name(), + variablesAsList, changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // version, sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setDprevStatus(""); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setStatus("403"); + // expectedResourceAuditJavaObject.setDesc(String.format(errorInfo.getMessageId() + // + ": " + errorInfo.getMessage(), version, + // serviceDetails.getServiceName())); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFICATION_IN_PROGRESS, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + "403", ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, sdncAdminDetails); + + } + + @Test + public void approveCertifiedService_bysdncGovernorDeatails() throws Exception { + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncGovernorDeatails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(changeDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_APPROVED, null, null, sdncGovernorDeatails); + } + + @Test + public void approveCertifiedService_bysdncAdminDetails() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(changeDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_APPROVED, null, null, sdncAdminDetails); + } + + @Test + public void approveCertifiedService_byDesigner() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncDesignerDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.RESTRICTED_OPERATION.name()); + // String auditAction="DApprove"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncDesignerDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setStatus("409"); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getMessageId() + ": + // " + errorInfo.getMessage()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncDesignerDetails); + } + + @Test + public void approveCertifiedService_byTester() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncTesterDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.RESTRICTED_OPERATION.name()); + // String auditAction="DApprove"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncTesterDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setStatus("409"); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getMessageId() + ": + // " + errorInfo.getMessage()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncTesterDetails); + } + + @Test + public void approveCertifiedService_byOps() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncOpsDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncOpsDetails); + + } + + @Test + public void rejectCertifiedService_bysdncGovernorDeatails() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncGovernorDeatails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(changeDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_REJECTED); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_REJECTED); + + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncGovernorDeatails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_REJECTED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_REJECTED, null, null, sdncGovernorDeatails); + + } + + @Test + public void rejectCertifiedService_bysdncAdminDetails() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(changeDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_REJECTED); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_REJECTED); + + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncAdminDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_REJECTED.name()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_REJECTED, null, null, sdncAdminDetails); + } + + @Test + public void rejectCertifiedService_byDesigner() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncDesignerDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.RESTRICTED_OPERATION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncDesignerDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setStatus("409"); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getMessageId() + ": + // " + errorInfo.getMessage()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncDesignerDetails); + } + + @Test + public void rejectCertifiedService_byTester() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncTesterDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.RESTRICTED_OPERATION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncTesterDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setStatus("409"); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getMessageId() + ": + // " + errorInfo.getMessage()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncTesterDetails); + } + + @Test + public void rejectCertifiedService_byOps() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncOpsDetails, 409, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + // ErrorInfo errorInfo = + // utils.parseYaml(ActionStatus.RESTRICTED_OPERATION.name()); + // String auditAction="DReject"; + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(certifyService, + // certifyService.getVersion(), sdncOpsDetails); + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setResourceType("Service"); + // expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.CERTIFIED.name()); + // expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + // expectedResourceAuditJavaObject.setDprevStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setDcurrStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED.name()); + // expectedResourceAuditJavaObject.setStatus("409"); + // expectedResourceAuditJavaObject.setDesc(errorInfo.getMessageId() + ": + // " + errorInfo.getMessage()); + // expectedResourceAuditJavaObject.setComment(userRemarks); + // expectedResourceAuditJavaObject.setPrevVersion("0.1"); + // + // AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, + // auditAction); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, "409", ActionStatus.RESTRICTED_OPERATION, + sdncOpsDetails); + } + + @Test + public void approveServiceNotFound() throws Exception { + String previuosId = serviceDetails.getUniqueId(); + serviceDetails.setUniqueId("dummyId"); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 404, serviceDetails.getVersion()); + serviceDetails.setUniqueId(previuosId); + + variablesAsList = Arrays.asList("dummyId"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), variablesAsList, + changeDistStatusAndValidate.getResponse()); + + } + + @Test + public void rejectServiceNotFound() throws Exception { + String previuosId = serviceDetails.getUniqueId(); + serviceDetails.setUniqueId("dummyId"); + + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 404, serviceDetails.getVersion()); + serviceDetails.setUniqueId(previuosId); + + variablesAsList = Arrays.asList("dummyId"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), variablesAsList, + changeDistStatusAndValidate.getResponse()); + + } + + @Test + public void rejectService_emptyComment() throws Exception { + userRemarks = ""; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + } + + @Test + public void rejectService_nullComment() throws Exception { + userRemarks = null; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + } + + @Test + public void rejectService_spaceComment() throws Exception { + userRemarks = " "; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + } + + @Test + public void approveService_emptyComment() throws Exception { + userRemarks = ""; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + } + + @Test + public void approveService_nullComment() throws Exception { + userRemarks = null; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + } + + @Test + public void approveService_spaceComment() throws Exception { + userRemarks = " "; + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse changeDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 400, certifyService.getVersion()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_CONTENT.name(), new ArrayList(), + changeDistStatusAndValidate.getResponse()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + } + + @Test + public void distributionStatusChange_approve_Reject_AprroveBysdncAdminDetails() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + + RestResponse approveDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncGovernorDeatails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(approveDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse rejectDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_REJECTED, sdncGovernorDeatails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(rejectDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_REJECTED); + + validateAudit("DReject", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_APPROVED, + DistributionStatusEnum.DISTRIBUTION_REJECTED, null, null, sdncGovernorDeatails); + + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse secondApproveDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncAdminDetails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(secondApproveDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + validateAudit("DApprove", LifecycleStateEnum.CERTIFIED, DistributionStatusEnum.DISTRIBUTION_REJECTED, + DistributionStatusEnum.DISTRIBUTION_APPROVED, null, null, sdncAdminDetails); + + } + + @Test + public void distributeNotCertifiedServiceTest() throws Exception { + RestResponse approveDistStatusAndValidate = changeDistStatusAndValidate(DistributionStatusEnum.DISTRIBUTED, + sdncGovernorDeatails, 200, serviceDetails.getVersion()); + + RestResponse getService = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTED); + + } + + @Test + public void distributeCertifiedServiceTest() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse approveDistStatusAndValidate = changeDistStatusAndValidate(DistributionStatusEnum.DISTRIBUTED, + sdncGovernorDeatails, 200, certifyService.getVersion()); + + RestResponse getService = ServiceRestUtils.getService(certifyService, sdncDesignerDetails); + getDistrubtionStatusValue(getService, DistributionStatusEnum.DISTRIBUTED); + + } + + @Test + public void approveCheckedoutCertifiedServiceTest() throws Exception { + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser + .convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + RestResponse approveDistStatusAndValidate = changeDistStatusAndValidate( + DistributionStatusEnum.DISTRIBUTION_APPROVED, sdncGovernorDeatails, 200, certifyService.getVersion()); + getDistrubtionStatusValue(approveDistStatusAndValidate, DistributionStatusEnum.DISTRIBUTION_APPROVED); + + RestResponse checkoutResp = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals(200, checkoutResp.getErrorCode().intValue()); + // Utils r = new Utils(); + + String distributionStatus = ResponseParser.getValueFromJsonResponse(checkoutResp.getResponse(), + "distributionStatus"); + // Utils r1 = new Utils(); + String lifecycleState = ResponseParser.getValueFromJsonResponse(checkoutResp.getResponse(), "lifecycleState"); + + assertTrue("NOT_CERTIFIED_CHECKOUT".equals(lifecycleState)); + assertTrue("DISTRIBUTION_NOT_APPROVED".equals(distributionStatus)); + } + + private RestResponse changeDistStatusAndValidate(DistributionStatusEnum distStatus, User user, int errorCode, + String serviceVersion) throws Exception { + RestResponse distributionResponse = LifecycleRestUtils.changeDistributionStatus(serviceDetails, serviceVersion, + user, userRemarks, distStatus); + assertNotNull(distributionResponse); + assertNotNull(distributionResponse.getErrorCode()); + assertEquals(errorCode, distributionResponse.getErrorCode().intValue()); + + if (userRemarks == " " || userRemarks == null) { + userRemarks = ""; + } + + return distributionResponse; + } + + private void getDistrubtionStatusValue(RestResponse response, DistributionStatusEnum expectedDistributionValue) + throws Exception { + String actualDistributionValue = ResponseParser.getValueFromJsonResponse(response.getResponse(), + "distributionStatus"); + assertEquals(expectedDistributionValue.name(), actualDistributionValue); + } + + private void validateAudit(String Action, LifecycleStateEnum currState, DistributionStatusEnum dPrevStatus, + DistributionStatusEnum dCurrStatus, String status, ActionStatus errorInfoFromFile, User user) + throws Exception { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceDetails.getVersion(), user); + expectedResourceAuditJavaObject.setAction(Action); + expectedResourceAuditJavaObject.setResourceType("Service"); + expectedResourceAuditJavaObject.setCurrState(currState.name()); + expectedResourceAuditJavaObject.setDprevStatus(dPrevStatus.name()); + expectedResourceAuditJavaObject.setDcurrStatus(dCurrStatus.name()); + expectedResourceAuditJavaObject.setComment(userRemarks); + expectedResourceAuditJavaObject.setDesc("OK"); + + if (errorInfoFromFile != null) { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorInfoFromFile.name()); + expectedResourceAuditJavaObject + .setDesc(AuditValidationUtils.buildAuditDescription(errorInfo, variablesAsList)); + } + + if (status != null) + expectedResourceAuditJavaObject.setStatus(status); + + if (currState != LifecycleStateEnum.CERTIFIED) { + expectedResourceAuditJavaObject.setModifierName(""); + } + + AuditValidationUtils.validateAuditDistribution(expectedResourceAuditJavaObject, Action); + } + + // private ServiceReqDetails certifyService() throws Exception + // { + // ServiceReqDetails certifyService = + // LifecycleRestUtils.certifyService(serviceDetails, + // serviceDetails.getVersion(), sdncAdminDetails); + //// version = certifyService.getVersion(); + // + // return certifyService; + // } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/CreateServiceMetadataApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/CreateServiceMetadataApiTest.java new file mode 100644 index 0000000000..56cfeb54ea --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/CreateServiceMetadataApiTest.java @@ -0,0 +1,1300 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import org.json.JSONObject; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ServiceValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.Test; + +import com.fasterxml.jackson.annotation.JsonIgnore; + +public class CreateServiceMetadataApiTest extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(CreateServiceMetadataApiTest.class.getName()); + + String serviceBaseVersion = "0.1"; + + @Rule + public static TestName name = new TestName(); + + public CreateServiceMetadataApiTest() { + super(name, CreateServiceMetadataApiTest.class.getName()); + } + + @Test + public void createDefaultService() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // String creator = + // ElementFactory.getDefaultUser(UserRoleEnum.ADMIN).getUserId(); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", 201, restResponse.getErrorCode().intValue()); + + // validate create service response vs actual + + Service service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, service, sdncUserDetails, + (LifecycleStateEnum) null); + + // validate get service response vs actual + restResponse = ServiceRestUtils.getService(serviceDetails, sdncUserDetails); + service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, service, sdncUserDetails, + (LifecycleStateEnum) null); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createDefaultServiceUserDesigner() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", 201, restResponse.getErrorCode().intValue()); + + // validate create service response vs actual + + Service service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, service, sdncUserDetails, + (LifecycleStateEnum) null); + + // validate get service response vs actual + restResponse = ServiceRestUtils.getService(serviceDetails, sdncUserDetails); + service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceUserNotFound() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncUserDetails.setUserId("no1234"); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, + restResponse.getResponse()); + + // validate audit + + sdncUserDetails.setFirstName(""); + sdncUserDetails.setLastName(""); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setModifierName(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceUserNotAllowed() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceEmptyName() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + String serviceName = ""; + serviceDetails.setName(serviceName); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_COMPONENT_NAME.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_COMPONENT_NAME.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceEmptyCategory() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + String category = ""; + + serviceDetails.setCategories(null); + // serviceDetails.addCategory(category); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_CATEGORY.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_CATEGORY.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceEmptyTag() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ArrayList tags = new ArrayList(); + tags.add(""); + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setTags(tags); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_FIELD_FORMAT.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service", "tag"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceEmptyDescription() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + String description = ""; + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setDescription(description); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_MISSING_DESCRIPTION.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceEmptyTags() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ArrayList tags = new ArrayList(); + tags.add(""); + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setTags(tags); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_FIELD_FORMAT.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service", "tag"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FIELD_FORMAT.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceByPutHttpMethod() throws Exception { + + String method = "PUT"; + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + + RestResponse restResponse = ServiceRestUtils.createServiceByHttpMethod(serviceDetails, sdncUserDetails, method, + Urls.CREATE_SERVICE); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.NOT_ALLOWED.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + restResponse.getResponse()); + + // //validate audit + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // resourceUtils.constructFieldsForAuditValidation(serviceDetails, + // serviceBaseVersion, sdncUserDetails); + // + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // + // String auditDesc = + // AuditValidationUtils.buildAuditDescription(errorInfo, variables); + // expectedResourceAuditJavaObject.setDesc(auditDesc); + // + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction); + + } + + @Test + public void createServiceByDeleteHttpMethod() throws Exception { + + String method = "DELETE"; + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + + RestResponse restResponse = ServiceRestUtils.createServiceByHttpMethod(serviceDetails, sdncUserDetails, method, + Urls.CREATE_SERVICE); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.NOT_ALLOWED.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.NOT_ALLOWED.name(), variables, + restResponse.getResponse()); + + // //validate audit + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // resourceUtils.constructFieldsForAuditValidation(serviceDetails, + // serviceBaseVersion, sdncUserDetails); + // + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + // + // String auditDesc = + // AuditValidationUtils.buildAuditDescription(errorInfo, variables); + // expectedResourceAuditJavaObject.setDesc(auditDesc); + // + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction); + + } + + @Test + public void createServiceTagLengthExceedLimit() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + StringBuffer tagBuffer = new StringBuffer(); + for (int i = 0; i < 1025; i++) { + tagBuffer.append("a"); + } + ArrayList tags = new ArrayList(); + tags.add(tagBuffer.toString()); + serviceDetails.setTags(tags); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("50"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT.name(), variables, + restResponse.getResponse()); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("50")); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + /* + * ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + * ServiceValidationUtils.constructFieldsForAuditValidation( + * serviceDetails, serviceBaseVersion, sdncUserDetails); + * + * String auditAction="Create"; + * expectedResourceAuditJavaObject.setAction(auditAction); + * expectedResourceAuditJavaObject.setPrevState(""); + * expectedResourceAuditJavaObject.setPrevVersion(""); + * expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum. + * NOT_CERTIFIED_CHECKOUT).toString()); + * expectedResourceAuditJavaObject.setStatus(errorInfo.getCode(). + * toString()); expectedResourceAuditJavaObject.setDesc(auditDesc); + * + * AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + * auditAction, null); + */ + + } + + @Test + public void createServiceAlreadyExistException() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // create service with the same name + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + + List variables = Arrays.asList("Service", serviceDetails.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_NAME_ALREADY_EXIST.name(), variables, + restResponse.getResponse()); + + // validate audit + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void createServiceWrongContactId() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setContactId("123as"); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.COMPONENT_INVALID_CONTACT.name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + } + + @Test + public void createServiceProjectName() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setProjectCode("12345"); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + Integer expectedCode = 201; + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", expectedCode, restResponse.getErrorCode()); + Service service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + + assertEquals("12345", service.getProjectCode()); + } + + @Test + public void createAndGetByNameAndVersion() throws Exception { + + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + // create + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + assertEquals("Check response code after create service", 201, restResponse.getErrorCode().intValue()); + + // get + restResponse = ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, serviceDetails.getName(), + serviceBaseVersion); + assertEquals("Check response code after get service", 200, restResponse.getErrorCode().intValue()); + + Service service = ResponseParser.convertServiceResponseToJavaObject(restResponse.getResponse()); + String uniqueId = service.getUniqueId(); + serviceDetails.setUniqueId(uniqueId); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, service, sdncUserDetails, + (LifecycleStateEnum) null); + } + + //// US553874 + + @JsonIgnore + @Test + public void createServiceIsVNF_isFalse() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after updating Interface Artifact", 201, + restResponse.getErrorCode().intValue()); + + // get service and verify that service created with isVNF defined in + // serviceDetails + RestResponse serviceByNameAndVersion = ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + serviceDetails.getName(), serviceBaseVersion); + Service serviceObject = ResponseParser + .convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, serviceObject, sdncUserDetails, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @JsonIgnore + @Test + public void createServiceIsVNF_isTrue() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after updating Interface Artifact", 201, + restResponse.getErrorCode().intValue()); + + // get service and verify that service created with isVNF defined in + // serviceDetails + RestResponse serviceByNameAndVersion = ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + serviceDetails.getName(), serviceBaseVersion); + Service serviceObject = ResponseParser + .convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, serviceObject, sdncUserDetails, + LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + // validate audit + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @JsonIgnore + @Test(enabled = false) + public void createServiceIsVNF_isNull() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + // clean audit DB before service creation + DbUtils.cleanAllAudits(); + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + assertNotNull("check response object is not null after create service", restResponse); + assertEquals("Check response code after updating Interface Artifact", 400, + restResponse.getErrorCode().intValue()); + List variables = Arrays.asList("VNF Service Indicator"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_DATA.name(), variables, + restResponse.getResponse()); + + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("VNF Service Indicator")); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + } + + @JsonIgnore + @Test(enabled = false) + public void createServiceEmptyIsVNF() throws Exception { + + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + + DbUtils.cleanAllAudits(); + + // send create service toward BE + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", restResponse.getErrorCode(), + restResponse.getErrorCode()); + + // validate create service response vs actual + List variables = Arrays.asList("VNF Service Indicator"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_DATA.name(), variables, + restResponse.getResponse()); + + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, serviceBaseVersion, sdncUserDetails); + + String auditAction = "Create"; + expectedResourceAuditJavaObject.setAction(auditAction); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + private RestResponse createServiceWithMissingAttribute(String serviceDetails, User sdncModifierDetails) + throws Exception { + + Config config = Utils.getConfig(); + + Map headersMap = ServiceRestUtils.prepareHeadersMap(sdncModifierDetails, false); + headersMap.put(HttpHeaderEnum.CACHE_CONTROL.getValue(), "no-cache"); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort()); + // TODO: ADD AUTHENTICATION IN REQUEST + logger.debug(url); + logger.debug("Send POST request to create service: {}", url); + logger.debug("Service body: {}", serviceDetails); + logger.debug("Service headers: {}", headersMap); + RestResponse sendCreateUserRequest = http.httpSendPost(url, serviceDetails, headersMap); + + return sendCreateUserRequest; + + } + + @JsonIgnore + @Test(enabled = false) + public void createServiceVersion_isVNFDoesNotExistInJson() throws Exception { + + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // clean audit DB before updating service + DbUtils.cleanAllAudits(); + + // remove isVNF from json sent to create service + JSONObject jObject = new JSONObject(serviceDetails); + jObject.remove("VNF"); + + // send create service toward BE + RestResponse restResponse = createServiceWithMissingAttribute(jObject.toString(), sdncUserDetails); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after updating Interface Artifact", 400, + restResponse.getErrorCode().intValue()); + List variables = new ArrayList(); + variables.add("VNF Service Indicator"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_DATA.name(), variables, + restResponse.getResponse()); + + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.MISSING_DATA.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = ServiceValidationUtils + .constructFieldsForAuditValidation(serviceDetails, "0.1", sdncUserDetails); + String auditAction = "Create"; + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc("VNF Service Indicator")); + AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null, false); + + } + + @Test + public void checkInvariantUuidIsImmutable() throws Exception { + // choose the user to create service + User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + Component resourceDetailsVFCcomp = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.ADMIN, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVFCcomp, UserRoleEnum.ADMIN, + true, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.ADMIN, + LifeCycleStatesEnum.CERTIFY, true); + + // fill new service details + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + String invariantUuidDefinedByUser = "!!!!!!!!!!!!!!!!!!!!!!!!"; + serviceDetails.setInvariantUUID(invariantUuidDefinedByUser); + + // create service + RestResponse restResponseCreation = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + BaseRestUtils.checkStatusCode(restResponseCreation, "create request failed", false, 201); + Service service = ResponseParser.convertServiceResponseToJavaObject(restResponseCreation.getResponse()); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, service, + UserRoleEnum.ADMIN, true); + + String invariantUUIDcreation = service.getInvariantUUID(); + + // validate get service response vs actual + RestResponse restResponseGetting = ServiceRestUtils.getService(serviceDetails, sdncUserDetails); + BaseRestUtils.checkSuccess(restResponseGetting); + service = ResponseParser.convertServiceResponseToJavaObject(restResponseGetting.getResponse()); + String invariantUUIDgetting = service.getInvariantUUID(); + + assertEquals(invariantUUIDcreation, invariantUUIDgetting); + + // Update service with new invariant UUID + RestResponse restResponseUpdate = ServiceRestUtils.updateService(serviceDetails, sdncUserDetails); + BaseRestUtils.checkSuccess(restResponseUpdate); + Service updatedService = ResponseParser.convertServiceResponseToJavaObject(restResponseUpdate.getResponse()); + String invariantUUIDupdating = updatedService.getInvariantUUID(); + assertEquals(invariantUUIDcreation, invariantUUIDupdating); + + // Do checkin + RestResponse restResponseCheckin = LifecycleRestUtils.changeServiceState(serviceDetails, sdncUserDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + BaseRestUtils.checkSuccess(restResponseCheckin); + Service checkinService = ResponseParser.convertServiceResponseToJavaObject(restResponseCheckin.getResponse()); + String invariantUUIDcheckin = checkinService.getInvariantUUID(); + String version = checkinService.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckin); + assertEquals(version, "0.1"); + + // Do checkout + RestResponse restResponseCheckout = LifecycleRestUtils.changeServiceState(serviceDetails, sdncUserDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + BaseRestUtils.checkSuccess(restResponseCheckout); + Service checkoutService = ResponseParser.convertServiceResponseToJavaObject(restResponseCheckout.getResponse()); + String invariantUUIDcheckout = checkoutService.getInvariantUUID(); + version = checkoutService.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcheckout); + assertEquals(version, "0.2"); + + // do certification request + RestResponse restResponseCertificationRequest = LifecycleRestUtils.changeServiceState(serviceDetails, + sdncUserDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + BaseRestUtils.checkSuccess(restResponseCertificationRequest); + Service certificationRequestService = ResponseParser + .convertServiceResponseToJavaObject(restResponseCertificationRequest.getResponse()); + String invariantUUIDcertificationRequest = certificationRequestService.getInvariantUUID(); + version = certificationRequestService.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcertificationRequest); + assertEquals(version, "0.2"); + + // start certification + RestResponse restResponseStartCertification = LifecycleRestUtils.changeServiceState(serviceDetails, + sdncUserDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.STARTCERTIFICATION); + BaseRestUtils.checkSuccess(restResponseStartCertification); + Service startCertificationRequestService = ResponseParser + .convertServiceResponseToJavaObject(restResponseStartCertification.getResponse()); + String invariantUUIDStartCertification = startCertificationRequestService.getInvariantUUID(); + version = startCertificationRequestService.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDStartCertification); + assertEquals(version, "0.2"); + + // certify + RestResponse restResponseCertify = LifecycleRestUtils.changeServiceState(serviceDetails, sdncUserDetails, + serviceDetails.getVersion(), LifeCycleStatesEnum.CERTIFY); + BaseRestUtils.checkSuccess(restResponseCertify); + Service certifyService = ResponseParser.convertServiceResponseToJavaObject(restResponseCertify.getResponse()); + String invariantUUIDcertify = certifyService.getInvariantUUID(); + version = certifyService.getVersion(); + assertEquals(invariantUUIDcreation, invariantUUIDcertify); + assertEquals(version, "1.0"); + + } + + // US672129 Benny + private void getServiceValidateInvariantUuid(String serviceUniqueId, String invariantUUIDcreation) + throws Exception { + RestResponse getService = ServiceRestUtils.getService(serviceUniqueId, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, getService.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(getService)); + } + + @Test // invariantUUID generated when the component is created and never + // changed + public void serviceInvariantUuid() throws Exception { + User designerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + User testerUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + User pmUser = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + Component resourceDetailsVFCcomp = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + // create service + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setInvariantUUID("123456"); + RestResponse restResponse = ServiceRestUtils.createService(serviceDetails, designerUser); + assertEquals("Check response code after create resource", BaseRestUtils.STATUS_CODE_CREATED, + restResponse.getErrorCode().intValue()); + Service service = ResponseParser.parseToObjectUsingMapper(restResponse.getResponse(), Service.class); + // invariantUUID generated when the component is created and never + // changed + String invariantUUIDcreation = ResponseParser.getInvariantUuid(restResponse); + // Add VF instance to service + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, service, + UserRoleEnum.DESIGNER, true); + // get resource and verify InvariantUuid is not changed + getServiceValidateInvariantUuid(service.getUniqueId(), invariantUUIDcreation); + + // Update service with new invariant UUID + restResponse = ServiceRestUtils.updateService(serviceDetails, designerUser); + assertEquals("Check response code after create resource", BaseRestUtils.STATUS_CODE_SUCCESS, + restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // Checkin + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, LifeCycleStatesEnum.CHECKIN); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // Checkout + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // certification request + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // start certification + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // certify + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, LifeCycleStatesEnum.CERTIFY); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // update resource + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + serviceDetails.setDescription("updatedDescription"); + restResponse = ServiceRestUtils.updateService(serviceDetails, designerUser); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // certification request + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // Checkout + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // certification request + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // start certification + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // cancel certification + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, + LifeCycleStatesEnum.CANCELCERTIFICATION); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // start certification + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, + LifeCycleStatesEnum.STARTCERTIFICATION); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // failure + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, testerUser, + LifeCycleStatesEnum.FAILCERTIFICATION); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // Checkout + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, + LifeCycleStatesEnum.CHECKOUT); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // Checkin + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, LifeCycleStatesEnum.CHECKIN); + assertEquals(BaseRestUtils.STATUS_CODE_SUCCESS, restResponse.getErrorCode().intValue()); + assertEquals(invariantUUIDcreation, ResponseParser.getInvariantUuid(restResponse)); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + // create instance + ProductReqDetails productDetails = ElementFactory.getDefaultProduct(); + RestResponse createProductResponse = ProductRestUtils.createProduct(productDetails, pmUser); + assertEquals(BaseRestUtils.STATUS_CODE_CREATED, createProductResponse.getErrorCode().intValue()); + ComponentInstanceReqDetails serviceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(serviceDetails); + RestResponse createServiceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + serviceInstanceReqDetails, pmUser, productDetails.getUniqueId(), ComponentTypeEnum.PRODUCT); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_CREATED, + createServiceInstanceResponse.getErrorCode().intValue()); + getServiceValidateInvariantUuid(serviceDetails.getUniqueId(), invariantUUIDcreation); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetAllServiceVersions.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetAllServiceVersions.java new file mode 100644 index 0000000000..760d002856 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetAllServiceVersions.java @@ -0,0 +1,350 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.lifecycle.LCSbaseTest; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GetAllServiceVersions extends ComponentBaseTest { + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected User sdncDesignerDetails; + protected User sdncDesignerDetails2; + protected User sdncAdminDetails; + protected User sdncGovernorDeatails; + protected User sdncTesterDetails; + protected User sdncOpsDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected Component resourceDetailsVFCcomp; + protected Service serviceServ; + + @Rule + public static TestName name = new TestName(); + + public GetAllServiceVersions() { + super(name, GetAllServiceVersions.class.getName()); + ; + } + + @BeforeMethod + public void setUp() throws Exception { + + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncDesignerDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncGovernorDeatails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + sdncTesterDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncOpsDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + resourceDetailsVFCcomp = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + true, true); + + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, + LifeCycleStatesEnum.CERTIFY, true); + serviceServ = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, serviceServ, + UserRoleEnum.DESIGNER, true); + + serviceDetails = new ServiceReqDetails(serviceServ); + + } + + @Test + public void GetAllServiceVersions_Version05() throws Exception { + + Map origVersionsMap = new HashMap(); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + } + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + + } + + @Test + public void GetAllServiceVersions_Version01() throws Exception { + + Map origVersionsMap = new HashMap(); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncDesignerDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_Version15() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + } + + RestResponse changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + // serviceServ.setUniqueId(serviceDetails.getUniqueId()); + // RestResponse changeServiceState = + // AtomicOperationUtils.changeComponentState(serviceServ, + // UserRoleEnum.ADMIN, LifeCycleStatesEnum.CERTIFY, false).getRight(); + + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + for (int x = 0; x < 5; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + } + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_Version25() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + } + + // getting to version 1.0 + RestResponse changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + // getting to version 1.5 + for (int x = 0; x < 5; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + } + + // getting to version 2.0 + changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + // getting to version 2.5 + for (int x = 0; x < 5; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + } + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_ReadyForCertification_version05() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + } + + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_CertifactionInProgress_version05() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + } + + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncAdminDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.STARTCERTIFICATION); + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_Certified_version10() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + // get to version 0.5 + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + + } + + // get version 1.0 + RestResponse changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_Certified_version20() throws Exception { + // addMandatoryArtifactsToService(); + Map origVersionsMap = new HashMap(); + // get to version 0.5 + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + } + + // get version 1.0 + RestResponse changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + // get version 1.5 + for (int x = 0; x < 4; x++) { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKIN); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), + LifeCycleStatesEnum.CHECKOUT); + } + + // get version 2.0 + changeServiceState = LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + assertTrue("certify service request returned status:" + changeServiceState.getErrorCode(), + changeServiceState.getErrorCode() == 200); + origVersionsMap.put(serviceDetails.getVersion(), serviceDetails.getUniqueId()); + + // validate get response + RestResponse serviceGetResponse = ServiceRestUtils.getService(serviceDetails, sdncAdminDetails); + Service res = ResponseParser.convertServiceResponseToJavaObject(serviceGetResponse.getResponse()); + Map getVersionsMap = res.getAllVersions(); + assertTrue(origVersionsMap.equals(getVersionsMap)); + } + + @Test + public void GetAllServiceVersions_ServiceNotFound() throws Exception { + + RestResponse serviceGetResponse = ServiceRestUtils.getService("123456789", sdncAdminDetails); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.SERVICE_NOT_FOUND.name()); + assertEquals("Check response code after get service without cache", errorInfo.getCode(), + serviceGetResponse.getErrorCode()); + + List variables = Arrays.asList("123456789"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_NOT_FOUND.name(), variables, + serviceGetResponse.getResponse()); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetComponentAuditApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetComponentAuditApiTest.java new file mode 100644 index 0000000000..b84728a06c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetComponentAuditApiTest.java @@ -0,0 +1,322 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.http.HttpStatus; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.JsonElement; + +import fj.data.Either; + +public class GetComponentAuditApiTest extends ComponentBaseTest { + + public static final String SERVICES_API = "services"; + public static final String RESOURCES_API = "resources"; + + protected User sdncAdminUser; + protected User sdncDesignerUser; + protected User sdncTesterUser; + + @Rule + public static TestName name = new TestName(); + + public GetComponentAuditApiTest() { + super(name, GetComponentAuditApiTest.class.getName()); + } + + // in case tests fail, run this method as test to create mapping in ES + public void updateElasticSearchMapping() throws IOException { + Either fileContentUTF8 = FileUtils.getFileContentUTF8("src\\test\\resources\\CI\\other\\mapping.json"); + AssertJUnit.assertTrue(fileContentUTF8.isLeft()); + + final String ES_TEMPLATE_URL = "http://%s:%s/_template/audit_template"; + String url = String.format(ES_TEMPLATE_URL, config.getEsHost(), config.getEsPort()); + + RestResponse sendHttpPost = new HttpRequest().sendHttpPost(url, fileContentUTF8.left().value(), null); + AssertJUnit.assertTrue(sendHttpPost.getErrorCode() == HttpStatus.SC_OK); + } + + @BeforeMethod + public void init() { + sdncAdminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncDesignerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncTesterUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + ; + + } + + @Test + public void testServiceAuditCertifiedVersion() throws Exception { + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + Wrapper versionZeroOneIDWrapper = new Wrapper(), versionZeroTwoIDWrapper = new Wrapper(); + + createBasicServiceForAudit(versionZeroOneIDWrapper, versionZeroTwoIDWrapper, serviceDetails, true); + // First Certification + + LifecycleRestUtils.certifyService(serviceDetails); + // LCSbaseTest.certifyService(serviceDetails); + AssertJUnit.assertTrue(serviceDetails.getVersion().equals("1.0")); + + // Second Certification + increaseServiceVersion(serviceDetails, "1.1"); + increaseServiceVersion(serviceDetails, "1.2"); + increaseServiceVersion(serviceDetails, "1.3"); + increaseServiceVersion(serviceDetails, "1.4"); + LifecycleRestUtils.certifyService(serviceDetails); + AssertJUnit.assertTrue(serviceDetails.getVersion().equals("2.0")); + String certifiedId = serviceDetails.getUniqueId(); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerUser, LifeCycleStatesEnum.CHECKOUT); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerUser, LifeCycleStatesEnum.CHECKIN); + + JsonElement element = getAuditJson(SERVICES_API, certifiedId); + // audits kept: 5*check ins + 4*check outs + 2*artifact payload + // updates(tosca) + certification request + certification start + + // certification success + // + 3 A&AI(ArtifactDelete, ArtifactUpload, ArtifactUpdate) + AssertJUnit.assertTrue("expected: 17, actual: " + element.getAsJsonArray().size(), element.getAsJsonArray().size() == 17); + + } + + protected void certifyResource(ResourceReqDetails defaultResource) throws IOException { + RestResponse response = LifecycleRestUtils.changeResourceState(defaultResource, sdncDesignerUser, LifeCycleStatesEnum.CERTIFICATIONREQUEST); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + response = LifecycleRestUtils.changeResourceState(defaultResource, sdncTesterUser, LifeCycleStatesEnum.STARTCERTIFICATION); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + response = LifecycleRestUtils.changeResourceState(defaultResource, sdncTesterUser, LifeCycleStatesEnum.CERTIFY); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + } + + protected JsonElement getAuditJson(String componentType, String componentId) throws IOException { + Map headers = new HashMap() { + { + put(Constants.USER_ID_HEADER, UserRoleEnum.ADMIN.getUserId()); + } + }; + String url = String.format(Urls.GET_COMPONENT_AUDIT_RECORDS, config.getCatalogBeHost(), config.getCatalogBePort(), componentType, componentId); + + RestResponse httpSendGet = new HttpRequest().httpSendGet(url, headers); + AssertJUnit.assertTrue(httpSendGet.getErrorCode() == HttpStatus.SC_OK); + JsonElement element = ResponseParser.parseToObject(httpSendGet.getResponse(), JsonElement.class); + AssertJUnit.assertTrue(element.isJsonArray()); + return element; + } + + protected void createBasicServiceForAudit(Wrapper versionZeroOneIDWrapper, Wrapper versionZeroTwoIDWrapper, ServiceReqDetails serviceDetails, Boolean withResInst) throws Exception { + + User designerUser = sdncDesignerUser; + + RestResponse response = ServiceRestUtils.createService(serviceDetails, designerUser); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_CREATED); + versionZeroOneIDWrapper.setInnerElement(serviceDetails.getUniqueId()); + + if (withResInst) { + Resource resourceObj = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceObj, UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.changeComponentState(resourceObj, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + ResourceReqDetails resource = new ResourceReqDetails(resourceObj); + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + resourceInstanceReqDetails.setComponentUid(resource.getUniqueId()); + ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncDesignerUser, serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + + // ServiceUtils.createCertResourceWithDeploymentArt(serviceDetails, + // "myResource"); + } + + response = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + AssertJUnit.assertTrue(serviceDetails.getVersion().equals("0.1")); + + response = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, LifeCycleStatesEnum.CHECKOUT); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + // ServiceUtils.addServiceDeploymentArtifact(serviceDetails.getUniqueId(), + // designerUser); + versionZeroTwoIDWrapper.setInnerElement(serviceDetails.getUniqueId()); + AssertJUnit.assertTrue(serviceDetails.getVersion().equals("0.2")); + response = LifecycleRestUtils.changeServiceState(serviceDetails, designerUser, LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + + increaseServiceVersion(serviceDetails, "0.3"); + + increaseServiceVersion(serviceDetails, "0.4"); + + increaseServiceVersion(serviceDetails, "0.5"); + + } + + protected void increaseServiceVersion(ServiceReqDetails serviceDetails, String excpectedVersion) throws Exception { + RestResponse response = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerUser, LifeCycleStatesEnum.CHECKOUT); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + AssertJUnit.assertTrue(serviceDetails.getVersion().equals(excpectedVersion)); + response = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerUser, LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + } + + protected void createBasicResourceForAudit(Wrapper versionOnePointTwoIDWrapper, ResourceReqDetails defaultResource) throws Exception { + + RestResponse response = ResourceRestUtils.createResource(defaultResource, sdncDesignerUser); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_CREATED); + + // ArtifactDefinition artifactDef = new + // ArtifactUtils().constructDefaultArtifactInfo(); + // response = resourceUtils.add_artifact(defaultResource, + // sdncDesignerUser, defaultResource.getVersion(), artifactDef); + // assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + + ArtifactReqDetails heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerUser, defaultResource.getUniqueId()); + AssertJUnit.assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), response.getErrorCode() == 200); + + response = LifecycleRestUtils.changeResourceState(defaultResource, sdncDesignerUser, LifeCycleStatesEnum.CHECKIN); + + increaseResourceVersion(defaultResource, "0.2"); + + increaseResourceVersion(defaultResource, "0.3"); + + increaseResourceVersion(defaultResource, "0.4"); + + increaseResourceVersion(defaultResource, "0.5"); + + certifyResource(defaultResource); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + AssertJUnit.assertTrue(defaultResource.getVersion().equals("1.0")); + + increaseResourceVersion(defaultResource, "1.1"); + + increaseResourceVersion(defaultResource, "1.2"); + versionOnePointTwoIDWrapper.setInnerElement(defaultResource.getUniqueId()); + + increaseResourceVersion(defaultResource, "1.3"); + + increaseResourceVersion(defaultResource, "1.4"); + + } + + protected void increaseResourceVersion(ResourceReqDetails defaultResource, String expectedVersion) throws IOException { + RestResponse response = LifecycleRestUtils.changeResourceState(defaultResource, sdncDesignerUser, LifeCycleStatesEnum.CHECKOUT); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + AssertJUnit.assertTrue(defaultResource.getVersion().equals(expectedVersion)); + response = LifecycleRestUtils.changeResourceState(defaultResource, sdncDesignerUser, LifeCycleStatesEnum.CHECKIN); + AssertJUnit.assertTrue(response.getErrorCode() == HttpStatus.SC_OK); + } + + @Test + public void testServiceAuditLastUncertifiedVersion() throws Exception { + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + Wrapper versionZeroOneIDWrapper = new Wrapper(), versionZeroTwoIDWrapper = new Wrapper(); + + createBasicServiceForAudit(versionZeroOneIDWrapper, versionZeroTwoIDWrapper, serviceDetails, false); + + JsonElement element = getAuditJson(SERVICES_API, versionZeroTwoIDWrapper.getInnerElement()); + + assertTrue(element.getAsJsonArray().size() == 3); + + } + + @Test + public void testServiceAuditFirstUncertifiedVersion() throws Exception { + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + Wrapper versionZeroOneIDWrapper = new Wrapper(), versionZeroTwoIDWrapper = new Wrapper(); + + createBasicServiceForAudit(versionZeroOneIDWrapper, versionZeroTwoIDWrapper, serviceDetails, false); + + JsonElement element = getAuditJson(SERVICES_API, versionZeroOneIDWrapper.getInnerElement()); + + assertTrue(element.getAsJsonArray().size() == 3); + + } + + @Test + public void testResourceAuditUncertifiedVersion() throws Exception { + + ResourceReqDetails defaultResource = ElementFactory.getDefaultResource(); + Wrapper versionOnePointTwoIDWrapper = new Wrapper(); + + createBasicResourceForAudit(versionOnePointTwoIDWrapper, defaultResource); + + JsonElement element = getAuditJson(RESOURCES_API, versionOnePointTwoIDWrapper.getInnerElement()); + + assertTrue(element.getAsJsonArray().size() == 3); + + } + + @Test + public void testResourceAuditCertifiedVersion() throws Exception { + + ResourceReqDetails defaultResource = ElementFactory.getDefaultResource(); + Wrapper versionOnePointTwoIDWrapper = new Wrapper(); + + createBasicResourceForAudit(versionOnePointTwoIDWrapper, defaultResource); + + certifyResource(defaultResource); + assertTrue(defaultResource.getVersion().equals("2.0")); + String certifiedId = defaultResource.getUniqueId(); + + increaseResourceVersion(defaultResource, "2.1"); + + increaseResourceVersion(defaultResource, "2.2"); + + JsonElement element = getAuditJson(RESOURCES_API, certifiedId); + + assertTrue(element.getAsJsonArray().size() == 13); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetServiceLatestVersionTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetServiceLatestVersionTest.java new file mode 100644 index 0000000000..19bed4d380 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/GetServiceLatestVersionTest.java @@ -0,0 +1,684 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_RESTRICTED_OPERATION; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +public class GetServiceLatestVersionTest extends ComponentInstanceBaseTest { + + protected ArtifactReqDetails heatArtifactDetails; + + @Rule + public static TestName name = new TestName(); + + public GetServiceLatestVersionTest() { + super(name, GetServiceLatestVersionTest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + initMembers(); + createAtomicResource(resourceDetailsVFC_01); + changeResourceStateToCertified(resourceDetailsVFC_01); + createAtomicResource(resourceDetailsCP_01); + changeResourceStateToCertified(resourceDetailsCP_01); + createAtomicResource(resourceDetailsVL_01); + changeResourceStateToCertified(resourceDetailsVL_01); + createVF(resourceDetailsVF_01); + certifyVf(resourceDetailsVF_01); + createService(serviceDetails_01); + createService(serviceDetails_02); + createService(serviceDetails_03); + createProduct(productDetails_01); + createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); // create + // certified + // VF + // instance + // in + // service + /* + * RestResponse restResponse = + * LifecycleRestUtils.changeServiceState(serviceDetails_01, + * sdncDesignerDetails, LifeCycleStates.CHECKIN); + * ResourceRestUtils.checkSuccess(restResponse); + */ + } + + public void initMembers() throws Exception { + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + sdncPsDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1); + sdncPmDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1); + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncTesterDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + resourceDetailsVFC_01 = ElementFactory.getDefaultResourceByType("VFC100", NormativeTypesEnum.COMPUTE, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VFC.toString()); // resourceType = VFC + resourceDetailsVF_01 = ElementFactory.getDefaultResourceByType("VF100", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VF.toString()); + resourceDetailsCP_01 = ElementFactory.getDefaultResourceByType("CP100", NormativeTypesEnum.PORT, + ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.CP.toString()); + resourceDetailsVL_01 = ElementFactory.getDefaultResourceByType("VL100", NormativeTypesEnum.NETWORK, + ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VL.toString()); + serviceDetails_01 = ElementFactory.getDefaultService("newtestservice1", ServiceCategoriesEnum.MOBILITY, + sdncDesignerDetails.getUserId()); + serviceDetails_02 = ElementFactory.getDefaultService("newtestservice2", ServiceCategoriesEnum.MOBILITY, + sdncDesignerDetails.getUserId()); + serviceDetails_03 = ElementFactory.getDefaultService("newtestservice3", ServiceCategoriesEnum.MOBILITY, + sdncDesignerDetails.getUserId()); + productDetails_01 = ElementFactory.getDefaultProduct("product01"); + } + + @Test + public void getServicesLatestVersionServiceInCheckOutState() throws Exception { + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncPsDetails1); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertNull("No Service returned, one service in checkout state 0.1", servcieFromList); + } + + @Test + public void getServicesLatestVersionServiceInCheckInState() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncPsDetails1); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.1")); + } + + @Test + public void getServicesLatestVersionByPm() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncPmDetails1); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.1")); + } + + @Test + public void getServicesLatestVersionByAdmin() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncAdminDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.1")); + } + + @Test + public void getServicesLatestVersionService02CheckOutState() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + String serviceUniqueID = ResponseParser.getUniqueIdFromResponse(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceUniqueID); + assertTrue(servcieFromList.getVersion().equals("0.1")); + servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertNull(servcieFromList); + } + + @Test + public void getServicesLatestVersionService02CheckInState() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.2")); + } + + @Test + public void getServicesLatestVersionServiceWaitingForCertification() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.2")); + } + + @Test + public void getServicesLatestVersionServiceCertificationInProgress() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.2")); + } + + @Test + public void getServicesLatestVersionServiceCertificationFail() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.FAILCERTIFICATION); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.2")); + } + + @Test + public void getServicesLatestVersionServiceCertifed() throws Exception { + certifyService(serviceDetails_01); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("1.0")); + } + + @Test + public void getLatestVersionServiceHasSeveralCertifedVersion_01() throws Exception { + RestResponse certifyServiceResponse; + String serviceUniqueIdFromResponse = null; + int numberOfCertifiedService = 3; + for (int i = 0; i < numberOfCertifiedService; i++) { + certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + if (i == (numberOfCertifiedService - 1)) { + serviceUniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(certifyServiceResponse); + } + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + } + // We have service with following versions : 1.0, 2.0 ,3.0 and + // 3.1(checkedOut) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceUniqueIdFromResponse); + assertTrue(servcieFromList.getVersion().equals("3.0")); + } + + @Test + public void getLatestVersionServiceHasSeveralCertifedVersions02() throws Exception { + RestResponse certifyServiceResponse; + certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + // We have service with following versions : 1.0, 2.0 + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("2.0")); + } + + @Test + public void getLatestVersionServiceCertifedWasCheckedOutAndCheckedin() throws Exception { + RestResponse certifyServiceResponse; + int numberOfCertifiedService = 3; + for (int i = 0; i < numberOfCertifiedService; i++) { + certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + } + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + // We have service with following versions : 1.0, 2.0 and 2.1(checkedIn) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("3.1")); + } + + @Test + public void getLatestVersionServiceCheckOutCertifedService() throws Exception { + RestResponse restResponse; + String serviceUniqueIdFromResponse = null; + RestResponse certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + for (int i = 0; i < 11; i++) { + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + if (i == (10)) { + serviceUniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(restResponse); + } + } + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + // We have service with following versions : 1.0 and 1.11(Check-out) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceUniqueIdFromResponse); + assertTrue(servcieFromList.getVersion().equals("1.11")); + } + + @Test + public void getLatestVersionServiceCheckOutCheckInCertifedService() throws Exception { + RestResponse restResponse; + String serviceUniqueIdFromResponse = null; + RestResponse certifyServiceResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(certifyServiceResponse); + for (int i = 0; i < 12; i++) { + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + if (i == (11)) { + serviceUniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(restResponse); + } + } + // We have service with following versions : 1.0 and 1.11(Check-out) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceUniqueIdFromResponse); + assertTrue(servcieFromList.getVersion().equals("1.12")); + } + + @Test + public void getLatestVersionServiceCertifedCheckedOutAndInWaitingForCertificationState() throws Exception { + certifyService(serviceDetails_01); // 1.0 + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ServiceRestUtils.checkSuccess(restResponse); + // We have service with following versions : 1.0 and 1.1(Waiting For + // Certification) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("1.1")); + } + + @Test + public void getLatestVersionServiceCertifedCheckedOutAndInCertificationInProgressState() throws Exception { + certifyService(serviceDetails_01); // 1.0 + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ServiceRestUtils.checkSuccess(restResponse); + // We have service with following versions : 1.0 and 1.1(Certification + // In Progress) + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("1.1")); + } + + // DE190818 + @Test(enabled = false) + public void getLatestVersionByNonAsdcUser() throws Exception { + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + nonAsdcUser.setUserId("gg750g"); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(nonAsdcUser); + assertTrue(getServicesLatestVersion.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + getServicesLatestVersion.getResponse()); + } + + // DE190818 + @Test(enabled = false) + public void getLatestVersionUserIdIsEmpty() throws Exception { + User nonAsdcUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + nonAsdcUser.setUserId(""); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(nonAsdcUser); + assertTrue(getServicesLatestVersion.getErrorCode() == STATUS_CODE_RESTRICTED_OPERATION); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_OPERATION.name(), new ArrayList(), + getServicesLatestVersion.getResponse()); + } + + @Test + public void getServicesLatestVersionByTester() throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncTesterDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 1); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_01.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.1")); + } + + @Test + public void getLatestVersionSeveralServicesInDifferentVersion() throws Exception { + RestResponse restResponse = certifyService(serviceDetails_01); // 1.0 + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = certifyService(serviceDetails_01); + ServiceRestUtils.checkSuccess(restResponse); + String service1_UniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); // serviceDetails_01 + // version is 2.1 + // (check-out) + + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_02, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); // serviceDetails_02 + // version 0.2 + // (Check-in) + + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_03, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + String service3_UniqueIdFromResponse = ResponseParser.getUniqueIdFromResponse(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails_03, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); // serviceDetails_03 + // version 0.2 + // (Check-out) + + RestResponse getServicesLatestVersion = ServiceRestUtils.getServiceLatestVersionList(sdncDesignerDetails); + ServiceRestUtils.checkSuccess(getServicesLatestVersion); + List serviceList = restResponseToResourceObjectList(getServicesLatestVersion); + assertTrue(serviceList.size() == 3); + Service servcieFromList = getResourceObjectFromResourceListByUid(serviceList, service1_UniqueIdFromResponse); + assertTrue(servcieFromList.getVersion().equals("2.0")); + servcieFromList = getResourceObjectFromResourceListByUid(serviceList, serviceDetails_02.getUniqueId()); + assertTrue(servcieFromList.getVersion().equals("0.2")); + servcieFromList = getResourceObjectFromResourceListByUid(serviceList, service3_UniqueIdFromResponse); + assertTrue(servcieFromList.getVersion().equals("0.1")); + } + + /////////////////////////////////////////////////////////////// + private RestResponse certifyService(ServiceReqDetails serviceDetails) throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKOUT); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + ServiceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeServiceState(serviceDetails, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + ServiceRestUtils.checkSuccess(restResponse); + return restResponse; + } + + protected List restResponseToResourceObjectList(RestResponse restResponse) { + JsonElement jelement = new JsonParser().parse(restResponse.getResponse()); + JsonArray jsonArray = jelement.getAsJsonArray(); + List restResponseArray = new ArrayList<>(); + Service service = null; + for (int i = 0; i < jsonArray.size(); i++) { + String serviceString = (String) jsonArray.get(i).toString(); + service = ResponseParser.convertServiceResponseToJavaObject(serviceString); + restResponseArray.add(service); + } + return restResponseArray; + } + + protected Service getResourceObjectFromResourceListByUid(List serviceList, String uid) { + if (serviceList != null && serviceList.size() > 0) { + for (Service service : serviceList) { + if (service.getUniqueId().equals(uid)) + return service; + } + } else + return null; + return null; + } + + private RestResponse changeResourceStateToCertified(ResourceReqDetails resourceDetails) throws Exception { + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponse; + if (restResponse.getErrorCode() == 200) { + restResponse = LifecycleRestUtils.changeResourceState(resourceDetails, sdncTesterDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponse.getErrorCode() == 200) { + String newVersion = ResponseParser.getVersionFromResponse(restResponse); + resourceDetails.setVersion(newVersion); + resourceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + resourceDetails.setLastUpdaterUserId(sdncTesterDetails.getUserId()); + resourceDetails.setLastUpdaterFullName(sdncTesterDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getValueFromJsonResponse(restResponse.getResponse(), + "uniqueId"); + resourceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponse; + } + + // private void certifyVf(ResourceReqDetails resource) throws Exception { + // RestResponse createAtomicResourceInstance = + // createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVFC_01, + // sdncDesignerDetails); + // ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + // createAtomicResourceInstance = + // createAtomicInstanceForVFDuringSetup(resource, resourceDetailsCP_01, + // sdncDesignerDetails); + // ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + // createAtomicResourceInstance = + // createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVL_01, + // sdncDesignerDetails); + // ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + // //createVFInstanceDuringSetup(service, resource, sdncDesignerDetails); + // RestResponse response = + // ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, + // sdncDesignerDetails, resource.getUniqueId()); + // ResourceRestUtils.checkSuccess(response); + // RestResponse changeResourceStateToCertified = + // changeResourceStateToCertified(resource); + // ResourceRestUtils.checkSuccess(changeResourceStateToCertified); + // } + + private void certifyVf(ResourceReqDetails resource) throws Exception { + RestResponse createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String cpCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVFC_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String computeCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resource, resourceDetailsVL_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String vlCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + // Fixing Vl/Cp req/cap + ComponentTypeEnum containerCompType = ComponentTypeEnum.RESOURCE; + User user = sdncDesignerDetails; + fulfillCpRequirement(resource, cpCompInstId, computeCompInstId, computeCompInstId, user, containerCompType); + consumeVlCapability(resource, cpCompInstId, vlCompInstId, cpCompInstId, user, containerCompType); + + RestResponse response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, + sdncDesignerDetails, resource.getUniqueId()); + ResourceRestUtils.checkSuccess(response); + RestResponse changeResourceStateToCertified = changeResourceStateToCertified(resource); + ResourceRestUtils.checkSuccess(changeResourceStateToCertified); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ReqCapOccurrencesTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ReqCapOccurrencesTest.java new file mode 100644 index 0000000000..c21deafcd8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ReqCapOccurrencesTest.java @@ -0,0 +1,1191 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; + +import org.apache.http.client.ClientProtocolException; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.general.ImportUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ReqCapOccurrencesTest extends ComponentInstanceBaseTest { + + private ImportReqDetails importReqDetails1; // atomic resource + private ImportReqDetails importReqDetails2; + private ImportReqDetails importReqDetails3; + private ImportReqDetails importReqDetails4; + private Resource resourceVFC1; + private Resource resourceVFC2; + private Resource resourceVFC3; + private Resource resourceVFC4; + private ResourceReqDetails resourceDetailsVF100; + private ResourceReqDetails resourceDetailsVF200; + private Resource resourceVF100; + private Resource resourceVF200; + protected String testResourcesPath; + + protected final String importYmlWithReq11 = "softwareComponentReq11.yml"; + protected final String importYmlWithReq12 = "softwareComponentReq12.yml"; + protected final String importYmlWithCap11 = "computeCap11.yml"; + protected final String importYmlWithCap1Unbounded = "computeCap1UNBOUNDED.yml"; + protected final String capabilitiesAndRequirementsType = "tosca.capabilities.Container"; + + public ReqCapOccurrencesTest() { + super(new TestName(), ReqCapOccurrencesTest.class.getSimpleName()); + } + + @BeforeMethod + public void before() throws Exception { + // Do not use call init() from ComponentInstanceBaseTest + expectedContainerCapabilities = new LinkedHashMap>(); + expectedContainerRequirements = new LinkedHashMap>(); + removedRequirements = new HashMap<>(); + expectedContInstReqCap = new HashMap<>(); + + RestResponse importResourceResponse; + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // import yml file location + String sourceDir = config.getResourceConfigDir(); + final String workDir = "importToscaResourceByCreateUrl"; + testResourcesPath = sourceDir + File.separator + workDir; + ///// Create atomic resources ///////////////////////// + // import VFC1 with Requirements : MIN=1 MAX=2 + ///// (tosca.capabilities.Container) + importReqDetails1 = ElementFactory.getDefaultImportResource("VFC1"); + importResourceResponse = importedResource(importReqDetails1, importYmlWithReq12); + // resourceVFC1 = + // ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + RestResponse restResponse = LifecycleRestUtils.changeResourceState(importReqDetails1, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + resourceVFC1 = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + // import VFC2 with Capabilities : MIN 1 MAX UNBOUNDED + // (tosca.capabilities.Container) + importReqDetails2 = ElementFactory.getDefaultImportResource("VFC2"); + importResourceResponse = importedResource(importReqDetails2, importYmlWithCap1Unbounded); + // resourceVFC2 = + // ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + restResponse = LifecycleRestUtils.changeResourceState(importReqDetails2, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + resourceVFC2 = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + // import VFC3 with Capabilities : MIN 1 MAX 1 + // (tosca.capabilities.Container) + importReqDetails3 = ElementFactory.getDefaultImportResource("VFC3"); + importResourceResponse = importedResource(importReqDetails3, importYmlWithCap11); + // resourceVFC3 = + // ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + restResponse = LifecycleRestUtils.changeResourceState(importReqDetails3, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + resourceVFC3 = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + // import VFC4 with Requirements : MIN 1 MAX 1 + // (tosca.capabilities.Container) + importReqDetails4 = ElementFactory.getDefaultImportResource("VFC4"); + importResourceResponse = importedResource(importReqDetails4, importYmlWithReq11); + // resourceVFC4 = + // ResponseParser.convertResourceResponseToJavaObject(importResourceResponse.getResponse()); + restResponse = LifecycleRestUtils.changeResourceState(importReqDetails4, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + resourceVFC4 = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + + // create VF100 + resourceDetailsVF100 = ElementFactory.getDefaultResourceByType("VF1000", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VF.toString()); + RestResponse createResourceVF100 = ResourceRestUtils.createResource(resourceDetailsVF100, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceVF100); + // create VF200 + resourceDetailsVF200 = ElementFactory.getDefaultResourceByType("VF2000", NormativeTypesEnum.ROOT, + ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, sdncDesignerDetails.getUserId(), + ResourceTypeEnum.VF.toString()); + RestResponse createResourceVF200 = ResourceRestUtils.createResource(resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createResourceVF200); + // Create Service + serviceDetails_01 = ElementFactory.getDefaultService("newtestservice1", ServiceCategoriesEnum.MOBILITY, + sdncDesignerDetails.getUserId()); + RestResponse createServiceRestResponse = ServiceRestUtils.createService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createServiceRestResponse); + + } + + // US628514 Capability/Requirement "Occurrences" attribute in CREATE/DELETE + // Relation APIs + // Container = SERVICE , Container instance = VF + @Test + public void capAndReqOccurrencesInServiceAndHisInstancesNoAssociation() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC1 (Req MIN=1 MAX=2) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC21 (Cap MIN=1 MAX=UNBOUNDED) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "1"; + String containerMaxReq = "2"; + String containerMinCap = "1"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test + public void serviceInstanceAssociationReqMaxOccurrencesNotReached() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC1 (Req MIN=1 MAX=2) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC2 (Cap MIN=1 MAX=UNBOUNDED) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test + public void serviceInstanceAssociationReqMaxOccurrencesIsReached() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC4 (Req MIN=1 MAX=1) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC2 (Cap MIN=1 MAX=UNBOUNDED) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test + public void associateServiceInstanceWhenReqMaxOccurrencesAlreadyReached() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC4 (Req MIN=1 MAX=1) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC2 (Cap MIN=1 MAX=UNBOUNDED) to VF2.00 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf1Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf2Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // associate same instances again - when requirement Max Occurrences + // reached + associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncDesignerDetails, + serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_NOT_FOUND, + associateInstances.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(vf1Name); + varibales.add(vf2Name); + varibales.add("host"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND.name(), varibales, + associateInstances.getResponse()); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test + public void serviceInstanceAssociationCapMaxOccurrencesIsReached() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC1 (Req MIN=1 MAX=2) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC3 (Cap MIN=1 MAX=1) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test + public void associationServiceInstanceWhenCapMaxOccurrencesAlreadyReached() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC1 (Req MIN=1 MAX=2) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC3 (Cap MIN=1 MAX=1) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + // RestResponse createVFInstResp = createVFInstance(serviceDetails_01, + // resourceDetailsVF100, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf1Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + // createVFInstResp = createVFInstance(serviceDetails_01, + // resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf2Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + // associate same instances again - when requirement Max Occurrences + // reached + associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncDesignerDetails, + serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_NOT_FOUND, + associateInstances.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(vf1Name); + varibales.add(vf2Name); + varibales.add("host"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND.name(), + varibales, associateInstances.getResponse()); + } + + @Test + public void associationAndDisassociateServiceInstancesWhenReqMaxOccurrencesAlreadyReached() + throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC4 (Req MIN=1 MAX=1) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC3 (Cap MIN=1 MAX=1) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + RestResponse createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + sdncDesignerDetails); + // RestResponse createVFInstResp = createVFInstance(serviceDetails_01, + // resourceDetailsVF100, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + // createVFInstResp = createVFInstance(serviceDetails_01, + // resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VF Instances + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + // Disassociate 2 VF Instances + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, + dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF100.getUniqueId()).isEmpty()); + // get service and verify Occurrences in container and container + // instance requirements and Capabilities + getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + containerMinReq = "1"; + containerMaxReq = "1"; + containerMinCap = "1"; + containerMaxCap = "1"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + } + + @Test(enabled = false) + public void aaaa() throws Exception, Exception { + RestResponse getResourseRestResponse; + // Add instance of VFC1 (Req MIN=1 MAX=2) to VF1000 + ComponentInstance componentInstanceReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceReq); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Add instance of VFC3 (Cap MIN=1 MAX=1) to VF2000 + ComponentInstance componentInstanceCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF200); + assertNotNull(componentInstanceCap); + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF200.getUniqueId()); + resourceVF200 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Check-In both VFs + RestResponse restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF100, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + restResponse = LifecycleRestUtils.changeResourceState(resourceDetailsVF200, sdncDesignerDetails, + LifeCycleStatesEnum.CHECKIN); + ResourceRestUtils.checkSuccess(restResponse); + // Create VF instances + // RestResponse createVFInstResp = + // createVFInstanceDuringSetup(serviceDetails_01, resourceDetailsVF100, + // sdncDesignerDetails); + RestResponse createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF100, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf1Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // createVFInstResp = createVFInstanceDuringSetup(serviceDetails_01, + // resourceDetailsVF200, sdncDesignerDetails); + createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF200, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String vf2Name = ResponseParser.getValueFromJsonResponse(createVFInstResp.getResponse(), "name"); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // associate 2 VFs + String capType = capabilitiesAndRequirementsType; + String reqName = "host"; + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList, componentInstanceReq.getUniqueId(), componentInstanceCap.getUniqueId()); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + // get service + RestResponse getServiceResponse = ServiceRestUtils.getService(serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getServiceResponse); + Service service = ResponseParser.parseToObjectUsingMapper(getServiceResponse.getResponse(), Service.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, containerMinReq, + containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(service, capabilitiesAndRequirementsType, + resourceVF200, resourceVF100); + // associate same instances again - when requirement Max Occurrences + // reached + associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncDesignerDetails, + serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_NOT_FOUND, + associateInstances.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(vf1Name); + varibales.add(vf2Name); + varibales.add("host"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND.name(), + varibales, associateInstances.getResponse()); + } + + ////////////////////////////////////////////////////////////////////////////////////////////////// + // US628514 Capability/Requirement "Occurrences" attribute in CREATE/DELETE + ////////////////////////////////////////////////////////////////////////////////////////////////// Relation + ////////////////////////////////////////////////////////////////////////////////////////////////// APIs + // Container = VF , Container instance = VFC + @Test + public void capAndReqOccurrencesInVfAndHisInstancesNoAssociation() throws Exception, Exception { + // Add VFC1 and VFC2 instances in VF + ComponentInstance createComponentInstance1 = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(createComponentInstance1); + ComponentInstance createComponentInstance2 = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(createComponentInstance2); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "1"; + String containerMaxReq = "2"; + String containerMinCap = "1"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC2, resourceVFC1); + } + + @Test + public void vfInstanceAssociationReqMaxOccurrencesNotReached() throws Exception, Exception { + // Add VFC1 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=2) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC2 (with Capabilities: tosca.capabilities.Container, MIN=1, + // MAX=UNBOUNDED ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC2, resourceVFC1); + + } + + @Test + public void vfInstanceAssociationReqMaxOccurrencesIsReached() throws Exception, Exception { + // Add VFC4 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=1) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC2 (with Capabilities: tosca.capabilities.Container, MIN=1, + // MAX=UNBOUNDED ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC2, resourceVFC4); + } + + @Test + public void associateVfInstanceWhenReqMaxOccurrencesAlreadyReached() throws Exception, Exception { + // Add VFC4 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=1) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC2 (with Capabilities: tosca.capabilities.Container, MIN=1, + // MAX=UNBOUNDED ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails2, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "UNBOUNDED"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC2, resourceVFC4); + // associate same instances again - when requirement Max Occurrences + // reached + associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncDesignerDetails, + resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_NOT_FOUND, + associateInstances.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(componentInstanceWithReq.getName()); + varibales.add(componentInstanceWithCap.getName()); + varibales.add("host"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND.name(), varibales, + associateInstances.getResponse()); + + } + + @Test + public void vfInstanceAssociationCapMaxOccurrencesIsReached() throws Exception, Exception { + // Add VFC1 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=2) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC3 (with Capabilities: tosca.capabilities.Container, MIN=1 + // MAX=1 ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC3, resourceVFC1); + } + + @Test + public void associationVfInstanceWhenCapMaxOccurrencesAlreadyReached() throws Exception, Exception { + // Add VFC1 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=2) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails1, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC3 (with Capabilities: tosca.capabilities.Container, MIN=1 + // MAX=1 ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", STATUS_CODE_SUCCESS, associateInstances.getErrorCode().intValue()); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "1"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC3, resourceVFC1); + // associate same instances again - when requirement Max Occurrences + // reached + associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, sdncDesignerDetails, + resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_NOT_FOUND, + associateInstances.getErrorCode().intValue()); + ArrayList varibales = new ArrayList(); + varibales.add(componentInstanceWithReq.getName()); + varibales.add(componentInstanceWithCap.getName()); + varibales.add("host"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND.name(), + varibales, associateInstances.getResponse()); + } + + @Test + public void associationAndDisassociateVfInstancesWhenReqMaxOccurrencesAlreadyReached() throws Exception, Exception { + // Add VFC4 (with Requirements: tosca.capabilities.Container, MIN=1 + // MAX=1) instance to VF + ComponentInstance componentInstanceWithReq = createComponentInstance(importReqDetails4, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithReq); + // Add VFC3 (with Capabilities: tosca.capabilities.Container, MIN=1 + // MAX=1 ) instance to VF + ComponentInstance componentInstanceWithCap = createComponentInstance(importReqDetails3, sdncDesignerDetails, + resourceDetailsVF100); + assertNotNull(componentInstanceWithCap); + // associate Instances + CapReqDef capReqDefBeforeAssociate = getResourceReqCap(resourceDetailsVF100); + RequirementCapabilityRelDef requirementDef = setRelationshipBetweenInstances(componentInstanceWithReq, + componentInstanceWithCap, capReqDefBeforeAssociate); + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkSuccess(associateInstances); + assertTrue(checkRealtionship(requirementDef.getFromNode(), requirementDef.getToNode(), + resourceDetailsVF100.getUniqueId())); + // GET resource + RestResponse getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + String containerMinReq = "0"; + String containerMaxReq = "0"; + String containerMinCap = "0"; + String containerMaxCap = "0"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC3, resourceVFC4); + // Disassociate 2 Instances + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + sdncDesignerDetails, resourceDetailsVF100.getUniqueId(), ComponentTypeEnum.RESOURCE); + assertEquals("Check response code ", BaseRestUtils.STATUS_CODE_SUCCESS, + dissociateInstances.getErrorCode().intValue()); + assertTrue(getComponentInstancesRelations(resourceDetailsVF100.getUniqueId()).isEmpty()); + // GET resource + getResourseRestResponse = ResourceRestUtils.getResource(sdncDesignerDetails, + resourceDetailsVF100.getUniqueId()); + resourceVF100 = ResponseParser.parseToObjectUsingMapper(getResourseRestResponse.getResponse(), Resource.class); + // Verify Container requirements and Capabilities + containerMinReq = "1"; + containerMaxReq = "1"; + containerMinCap = "1"; + containerMaxCap = "1"; + verifyContainerCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + containerMinReq, containerMaxReq, containerMinCap, containerMaxCap); + verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(resourceVF100, capabilitiesAndRequirementsType, + resourceVFC3, resourceVFC4); + } + + /////////////////////////////////////// + + private boolean checkRealtionship(String fromNode, String toNode, String resourceUniqueId) throws Exception { + List componentInstancesRelations = getComponentInstancesRelations( + resourceUniqueId); + RequirementCapabilityRelDef requirementCapabilityRelDef = componentInstancesRelations.get(0); + boolean fromNodeCheck = requirementCapabilityRelDef.getFromNode().equals(fromNode); + boolean toNodeCheck = requirementCapabilityRelDef.getToNode().equals(toNode); + + return fromNodeCheck && toNodeCheck; + } + + private List getComponentInstancesRelations(String resourceUniqueId) + throws ClientProtocolException, IOException { + Resource resource = getVfAsResourceObject(resourceUniqueId); + List componenRelationInstances = resource.getComponentInstancesRelations(); + + return componenRelationInstances; + } + + private Resource getVfAsResourceObject(String resourceUniqueId) throws ClientProtocolException, IOException { + RestResponse getResource = ResourceRestUtils.getResource(resourceUniqueId); + Resource resource = ResponseParser.parseToObjectUsingMapper(getResource.getResponse(), Resource.class); + return resource; + } + + private RequirementCapabilityRelDef setRelationshipBetweenInstances(ComponentInstance riReq, + ComponentInstance riCap, CapReqDef capReqDef) throws Exception { + + String capbilityUid = capReqDef.getCapabilities().get("tosca.capabilities.Container").get(0).getUniqueId(); + String requirementUid = capReqDef.getRequirements().get("tosca.capabilities.Container").get(0).getUniqueId(); + + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(riReq.getUniqueId()); + requirementDef.setToNode(riCap.getUniqueId()); + + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(riReq.getUniqueId()); + pair.setCapabilityOwnerId(riCap.getUniqueId()); + pair.setRequirement("host"); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType("tosca.capabilities.Container"); + pair.setRelationships(relationship); + pair.setCapabilityUid(capbilityUid); + pair.setRequirementUid(requirementUid); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + return requirementDef; + } + + private CapReqDef getResourceReqCap(ResourceReqDetails res) throws IOException { + RestResponse getResourceBeforeAssociate = ComponentRestUtils + .getComponentRequirmentsCapabilities(sdncDesignerDetails, resourceDetailsVF100); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceBeforeAssociate.getResponse(), CapReqDef.class); + return capReqDef; + } + + private RestResponse importedResource(ImportReqDetails importReqDetails, String ymlFile) throws Exception { + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, testResourcesPath, + ymlFile); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, + sdncDesignerDetails, null); + assertEquals("Check response code after importing resource", BaseRestUtils.STATUS_CODE_CREATED, + importResourceResponse.getErrorCode().intValue()); + return importResourceResponse; + } + + private ComponentInstance createComponentInstance(ResourceReqDetails res, User user, ResourceReqDetails vf) + throws Exception { + RestResponse response = ResourceRestUtils.createResourceInstance(res, user, vf.getUniqueId()); + ResourceRestUtils.checkCreateResponse(response); + ComponentInstance compInstance = ResponseParser.parseToObject(response.getResponse(), ComponentInstance.class); + return compInstance; + } + + private void verifyContainerCapabilitiesAndRequirementsOccurrences(Component component, + String CapabilitiesAndRequirementsType, String minReqOccurrences, String maxReqOccurrences, + String minCapabilities, String maxCapabilities) throws Exception { + boolean isRequirementAppear = false; + boolean isCapabilityAppear = false; + List requirements; + List capabilities; + requirements = component.getRequirements().get(CapabilitiesAndRequirementsType); + if (maxReqOccurrences == "0") { + assertTrue(requirements == null); + } // if container MAX requirement = 0 + if (maxReqOccurrences != "0") { + assertNotNull(requirements); + for (RequirementDefinition req : requirements) { + switch (req.getName()) { + case "host": + assertTrue("Check Min Requirement Occurrences ", req.getMinOccurrences().equals(minReqOccurrences)); + assertTrue("Check Max Requirement Occurrences ", req.getMaxOccurrences().equals(maxReqOccurrences)); + isRequirementAppear = true; + break; + } + assertTrue(isRequirementAppear); + isRequirementAppear = false; + } + } + // Container Capabilities + capabilities = component.getCapabilities().get(CapabilitiesAndRequirementsType); + if (maxCapabilities == "0") {// if container MAX capabilities = 0 + assertTrue(capabilities == null); + } + if (maxCapabilities != "0") { + assertNotNull(capabilities); + for (CapabilityDefinition cap : capabilities) { + switch (cap.getName()) { + case "host": + assertTrue("Check Min capability Occurrences ", cap.getMinOccurrences().equals(minCapabilities)); + assertTrue("Check Max capability Occurrences ", cap.getMaxOccurrences().equals(maxCapabilities)); + isCapabilityAppear = true; + break; + } + assertTrue(isCapabilityAppear); + isCapabilityAppear = false; + } + } + + } + + private void verifyContainerInstanceCapabilitiesAndRequirementsOccurrences(Component component, + String CapabilitiesAndRequirementsType, Resource vfWithCapabilities, Resource vfWithRequirements) + throws Exception { + boolean isCapReqAppear = false; + List listOfComponentInstances = component.getComponentInstances(); + + for (ComponentInstance instance : listOfComponentInstances) { + if (instance.getComponentUid().equals(vfWithCapabilities.getUniqueId())) { + List capFromResource = vfWithCapabilities.getCapabilities() + .get(CapabilitiesAndRequirementsType); + List capFromInstance = instance.getCapabilities() + .get(CapabilitiesAndRequirementsType); + for (CapabilityDefinition resourceCap : capFromResource) + for (CapabilityDefinition instanceReq : capFromInstance) { + if (resourceCap.getUniqueId().equals(instanceReq.getUniqueId())) { + assertTrue("Check Min capability Occurrences ", + resourceCap.getMinOccurrences().equals(instanceReq.getMinOccurrences())); + assertTrue("Check Max capability Occurrences ", + resourceCap.getMaxOccurrences().equals(instanceReq.getMaxOccurrences())); + isCapReqAppear = true; + break; + } + + } + } + + if (instance.getComponentUid().equals(vfWithRequirements.getUniqueId())) { + List reqFromAtomicResource = vfWithRequirements.getRequirements() + .get(CapabilitiesAndRequirementsType); + List reqFromInstance = instance.getRequirements() + .get(CapabilitiesAndRequirementsType); + for (RequirementDefinition resourceReq : reqFromAtomicResource) + for (RequirementDefinition instanceReq : reqFromInstance) { + if (resourceReq.getUniqueId().equals(instanceReq.getUniqueId())) { + assertTrue("Check Min Requirement Occurrences ", + resourceReq.getMinOccurrences().equals(instanceReq.getMinOccurrences())); + assertTrue("Check Max Requirement Occurrences ", + resourceReq.getMaxOccurrences().equals(instanceReq.getMaxOccurrences())); + isCapReqAppear = true; + break; + } + } + } + assertTrue(isCapReqAppear); + isCapReqAppear = false; + } + + } + + private RequirementCapabilityRelDef getReqCapRelation(String reqCompInstId, String capCompInstId, String capType, + String reqName, List capList, List reqList, + String vfc1UniqueId, String vfc2UniqueId) { + return ElementFactory.getReqCapRelation(reqCompInstId, capCompInstId, vfc1UniqueId, vfc2UniqueId, capType, + reqName, capList, reqList); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ServiceComponentInstanceCRUDTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ServiceComponentInstanceCRUDTest.java new file mode 100644 index 0000000000..b2728ea0da --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/ServiceComponentInstanceCRUDTest.java @@ -0,0 +1,1624 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertTrue; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.codehaus.jettison.json.JSONException; +import org.json.JSONArray; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentInstanceBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.BaseValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class ServiceComponentInstanceCRUDTest extends ComponentInstanceBaseTest { + private static Logger log = LoggerFactory.getLogger(ServiceComponentInstanceCRUDTest.class.getName()); + private static final String SPACE_STRING = " "; + private static String REQUIREMENT_NAME = "host"; + private static String CAPABILITY_TYPE = "tosca.capabilities.Container"; + + private String reqOwnerId; + private String capOwnerId; + + public ServiceComponentInstanceCRUDTest() { + super(new TestName(), ServiceComponentInstanceCRUDTest.class.getSimpleName()); + } + + @BeforeMethod(alwaysRun = true) + public void before() throws Exception { + init(); + createComponents(); + } + + private void createComponents() throws Exception { + createAtomicResource(resourceDetailsVFC_01); + createAtomicResource(resourceDetailsVFC_02); + createAtomicResource(resourceDetailsCP_01); + createAtomicResource(resourceDetailsVL_01); + createAtomicResource(resourceDetailsVL_02); + createVF(resourceDetailsVF_01); + createVF(resourceDetailsVF_02); + createService(serviceDetails_01); + certifyResource(resourceDetailsVFC_01); + certifyResource(resourceDetailsVFC_02); + RestResponse createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resourceDetailsVF_01, + resourceDetailsVFC_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + reqOwnerId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + createAtomicResourceInstance = createAtomicInstanceForVFDuringSetup(resourceDetailsVF_02, resourceDetailsVFC_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + capOwnerId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance);// should + // be + // updated + // to + // getUniqueIdOfFirstInstance + // in + // service + // context + } + + private void certifyResource(ResourceReqDetails resource) throws Exception { + changeResourceLifecycleState(resource, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + changeResourceLifecycleState(resource, sdncTesterDetails.getUserId(), LifeCycleStatesEnum.STARTCERTIFICATION); + changeResourceLifecycleState(resource, sdncTesterDetails.getUserId(), LifeCycleStatesEnum.CERTIFY); + } + + private void changeResourceLifecycleState(ResourceReqDetails resourceDetails, String userUserId, + LifeCycleStatesEnum lifeCycleStates) throws Exception { + RestResponse response = LifecycleRestUtils.changeResourceState(resourceDetails, userUserId, lifeCycleStates); + LifecycleRestUtils.checkLCS_Response(response); + } + + private void changeServiceLifecycleState(ServiceReqDetails serviceDetails, User user, + LifeCycleStatesEnum lifeCycleStates) throws Exception { + RestResponse response = LifecycleRestUtils.changeServiceState(serviceDetails, user, lifeCycleStates); + LifecycleRestUtils.checkLCS_Response(response); + } + + private void createVFInstanceFailWithoutChangeState(ActionStatus actionStatus, List variables, + ResourceReqDetails vfResource, User user, int errorCode) throws Exception { + RestResponse createVFInstanceSuccessfullyWithoutChangeStateResp = createVFInstance(serviceDetails_01, + vfResource, user); + checkErrorMessage(actionStatus, variables, errorCode, createVFInstanceSuccessfullyWithoutChangeStateResp); + } + + private void createVFInstanceFail(ActionStatus actionStatus, List variables, ResourceReqDetails vfResource, + User user, int errorCode) throws Exception, FileNotFoundException, JSONException { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, vfResource, user); + checkErrorMessage(actionStatus, variables, errorCode, createVFInstResp); + } + + private void deleteVFInstanceFail(ActionStatus actionStatus, List variables, ResourceReqDetails vfResource, + User user, int errorCode) throws Exception, FileNotFoundException, JSONException { + RestResponse deleteVFInstResp = deleteVFInstance(vfResource.getUniqueId(), serviceDetails_01, user); + checkErrorMessage(actionStatus, variables, errorCode, deleteVFInstResp); + } + + private void createAtomicResourceInstanceFailWithoutChangeState(ActionStatus actionStatus, List variables, + ResourceReqDetails atomicResource, User user, int errorCode) + throws Exception, FileNotFoundException, JSONException { + RestResponse createAtomicInstResp = createAtomicInstanceForService(serviceDetails_01, atomicResource, user); + checkErrorMessage(actionStatus, variables, errorCode, createAtomicInstResp); + } + + private void createAtomicResourceInstanceFail(ActionStatus actionStatus, List variables, + ResourceReqDetails atomicResource, User user, int errorCode) + throws Exception, FileNotFoundException, JSONException { + RestResponse createAtomicInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, atomicResource, + user); + checkErrorMessage(actionStatus, variables, errorCode, createAtomicInstResp); + } + + private void deleteAtomicResourceInstanceFail(ActionStatus actionStatus, List variables, + ResourceReqDetails atomicResource, User user, int errorCode) + throws Exception, FileNotFoundException, JSONException { + RestResponse deleteAtomicInstResp = deleteAtomicInstanceForService(atomicResource.getUniqueId(), + serviceDetails_01, user); + checkErrorMessage(actionStatus, variables, errorCode, deleteAtomicInstResp); + } + + private void checkErrorMessage(ActionStatus actionStatus, List variables, int errorCode, + RestResponse response) throws Exception { + + log.debug(response.getResponse()); + AssertJUnit.assertEquals(errorCode, response.getErrorCode().intValue()); + ErrorValidationUtils.checkBodyResponseOnError(actionStatus.name(), variables, response.getResponse()); + } + + private RestResponse createCheckedinVFInstance(ServiceReqDetails containerDetails, + ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + changeResourceLifecycleState(compInstOriginDetails, compInstOriginDetails.getCreatorUserId(), + LifeCycleStatesEnum.CHECKIN); + return createVFInstance(containerDetails, compInstOriginDetails, modifier); + } + + private RestResponse createCheckedinAtomicInstanceForService(ServiceReqDetails containerDetails, + ResourceReqDetails compInstOriginDetails, User modifier) throws Exception { + changeResourceLifecycleState(compInstOriginDetails, compInstOriginDetails.getCreatorUserId(), + LifeCycleStatesEnum.CHECKIN); + return createAtomicInstanceForService(containerDetails, compInstOriginDetails, modifier); + } + + private void createVFInstanceAndAtomicResourceInstanceWithoutCheckin(ResourceReqDetails vf, + ResourceReqDetails atomicResource, User user) throws Exception { + RestResponse createVFInstance = createVFInstance(serviceDetails_01, vf, user); + ResourceRestUtils.checkCreateResponse(createVFInstance); + RestResponse atomicInstanceForService = createAtomicInstanceForService(serviceDetails_01, atomicResource, user); + ResourceRestUtils.checkCreateResponse(atomicInstanceForService); + } + + private void createVFInstanceAndAtomicResourceInstanceSuccessully(ResourceReqDetails vf, + ResourceReqDetails atomicResource) throws Exception, IOException { + createVFInstanceAndAtomicResourceInstanceSuccessully(vf, atomicResource, sdncDesignerDetails); + } + + private void createVFInstanceAndAtomicResourceInstanceSuccessully(ResourceReqDetails vf, + ResourceReqDetails atomicResource, User user) throws Exception, IOException { + changeResourceLifecycleState(vf, vf.getCreatorUserId(), LifeCycleStatesEnum.CHECKIN); + changeResourceLifecycleState(atomicResource, atomicResource.getCreatorUserId(), LifeCycleStatesEnum.CHECKIN); + createVFInstanceAndAtomicResourceInstanceWithoutCheckin(vf, atomicResource, user); + } + + @Test + public void createVFInstanceSuccessfullyTest() throws Exception { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void createVFAndAtomicInstanceTest() throws Exception { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsVL_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsVL_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + getComponentAndValidateRIs(serviceDetails_01, 4, 0); + } + + @Test + public void deleteAtomicInstanceTest() throws Exception { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + // 1 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsCP_01, + sdncDesignerDetails); + // 2 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsVL_01, + sdncDesignerDetails); + // 3 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsVL_02, + sdncDesignerDetails); + // 4 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + // To delete + String compInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // 3 rel + createVFInstResp = deleteAtomicInstanceForService(compInstId, serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(createVFInstResp); + getComponentAndValidateRIs(serviceDetails_01, 3, 0); + } + + @Test + public void deleteVFInstanceTest() throws Exception { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + // 1 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + String compInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + // 2 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + createVFInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, resourceDetailsCP_01, + sdncDesignerDetails); + // 3 rel + ResourceRestUtils.checkCreateResponse(createVFInstResp); + // 2 rel + createVFInstResp = deleteVFInstance(compInstId, serviceDetails_01, sdncDesignerDetails); + ResourceRestUtils.checkDeleteResponse(createVFInstResp); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void associateDissociateTwoVFs() throws Exception { + + RestResponse createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String fromCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String toCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + + String capType = CAPABILITY_TYPE; + String reqName = REQUIREMENT_NAME; + + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(fromCompInstId, toCompInstId, capType, reqName, + capList, reqList); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List list = capReqDef.getRequirements().get(capType); + AssertJUnit.assertEquals("Check requirement", null, list); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + dissociateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + list = capReqDef.getRequirements().get(capType); + AssertJUnit.assertEquals("Check requirement", 1, list.size()); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + private RequirementCapabilityRelDef getReqCapRelation(String reqCompInstId, String capCompInstId, String capType, + String reqName, List capList, List reqList) { + return ElementFactory.getReqCapRelation(reqCompInstId, capCompInstId, reqOwnerId, capOwnerId, capType, reqName, + capList, reqList); + } + + @Test + public void createResourceInstanceByDifferentDesignerTest() throws Exception { + createVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), 409); + createAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), 409); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void createResourceInstanceByDifferentDesignerTest_ServiceIsCheckedin() throws Exception { + User designer2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, designer2, LifeCycleStatesEnum.CHECKOUT); + + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01, designer2); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + } + + @Test + public void createResourceInstanceByTester() throws Exception { + createVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + ElementFactory.getDefaultUser(UserRoleEnum.TESTER), 409); + createAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), 409); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void createResourceInstanceWithNotASDCUserTest() throws Exception { + sdncDesignerDetails.setUserId("ab0001"); + createVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + sdncDesignerDetails, 409); + createAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, sdncDesignerDetails, 409); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void createResourceInstanceWithEmptyUserIdTest() throws Exception { + sdncDesignerDetails.setUserId(""); + createVFInstanceFail(ActionStatus.MISSING_INFORMATION, new ArrayList(), resourceDetailsVF_01, + sdncDesignerDetails, 403); + createAtomicResourceInstanceFail(ActionStatus.MISSING_INFORMATION, new ArrayList(), + resourceDetailsCP_01, sdncDesignerDetails, 403); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void createResourceInstanceWithEmptyServiceUidTest() throws Exception { + serviceDetails_01.setUniqueId(""); + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + assertEquals(404, createVFInstResp.getErrorCode().intValue()); + RestResponse createAtomicInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, + resourceDetailsCP_01, sdncDesignerDetails); + assertEquals(404, createAtomicInstResp.getErrorCode().intValue()); + } + + @Test + public void createResourceInstanceWhileResourceNotExistTest() throws Exception { + String vfResourceUniqueId = "1234"; + String atomicResourceUniqueId = "5678"; + + resourceDetailsVF_01.setUniqueId(vfResourceUniqueId); + resourceDetailsCP_01.setUniqueId(atomicResourceUniqueId); + + createVFInstanceFailWithoutChangeState(ActionStatus.RESOURCE_NOT_FOUND, + new ArrayList(Arrays.asList("")), resourceDetailsVF_01, sdncDesignerDetails, 404); + createAtomicResourceInstanceFailWithoutChangeState(ActionStatus.RESOURCE_NOT_FOUND, + new ArrayList(Arrays.asList("")), resourceDetailsCP_01, sdncDesignerDetails, 404); + } + + @Test + public void createResourceInstanceInServiceNotExistsTest() throws Exception { + serviceDetails_01.setUniqueId("1234"); + createVFInstanceFail(ActionStatus.SERVICE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsVF_01, sdncDesignerDetails, 404); + createAtomicResourceInstanceFail(ActionStatus.SERVICE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsCP_01, sdncDesignerDetails, 404); + } + + @Test + public void createResourceInstanceInCheckedinServiceTest() throws Exception { + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + + createVFInstanceFailWithoutChangeState(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsVF_01, sdncDesignerDetails, 409); + createAtomicResourceInstanceFailWithoutChangeState(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, sdncDesignerDetails, 409); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test(enabled = false) + public void createResourceInstance_ResourceInCheckoutStateTest() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + RestResponse createVFInstanceWithoutChangeStateResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ComponentInstanceRestUtils.checkCreateResponse(createVFInstanceWithoutChangeStateResp); + RestResponse createAtomicInstWithoutCheangeStateResp = createAtomicInstanceForService(serviceDetails_01, + resourceDetailsCP_01, sdncDesignerDetails); + ComponentInstanceRestUtils.checkCreateResponse(createAtomicInstWithoutCheangeStateResp); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void createResourceInstance_ResourceInCertificationRequestStateTest() throws Exception { + changeResourceLifecycleState(resourceDetailsVF_01, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + changeResourceLifecycleState(resourceDetailsCP_01, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void createResourceInstance_startCertificationStateTest() throws Exception { + changeResourceLifecycleState(resourceDetailsVF_01, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + changeResourceLifecycleState(resourceDetailsCP_01, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + + changeResourceLifecycleState(resourceDetailsVF_01, sdncTesterDetails.getUserId(), + LifeCycleStatesEnum.STARTCERTIFICATION); + changeResourceLifecycleState(resourceDetailsCP_01, sdncTesterDetails.getUserId(), + LifeCycleStatesEnum.STARTCERTIFICATION); + + createVFInstanceAndAtomicResourceInstanceWithoutCheckin(resourceDetailsVF_01, resourceDetailsCP_01, + sdncDesignerDetails); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + } + + @Test + public void createResourceInstance_certifiedStateTest() throws Exception { + certifyResource(resourceDetailsVF_01); + certifyResource(resourceDetailsCP_01); + + createVFInstanceAndAtomicResourceInstanceWithoutCheckin(resourceDetailsVF_01, resourceDetailsCP_01, + sdncDesignerDetails); + } + + @Test + public void createResourceInstance_OneHasDifferentOwner() throws Exception { + User designer2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + + ResourceReqDetails vfResource = new ResourceReqDetails(resourceDetailsVF_01, "0.1"); + vfResource.setUniqueId(null); + vfResource.setName("newVF"); + vfResource.setTags(new ArrayList(Arrays.asList(vfResource.getName()))); + createVF(vfResource, designer2); + + RestResponse atomicInstanceForService = createCheckedinAtomicInstanceForService(serviceDetails_01, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(atomicInstanceForService); + createVFInstanceFailWithoutChangeState(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), vfResource, + designer2, 409); + + getComponentAndValidateRIs(serviceDetails_01, 1, 0); + } + + @Test + public void indexesOfVFInstancesTest() throws Exception { + String firstInstanceName = resourceDetailsVF_01.getName() + SPACE_STRING + "1"; + String secondInstanceName = resourceDetailsVF_01.getName() + SPACE_STRING + "2"; + String thirdInstanceName = resourceDetailsVF_01.getName() + SPACE_STRING + "3"; + + LifecycleRestUtils.changeResourceState(resourceDetailsVF_01, sdncDesignerDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + + RestResponse createFirstVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createSecondVFInstResp); + RestResponse createThirdVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createThirdVFInstResp); + + Component service = getComponentAndValidateRIs(serviceDetails_01, 3, 0); + List componentInstancesList = service.getComponentInstances(); + for (ComponentInstance instance : componentInstancesList) { + String instanceName = instance.getName(); + boolean isEqualToFirstInstanceName = instanceName.equals(firstInstanceName); + boolean isEqualToSecondInstanceName = instanceName.equals(secondInstanceName); + boolean isEqualToThirdInstanceName = instanceName.equals(thirdInstanceName); + assertTrue(isEqualToFirstInstanceName || isEqualToSecondInstanceName || isEqualToThirdInstanceName); + } + } + + @Test + public void vfInstancesAmountInTwoServiceVersionsTest() throws Exception { + String oldServiceUniqueId = serviceDetails_01.getUniqueId(); + + createTwoCheckedinVFInstances(); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKOUT); + + String newSerivceUniqueIdAfterChangeLifecycleState = serviceDetails_01.getUniqueId(); + getComponentAndValidateRIsAfterChangeLifecycleState(oldServiceUniqueId, serviceDetails_01, 2, 0); + + // Check old version + checkServiceOldVersionRIs(oldServiceUniqueId, newSerivceUniqueIdAfterChangeLifecycleState, 2, 0); + + // Add one more resource instance to second version of service + LifecycleRestUtils.changeResourceState(resourceDetailsVL_01, sdncDesignerDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + RestResponse createAtomicResourceInstResp = createAtomicResourceInstanceToSecondServiceVersion( + newSerivceUniqueIdAfterChangeLifecycleState, resourceDetailsVL_01); + String atomicResourceUniqueId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstResp); + getComponentAndValidateRIsAfterAddingAtomicResourceInstance(oldServiceUniqueId, serviceDetails_01, 3, 0); + + // Check that RIs are same as in the beginning - like in old version of + // service + deleteCompInstReqCapFromExpected(atomicResourceUniqueId); + checkServiceOldVersionRIs(oldServiceUniqueId, newSerivceUniqueIdAfterChangeLifecycleState, 2, 0); + + } + + private void createTwoCheckedinVFInstances() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createSecondVFInstResp); + } + + private void getComponentAndValidateRIsAfterAddingAtomicResourceInstance(String oldComponentUniqueId, + ComponentReqDetails componentDetails, int numOfRIs, int numOfRelations) throws Exception { + getComponentAndValidateRIsAfterChangeLifecycleState(oldComponentUniqueId, componentDetails, numOfRIs, + numOfRelations); + + } + + private void checkServiceOldVersionRIs(String oldUniqueId, String newUniqueId, int numOfRIs, int numOfRelations) + throws IOException, Exception { + serviceDetails_01.setUniqueId(oldUniqueId); + getComponentAndValidateRIsAfterChangeLifecycleState(newUniqueId, serviceDetails_01, numOfRIs, numOfRelations); + } + + private RestResponse createAtomicResourceInstanceToSecondServiceVersion(String secondServiceUniqueId, + ResourceReqDetails resourceToAdd) throws Exception { + serviceDetails_01.setUniqueId(secondServiceUniqueId); + RestResponse createAtomicResourceInstResp = createAtomicInstanceForService(serviceDetails_01, resourceToAdd, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstResp); + return createAtomicResourceInstResp; + } + + @Test + public void createResourceInstanceToUnsupportedComponentTest() throws Exception { + String unsupportedType = "unsupported"; + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentResourceInstance(resourceDetailsCP_01); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, sdncDesignerDetails, serviceDetails_01.getUniqueId(), unsupportedType); + checkErrorMessage(ActionStatus.UNSUPPORTED_ERROR, new ArrayList(Arrays.asList(unsupportedType)), 400, + createResourceInstanceResponse); + } + + @Test + public void deleteResourceInstanceByDifferentDesignerTest() throws Exception { + + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01); + + deleteVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), 409); + deleteAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), 409); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void deleteResourceInstanceByDifferentDesignerTest_ServiceIsCheckedin() throws Exception { + + String oldServiceUniqueId = serviceDetails_01.getUniqueId(); + + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + RestResponse createAtomicResourceInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, + resourceDetailsCP_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstResp); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), + LifeCycleStatesEnum.CHECKOUT); + String newServiceUniqueId = serviceDetails_01.getUniqueId(); + + String oldVFInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + String newVFInstanceUniqueId = oldVFInstanceUniqueId.replaceAll(oldServiceUniqueId, + serviceDetails_01.getUniqueId()); + String oldAtomicResourceInstanceUniqueId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstResp); + String newAtomicResourceInstanceUniqueId = oldAtomicResourceInstanceUniqueId.replaceAll(oldServiceUniqueId, + serviceDetails_01.getUniqueId()); + + deleteVFInstanceAndAtomicResourceInstanceSuccessfully(newVFInstanceUniqueId, newAtomicResourceInstanceUniqueId, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2)); + + serviceDetails_01.setUniqueId(oldServiceUniqueId); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + serviceDetails_01.setUniqueId(newServiceUniqueId); + updateExpectedReqCapAfterChangeLifecycleState(oldServiceUniqueId, serviceDetails_01.getUniqueId()); + deleteCompInstReqCapFromExpected(newVFInstanceUniqueId); + deleteCompInstReqCapFromExpected(newAtomicResourceInstanceUniqueId); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + private void deleteVFInstanceAndAtomicResourceInstanceSuccessfully(String vfInstanceUniqueId, + String atomicResourceInstanceUniqueId) throws IOException, Exception { + deleteVFInstanceAndAtomicResourceInstanceSuccessfully(vfInstanceUniqueId, atomicResourceInstanceUniqueId, + sdncDesignerDetails); + } + + private void deleteVFInstanceAndAtomicResourceInstanceSuccessfully(String vfInstanceUniqueId, + String atomicResourceInstanceUniqueId, User user) throws IOException, Exception { + RestResponse deleteVFInstResp = deleteVFInstance(vfInstanceUniqueId, serviceDetails_01, user); + ResourceRestUtils.checkDeleteResponse(deleteVFInstResp); + RestResponse deleteAtomicResourceInsResp = deleteAtomicInstanceForService(atomicResourceInstanceUniqueId, + serviceDetails_01, user); + ResourceRestUtils.checkDeleteResponse(deleteAtomicResourceInsResp); + } + + @Test + public void deleteResourceInstanceByTesterUserTest() throws Exception { + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01); + deleteVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + ElementFactory.getDefaultUser(UserRoleEnum.TESTER), 409); + deleteAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), 409); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void deleteResourceInstanceByNotASDCUserTest() throws Exception { + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01); + User notASDCUser = new User(); + notASDCUser.setUserId("ab0001"); + deleteVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + notASDCUser, 409); + deleteAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, notASDCUser, 409); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void deleteResourceInstanceFromCheckedinServiceTest() throws Exception { + createVFInstanceAndAtomicResourceInstanceSuccessully(resourceDetailsVF_01, resourceDetailsCP_01); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + deleteVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + sdncDesignerDetails, 409); + deleteAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, sdncDesignerDetails, 409); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void deleteResourceInstanceWhileResourceCertifiedStateTest() throws Exception { + certifyResource(resourceDetailsVF_01); + certifyResource(resourceDetailsCP_01); + + RestResponse createVFInstance = createVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstance); + String vfInstUniqueId = ResponseParser.getUniqueIdFromResponse(createVFInstance); + RestResponse atomicInstanceForService = createAtomicInstanceForService(serviceDetails_01, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(atomicInstanceForService); + String atomicInstUniqueId = ResponseParser.getUniqueIdFromResponse(atomicInstanceForService); + + deleteVFInstanceAndAtomicResourceInstanceSuccessfully(vfInstUniqueId, atomicInstUniqueId); + + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + // fail - bug DE191849 + @Test + public void deleteNotFoundResourceInstanceTest() throws Exception, Throwable { + + resourceDetailsVF_01.setUniqueId("1234"); + resourceDetailsCP_01.setUniqueId("5678"); + + deleteVFInstanceFail(ActionStatus.RESOURCE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsVF_01, sdncDesignerDetails, 404); + deleteAtomicResourceInstanceFail(ActionStatus.RESOURCE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsCP_01, sdncDesignerDetails, 404); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + + // {"requestError":{"serviceException":{"messageId":"SVC4503","text":"Error: + // Requested '%1' service was not found.","variables":["1234"]}}}> + } + + @Test + public void deleteResourceInstanceFromServiceNotFoundTest() throws Exception, Throwable { + serviceDetails_01.setUniqueId("1234"); + deleteVFInstanceFail(ActionStatus.SERVICE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsVF_01, sdncDesignerDetails, 404); + deleteAtomicResourceInstanceFail(ActionStatus.SERVICE_NOT_FOUND, new ArrayList(Arrays.asList("")), + resourceDetailsCP_01, sdncDesignerDetails, 404); + } + + @Test + public void deleteResourceInstanceFromUnsupportedTypeTest() throws Exception { + String unsupportedType = "unsupportedType"; + RestResponse deleteVFInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(sdncDesignerDetails, + serviceDetails_01.getUniqueId(), resourceDetailsVF_01.getUniqueId(), unsupportedType); + checkErrorMessage(ActionStatus.UNSUPPORTED_ERROR, new ArrayList(Arrays.asList(unsupportedType)), 400, + deleteVFInstanceResponse); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void deleteResourceInstanceWithEmptyServiceUidTest() throws Exception, Throwable { + serviceDetails_01.setUniqueId(""); + RestResponse deleteVFInstResp = deleteVFInstance(resourceDetailsVF_01.getUniqueId(), serviceDetails_01, + sdncDesignerDetails); + assertEquals(404, deleteVFInstResp.getErrorCode().intValue()); + } + + @Test + public void deleteResourceInstanceWithEmptyResourceInstanceUidTest() throws Exception, Throwable { + RestResponse deleteVFInstResp = deleteVFInstance("", serviceDetails_01, sdncDesignerDetails); + assertEquals(405, deleteVFInstResp.getErrorCode().intValue()); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + @Test + public void deleteResourceInstanceWithEmptyUserIdTest() throws Exception { + sdncDesignerDetails.setUserId(""); + deleteVFInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), resourceDetailsVF_01, + sdncDesignerDetails, 409); + deleteAtomicResourceInstanceFail(ActionStatus.RESTRICTED_OPERATION, new ArrayList(), + resourceDetailsCP_01, sdncDesignerDetails, 409); + getComponentAndValidateRIs(serviceDetails_01, 0, 0); + } + + // fail - bug DE188994 + @Test + public void associateResourceInstanceToResourceInstanceNotFoundTest() throws Exception, Throwable { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + String capCompInstId = "1234"; + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + List capListBeforeAssociate = new ArrayList(); + CapabilityDefinition cap = new CapabilityDefinition(); + cap.setUniqueId(capCompInstId); + capListBeforeAssociate.add(cap); + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + assocaiteInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, 404, + new ArrayList(Arrays.asList(capCompInstId))); + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capabilitiesAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List requirementsAfterAssoicate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, + // requirementsAfterAssoicate); + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capabilitiesAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 1, 0); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "VF100 1", + // "9ae76786-2a9c-4409-95cb-db32885ed07f.eece8aaf-eb9f-4aff-b9a5-a11ca11de9e5.vf1001", + // "host" + // ] + } + + // this case is not relevant any more, it is tested as part of occurrences + // story + @Test(enabled = false) + public void associateOnceAgainExistingRelationTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + ////////////////////////////////////////////// + // NO ERROR - RELATION ALREADY EXIST + // assocaiteInstancesFail(requirementDef, sdncDesignerDetails, + // ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, 404, new + // ArrayList(Arrays.asList(capCompInstId))); + ////////////////////////////////////////////// + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListAfterAssociate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + // AssertJUnit.assertEquals("Check requirement", null, + // reqListAfterAssociate); + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capListAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + // "messageId": "SVC4119", + // "text": "Error: No relation found between resource instances + // \u0027%1\u0027 and \u0027%2\u0027 for requirement \u0027%3\u0027.", + // "variables": [ + // "VF100 1", + // "VF_admin 2", + // "host" + + } + + @Test + public void associateInstancesInMissingServiceTest() throws Exception { + serviceDetails_01.setUniqueId("1234"); + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + assocaiteInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.SERVICE_NOT_FOUND, 404, + new ArrayList(Arrays.asList(""))); + } + + @Test + public void associateAfterDeletingResourceTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + ResourceRestUtils.deleteResource(resourceDetailsVF_01.getUniqueId(), sdncDesignerDetails.getUserId()); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + + // for (CapabilityDefinition capabilityDefinition : + // capListBeforeAssociate) { + // if (capabilityDefinition.getType().equals(CAPABILITY_TYPE)){ + // capabilityDefinition.setMinOccurrences("0"); + // } + // } + // + // List reqListAfterAssociate = + // capReqDefAfterAssociate.getRequirements().get(CAPABILITY_TYPE); + // + // AssertJUnit.assertEquals("Check requirement", null, + // reqListAfterAssociate); + // + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capListAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + } + + @Test + public void associateInstancesInCheckedinServiceTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + + assocaiteInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESTRICTED_OPERATION, 409, + new ArrayList()); + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capabilitiesAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List requirementsAfterAssoicate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, requirementsAfterAssoicate); + AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, capabilitiesAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + // fail - bug DE188994 + @Test + public void associateAfterCheckoutAllInstancesTest() throws Exception { + String firstVFUniqueId = resourceDetailsVF_01.getUniqueId(); + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + String secondVFUniqueId = resourceDetailsVF_02.getUniqueId(); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + changeResourceLifecycleState(resourceDetailsVF_01, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CHECKOUT); + changeResourceLifecycleState(resourceDetailsVF_02, sdncDesignerDetails.getUserId(), + LifeCycleStatesEnum.CHECKOUT); + + requirementDef.setFromNode( + requirementDef.getFromNode().replaceAll(firstVFUniqueId, resourceDetailsVF_01.getUniqueId())); + requirementDef + .setToNode(requirementDef.getToNode().replaceAll(secondVFUniqueId, resourceDetailsVF_02.getUniqueId())); + + assocaiteInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESTRICTED_OPERATION, 409, + new ArrayList()); + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capabilitiesAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List requirementsAfterAssoicate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, + // requirementsAfterAssoicate); + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capabilitiesAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + // "messageId": "SVC4116", + // "text": "Error: Invalid Content.", + // "variables": [ + // "e9dcea15-ce27-4381-a554-4278973cefb1.d0b3affd-cf92-4626-adfe-961b44103924.vf1001", + // "e9dcea15-ce27-4381-a554-4278973cefb1.d0b3affd-cf92-4626-adfe-961b44103924.vf1001", + // "host" + // ] + + } + + @Test + public void associateInstancesByDifferentUsersTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + assocaiteInstancesFail(requirementDef, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2), + ActionStatus.RESTRICTED_OPERATION, 409, new ArrayList()); + assocaiteInstancesFail(requirementDef, ElementFactory.getDefaultUser(UserRoleEnum.TESTER), + ActionStatus.RESTRICTED_OPERATION, 409, new ArrayList()); + assocaiteInstancesFail(requirementDef, ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR), + ActionStatus.RESTRICTED_OPERATION, 409, new ArrayList()); + assocaiteInstancesFail(requirementDef, ElementFactory.getDefaultUser(UserRoleEnum.OPS), + ActionStatus.RESTRICTED_OPERATION, 409, new ArrayList()); + assocaiteInstancesFail(requirementDef, ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1), + ActionStatus.RESTRICTED_OPERATION, 409, new ArrayList()); + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capabilitiesAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List requirementsAfterAssoicate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, requirementsAfterAssoicate); + AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, capabilitiesAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + private void assocaiteInstancesFail(RequirementCapabilityRelDef requirementDef, User user, + ActionStatus actionStatus, int errorCode, List variables) throws IOException, Exception { + RestResponse associateInstancesResp = ComponentInstanceRestUtils.associateInstances(requirementDef, user, + serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + checkErrorMessage(actionStatus, variables, errorCode, associateInstancesResp); + } + + private void dissoicateInstancesFail(RequirementCapabilityRelDef requirementDef, User user, + ActionStatus actionStatus, int errorCode, List variables) throws IOException, Exception { + RestResponse dissoicateInstancesResp = ComponentInstanceRestUtils.dissociateInstances(requirementDef, user, + serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + checkErrorMessage(actionStatus, variables, errorCode, dissoicateInstancesResp); + } + + @Test + public void associateWithMissingServiceUidTest() throws Exception { + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + serviceDetails_01.setUniqueId(""); + RestResponse associateInstancesResp = ComponentInstanceRestUtils.associateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals(404, associateInstancesResp.getErrorCode().intValue()); + } + + // fail - bug DE191824 + @Test + public void associateNotCompitableReqCapTest() throws Exception { + RestResponse createFirstAtomicResourceInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, + resourceDetailsCP_01, sdncDesignerDetails); + String reqCompInstName = ResponseParser.getNameFromResponse(createFirstAtomicResourceInstResp); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstAtomicResourceInstResp); + RestResponse createSecondAtomicResourceInstResp = createCheckedinAtomicInstanceForService(serviceDetails_01, + resourceDetailsVL_02, sdncDesignerDetails); + String capCompInstName = ResponseParser.getNameFromResponse(createSecondAtomicResourceInstResp); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondAtomicResourceInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + List variables = new ArrayList(); + variables.add(reqCompInstName); + variables.add(capCompInstName); + variables.add(REQUIREMENT_NAME); + + assocaiteInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND, 404, + variables); + + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capabilitiesAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List requirementsAfterAssoicate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, + // requirementsAfterAssoicate); + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capabilitiesAfterAssociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + // {"requestError":{"serviceException":{"messageId":"SVC4119","text":"Error: + // No relation found between resource instances '%1' and '%2' for + // requirement '%3'.","variables":["CP100 1","VL200 2","host"]}}}> + } + + @Test + public void associateInstancesInTwoServiceVersionsTest() throws Exception { + String oldServiceUniqueId = serviceDetails_01.getUniqueId(); + RestResponse createFirstVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKOUT); + String secondServiceUniqueId = serviceDetails_01.getUniqueId(); + + serviceDetails_01.setUniqueId(oldServiceUniqueId); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + updateCapabilitiesOwnerId(oldServiceUniqueId, capListBeforeAssociate, secondServiceUniqueId); + updateExpectedReqCapAfterChangeLifecycleState(oldServiceUniqueId, secondServiceUniqueId); + CapReqDef capReqDefAfterAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterAssociate = capReqDefAfterAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListAfterAssociate = capReqDefAfterAssociate.getRequirements() + .get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", null, + // reqListAfterAssociate); + // AssertJUnit.assertEquals("Check capabilities", + // capListBeforeAssociate, capListAfterAssociate); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + RestResponse createThirdVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqSecondCompInstId = ResponseParser.getUniqueIdFromResponse(createThirdVFInstResp); + + CapReqDef capReqDefBeforeSeconderyAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeSeconderyAssociate = capReqDefBeforeSeconderyAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeSeconderyAssociate = capReqDefBeforeSeconderyAssociate + .getRequirements().get(CAPABILITY_TYPE); + + capCompInstId = capCompInstId.replaceAll(oldServiceUniqueId, secondServiceUniqueId); + RequirementCapabilityRelDef secondRequirementDef = getReqCapRelation(reqSecondCompInstId, capCompInstId, + CAPABILITY_TYPE, REQUIREMENT_NAME, capListBeforeSeconderyAssociate, reqListBeforeSeconderyAssociate); + associateComponentInstancesForService(secondRequirementDef, serviceDetails_01, sdncDesignerDetails); + + CapReqDef capReqDefAfterSeconderyAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterSeconderyAssociate = capReqDefAfterSeconderyAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListAfterSeconderyAssociate = capReqDefAfterSeconderyAssociate.getRequirements() + .get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", null, + // reqListAfterSeconderyAssociate); + // AssertJUnit.assertEquals("Check capabilities", + // capListBeforeAssociate, capListAfterSeconderyAssociate); + getComponentAndValidateRIs(serviceDetails_01, 3, 2); + } + + private void updateCapabilitiesOwnerId(String oldUniqueId, List capList, String newUniqueId) { + serviceDetails_01.setUniqueId(newUniqueId); + for (CapabilityDefinition cap : capList) { + String oldOwnerId = cap.getOwnerId(); + String newOwnerId = oldOwnerId.replaceAll(oldUniqueId, newUniqueId); + cap.setOwnerId(newOwnerId); + } + } + + @Test + public void dissociateRelationNotFoundTest() throws Exception { + createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + String reqCompInstId = "1234"; + createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + String capCompInstId = "4567"; + + CapReqDef capReqDef = ComponentRestUtils.getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + List capList = capReqDef.getCapabilities().get(CAPABILITY_TYPE); + List reqList = capReqDef.getRequirements().get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capList, reqList); + + List variables = new ArrayList(); + variables.add(reqCompInstId); + variables.add(capCompInstId); + variables.add(REQUIREMENT_NAME); + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND, + 404, variables); + + CapReqDef capReqDefAfterDissociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterDissociate = capReqDefAfterDissociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListAfterDissociate = capReqDefAfterDissociate.getRequirements() + .get(CAPABILITY_TYPE); + + AssertJUnit.assertEquals("Check requirement", 1, reqListAfterDissociate.size()); + AssertJUnit.assertEquals("Check requirement", reqList, reqListAfterDissociate); + AssertJUnit.assertEquals("Check capabilities", capList, capListAfterDissociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + + } + + @Test + public void dissociateRelationInServiceNotFoundTest() throws Exception { + String uniqueId = "1234"; + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + serviceDetails_01.setUniqueId(uniqueId); + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.SERVICE_NOT_FOUND, 404, + new ArrayList(Arrays.asList(""))); + + } + + @Test + public void dissoicateRelationWhileInstanceNotFound() throws Exception { + String capUniqueId = "1234"; + + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + String capCompInstId = capUniqueId; + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + List variables = new ArrayList(); + variables.add(reqCompInstId); + variables.add(capCompInstId); + variables.add(REQUIREMENT_NAME); + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND, + 404, variables); + + CapReqDef capReqDefAfterDissociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListAfterDissociate = capReqDefAfterDissociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListAfterDissociate = capReqDefAfterDissociate.getRequirements() + .get(CAPABILITY_TYPE); + AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, reqListAfterDissociate); + AssertJUnit.assertEquals("Check capabilities", capListBeforeAssociate, capListAfterDissociate); + + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void dissociateWhileServiceCheckedinTest() throws Exception { + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESTRICTED_OPERATION, 409, + new ArrayList()); + } + + @Test + public void dissoicateWithEmptyUserIdHeaderTest() throws Exception { + sdncDesignerDetails.setUserId(""); + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESTRICTED_OPERATION, 409, + new ArrayList()); + } + + @Test + public void dissociateWithMissingUidOfServiceTest() throws Exception { + serviceDetails_01.setUniqueId(""); + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + RestResponse dissociateResp = ComponentInstanceRestUtils.dissociateInstances(requirementDef, + sdncDesignerDetails, serviceDetails_01.getUniqueId(), ComponentTypeEnum.SERVICE); + assertEquals(404, dissociateResp.getErrorCode().intValue()); + } + + @Test + public void relationDeletedAfterDeletingResourceInstanceTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + + RestResponse deleteVFInstance = deleteVFInstance(reqCompInstId, serviceDetails_01, sdncDesignerDetails); + ComponentInstanceRestUtils.checkDeleteResponse(deleteVFInstance); + getComponentAndValidateRIs(serviceDetails_01, 1, 0); + } + + @Test + public void relationNotFoundInSecondVersionAfterDissociateTest() throws Exception { + String oldContainerUniqueIdToReplace = serviceDetails_01.getUniqueId(); + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + dissociateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKOUT); + + updateExpectedReqCapAfterChangeLifecycleState(oldContainerUniqueIdToReplace, serviceDetails_01.getUniqueId()); + getComponentAndValidateRIs(serviceDetails_01, 2, 0); + } + + @Test + public void dissociateOnceAgainTest() throws Exception { + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + String reqCompInsName = ResponseParser + .convertComponentInstanceResponseToJavaObject(createFirstVFInstResp.getResponse()).getName(); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + String capCompInstName = ResponseParser + .convertComponentInstanceResponseToJavaObject(createSecondVFInstResp.getResponse()).getName(); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, CAPABILITY_TYPE, + REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + dissociateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + + List variables = new ArrayList(); + variables.add(reqCompInsName); + variables.add(capCompInstName); + variables.add(REQUIREMENT_NAME); + + dissoicateInstancesFail(requirementDef, sdncDesignerDetails, ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND, + 404, variables); + } + + // fail - bug : DE191707 + @Test + public void associateTwoRelations_CheckinCheckout_DissoicateOneRelationInSecondVersion() throws Exception { + String oldContainerUniqueIdToReplace = serviceDetails_01.getUniqueId(); + RestResponse createFirstVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createFirstVFInstResp); + RestResponse createSecondVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createSecondVFInstResp); + RestResponse createThirdVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + String secondReqCompInstId = ResponseParser.getUniqueIdFromResponse(createThirdVFInstResp); + + CapReqDef capReqDefBeforeAssociate = ComponentRestUtils + .getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, serviceDetails_01); + List capListBeforeAssociate = capReqDefBeforeAssociate.getCapabilities() + .get(CAPABILITY_TYPE); + List reqListBeforeAssociate = capReqDefBeforeAssociate.getRequirements() + .get(CAPABILITY_TYPE); + + RequirementCapabilityRelDef requirementDefFirstRelation = getReqCapRelation(reqCompInstId, capCompInstId, + CAPABILITY_TYPE, REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + RequirementCapabilityRelDef requirementDefSecondRelation = getReqCapRelation(secondReqCompInstId, capCompInstId, + CAPABILITY_TYPE, REQUIREMENT_NAME, capListBeforeAssociate, reqListBeforeAssociate); + + associateComponentInstancesForService(requirementDefFirstRelation, serviceDetails_01, sdncDesignerDetails); + associateComponentInstancesForService(requirementDefSecondRelation, serviceDetails_01, sdncDesignerDetails); + getComponentAndValidateRIs(serviceDetails_01, 3, 2); + + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKOUT); + String newContainerUniqueId = serviceDetails_01.getUniqueId(); + + // check if dissoicate of old relation is possibile + // dissoicateInstancesFail(requirementDefFirstRelation, + // sdncDesignerDetails, actionStatus, errorCode, variables); + getComponentAndValidateRIs(serviceDetails_01, 3, 2); + + requirementDefFirstRelation + .setFromNode(reqCompInstId.replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + requirementDefFirstRelation + .setToNode(reqCompInstId.replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + + dissociateComponentInstancesForService(requirementDefFirstRelation, serviceDetails_01, sdncDesignerDetails); + + // updateCapabilitiesOwnerId(oldContainerUniqueIdToReplace, + // capListBeforeAssociate, newContainerUniqueId); + // CapReqDef capReqDefAfterAssociate = + // ComponentRestUtils.getAndParseComponentRequirmentsCapabilities(sdncDesignerDetails, + // serviceDetails_01); + // List capListAfterAssociate = + // capReqDefAfterAssociate.getCapabilities().get(CAPABILITY_TYPE); + // List reqListAfterAssociate = + // capReqDefAfterAssociate.getRequirements().get(CAPABILITY_TYPE); + // AssertJUnit.assertEquals("Check requirement", reqListBeforeAssociate, + // reqListAfterAssociate); + // AssertJUnit.assertEquals("Check requirement", capListBeforeAssociate, + // capListAfterAssociate); + updateExpectedReqCapAfterChangeLifecycleState(oldContainerUniqueIdToReplace, serviceDetails_01.getUniqueId()); + getComponentAndValidateRIs(serviceDetails_01, 3, 1); + } + + @Test + public void createResourceInstancesAndUpdatedServiceMetadataTest() throws Exception, Exception { + serviceDetails_02.setUniqueId(serviceDetails_01.getUniqueId()); + createTwoCheckedinVFInstances(); + LifecycleRestUtils.changeResourceState(resourceDetailsCP_01, sdncDesignerDetails, "0.1", + LifeCycleStatesEnum.CHECKIN); + createVFInstanceAndAtomicResourceInstanceWithoutCheckin(resourceDetailsVF_01, resourceDetailsCP_01, + sdncDesignerDetails); + RestResponse updateServiceResp = ServiceRestUtils.updateService(serviceDetails_02, sdncDesignerDetails); + ServiceRestUtils.checkSuccess(updateServiceResp); + getComponentAndValidateRIs(serviceDetails_01, 4, 0); + } + + @Test(enabled = false) + public void forAcceptanceUserStory() throws Exception { + RestResponse createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String reqCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_02, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + String capCompInstId = ResponseParser.getUniqueIdFromResponse(createVFInstResp); + + String capType = CAPABILITY_TYPE; + String reqName = REQUIREMENT_NAME; + + RestResponse getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + ResourceRestUtils.checkSuccess(getResourceResponse); + CapReqDef capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List capList = capReqDef.getCapabilities().get(capType); + List reqList = capReqDef.getRequirements().get(capType); + + RequirementCapabilityRelDef requirementDef = getReqCapRelation(reqCompInstId, capCompInstId, capType, reqName, + capList, reqList); + + associateComponentInstancesForService(requirementDef, serviceDetails_01, sdncDesignerDetails); + getResourceResponse = ComponentRestUtils.getComponentRequirmentsCapabilities(sdncDesignerDetails, + serviceDetails_01); + capReqDef = ResponseParser.parseToObject(getResourceResponse.getResponse(), CapReqDef.class); + List list = capReqDef.getRequirements().get(capType); + AssertJUnit.assertEquals("Check requirement", null, list); + + serviceDetails_02.setUniqueId(serviceDetails_01.getUniqueId()); + RestResponse updateServiceResp = ServiceRestUtils.updateService(serviceDetails_02, sdncDesignerDetails); + ServiceRestUtils.checkSuccess(updateServiceResp); + changeServiceLifecycleState(serviceDetails_01, sdncDesignerDetails, LifeCycleStatesEnum.CHECKIN); + getComponentAndValidateRIs(serviceDetails_01, 2, 1); + } + + @Test + public void testUnsatisfiedCpReqInService() throws Exception { + + // Certify all the needed atomic resources + RestResponse response = LifecycleRestUtils.certifyResource(resourceDetailsCP_01); + ResourceRestUtils.checkSuccess(response); + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails, + resourceDetailsVF_02.getUniqueId()); + ResourceRestUtils.checkSuccess(response); + response = LifecycleRestUtils.certifyResource(resourceDetailsVF_02); + ResourceRestUtils.checkSuccess(response); + capOwnerId = getUniqueIdOfFirstInstanceFromResponse(response); + + RestResponse createAtomicResourceInstance = createVFInstance(serviceDetails_01, resourceDetailsVF_02, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String vfCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + createAtomicResourceInstance = createAtomicInstanceForService(serviceDetails_01, resourceDetailsCP_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createAtomicResourceInstance); + String compInstName = ResponseParser.getNameFromResponse(createAtomicResourceInstance); + String cpCompInstId = ResponseParser.getUniqueIdFromResponse(createAtomicResourceInstance); + + RestResponse submitForTesting = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + String[] variables = new String[] { serviceDetails_01.getName(), "service", "CP (Connection Point)", + compInstName, "requirement", "tosca.capabilities.network.Bindable", "fulfilled" }; + BaseValidationUtils.checkErrorResponse(submitForTesting, + ActionStatus.REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION, variables); + + fulfillCpRequirement(serviceDetails_01, cpCompInstId, vfCompInstId, capOwnerId, sdncDesignerDetails, + ComponentTypeEnum.SERVICE); + + submitForTesting = LifecycleRestUtils.changeServiceState(serviceDetails_01, sdncDesignerDetails, + LifeCycleStatesEnum.CERTIFICATIONREQUEST); + BaseValidationUtils.checkSuccess(submitForTesting); + } + + @Test + public void getVFInstanceSuccessfullyTest() throws Exception { + RestResponse createVFInstResp = createCheckedinVFInstance(serviceDetails_01, resourceDetailsVF_01, + sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + System.out.println("instance successfuly created"); + RestResponse getInstancesResponce = ComponentInstanceRestUtils.getComponentInstances(ComponentTypeEnum.SERVICE, + serviceDetails_01.getUniqueId(), sdncDesignerDetails); + + for (int i = 0; i < 1500; i++) { + createVFInstResp = createVFInstance(serviceDetails_01, resourceDetailsVF_01, sdncDesignerDetails); + ResourceRestUtils.checkCreateResponse(createVFInstResp); + System.out.println("instance " + i + "successfuly created"); + } + + getInstancesResponce = ComponentInstanceRestUtils.getComponentInstances(ComponentTypeEnum.SERVICE, + serviceDetails_01.getUniqueId(), sdncDesignerDetails); + + BaseValidationUtils.checkSuccess(getInstancesResponce); + + } + + private String getUniqueIdOfFirstInstanceFromResponse(RestResponse response) { + try { + JSONArray value = ResponseParser.getListFromJson(response, "componentInstances"); + return ResponseParser.getValueFromJsonResponse(value.get(0).toString(), "uniqueId"); + } catch (Exception e) { + return null; + } + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/UpdateServiceMetadataTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/UpdateServiceMetadataTest.java new file mode 100644 index 0000000000..2f5b47452e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/service/UpdateServiceMetadataTest.java @@ -0,0 +1,1984 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.service; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.codehaus.jettison.json.JSONException; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ServiceValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class UpdateServiceMetadataTest extends ComponentBaseTest { + + protected ArrayList listForMessage = new ArrayList(); + + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected User sdncDesignerDetails; + protected User sdncDesignerDetails2; + protected User sdncAdminDetails; + protected User sdncGovernorDeatails; + protected User sdncTesterDetails; + protected User sdncOpsDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected Component resourceDetailsVFCcomp; + protected Component serviceDetailsCompp; + + @Rule + public static TestName name = new TestName(); + protected ServiceReqDetails updatedServiceDetails; + + public UpdateServiceMetadataTest() { + super(name, UpdateServiceMetadataTest.class.getName()); + } + + @BeforeMethod + public void setUp() throws Exception { + + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncDesignerDetails2 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER2); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncAdminDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN4); + sdncGovernorDeatails = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + sdncTesterDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncOpsDetails = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + resourceDetailsVFCcomp = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, true, true); + + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true); + Service serviceServ = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp, serviceServ, UserRoleEnum.DESIGNER, true); + + serviceDetails = new ServiceReqDetails(serviceServ); + updatedServiceDetails = updatedServiceDetails(serviceDetails); + + } + + protected void certifyService(ServiceReqDetails serviceDetails, String version) throws Exception { + LifecycleRestUtils.certifyService(serviceDetails); + } + + protected ServiceReqDetails updatedServiceDetails(ServiceReqDetails service) { + ServiceReqDetails updatedServiceDetails = new ServiceReqDetails(service); + + updatedServiceDetails.setDescription("updatedDescription"); + updatedServiceDetails.setName(service.getName()); + updatedServiceDetails.setProjectCode("987654654"); + updatedServiceDetails.setIcon("icon-service-red3"); + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("updateTag", updatedServiceDetails.getName()))); + updatedServiceDetails.removeAllCategories(); + updatedServiceDetails.setCategories(null); + updatedServiceDetails.addCategory(ServiceCategoriesEnum.VOIP.getValue()); + updatedServiceDetails.setContactId("xy0123"); + + return updatedServiceDetails; + } + + protected void addMandatoryArtifactsToService() throws Exception { + // TODO Andrey US575052 + // ServiceRestUtils.addServiceMandatoryArtifacts(sdncDesignerDetails, + // createServiceResponse); + } + + protected void getServiceAndValidate(ServiceReqDetails excpectedService, User creator, User updater, LifecycleStateEnum lifeCycleState) throws Exception { + RestResponse getServiceResponse = ServiceRestUtils.getService(excpectedService.getUniqueId(), sdncDesignerDetails); + AssertJUnit.assertNotNull("check response object is not null after updating service", getServiceResponse); + AssertJUnit.assertNotNull("check if error code exists in response after updating service", getServiceResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after updating service", 200, getServiceResponse.getErrorCode().intValue()); + Service actualService = ResponseParser.convertServiceResponseToJavaObject(getServiceResponse.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(excpectedService, actualService, creator, updater, lifeCycleState); + } + + public void getServiceAndValidate(ServiceReqDetails excpectedService, LifecycleStateEnum lifecycleState) throws Exception { + getServiceAndValidate(excpectedService, sdncDesignerDetails, sdncDesignerDetails, lifecycleState); + } + + protected void validateResponse(RestResponse response, int errorCode, ActionStatus actionResponse, List listOfVariables) throws Exception { + AssertJUnit.assertNotNull("check response object is not null after updating service", response); + AssertJUnit.assertNotNull("check if error code exists in response after updating service", response.getErrorCode()); + AssertJUnit.assertEquals("Check response code after updating service", errorCode, response.getErrorCode().intValue()); + + if (actionResponse != null) { + ErrorValidationUtils.checkBodyResponseOnError(actionResponse.name(), listOfVariables, response.getResponse()); + return; + } + + Service actualService = ResponseParser.convertServiceResponseToJavaObject(response.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(updatedServiceDetails, actualService, sdncDesignerDetails, sdncDesignerDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + protected void validateActualVsExpected(ServiceReqDetails expectedService, RestResponse actualServiceFromResponse) { + Service actualService = ResponseParser.convertServiceResponseToJavaObject(actualServiceFromResponse.getResponse()); + ServiceValidationUtils.validateServiceResponseMetaData(updatedServiceDetails, actualService, sdncDesignerDetails, sdncDesignerDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + protected String multipleString(String ch, int repeat) { + return StringUtils.repeat(ch, repeat); + } + + protected void correctUpdate() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 200, null, listForMessage); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + protected void updateWithInvalidValue(ActionStatus invalidValue, List arr) throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, invalidValue, arr); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + protected void charactersInRangeChecking(int min, int max, String field) throws Exception { + if (field != null) { + if (field == "name") { + for (char ch = (char) min; ch <= (char) max; ch++) { + updatedServiceDetails.setName("testname" + String.valueOf(ch)); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + updateWithInvalidValue(ActionStatus.INVALID_COMPONENT_NAME, new ArrayList<>(Arrays.asList("Service"))); + } + } else if (field == "icon") { + for (char ch = (char) min; ch <= (char) max; ch++) { + updatedServiceDetails.setIcon("testname" + String.valueOf(ch)); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_ICON, new ArrayList<>(Arrays.asList("Service"))); + } + } else if (field == "tags") { + List variables = Arrays.asList("Service", "tag"); + for (char ch = (char) min; ch <= (char) max; ch++) { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(String.valueOf(ch), updatedServiceDetails.getName()))); + updateWithInvalidValue(ActionStatus.INVALID_FIELD_FORMAT, variables); + } + } else if (field == "category") { + for (char ch = (char) min; ch <= (char) max; ch++) { + updatedServiceDetails.addCategoryChain(multipleString("1", 5) + String.valueOf(ch), multipleString("1", 5) + String.valueOf(ch)); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CATEGORY, new ArrayList<>(Arrays.asList("Service"))); + } + } + + else if (field == "projectCode") { + for (char ch = (char) min; ch <= (char) max; ch++) { + updatedServiceDetails.setProjectCode(multipleString("1", 5) + String.valueOf(ch)); + updateWithInvalidValue(ActionStatus.INVALID_PROJECT_CODE, listForMessage); + } + } + + else + return; + } + + } + + protected void specialCharsChecking(String field) throws Exception { + charactersInRangeChecking(33, 44, field); + charactersInRangeChecking(47, 47, field); + charactersInRangeChecking(58, 64, field); + charactersInRangeChecking(91, 94, field); + charactersInRangeChecking(96, 96, field); + charactersInRangeChecking(123, 126, field); + } + + @Test + public void updateServiceSuccessfully() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 200, null, listForMessage); + + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + } + + protected void checkErrorResponse(ActionStatus actionStatus, ArrayList arrList, RestResponse response) throws Exception, JSONException { + ErrorValidationUtils.checkBodyResponseOnError(actionStatus.name(), arrList, response.getResponse()); + } + + protected List addServiceNameToTagsList(String serviceName, List tagsList) { + tagsList.add(serviceName); + return tagsList; + + } + + @Test + public void updateService_ByOtherDesigner() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails2); + validateResponse(updateServiceResponse, 409, ActionStatus.RESTRICTED_OPERATION, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void updateService_ByAdmin() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncAdminDetails); + validateResponse(updateServiceResponse, 409, ActionStatus.RESTRICTED_OPERATION, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void updateServiceNotExist() throws Exception { + updatedServiceDetails.setUniqueId("nnnnn"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 404, ActionStatus.SERVICE_NOT_FOUND, new ArrayList(Arrays.asList(""))); + } + + @Test + public void updateCheckedinService() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 409, ActionStatus.RESTRICTED_OPERATION, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + } + + @Test + public void updateCertifiedService() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 409, ActionStatus.RESTRICTED_OPERATION, listForMessage); + getServiceAndValidate(serviceDetails, sdncDesignerDetails, sdncAdminDetails, LifecycleStateEnum.CERTIFIED); + } + + // TODO Irrelevant + // @Test(enabled = false) + // public void updateService_NameCaseSensitiveTest() throws Exception { + // ServiceRestUtils.setServiceUniqueId(serviceDetails.getName().toUpperCase()); + // + // RestResponse updateServiceResponse = + // ServiceRestUtils.updateService(updatedServiceDetails, + // sdncDesignerDetails); + // validateResponse(updateServiceResponse, 200, null, listForMessage); + // + // Service serviceFromJsonResponse = + // ResponseParser.convertServiceResponseToJavaObject(updateServiceResponse.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(updatedServiceDetails, + // serviceFromJsonResponse, sdncDesignerDetails, (LifecycleStateEnum)null); + // + // getServiceAndValidate(updatedServiceDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // } + + // @Test + // public void updateApprovedDistributionServiceTest() throws Exception { + // // addMandatoryArtifactsToService(); + // certifyService(serviceDetails, serviceDetails.getVersion()); + // + // RestResponse approveResponse = + // ServiceRestUtils.sendApproveDistribution(sdncAdminDetails, + // serviceDetails.getUniqueId(), userRemarks); + // // validateResponse(approveResponse, 200, null, listForMessage); + // + // RestResponse updateServiceResponse = + // ServiceRestUtils.updateService(updatedServiceDetails, + // sdncDesignerDetails); + // validateResponse(updateServiceResponse, 409, + // ActionStatus.RESTRICTED_OPERATION, listForMessage); + // + // getServiceAndValidate(serviceDetails, sdncDesignerDetails, + // sdncAdminDetails,LifecycleStateEnum.CERTIFIED); + // } + + @Test + public void updateServiceByMethod_delete() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.createServiceByHttpMethod(updatedServiceDetails, sdncDesignerDetails, "DELETE", Urls.UPDATE_SERVICE_METADATA); + validateResponse(updateServiceResponse, 405, ActionStatus.NOT_ALLOWED, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void updateServiceByMethod_get() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.createServiceByHttpMethod(updatedServiceDetails, sdncDesignerDetails, "GET", Urls.UPDATE_SERVICE_METADATA); + validateResponse(updateServiceResponse, 405, ActionStatus.NOT_ALLOWED, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void updateServiceByMethod_post() throws Exception { + RestResponse updateServiceResponse = ServiceRestUtils.createServiceByHttpMethod(updatedServiceDetails, sdncDesignerDetails, "POST", Urls.UPDATE_SERVICE_METADATA); + validateResponse(updateServiceResponse, 405, ActionStatus.NOT_ALLOWED, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void updateCheckoutCertifiedService() throws Exception // certify a + // service + // and + // checkout + // it + { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED, listForMessage); + + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + // ---------------------------------------------------------Validation + // Tests--------------------------------------------------------- + + @Test + public void missingCategoryTest1() throws Exception { + List categories = updatedServiceDetails.getCategories(); + CategoryDefinition categoryDefinition = categories.get(0); + CategoryDefinition categoryDefinition2 = categoryDefinition; + categoryDefinition2.setName(""); + categories.set(0, categoryDefinition2); + updatedServiceDetails.setCategories(categories); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_CATEGORY, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingCategoryTest2() throws Exception { + updatedServiceDetails.setCategories(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_CATEGORY, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingServiceNameTest1() throws Exception { + updatedServiceDetails.setName(StringUtils.EMPTY); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.MISSING_COMPONENT_NAME, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingServiceNameTest2() throws Exception { + + updatedServiceDetails.setName(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.MISSING_COMPONENT_NAME, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + // TODO Irrelevant + @Test(enabled = false) + public void missingProjectCodeTest1() throws Exception { + updatedServiceDetails.setProjectCode(StringUtils.EMPTY); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.MISSING_PROJECT_CODE, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + // TODO Irrelevant + @Test(enabled = false) + public void missingProjectCodeTest2() throws Exception { + updatedServiceDetails.setProjectCode(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.MISSING_PROJECT_CODE, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingIconTest1() throws Exception { + updatedServiceDetails.setIcon(StringUtils.EMPTY); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_ICON, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingIconTest2() throws Exception { + updatedServiceDetails.setIcon(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_ICON, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingDescriptionTest1() throws Exception { + updatedServiceDetails.setDescription(StringUtils.EMPTY); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_DESCRIPTION, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingDescriptionTest2() throws Exception { + updatedServiceDetails.setDescription(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_DESCRIPTION, Arrays.asList("Service")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingTagsTest1() throws Exception { + updatedServiceDetails.setTags(new ArrayList()); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_TAGS, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingTagsTest2() throws Exception { + updatedServiceDetails.setTags(null); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.COMPONENT_MISSING_TAGS, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingTagsTest3() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(StringUtils.EMPTY))); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.INVALID_FIELD_FORMAT, Arrays.asList("Service", "tag")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void missingTagsTest4() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(StringUtils.EMPTY, updatedServiceDetails.getName()))); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse, 400, ActionStatus.INVALID_FIELD_FORMAT, Arrays.asList("Service", "tag")); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + // update non-settable/"updatable" parameters tests + + // ------------------------------------------correct + // values------------------------------------------ + @Test + public void contactIdValidationTest1() throws Exception { + updatedServiceDetails.setContactId("ab3456"); + correctUpdate(); + } + + @Test + public void contactIdValidationTest2() throws Exception { + + updatedServiceDetails.setContactId("cd789E"); + correctUpdate(); + } + + @Test + public void contactIdValidationTest3() throws Exception { + + updatedServiceDetails.setContactId("ef4567"); + correctUpdate(); + } + + @Test + public void contactIdValidationTest4() throws Exception { + updatedServiceDetails.setContactId("AA012A"); + correctUpdate(); + } + + @Test + public void contactIdValidationTest5() throws Exception { + updatedServiceDetails.setContactId("CD012c"); + correctUpdate(); + } + + @Test + public void contactIdValidationTest6() throws Exception { + updatedServiceDetails.setContactId("EF0123"); + correctUpdate(); + } + + // ------------------------------------------invalid + // values------------------------------------------ + @Test + public void contactIdValidationTest7() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + updatedServiceDetails.setContactId("ab0001"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void contactIdValidationTest8() throws Exception { + // addMandatoryArtifactsToService(); + + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser.convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + updatedServiceDetails = new ServiceReqDetails(certifyService); + updatedServiceDetails.setContactId("ab0001"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void contactIdValidationTest9() throws Exception { + updatedServiceDetails.setContactId("01345a"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, Arrays.asList("Service")); + } + + @Test + public void contactIdValidationTest10() throws Exception { + updatedServiceDetails.setContactId("0y000B"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, Arrays.asList("Service")); + } + + @Test + public void contactIdValidationTest11() throws Exception { + updatedServiceDetails.setContactId("Y1000b"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, Arrays.asList("Service")); + } + + @Test + public void contactIdValidationTest12() throws Exception { + updatedServiceDetails.setContactId("abxyzC"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, Arrays.asList("Service")); + } + + @Test + public void contactIdValidationTest13() throws Exception { + updatedServiceDetails.setContactId("cdXYZc"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest14() throws Exception { + updatedServiceDetails.setContactId("efXY1D"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest15() throws Exception { + updatedServiceDetails.setContactId("EFabcD"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest16() throws Exception { + updatedServiceDetails.setContactId("EFABCD"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest17() throws Exception { + updatedServiceDetails.setContactId("EFABC1"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest18() throws Exception { + updatedServiceDetails.setContactId("efui1D"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest19() throws Exception { + updatedServiceDetails.setContactId("efui1!"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest20() throws Exception { + updatedServiceDetails.setContactId("ef555!"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest21() throws Exception { + updatedServiceDetails.setContactId(",f555"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest22() throws Exception { + updatedServiceDetails.setContactId("EF55.5"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest23() throws Exception { + updatedServiceDetails.setContactId("ab000"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest24() throws Exception { + updatedServiceDetails.setContactId("ab000c0"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest25() throws Exception { + updatedServiceDetails.setContactId(" ab0001"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CONTACT, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void contactIdValidationTest26() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails.setContactId("xy0002"); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest1() throws Exception { + updatedServiceDetails.setName(multipleString("a", 49)); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest2() throws Exception { + updatedServiceDetails.setName(multipleString("b", 50)); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest3() throws Exception { + updatedServiceDetails.setName("testNamE"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest4() throws Exception { + updatedServiceDetails.setName("Testname"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest5() throws Exception { + updatedServiceDetails.setName("Test_name"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest6() throws Exception { + updatedServiceDetails.setName("Test name"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest7() throws Exception { + updatedServiceDetails.setName("Test-name"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest8() throws Exception { + updatedServiceDetails.setName("Test.name"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest9() throws Exception { + updatedServiceDetails.setName("...1..."); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest10() throws Exception { + updatedServiceDetails.setName("-a_1. Arrrrrr"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest11() throws Exception { + updatedServiceDetails.setName("Testname1234567890"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + correctUpdate(); + } + + @Test + public void serviceNameValidationTest14() throws Exception { + updatedServiceDetails.setName(StringUtils.SPACE); // one space with + // nothing + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + // updateWithInvalidValue(ActionStatus.INVALID_COMPONENT_NAME, new + // ArrayList<>(Arrays.asList("Service"))); + validateResponse(updateServiceResponse, 400, ActionStatus.MISSING_COMPONENT_NAME, new ArrayList<>(Arrays.asList("Service"))); + } + + // ------------------------------------------invalid + // values------------------------------------------ + @Test + public void serviceNameValidationTest12() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + updatedServiceDetails.setName("TestNamE"); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + } + + @Test + public void serviceNameValidationTest13() throws Exception { + updatedServiceDetails.setName(multipleString("c", 51)); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + updateWithInvalidValue(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, new ArrayList<>(Arrays.asList("Service", "50"))); + } + + @Test + public void serviceNameValidationTest15() throws Exception { + specialCharsChecking("name"); + } + + @Test + public void serviceNameValidationTest16() throws Exception { + // addMandatoryArtifactsToService(); + LifecycleRestUtils.certifyService(serviceDetails); + updatedServiceDetails.setName("testnamename"); + updatedServiceDetails.setCategories(serviceDetails.getCategories()); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + getServiceAndValidate(serviceDetails, sdncDesignerDetails, sdncTesterDetails, LifecycleStateEnum.CERTIFIED); + } + + @Test + public void serviceNameValidationTest17() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + updatedServiceDetails.setName("TestNamE"); + updatedServiceDetails.setCategories(serviceDetails.getCategories()); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + RestResponse updateServiceResponse2 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse2, 400, ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void serviceNameValidationTest18() throws Exception { + updatedServiceDetails.setName(" testname "); + updatedServiceDetails.setTags(addServiceNameToTagsList(updatedServiceDetails.getName(), updatedServiceDetails.getTags())); + RestResponse updateServiceResponse1 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse1); + assertNotNull(updateServiceResponse1.getErrorCode()); + assertEquals(200, updateServiceResponse1.getErrorCode().intValue()); + updatedServiceDetails.setName(updatedServiceDetails.getName()); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse1); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void iconValidationTest1() throws Exception { + updatedServiceDetails.setIcon(multipleString("a", 24)); + correctUpdate(); + } + + @Test + public void iconValidationTest2() throws Exception { + updatedServiceDetails.setIcon(multipleString("b", 25)); + correctUpdate(); + } + + @Test + public void iconValidationTest3() throws Exception { + updatedServiceDetails.setIcon("testNamE"); + correctUpdate(); + } + + @Test + public void iconValidationTest4() throws Exception { + updatedServiceDetails.setIcon("Testname"); + correctUpdate(); + } + + @Test + public void iconValidationTest5() throws Exception { + updatedServiceDetails.setIcon("Test_name"); + correctUpdate(); + } + + @Test + public void iconValidationTest6() throws Exception { + updatedServiceDetails.setIcon("Test-name"); + correctUpdate(); + } + + @Test + public void iconValidationTest7() throws Exception { + updatedServiceDetails.setIcon("Testname1234567890"); + correctUpdate(); + } + + @Test + public void iconValidationTest8() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + updatedServiceDetails.setIcon("TestNamE"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void iconValidationTest9() throws Exception { + // addMandatoryArtifactsToService(); + LifecycleRestUtils.certifyService(serviceDetails); + updatedServiceDetails.setIcon("testnamename"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + // ------------------------------------------invalid + // values------------------------------------------ + @Test + public void iconValidationTest10() throws Exception { + updatedServiceDetails.setIcon("Test name"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_ICON, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void iconValidationTest11() throws Exception { + updatedServiceDetails.setIcon(StringUtils.SPACE); // one space with + // nothing + updateWithInvalidValue(ActionStatus.COMPONENT_MISSING_ICON, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void iconValidationTest12() throws Exception { + updatedServiceDetails.setIcon("Test.name"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_ICON, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void iconValidationTest13() throws Exception { + specialCharsChecking("icon"); + charactersInRangeChecking(46, 46, "icon"); + } + + @Test + public void iconValidationTest14() throws Exception { + updatedServiceDetails.setIcon(multipleString("c", 26)); + updateWithInvalidValue(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, new ArrayList<>(Arrays.asList("Service", "25"))); + } + + @Test + public void iconValidationTest15() throws Exception { + // addMandatoryArtifactsToService(); + RestResponse certifyServiceResp = LifecycleRestUtils.certifyService(serviceDetails); + Service certifyServiceServ = ResponseParser.convertServiceResponseToJavaObject(certifyServiceResp.getResponse()); + ServiceReqDetails certifyService = new ServiceReqDetails(certifyServiceServ); + updatedServiceDetails = new ServiceReqDetails(certifyService); + updatedServiceDetails.setIcon("testnamename"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void iconValidationTest16() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails.setIcon("TestNamE"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED, listForMessage, updateServiceResponse); + } + + @Test + public void iconValidationTest17() throws Exception { + updatedServiceDetails.setIcon(" Icon "); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_ICON, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void categoryValidationTest1() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + updatedServiceDetails.addCategory(ServiceCategoriesEnum.VOIP.getValue()); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void categoryValidationTest2() throws Exception { + // updatedServiceDetails.addCategory("someCategory"); + updatedServiceDetails.setCategories(null); + updatedServiceDetails.addCategoryChain("someCategory", null); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CATEGORY, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void categoryValidationTest3() throws Exception { + updatedServiceDetails.setCategories(null); + updatedServiceDetails.addCategoryChain("SomeCategory10", null); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CATEGORY, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void categoryValidationTest4() throws Exception { + updatedServiceDetails.setCategories(null); + updatedServiceDetails.addCategoryChain("some Category", null); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_CATEGORY, new ArrayList<>(Arrays.asList("Service"))); + } + + @Test + public void categoryValidationTest5() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails.addCategory("Network L1-3"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void categoryValidationTest6() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails = serviceDetails; + List categories = updatedServiceDetails.getCategories(); + CategoryDefinition categoryDefinition = categories.get(0); + CategoryDefinition categoryDefinition2 = categoryDefinition; + categoryDefinition2.setName("ccc"); + categories.set(0, categoryDefinition2); + updatedServiceDetails.setCategories(categories); + RestResponse updateServiceResponse2 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + validateResponse(updateServiceResponse2, 400, ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED, listForMessage); + getServiceAndValidate(serviceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void categoryValidationTest7() throws Exception { + updatedServiceDetails.removeAllCategories(); + updatedServiceDetails.addCategory(ServiceCategoriesEnum.NETWORK_L3.getValue()); + correctUpdate(); + } + + @Test + public void categoryValidationTest8() throws Exception { + updatedServiceDetails.setCategories(null); + updatedServiceDetails.addCategoryChain("Network L1-3", null); + correctUpdate(); + } + + @Test + public void tagsValidationTest1() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(multipleString("a", 49), updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest2() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(multipleString("B", 50), updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest3() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(multipleString("A", 50), multipleString("B", 50), updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest5() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("testTaG", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest6() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Testtag", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest7() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Test_tag", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest8() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Test tag", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest9() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Test-tag", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest10() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Test.tag", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest11() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("...1...", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest12() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("-a_1. Arrrrrr", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest13() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("Testtag1234567890", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest14() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("1", "2", "2", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest15() throws Exception { + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKIN); + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("TestTaG", updatedServiceDetails.getName()))); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void tagsValidationTest16() throws Exception { + // addMandatoryArtifactsToService(); + LifecycleRestUtils.certifyService(serviceDetails); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("testtagtag", updatedServiceDetails.getName()))); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + checkErrorResponse(ActionStatus.RESTRICTED_OPERATION, listForMessage, updateServiceResponse); + } + + @Test + public void tagsValidationTest17() throws Exception { + // addMandatoryArtifactsToService(); + certifyService(serviceDetails, serviceDetails.getVersion()); + LifecycleRestUtils.changeServiceState(serviceDetails, sdncDesignerDetails, serviceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + updatedServiceDetails = new ServiceReqDetails(serviceDetails); + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList("TestTaG", updatedServiceDetails.getName()))); + correctUpdate(); + } + + @Test + public void tagsValidationTest18() throws Exception { + int lengthOfServiceName = updatedServiceDetails.getName().length(); + int maxLengthTag = 50; + int tagsCount = 1024 - lengthOfServiceName; + ArrayList tagsList = new ArrayList<>(); + tagsList.add(updatedServiceDetails.getName()); + while (tagsCount > maxLengthTag) { + tagsList.add(multipleString("a", maxLengthTag)); + tagsCount -= maxLengthTag + 1 + 1/* (50 and comma of each tag + one space, totally 52) */; + } + tagsList.add(multipleString("a", tagsCount)); + updatedServiceDetails.setTags(tagsList); + correctUpdate(); + } + + @Test + public void tagsValidationTest19() throws Exception { + updatedServiceDetails.setTags(new ArrayList<>(Arrays.asList(" Tag ", updatedServiceDetails.getName()))); + RestResponse updateServiceResponse1 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse1); + assertNotNull(updateServiceResponse1.getErrorCode()); + assertEquals(200, updateServiceResponse1.getErrorCode().intValue()); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse1); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void tagsValidationTest20() throws Exception { + ArrayList tagsList = new ArrayList<>(); + tagsList.add(updatedServiceDetails.getName()); + tagsList.add(""); + updatedServiceDetails.setTags(tagsList); + updateWithInvalidValue(ActionStatus.INVALID_FIELD_FORMAT, Arrays.asList("Service", "tag")); + } + + // ------------------------------------------invalid + // values------------------------------------------ + + @Test + public void tagsValidationTest21() throws Exception { + ArrayList tagsList = new ArrayList<>(); + tagsList.add("onetag"); + updatedServiceDetails.setTags(tagsList); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME, listForMessage); + + } + + @Test + public void tagsValidationTest22() throws Exception { + specialCharsChecking("tags"); + } + + @Test + public void descriptionValidationTest1() throws Exception { + updatedServiceDetails.setDescription(multipleString("a", 1023)); + correctUpdate(); + } + + @Test + public void descriptionValidationTest2() throws Exception { + updatedServiceDetails.setDescription(multipleString("a", 1024)); + correctUpdate(); + } + + @Test + public void descriptionValidationTest3() throws Exception { + updatedServiceDetails.setDescription(multipleString("aB", 1024 / 2)); + correctUpdate(); + } + + @Test + public void descriptionValidationTest4() throws Exception { + updatedServiceDetails.setDescription("1234567890"); + correctUpdate(); + } + + @Test + public void descriptionValidationTest5() throws Exception { + updatedServiceDetails.setDescription("desc ription"); + correctUpdate(); + } + + @Test + public void descriptionValidationTest6() throws Exception { + updatedServiceDetails.setDescription("desc\tription"); + RestResponse updateServiceResponse1 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse1); + assertNotNull(updateServiceResponse1.getErrorCode()); + assertEquals(200, updateServiceResponse1.getErrorCode().intValue()); + updatedServiceDetails.setDescription("desc ription"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse1); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest7() throws Exception { + updatedServiceDetails.setDescription("desc ription "); + RestResponse updateServiceResponse2 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse2); + assertNotNull(updateServiceResponse2.getErrorCode()); + assertEquals(200, updateServiceResponse2.getErrorCode().intValue()); + updatedServiceDetails.setDescription("desc ription"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse2); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest8() throws Exception { + updatedServiceDetails.setDescription("desc" + StringUtils.LF + "ription"); + RestResponse updateServiceResponse3 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse3); + assertNotNull(updateServiceResponse3.getErrorCode()); + assertEquals(200, updateServiceResponse3.getErrorCode().intValue()); + updatedServiceDetails.setDescription("desc ription"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse3); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest9() throws Exception { + updatedServiceDetails.setDescription("Hello, world!"); + RestResponse updateServiceResponse4 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse4); + assertNotNull(updateServiceResponse4.getErrorCode()); + assertEquals(200, updateServiceResponse4.getErrorCode().intValue()); + updatedServiceDetails.setDescription("Hello, world!"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse4); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest10() throws Exception { + updatedServiceDetails.setDescription("\uC2B5"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_DESCRIPTION, new ArrayList<>(Arrays.asList("Service"))); + + } + + @Test + public void descriptionValidationTest10_a() throws Exception { + updatedServiceDetails.setDescription("文"); + updateWithInvalidValue(ActionStatus.COMPONENT_INVALID_DESCRIPTION, new ArrayList<>(Arrays.asList("Service"))); + + } + + @Test + public void descriptionValidationTest10_b() throws Exception { + updatedServiceDetails.setDescription("\uC2B5"); + RestResponse updateServiceResponse5 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse5); + assertNotNull(updateServiceResponse5.getErrorCode()); + assertEquals(200, updateServiceResponse5.getErrorCode().intValue()); + updatedServiceDetails.setDescription("abc"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse5); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + } + + @Test + public void descriptionValidationTest11() throws Exception { + updatedServiceDetails.setDescription("&<>"); + RestResponse updateServiceResponse6 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse6); + assertNotNull(updateServiceResponse6.getErrorCode()); + assertEquals(200, updateServiceResponse6.getErrorCode().intValue()); + updatedServiceDetails.setDescription("&<>"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse6); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest12() throws Exception { + updatedServiceDetails.setDescription("文 test"); + RestResponse updateServiceResponse7 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse7); + assertNotNull(updateServiceResponse7.getErrorCode()); + assertEquals(200, updateServiceResponse7.getErrorCode().intValue()); + updatedServiceDetails.setDescription("test"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse7); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest13() throws Exception { + updatedServiceDetails.setDescription(" description"); + RestResponse updateServiceResponse8 = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse8); + assertNotNull(updateServiceResponse8.getErrorCode()); + assertEquals(200, updateServiceResponse8.getErrorCode().intValue()); + updatedServiceDetails.setDescription("description"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse8); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + @Test + public void descriptionValidationTest14() throws Exception { + updatedServiceDetails.setDescription(multipleString("a", 1025)); + updateWithInvalidValue(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, new ArrayList<>(Arrays.asList("Service", "1024"))); + } + + @Test + public void projectCodeValidationTest1() throws Exception { + String desc = StringUtils.EMPTY; + for (int i = 0; i < 10; i++) { + desc += Integer.toString(i); + if (i >= 4) { + updatedServiceDetails.setProjectCode(desc); + correctUpdate(); + } + } + } + + @Test + public void projectCodeValidationTest2() throws Exception { + updatedServiceDetails.setProjectCode(multipleString("1", 6)); + correctUpdate(); + } + + @Test + public void projectCodeValidationTest3() throws Exception { + this.specialCharsChecking("projectCode"); + } + + // TODO Irrelevant + @Test(enabled = false) + public void projectCodeValidationTest4() throws Exception { + updatedServiceDetails.setProjectCode(multipleString(" ", 5) + "99999"); + RestResponse updateServiceResponse = ServiceRestUtils.updateService(updatedServiceDetails, sdncDesignerDetails); + assertNotNull(updateServiceResponse); + assertNotNull(updateServiceResponse.getErrorCode()); + assertEquals(200, updateServiceResponse.getErrorCode().intValue()); + updatedServiceDetails.setProjectCode("12345"); + validateActualVsExpected(updatedServiceDetails, updateServiceResponse); + getServiceAndValidate(updatedServiceDetails, LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + + } + + @Test + public void projectCodeValidationTest5() throws Exception { + updatedServiceDetails.setProjectCode(multipleString("0", 11)); + updateWithInvalidValue(ActionStatus.INVALID_PROJECT_CODE, listForMessage); + } + + @Test + public void projectCodeValidationTest6() throws Exception { + updatedServiceDetails.setProjectCode(multipleString("1", 4)); + updateWithInvalidValue(ActionStatus.INVALID_PROJECT_CODE, listForMessage); + } + + @Test + public void projectCodeValidationTest7() throws Exception { + updatedServiceDetails.setProjectCode("123456789"); + correctUpdate(); + } + + // ////US553874 + // @JsonIgnore + // @Test + // public void UpdateServiceVersion01_isVNF_toTrue() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to True + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 200, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion02_isVNF_toFalse() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to True + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 200, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion01_isVNF_TrueToNull() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to True + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 400, restResponse.getErrorCode().intValue()); + // List variables = Arrays.asList("VNF Service Indicator"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_DATA.name(), + // variables, restResponse.getResponse()); + // + // //get service and verify that service created with isVNF is remained with + // isVNF = true + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion01_isVNF_FalseToNull() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to True + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 400, restResponse.getErrorCode().intValue()); + // List variables = Arrays.asList("VNF Service Indicator"); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.MISSING_DATA.name(), + // variables, restResponse.getResponse()); + // + // //get service and verify that service created with isVNF is remained with + // isVNF = true + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion02_IsVNF_toTrue() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // LifecycleRestUtils.changeServiceState(serviceDetails, + // sdncDesignerDetails, serviceDetails.getVersion(), + // LifeCycleStatesEnum.CHECKIN); + // LifecycleRestUtils.changeServiceState(serviceDetails, + // sdncDesignerDetails, serviceDetails.getVersion(), + // LifeCycleStatesEnum.CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to True + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 200, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion02_IsVNF_toFalse() throws Exception{ + // + // //choose the user to create service + // User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // LifecycleRestUtils.changeServiceState(serviceDetails, + // sdncDesignerDetails, serviceDetails.getVersion(), + // LifeCycleStatesEnum.CHECKIN); + // LifecycleRestUtils.changeServiceState(serviceDetails, + // sdncDesignerDetails, serviceDetails.getVersion(), + // LifeCycleStatesEnum.CHECKOUT); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + // + // //Update Service IsVNF to false + // restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // //restResponse = + // ServiceRestUtils.updateService(serviceDetails.getUniqueId(), + // serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 200, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion11_IsVNF_toFalse() throws Exception{ + // // Can't update isVNF when service version is 1.X + // User sdncUserDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // //String serviceUniqueName = + // ServiceRestUtils.getServiceUniqueId(serviceByNameAndVersion); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, "0.1", + // sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + //// ServiceRestUtils.addServiceMandatoryArtifacts(sdncUserDetails, + // restResponse); + // RestResponse response = + // ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + // sdncUserDetails, serviceDetails.getUniqueId(), + // ComponentTypeEnum.SERVICE); + // assertTrue("response code is not 201, returned: " + + // response.getErrorCode(),response.getErrorCode() == 201); + // RestResponse changeServiceState = + // LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + // assertTrue("certify service request returned status:" + + // changeServiceState.getErrorCode(),changeServiceState.getErrorCode() == + // 200); + // LifecycleRestUtils.changeServiceState(serviceDetails, sdncUserDetails, + // LifeCycleStatesEnum.CHECKOUT); + // + // //Update Service IsVNF to false + // restResponse = ServiceRestUtils.updateService(serviceDetails, + // sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating service metadata", 400, + // restResponse.getErrorCode().intValue()); + // List variables = new ArrayList(); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_IS_VNF_CANNOT_BE_CHANGED.name(), + // variables, restResponse.getResponse()); + // + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "1.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // + // } + // + // @JsonIgnore + // @Test + // public void UpdateServiceVersion11_IsVNF_toTrue() throws Exception{ + // // Can't update isVNF when service version is 1.X + // User sdncUserDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // // new service details + // // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // // clean audit DB before updating service + // DbUtils.cleanAllAudits(); + // ServiceRestUtils.deleteServiceById(serviceDetails.getUniqueId(), + // sdncUserDetails.getUserId()); + // serviceDetails = ElementFactory.getDefaultService(); + // + // //send create service toward BE + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating Interface Artifact", + // 201, restResponse.getErrorCode().intValue()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // RestResponse serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "0.1"); + // Service serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // //String serviceUniqueName = + // ServiceRestUtils.getServiceUniqueId(serviceByNameAndVersion); + // + // //validate audit + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceValidationUtils.constructFieldsForAuditValidation(serviceDetails, + // "0.1", sdncUserDetails); + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + //// ServiceRestUtils.addServiceMandatoryArtifacts(sdncUserDetails, + // restResponse); + // RestResponse response = + // ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, + // sdncUserDetails, serviceDetails.getUniqueId(), + // ComponentTypeEnum.SERVICE); + // assertTrue("response code is not 201, returned: " + + // response.getErrorCode(),response.getErrorCode() == 201); + // RestResponse changeServiceState = + // LCSbaseTest.certifyService(serviceDetails, sdncDesignerDetails); + // assertTrue("certify service request returned status:" + + // changeServiceState.getErrorCode(),changeServiceState.getErrorCode() == + // 200); + // LifecycleRestUtils.changeServiceState(serviceDetails, sdncUserDetails, + // LifeCycleStatesEnum.CHECKOUT); + // + // //Update Service IsVNF to false + // restResponse = ServiceRestUtils.updateService(serviceDetails, + // sdncUserDetails); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after updating service metadata", 400, + // restResponse.getErrorCode().intValue()); + // List variables = new ArrayList(); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.SERVICE_IS_VNF_CANNOT_BE_CHANGED.name(), + // variables, restResponse.getResponse()); + // + // //get service and verify that service created with isVNF defined in + // serviceDetails + // serviceByNameAndVersion = + // ServiceRestUtils.getServiceByNameAndVersion(sdncUserDetails, + // serviceDetails.getName(), "1.1"); + // serviceObject = + // ResponseParser.convertServiceResponseToJavaObject(serviceByNameAndVersion.getResponse()); + // ServiceValidationUtils.validateServiceResponseMetaData(serviceDetails, + // serviceObject, sdncUserDetails, + // LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + // } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/ActivateDeActivateDeleteUser.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/ActivateDeActivateDeleteUser.java new file mode 100644 index 0000000000..c83018241b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/ActivateDeActivateDeleteUser.java @@ -0,0 +1,832 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.user; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.HttpStatus; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedUserCRUDAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.users.UserResponseMessageEnum; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.CatalogRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ImportRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.UserRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ResourceValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.UserValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.google.gson.reflect.TypeToken; + +/** + * @author alitvinsky + * + */ +public class ActivateDeActivateDeleteUser extends ComponentBaseTest { + private static Logger logger = LoggerFactory.getLogger(ActivateDeActivateDeleteUser.class.getName()); + protected Gson gson = new Gson(); + protected User sdncAdminUser; + + @BeforeMethod + public void init() { + sdncAdminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + } + + @Rule + public static TestName name = new TestName(); + + public ActivateDeActivateDeleteUser() { + super(name, ActivateDeActivateDeleteUser.class.getName()); + } + + @Test + public void authorizeDeActivatedUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + AssertJUnit.assertEquals("Check response code after deActive user", errorInfo.getCode(), + getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + // clean audit before authorization test + DbUtils.cleanAllAudits(); + + // Perform login from WebSeal + User sealUserDetails = sdncUserDetails; + RestResponse authorizedUserResponse = UserRestUtils.authorizedUserTowardsCatalogBeQA(sealUserDetails); + + // validate response + + ErrorInfo errorInfo2 = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_ACCESS.name()); + + AssertJUnit.assertNotNull("check response object is not null after user login", authorizedUserResponse); + AssertJUnit.assertNotNull("check error code exists in response after user login", + authorizedUserResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after deActive user", errorInfo2.getCode(), + authorizedUserResponse.getErrorCode()); + + List variables2 = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESTRICTED_ACCESS.name(), variables2, + authorizedUserResponse.getResponse()); + + // validate against ES DB + + UserValidationUtils.validateDataAgainstAuditDB_access(sealUserDetails, + DbUtils.parseAuditRespByAction("Access"), authorizedUserResponse, errorInfo2, variables2); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + public User getDefaultUserDetails() { + + String httpCspUserId = "km2000"; + String userFirstName = "Kot"; + String userLastName = "May"; + String email = "km2000@intl.sdc.com"; + String role = UserRoleEnum.ADMIN.name(); + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + return sdncUserDetails; + } + + public void validateSuccessCreateUserResponse(User sdncUserDetails, RestResponse createUserResponse) + throws Exception { + + AssertJUnit.assertNotNull("check response object is not null after create user", createUserResponse); + AssertJUnit.assertNotNull("check error code exists in response after create user", + createUserResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create user", HttpStatus.SC_CREATED, + createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + // UserRestUtils.validateAddUserAuditMessage(sdncUserDetails, + // sdncAdminUser, String.valueOf(HttpStatus.SC_CREATED), + // UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + // UserRestUtils.getAddUserAuditMessage("AddUser")); + String addUser = "AddUser"; + ExpectedUserCRUDAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(addUser, + sdncAdminUser, ActionStatus.CREATED, sdncUserDetails, null); + AuditValidationUtils.validateAddUserAudit(constructFieldsForAuditValidation, addUser); + + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + + } + + public void validateSuccessDeActivateUserResponse(User sdncUserDetails, RestResponse deActivateUserResponse) + throws Exception { + + AssertJUnit.assertNotNull("check response object is not null after deActive user", deActivateUserResponse); + AssertJUnit.assertNotNull("check error code exists in response after deActive user", + deActivateUserResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after deActive user", 200, + deActivateUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, deActivateUserResponse.getResponse()); + + String deleteUser = "DeleteUser"; + ExpectedUserCRUDAudit constructFieldsForAuditValidation = Convertor + .constructFieldsForAuditValidation(deleteUser, sdncAdminUser, ActionStatus.OK, null, sdncUserDetails); + AuditValidationUtils.validateAddUserAudit(constructFieldsForAuditValidation, deleteUser); + + } + + // US498322 - Add Status Field to USER + + @Test + public void createNewUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + @Test + public void createDefaultUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + sdncUserDetails.setFirstName(null); + sdncUserDetails.setLastName(null); + sdncUserDetails.setEmail(null); + sdncUserDetails.setRole(null); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + @Test + public void createTesterUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + sdncUserDetails.setLastName(null); + sdncUserDetails.setRole(UserRoleEnum.TESTER.name()); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + @Test + public void deActivateCreatedAdminUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + assertEquals("Check response code after get user", errorInfo.getCode(), getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + @Test + public void deActivateTheSameUserTwice() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + assertEquals("Check response code after deActive user", errorInfo.getCode(), + getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + // deActivate the same user once time more + RestResponse deActivateUserResponse2 = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + ErrorInfo errorInfo2 = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + assertEquals("Check response code after deActive user", errorInfo2.getCode(), + deActivateUserResponse2.getErrorCode()); + + List variables2 = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables2, + deActivateUserResponse2.getResponse()); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + @Test + public void createAgainDeActivatedUser() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + + try { + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + assertEquals("Check response code after deActive user", errorInfo.getCode(), + getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + // create the user with the same UserId(details) as deActivated user + DbUtils.cleanAllAudits(); + + RestResponse createUserResponse2 = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + ErrorInfo errorInfo2 = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + assertEquals("Check response code after deActive user", errorInfo2.getCode(), + createUserResponse2.getErrorCode()); + + List variables2 = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables2, + createUserResponse2.getResponse()); + + } finally { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + // very not recommend to run this test, resources/services may be zombie + // @Test + public void deActivateLastAdminUser() throws Exception { + + try { + + // send get all ADMIN user request toward BE + RestResponse getAllAdminUsers = UserRestUtils.getAllAdminUsers(sdncAdminUser); + + assertNotNull("check response object is not null after create user", getAllAdminUsers); + assertNotNull("check error code exists in response after create user", getAllAdminUsers.getErrorCode()); + assertEquals("Check response code after create user", 200, getAllAdminUsers.getErrorCode().intValue()); + + TypeToken> typeToken = new TypeToken>() { + }; + List listOfUsersOnResponse = gson.fromJson(getAllAdminUsers.getResponse(), typeToken.getType()); + logger.debug("listOfUsers: {}", listOfUsersOnResponse); + + // build map of all Admin users from listOfUsersOnResponse from + // response + Map mapAllUsersOnResponse = new HashMap(); + for (User sdncUser : listOfUsersOnResponse) { + mapAllUsersOnResponse.put(sdncUser.getUserId(), sdncUser); + } + + // remove from mapAllUsersOnResponse map one of admin users + mapAllUsersOnResponse.remove(sdncAdminUser.getUserId()); + logger.debug("map Of all Admin users exclude one : {}", mapAllUsersOnResponse); + + // deActivate all Admin users from the userIdAllAdminList list + for (Entry entry : mapAllUsersOnResponse.entrySet()) { + UserRestUtils.deActivateUser(entry.getValue(), sdncAdminUser); + } + + // deActivate last Admin user user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncAdminUser, sdncAdminUser); + + ErrorInfo errorInfo = ErrorValidationUtils + .parseErrorConfigYaml(ActionStatus.DELETE_USER_ADMIN_CONFLICT.name()); + + assertEquals("Check response code after deActive user", errorInfo.getCode(), + deActivateUserResponse.getErrorCode()); + + List variables = Arrays.asList(); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.DELETE_USER_ADMIN_CONFLICT.name(), variables, + deActivateUserResponse.getResponse()); + + } finally { + // UserRestUtils.deleteUser(UserRestUtils.getAdminDetails2(), + // sdncAdminUser); + // UserRestUtils.deleteUser(UserRestUtils.getAdminDetails3(), + // sdncAdminUser); + // UserRestUtils.createUser(UserRestUtils.getAdminDetails2(), + // sdncAdminUser); + // UserRestUtils.createUser(UserRestUtils.getAdminDetails3(), + // sdncAdminUser); + } + + } + + // test check the resource accessibility via catalog view, resource was + // created by user which was deActivated + + @Test + public void resourceAccessibility() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource("tosca.nodes.newresource4test4", + NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, "jh0003"); + String resourceBaseVersion = "0.1"; + + try { + // Delete resource + // resourceUtils.deleteResource_allVersions(resourceDetails, + // sdncAdminUser); + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + + DbUtils.cleanAllAudits(); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // ------------------------Start create + // resource--------------------------------------------------------------------------------- + + // create resource + RestResponse createResponse = ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + assertEquals("Check response code after create", 201, createResponse.getErrorCode().intValue()); + + Resource createdResource = ResponseParser.convertResourceResponseToJavaObject(createResponse.getResponse()); + + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncUserDetails, + createdResource.getUniqueId()); + assertEquals("Check response code after get", 200, resourceGetResponse.getErrorCode().intValue()); + + // validate get response + ResourceRespJavaObject resourceRespJavaObject = Convertor.constructFieldsForRespValidation(resourceDetails, + resourceBaseVersion); + resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setAbstractt("false"); + resourceRespJavaObject.setCreatorUserId(sdncUserDetails.getUserId()); + resourceRespJavaObject.setLastUpdaterUserId(sdncUserDetails.getUserId()); + + resourceRespJavaObject + .setCreatorFullName(sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName()); + resourceRespJavaObject + .setLastUpdaterFullName(sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName()); + + ResourceValidationUtils.validateResp(resourceGetResponse, resourceRespJavaObject); + + // ------------------------End create + // resource--------------------------------------------------------------------------------- + + // clean audit before authorization test + DbUtils.cleanAllAudits(); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + UserValidationUtils.validateDeleteUserAuditMessage(sdncUserDetails, sdncAdminUser, "200", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("DeleteUser")); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + assertEquals("Check response code after deActive user", errorInfo.getCode(), + getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + // checking if created resource is accessible + DbUtils.cleanAllAudits(); + + RestResponse getCatalogDataResponse = CatalogRestUtils.getCatalog(sdncAdminUser.getUserId()); + + // validate response + + assertNotNull("check response object is not null after user login", getCatalogDataResponse); + assertNotNull("check error code exists in response after user login", + getCatalogDataResponse.getErrorCode()); + assertEquals("Check response code after deActive user", 200, + getCatalogDataResponse.getErrorCode().intValue()); + + // expected resource list + List resourceExpectedUniqIdList = new ArrayList(); + resourceExpectedUniqIdList.add(resourceDetails.getUniqueId()); + logger.debug("resourceExpectedUniqIdList: {}", resourceExpectedUniqIdList); + + compareResourceUniqIdList(getCatalogDataResponse.getResponse(), resourceExpectedUniqIdList, true); + + } finally { + // resourceUtils.deleteResource_allVersions(resourceDetails, + // sdncAdminUser); + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + // test check the resource accessibility via catalog view, resource was + // created by user which was deActivated + + @Test + public void resourceAccessibilityOnImport() throws Exception { + + User sdncUserDetails = getDefaultUserDetails(); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource("importResource4test", + NormativeTypesEnum.ROOT, ResourceCategoryEnum.NETWORK_L2_3_ROUTERS, "jh0003"); + resourceDetails.addCategoryChain(ResourceCategoryEnum.GENERIC_DATABASE.getCategory(), + ResourceCategoryEnum.GENERIC_DATABASE.getSubCategory()); + // String resourceBaseVersion = "1.0"; + + try { + // Delete resource + // resourceUtils.deleteResource_allVersions(resourceDetails, + // sdncAdminUser); + RestResponse deleteUserResponse = UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + assertTrue("delete user request failed", + deleteUserResponse.getErrorCode() == 200 || deleteUserResponse.getErrorCode() == 404); + DbUtils.cleanAllAudits(); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + + // ------------------------Start import + // resource--------------------------------------------------------------------------------- + + // import new resource with CERTIFIED state + User importer = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN4); + RestResponse importResponse = ImportRestUtils.importResourceByName(resourceDetails, importer); + + assertNotNull("check response object is not null after create user", importResponse); + assertNotNull("check error code exists in response after create user", importResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, importResponse.getErrorCode().intValue()); + + // ------------------------End import + // resource--------------------------------------------------------------------------------- + + // clean audit before authorization test + DbUtils.cleanAllAudits(); + + // deActivate created user + RestResponse deActivateUserResponse = UserRestUtils.deActivateUser(sdncUserDetails, sdncAdminUser); + sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + validateSuccessDeActivateUserResponse(sdncUserDetails, deActivateUserResponse); + + UserValidationUtils.validateDeleteUserAuditMessage(sdncUserDetails, sdncAdminUser, "200", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("DeleteUser")); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + + assertEquals("Check response code after deActive user", errorInfo.getCode(), + getUserResponse.getErrorCode()); + + List variables = Arrays.asList(sdncUserDetails.getUserId()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), variables, + getUserResponse.getResponse()); + + // checking if created resource is accessible + DbUtils.cleanAllAudits(); + + RestResponse getCatalogDataResponse = CatalogRestUtils.getCatalog(sdncAdminUser.getUserId()); + + // validate response + + assertNotNull("check response object is not null after user login", getCatalogDataResponse); + assertNotNull("check error code exists in response after user login", + getCatalogDataResponse.getErrorCode()); + assertEquals("Check response code after deActive user", 200, + getCatalogDataResponse.getErrorCode().intValue()); + + // expected resource list + List resourceExpectedUniqIdList = new ArrayList(); + resourceExpectedUniqIdList.add(resourceDetails.getUniqueId()); + logger.debug("resourceExpectedUniqIdList: {}", resourceExpectedUniqIdList); + + compareResourceUniqIdList(getCatalogDataResponse.getResponse(), resourceExpectedUniqIdList, true); + + } finally { + // resourceUtils.deleteResource_allVersions(resourceDetails, + // sdncAdminUser); + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + } + + } + + // test check the service accessibility via catalog view, service was + // created by user which was deActivated + + // @Test + // public void serviceAccessibility() throws Exception{ + // + // User sdncUserDetails = getDefaultUserDetails(); + //// fill new service details + // ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + // String serviceBaseVersion = "0.1"; + // + // try{ + // //Delete service + //// ServiceRestUtils.deleteService_allVersions(serviceDetails, + // sdncAdminUser); + // UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + // + // DbUtils.cleanAllAudits(); + // RestResponse createUserResponse = + // UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + // validateSuccessCreateUserResponse(sdncUserDetails, createUserResponse); + // + //// ------------------------Start create + // service--------------------------------------------------------------------------------- + // RestResponse restResponse = + // ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + // + // assertNotNull("check response object is not null after create service", + // restResponse); + // assertNotNull("check error code exists in response after create service", + // restResponse.getErrorCode()); + // assertEquals("Check response code after create service", 201, + // restResponse.getErrorCode().intValue()); + // + //// validate create service response vs actual + // + // Service service = + // ServiceRestUtils.convertServiceResponseToJavaObject(restResponse.getResponse()); + // UserValidationUtils.validateServiceResponseMetaData(serviceDetails,service,sdncUserDetails, + // (LifecycleStateEnum)null); + // + //// validate get service response vs actual + // restResponse = ServiceRestUtils.getService(serviceDetails.getUniqueId(), + // sdncUserDetails); + // service = + // ServiceRestUtils.convertServiceResponseToJavaObject(restResponse.getResponse()); + // UserValidationUtils.validateServiceResponseMetaData(serviceDetails,service,sdncUserDetails, + // (LifecycleStateEnum)null); + // + // //validate audit + // + // ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + // ServiceRestUtils.constructFieldsForAuditValidation(serviceDetails, + // serviceBaseVersion, sdncUserDetails); + // + // String auditAction="Create"; + // expectedResourceAuditJavaObject.setAction(auditAction); + // expectedResourceAuditJavaObject.setPrevState(""); + // expectedResourceAuditJavaObject.setPrevVersion(""); + // expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + // expectedResourceAuditJavaObject.setStatus("201"); + // expectedResourceAuditJavaObject.setDesc("OK"); + // + // AuditValidationUtils.validateAudit(expectedResourceAuditJavaObject, + // auditAction, null, false); + // + //// ------------------------End create + // service--------------------------------------------------------------------------------- + // + //// clean audit before authorization test + // DbUtils.cleanAllAudits(); + // + //// deActivate created user + // RestResponse deActivateUserResponse = + // UserRestUtils.deActivateUser(sdncUserDetails,sdncAdminUser); + // sdncUserDetails.setStatus(UserStatusEnum.INACTIVE); + // validateSuccessDeActivateUserResponse(sdncUserDetails, + // deActivateUserResponse); + // + // UserValidationUtils.validateDeleteUserAuditMessage(sdncUserDetails, + // sdncAdminUser, "200", UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + // UserValidationUtils.getAddUserAuditMessage("DeleteUser")); + // + // ErrorInfo errorInfo = + // ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_INACTIVE.name()); + // RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, + // sdncAdminUser); + // + // assertEquals("Check response code after deActive user", + // errorInfo.getCode(), getUserResponse.getErrorCode()); + // + // List variables = Arrays.asList(sdncUserDetails.getUserId()); + // ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.USER_INACTIVE.name(), + // variables, getUserResponse.getResponse()); + // + // //checking if created service is accessible + // DbUtils.cleanAllAudits(); + // + // RestResponse getCatalogDataResponse = + // CatalogRestUtils.getCatalog(sdncAdminUser.getUserId()); + // + // //validate response + // + // assertNotNull("check response object is not null after user login", + // getCatalogDataResponse); + // assertNotNull("check error code exists in response after user login", + // getCatalogDataResponse.getErrorCode()); + // assertEquals("Check response code after deActive user", 200, + // getCatalogDataResponse.getErrorCode().intValue()); + // + //// expected service list + // List serviceExpectedUniqIdList= new ArrayList(); + // serviceExpectedUniqIdList.add(serviceDetails.getUniqueId()); + // logger.debug("serviceExpectedUniqIdList: {}", serviceExpectedUniqIdList); + // + // compareServiceUniqIdList(getCatalogDataResponse.getResponse(), + // serviceExpectedUniqIdList, true); + // + // + // }finally{ + //// ServiceRestUtils.deleteService_allVersions(serviceDetails, + // sdncAdminUser); + // UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + // } + // + // } + + public void compareServiceUniqIdList(String response, List expectedList, boolean flag) { + + JsonElement jelement = new JsonParser().parse(response); + JsonObject jobject = jelement.getAsJsonObject(); + JsonArray serviceArray = (JsonArray) jobject.get("services"); + logger.debug("{}", serviceArray); + assertTrue("expected service count: " + expectedList.size() + " or more" + ", actual: " + serviceArray.size(), + serviceArray.size() >= expectedList.size()); + + // build service list from response + List serviceReqDetailsListOnResponse = new ArrayList(); + for (int i = 0; i < serviceArray.size(); i++) { + ServiceReqDetails json = gson.fromJson(serviceArray.get(i), ServiceReqDetails.class); + serviceReqDetailsListOnResponse.add(json); + } + } + + public void compareResourceUniqIdList(String response, List expectedList, boolean flag) { + + JsonElement jelement = new JsonParser().parse(response); + JsonObject jobject = jelement.getAsJsonObject(); + JsonArray resourceArray = (JsonArray) jobject.get("resources"); + logger.debug("{}", resourceArray); + assertTrue("expected resource count: " + expectedList.size() + " or more" + ", actual: " + resourceArray.size(), + resourceArray.size() >= expectedList.size()); + + // build resource list from response + List resourceReqDetailsListOnResponse = new ArrayList(); + for (int i = 0; i < resourceArray.size(); i++) { + ResourceReqDetails json = gson.fromJson(resourceArray.get(i), ResourceReqDetails.class); + resourceReqDetailsListOnResponse.add(json); + } + + logger.debug("ResourceReqDetails list on response: {}", resourceReqDetailsListOnResponse); + + List resourceActualUniqIdList = new ArrayList(); + for (ResourceReqDetails resource : resourceReqDetailsListOnResponse) { + resourceActualUniqIdList.add(resource.getUniqueId()); + } + logger.debug("resourceActualUniqIdList on response: {}", resourceActualUniqIdList); + logger.debug("resourceExpectedUniqIdList on response: {}", expectedList); + + if (flag) { + assertTrue("actual list does not contain expected list", + resourceActualUniqIdList.containsAll(expectedList)); + } else { + assertFalse("actual list contains non expected list elements", + resourceActualUniqIdList.containsAll(expectedList)); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/CreateUserApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/CreateUserApiTest.java new file mode 100644 index 0000000000..8684910a18 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/CreateUserApiTest.java @@ -0,0 +1,1451 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.user; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedUserCRUDAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.users.UserResponseMessageEnum; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.Convertor; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.UserRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.UserValidationUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.AfterMethod; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class CreateUserApiTest extends ComponentBaseTest { + + protected User sdncAdminUser; + protected User sdncDesignerUser; + protected User sdncGovernorUser; + protected User sdncTesterUser; + + public static final int STATUS_CODE_SUCCESS = 200; + public static final int STATUS_CODE_SUCSESS_CREATED = 201; + public static final int STATUS_CODE_SUCCESS_DELETE_GET = 200; + public static final int STATUS_CODE_INVALID_CONTENT = 400; + public static final int STATUS_CODE_MISSING_DATA = 400; + public static final int STATUS_CODE_MISSING_INFORMATION = 403; + public static final int STATUS_CODE_RESTRICTED_ACCESS = 403; + public static final int STATUS_CODE_NOT_FOUND = 404; + public static final int STATUS_CODE_RESTRICTED_OPERATION = 409; + public static final int USER_ALREADY_EXIST = 409; + public static final int INVALID_ROLE = 400; + + @Rule + public static TestName name = new TestName(); + + public CreateUserApiTest() { + super(name, CreateUserApiTest.class.getName()); + } + + @BeforeMethod + public void init() { + sdncAdminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + sdncDesignerUser = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncGovernorUser = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + sdncTesterUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + + } + + // Story : REST API to provision new user (POST) - US429379 + // must parameters: UserId and Email + + // **********************************************************201*************************************************** + // create user with full parameter set(UserID, First Name, Last Name, Email, + // Role = "DESIGNER", Creator details) + // expected 201 Created + @Test + public void createUser() throws Exception { + + // user initialization + String httpCspUserId = "km2000"; + String userFirstName = "Kot"; + String userLastName = "Matroskin"; + String email = "km2000@intl.sdc.com"; + String role = "ADMIN"; + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + String addUser = "AddUser"; + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + + AssertJUnit.assertNotNull("check response object is not null after create user", createUserResponse); + AssertJUnit.assertNotNull("check error code exists in response after create user", + createUserResponse.getErrorCode()); + AssertJUnit.assertEquals("Check response code after create user", 201, + createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + + ExpectedUserCRUDAudit constructFieldsForAuditValidation = Convertor.constructFieldsForAuditValidation(addUser, + sdncAdminUser, ActionStatus.CREATED, sdncUserDetails, null); + AuditValidationUtils.validateAddUserAudit(constructFieldsForAuditValidation, addUser); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + } + + protected static final String ADD_USER = "AddUser"; + + private User mechIdUser = new User(); + private User emptyUser = new User(); + private static final User adminUser = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + + @AfterMethod + public void setup() throws IOException { + UserRestUtils.deactivateUser(mechIdUser, adminUser); + } + + // create default user(UserID, Email, Creator details) + // expected: role = DESIGNER, first and last name = null, 201 Created + @Test + public void createDefaultUser() throws Exception { + // user initialization + String httpCspUserId = "km2000"; + String userFirstName = null; + String userLastName = null; + String email = null; + String role = null; + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + deleteUserAndAudit(sdncUserDetails); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + UserValidationUtils.validateAddUserAuditMessage(sdncUserDetails, sdncAdminUser, "201", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + + } + + // create user with one optional parameter first name (UserID, Email, First + // Name, Creator details) + // expected: role = DESIGNER, last name = null, 201 Created + @Test + public void createUserFirstName() throws Exception { + // user initialization + String httpCspUserId = "km2000"; + String userFirstName = "Kot"; + String userLastName = null; + String email = null; + String role = null; + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + deleteUserAndAudit(sdncUserDetails); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + UserValidationUtils.validateAddUserAuditMessage(sdncUserDetails, sdncAdminUser, "201", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + } + + @Test + public void createDeleteOpsUser() throws Exception { + + String httpCspUserId = "oo2000"; + String userFirstName = "ops"; + String userLastName = "opsLast"; + String email = "ops@intl.sdc.com"; + String role = "OPS"; + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + deleteUserAndAudit(sdncUserDetails); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + UserValidationUtils.validateAddUserAuditMessage(sdncUserDetails, sdncAdminUser, "201", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + RestResponse getDeletedUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + assertEquals("Check response code after delete user", 404, getDeletedUserResponse.getErrorCode().intValue()); + + } + + @Test + public void createDeleteGOVERNORUser() throws Exception { + + String httpCspUserId = "gg2000"; + String userFirstName = "gov"; + String userLastName = "govLast"; + String email = "gov@intl.sdc.com"; + String role = "GOVERNOR"; + User sdncUserDetails = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + deleteUserAndAudit(sdncUserDetails); + RestResponse createUserResponse = UserRestUtils.createUser(sdncUserDetails, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, createUserResponse.getResponse()); + UserValidationUtils.validateAddUserAuditMessage(sdncUserDetails, sdncAdminUser, "201", + UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + RestResponse getUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(sdncUserDetails, getUserResponse.getResponse()); + + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + RestResponse getDeletedUserResponse = UserRestUtils.getUser(sdncUserDetails, sdncAdminUser); + assertEquals("Check response code after delete user", 404, getDeletedUserResponse.getErrorCode().intValue()); + + } + + // Benny + // Admin Create OPS user + @Test + public void createOpsUser() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "aa1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + User expectedOpsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedOpsUser); + RestResponse createUserResponse = UserRestUtils.createUser(expectedOpsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedOpsUser, createUserResponse.getResponse()); + deleteAndCheckUserResponse(expectedOpsUser, 200); + + } + + // Admin Create GOVERNOR user + @Test + public void createGovernorUser() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "aa1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + User expectedUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedUser); + RestResponse createUserResponse = UserRestUtils.createUser(expectedUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedUser, createUserResponse.getResponse()); + RestResponse getUserResponse = UserRestUtils.getUser(expectedUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedUser, getUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(expectedUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from OPS to GOVERNOR + @Test + public void updateOpsUserRole() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ab1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(governerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(governerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Designer Create OPS user -409 Response Restricted operation + @Test + public void createOpsUserByDesigner() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "aa1122"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + User expectedOpsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedOpsUser); + RestResponse createUserResponse = UserRestUtils.createUser(expectedOpsUser, sdncDesignerUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 409, createUserResponse.getErrorCode().intValue()); + assertEquals("Check response code after create user", "Conflict", createUserResponse.getResponseMessage()); + } + + // Tester Create OPS user -409 Response Restricted operation + @Test + public void createOpsUserByTester() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "aa1122"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + User expectedOpsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedOpsUser); + RestResponse createUserResponse = UserRestUtils.createUser(expectedOpsUser, sdncTesterUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 409, createUserResponse.getErrorCode().intValue()); + assertEquals("Check response code after create user", "Conflict", createUserResponse.getResponseMessage()); + } + + // Designer Try Update OPS user role to GOVERNOR - Response 409 + @Test + public void updateOpsUserRolebyDesigner() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "bt751e"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // Admin create user with OPS role + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // Designer user try to update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncDesignerUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 409, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Conflict", + updateUserRoleResponse.getResponseMessage()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Tester Try Update OPS user role to GOVERNOR - Response 409 + @Test + public void updateOpsUserRolebyTester() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "bt751w"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // Admin create user with OPS role + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // Designer user try to update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncTesterUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 409, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Conflict", + updateUserRoleResponse.getResponseMessage()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from OPS to Designer + @Test + public void updateOpsUserRoleFromOpsToDesigner() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ab1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "DESIGNER"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User designerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(designerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(designerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from OPS to TESTER + @Test + public void updateOpsUserRoleFromOpsToTester() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ac1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "TESTER"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User testerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(testerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(testerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Tester try to Update user role from OPS to GOVERNOR - Response 409 + // Conflict + @Test + public void updateOpsUserRoleByTester() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ad1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + // Create user by Admin + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR by Tester + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncTesterUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 409, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Conflict", + updateUserRoleResponse.getResponseMessage()); + + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Designer try to Update user role from OPS to GOVERNOR - Response 409 + // Conflict + @Test + public void updateOpsUserRoleByDesigner() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ad1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + // User governerUser = new User(userFirstName, + // userLastName,httpCspUserId, email, updatedRole); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + // Create user by Admin + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR by Tester + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncDesignerUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 409, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Conflict", + updateUserRoleResponse.getResponseMessage()); + + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Create OPS user - user already exist + @Test + public void createOpsUserAlreadyExist() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "af1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "OPS"; + User expectedOpsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedOpsUser); + RestResponse createUserResponse = UserRestUtils.createUser(expectedOpsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedOpsUser, createUserResponse.getResponse()); + // Create user that already exists + RestResponse createUserAgainResponse = UserRestUtils.createUser(expectedOpsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserAgainResponse); + assertNotNull("check error code exists in response after create user", createUserAgainResponse.getErrorCode()); + assertEquals("Check response code after create user", 409, createUserAgainResponse.getErrorCode().intValue()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(expectedOpsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from OPS to GOVERNOR - user already has GOVERNOR + // role + @Test + public void updateRoleToSameRole() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ag1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "GOVERNOR"; + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + RestResponse createUserResponse = UserRestUtils.createUser(opsUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from GOVERNOR to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + opsUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(governerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(governerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from Tester to GOVERNOR - 200 response + + // Admin Update user role from Designer to GOVERNOR - 200 response + @Test + public void updateUserRoleDesignerToGovernor() throws Exception { + DbUtils.cleanAllAudits(); + String httpCspUserId = "ah1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "DESIGNER"; + String updatedRole = "GOVERNOR"; + User designerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(designerUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(designerUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from TESTER to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + designerUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + // Update user role + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(governerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(governerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(designerUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update deactivated user role - response 404 (user not found) + @Test + public void updateRoleToDeactivatedUser() throws Exception { + DbUtils.cleanAllAudits(); + String httpCspUserId = "aj1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "DESIGNER"; + String updatedRole = "GOVERNOR"; + User designerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User governerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(designerUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(designerUser, createUserResponse.getResponse()); + deleteAndCheckUserResponse(designerUser, 200); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role - user deActivted + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + designerUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after create user", 404, updateUserRoleResponse.getErrorCode().intValue()); + } + + // Admin Update user role, user does not exist in DB - response 404 (user + // not found) + @Test + public void updateRoleForNonExistingUser() throws Exception { + DbUtils.cleanAllAudits(); + String httpCspUserId = "aj1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "DESIGNER"; + String updatedRole = "GOVERNOR"; + User designerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + // User governerUser = new User(userFirstName, + // userLastName,httpCspUserId, email, updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role - user deActivted + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + designerUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 404, updateUserRoleResponse.getErrorCode().intValue()); + + } + + // Admin Update user role from GOVERNOR to TESTER + @Test + public void updateRoleFromGovernorToTester() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ak1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "TESTER"; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User testerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(testerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(testerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(governorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from GOVERNOR to DESIGNER + @Test + public void updateRoleFromGovernorToDesigner() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ak1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "DESIGNER"; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User designerUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(designerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(designerUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(governorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role from GOVERNOR to OPS + @Test + public void updateRoleFromGovernorToOps() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ak1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "OPS"; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User opsUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(opsUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(opsUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + deleteAndCheckUserResponse(governorUser, 200); + + } + + private void deleteAndCheckUserResponse(User userDetailes, int expectedResponseCode) throws IOException { + RestResponse deleteUser = UserRestUtils.deleteUser(sdncGovernorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteUser); + assertEquals("Check response code after deleting user", expectedResponseCode, + deleteUser.getErrorCode().intValue()); + } + + // Admin Update user role from GOVERNOR to ADMIN + @Test + public void updateRoleFromGovernorToAdmin() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ak1000"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "ADMIN"; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User adminUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 200, updateUserRoleResponse.getErrorCode().intValue()); + + RestResponse getUpdatedRoleUserResponse = UserRestUtils.getUser(adminUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(adminUser, getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(governorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role to non existing role - Response 400 Bad Request + @Test + public void updateRoleToNonExistingRole() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "al1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = "VVVVVVV"; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User newUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role from OPS to GOVERNOR + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 400, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Bad Request", + updateUserRoleResponse.getResponseMessage()); + + // RestResponse getUpdatedRoleUserResponse = + // UserRestUtils.getUser(adminUser,sdncAdminUser); + // UserValidationUtils.validateUserDetailsOnResponse(adminUser,getUpdatedRoleUserResponse.getResponse()); + // Delete OPS user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(governorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + // Admin Update user role to null - Response 400 Bad Request + @Test + public void updateRoleToNull() throws Exception { + DbUtils.cleanAllAudits(); + + String httpCspUserId = "ax1001"; + String userFirstName = "Benny"; + String userLastName = "Tal"; + String email = "optBenny@intl.sdc.com"; + String role = "GOVERNOR"; + String updatedRole = ""; + User governorUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + User newUser = new User(userFirstName, userLastName, httpCspUserId, email, updatedRole, null); + // UserRestUtils.deleteUser(opsUser, sdncAdminUser, true); + // UserRestUtils.deleteUser(UserUpdateRole, sdncAdminUser); + RestResponse createUserResponse = UserRestUtils.createUser(governorUser, sdncAdminUser); + assertNotNull("check response object is not null after create user", createUserResponse); + assertNotNull("check error code exists in response after create user", createUserResponse.getErrorCode()); + assertEquals("Check response code after create user", 201, createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(governorUser, createUserResponse.getResponse()); + // opsUser.setRole(updatedRole); + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // update user role + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + governorUser.getUserId()); + assertNotNull("check response object is not null after updating user", updateUserRoleResponse); + assertNotNull("check error code exists in response after updating user", updateUserRoleResponse.getErrorCode()); + assertEquals("Check response code after updating user", 400, updateUserRoleResponse.getErrorCode().intValue()); + assertEquals("Check response code after updating user", "Bad Request", + updateUserRoleResponse.getResponseMessage()); + // Delete user + RestResponse deleteOpsUser = UserRestUtils.deleteUser(governorUser, sdncAdminUser, true); + assertNotNull("check response object is not null after deleting user", deleteOpsUser); + assertEquals("Check response code after deleting user", 200, deleteOpsUser.getErrorCode().intValue()); + + } + + @Test + public void createProductManagerUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Man"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_MANAGER"; + User expectedProductManagerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, true); + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, createUserResponse.getResponse()); + // Audit validation + UserValidationUtils.validateAddUserAuditMessage(expectedProductManagerUser, sdncAdminUser, + Integer.toString(STATUS_CODE_SUCSESS_CREATED), UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductManagerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test + public void createProductStrategistUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodStr@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + UserRestUtils.deleteUser(expectedProductStrategistUser, sdncAdminUser, true); + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductStrategistUser, + createUserResponse.getResponse()); + // Audit validation + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, sdncAdminUser, + Integer.toString(STATUS_CODE_SUCSESS_CREATED), UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductStrategistUser, getUserResponse.getResponse()); + // Delete ProductStrategist user + RestResponse deleteProductStrategistUser = UserRestUtils.deleteUser(expectedProductStrategistUser, + sdncAdminUser, true); + assertNotNull("Check response object is not null after deleting OPS user", deleteProductStrategistUser); + assertEquals("Check response code after deleting OPS user", 200, + deleteProductStrategistUser.getErrorCode().intValue()); + } + + @Test + public void createProductStrategistUserByNonAdminUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodStr@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + UserRestUtils.deleteUser(expectedProductStrategistUser, sdncAdminUser, true); + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, sdncDesignerUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_RESTRICTED_OPERATION, + createUserResponse.getErrorCode().intValue()); + // Audit validation + expectedProductStrategistUser.setUserId(""); + expectedProductStrategistUser.setFirstName(null); + expectedProductStrategistUser.setLastName(null); + expectedProductStrategistUser.setEmail(""); + expectedProductStrategistUser.setRole(""); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, sdncDesignerUser, + Integer.toString(STATUS_CODE_RESTRICTED_OPERATION), errorInfo.getAuditDesc(""), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // Try to get user - user is not created + expectedProductStrategistUser.setUserId("pm1000"); + expectedProductStrategistUser.setFirstName("Prod"); + expectedProductStrategistUser.setLastName("Strategist"); + expectedProductStrategistUser.setEmail("prodStr@intl.sdc.com"); + expectedProductStrategistUser.setRole("PRODUCT_STRATEGIST"); + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, getUserResponse.getErrorCode().intValue()); + } + + @Test + public void createProductManagerUserByNonAdminUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Man"; + String email = "prodStr@intl.sdc.com"; + String role = "PRODUCT_MANAGER"; + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + UserRestUtils.deleteUser(expectedProductStrategistUser, sdncAdminUser, true); + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, sdncDesignerUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_RESTRICTED_OPERATION, + createUserResponse.getErrorCode().intValue()); + // Audit validation + expectedProductStrategistUser.setUserId(""); + expectedProductStrategistUser.setFirstName(null); + expectedProductStrategistUser.setLastName(null); + expectedProductStrategistUser.setEmail(""); + expectedProductStrategistUser.setRole(""); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, sdncDesignerUser, + Integer.toString(STATUS_CODE_RESTRICTED_OPERATION), errorInfo.getAuditDesc(""), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // Try to get user - user is not created + expectedProductStrategistUser.setUserId("pm1000"); + expectedProductStrategistUser.setFirstName("Prod"); + expectedProductStrategistUser.setLastName("Strategist"); + expectedProductStrategistUser.setEmail("prodStr@intl.sdc.com"); + expectedProductStrategistUser.setRole("PRODUCT_MANAGER"); + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, getUserResponse.getErrorCode().intValue()); + } + + @Test + public void createProductStrategistUserByNonExistingUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodStr@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + User noSdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + noSdncUserDetails.setRole("blabla"); + noSdncUserDetails.setUserId("bt750h"); + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, noSdncUserDetails); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_NOT_FOUND, + createUserResponse.getErrorCode().intValue()); + // Audit validation + expectedProductStrategistUser.setUserId(""); + expectedProductStrategistUser.setFirstName(null); + expectedProductStrategistUser.setLastName(null); + expectedProductStrategistUser.setEmail(""); + expectedProductStrategistUser.setRole(""); + noSdncUserDetails.setFirstName(""); + noSdncUserDetails.setLastName(""); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_NOT_FOUND.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, noSdncUserDetails, + Integer.toString(STATUS_CODE_NOT_FOUND), errorInfo.getAuditDesc(noSdncUserDetails.getUserId()), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // Try to get user - user is not created + expectedProductStrategistUser.setUserId("pm1000"); + expectedProductStrategistUser.setFirstName("Prod"); + expectedProductStrategistUser.setLastName("Strategist"); + expectedProductStrategistUser.setEmail("prodStr@intl.sdc.com"); + expectedProductStrategistUser.setRole("PRODUCT_STRATEGIST"); + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, getUserResponse.getErrorCode().intValue()); + } + + @Test + public void createProductManagerUserByNonExistingUser() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Man"; + String email = "prodStr@intl.sdc.com"; + String role = "PRODUCT_MANAGER"; + User noSdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + noSdncUserDetails.setRole("blabla"); + noSdncUserDetails.setUserId("bt750h"); + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + + DbUtils.deleteFromEsDbByPattern("_all"); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, noSdncUserDetails); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_NOT_FOUND, + createUserResponse.getErrorCode().intValue()); + // Audit validation + expectedProductStrategistUser.setUserId(""); + expectedProductStrategistUser.setFirstName(null); + expectedProductStrategistUser.setLastName(null); + expectedProductStrategistUser.setEmail(""); + expectedProductStrategistUser.setRole(""); + noSdncUserDetails.setFirstName(""); + noSdncUserDetails.setLastName(""); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_NOT_FOUND.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, noSdncUserDetails, + Integer.toString(STATUS_CODE_NOT_FOUND), errorInfo.getAuditDesc(noSdncUserDetails.getUserId()), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // Try to get user - user is not created + expectedProductStrategistUser.setUserId("pm1000"); + expectedProductStrategistUser.setFirstName("Prod"); + expectedProductStrategistUser.setLastName("Strategist"); + expectedProductStrategistUser.setEmail("prodStr@intl.sdc.com"); + expectedProductStrategistUser.setRole("PRODUCT_MANAGER"); + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code ", STATUS_CODE_NOT_FOUND, getUserResponse.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void updateProjectManagerRole() throws Exception { + // Update user role from PRODUCT_STRATEGIST to PRODUCT_MANAGER + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Man"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_MANAGER"; + String updatedRole = "GOVERNOR"; + User expectedProductManagerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductManagerUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, createUserResponse.getResponse()); + // Update user role + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // Update user role from PRODUCT_STRATEGIST to PRODUCT_MANAGER + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + expectedProductManagerUser.getUserId()); + assertEquals("Check response code after create user", STATUS_CODE_SUCCESS, + updateUserRoleResponse.getErrorCode().intValue()); + expectedProductManagerUser.setRole(updatedRole); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, + updateUserRoleResponse.getResponse()); + // Audit validation + UserValidationUtils.validateAddUserAuditMessage(expectedProductManagerUser, sdncAdminUser, + Integer.toString(STATUS_CODE_SUCCESS), UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("UpdateUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductManagerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void updateProductStrategistRole() throws Exception { + // Update user role from PRODUCT_STRATEGIST to PRODUCT_MANAGER + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + String updatedRole = "TESTER"; + User expectedProductManagerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductManagerUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, createUserResponse.getResponse()); + // Update user role + User newRoleUser = new User(); + newRoleUser.setRole(updatedRole); + // Update user role from PRODUCT_STRATEGIST to PRODUCT_MANAGER + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + expectedProductManagerUser.getUserId()); + assertEquals("Check response code after create user", STATUS_CODE_SUCCESS, + updateUserRoleResponse.getErrorCode().intValue()); + expectedProductManagerUser.setRole(updatedRole); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, + updateUserRoleResponse.getResponse()); + // Audit validation + UserValidationUtils.validateAddUserAuditMessage(expectedProductManagerUser, sdncAdminUser, + Integer.toString(STATUS_CODE_SUCCESS), UserResponseMessageEnum.SUCCESS_MESSAGE.getValue(), + UserValidationUtils.getAddUserAuditMessage("UpdateUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductManagerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test + public void createProductManagerUserAlreadyExit() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Man"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_MANAGER"; + User expectedProductManagerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductManagerUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, createUserResponse.getResponse()); + // create same user again + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse createUserAgainResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", USER_ALREADY_EXIST, + createUserAgainResponse.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_ALREADY_EXIST.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductManagerUser, sdncAdminUser, + Integer.toString(USER_ALREADY_EXIST), errorInfo.getAuditDesc(expectedProductManagerUser.getUserId()), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductManagerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test + public void createProductStrategistUserAlreadyExit() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + User expectedProductManagerUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductManagerUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, createUserResponse.getResponse()); + // create same user again + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse createUserAgainResponse = UserRestUtils.createUser(expectedProductManagerUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", USER_ALREADY_EXIST, + createUserAgainResponse.getErrorCode().intValue()); + // Audit validation + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.USER_ALREADY_EXIST.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductManagerUser, sdncAdminUser, + Integer.toString(USER_ALREADY_EXIST), errorInfo.getAuditDesc(expectedProductManagerUser.getUserId()), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductManagerUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductManagerUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductManagerUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void UpdateProductStrategistToNonExistingRole() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodMan@intl.sdc.com"; + String role = "PRODUCT_STRATEGIST"; + String nonExistingRole = "BLABLA"; + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductStrategistUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", STATUS_CODE_SUCSESS_CREATED, + createUserResponse.getErrorCode().intValue()); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductStrategistUser, + createUserResponse.getResponse()); + // Update user Role to non Existing role + User newRoleUser = new User(); + newRoleUser.setRole(nonExistingRole); + DbUtils.deleteFromEsDbByPattern("_all"); + RestResponse updateUserRoleResponse = UserRestUtils.updateUserRole(newRoleUser, sdncAdminUser, + expectedProductStrategistUser.getUserId()); + assertEquals("Check response code after updating user role", INVALID_ROLE, + updateUserRoleResponse.getErrorCode().intValue()); + + // Audit validation + /* + * expectedProductStrategistUser.setUserId(""); + * expectedProductStrategistUser.setFirstName(null); + * expectedProductStrategistUser.setLastName(null); + * expectedProductStrategistUser.setEmail(""); + * expectedProductStrategistUser.setRole(""); + */ + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_ROLE.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, sdncAdminUser, + Integer.toString(INVALID_ROLE), errorInfo.getAuditDesc(nonExistingRole), + UserValidationUtils.getAddUserAuditMessage("UpdateUser")); + // get user and compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + UserValidationUtils.validateUserDetailsOnResponse(expectedProductStrategistUser, getUserResponse.getResponse()); + // Delete ProductManager user + RestResponse deleteProductManagerUser = UserRestUtils.deleteUser(expectedProductStrategistUser, sdncAdminUser, + true); + assertEquals("Check response code after deleting OPS user", STATUS_CODE_SUCCESS, + deleteProductManagerUser.getErrorCode().intValue()); + } + + @Test(enabled = false) + public void createUserWithNonExistingRole() throws Exception { + String httpCspUserId = "pm1000"; + String userFirstName = "Prod"; + String userLastName = "Strategist"; + String email = "prodMan@intl.sdc.com"; + String role = "BLABLA"; + User expectedProductStrategistUser = new User(userFirstName, userLastName, httpCspUserId, email, role, null); + deleteUserAndAudit(expectedProductStrategistUser); + // create user + RestResponse createUserResponse = UserRestUtils.createUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check response code after create Product-Manager user", INVALID_ROLE, + createUserResponse.getErrorCode().intValue()); + + // Audit validation + /* + * expectedProductStrategistUser.setUserId(""); + * expectedProductStrategistUser.setFirstName(null); + * expectedProductStrategistUser.setLastName(null); + * expectedProductStrategistUser.setEmail(""); + * expectedProductStrategistUser.setRole(""); + */ + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_ROLE.name()); + UserValidationUtils.validateAddUserAuditMessage(expectedProductStrategistUser, sdncAdminUser, + Integer.toString(INVALID_ROLE), errorInfo.getAuditDesc(role), + UserValidationUtils.getAddUserAuditMessage("AddUser")); + // get user - verify user is not createdand compare with expected + RestResponse getUserResponse = UserRestUtils.getUser(expectedProductStrategistUser, sdncAdminUser); + assertEquals("Check user not created", STATUS_CODE_NOT_FOUND, getUserResponse.getErrorCode().intValue()); + + } + + private void deleteUserAndAudit(User sdncUserDetails) throws IOException { + UserRestUtils.deleteUser(sdncUserDetails, sdncAdminUser, true); + DbUtils.cleanAllAudits(); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/GovernorWorkspaceApiTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/GovernorWorkspaceApiTest.java new file mode 100644 index 0000000000..a7552ad3be --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/execute/user/GovernorWorkspaceApiTest.java @@ -0,0 +1,354 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.execute.user; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.List; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ServiceValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GovernorWorkspaceApiTest extends ComponentBaseTest { + + private static Logger logger = LoggerFactory.getLogger(GovernorWorkspaceApiTest.class.getName()); + @Rule + public static TestName name = new TestName(); + + public GovernorWorkspaceApiTest() { + super(name, GovernorWorkspaceApiTest.class.getName()); + + } + + protected final User admin1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected final User governor = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + protected final User sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected ResourceReqDetails resourceDetails1; + protected ComponentInstanceReqDetails componentInstanceReqDetails; + protected ArtifactReqDetails heatArtifactDetails; + + protected final String serviceVersion = "0.1"; + protected final String servicesString = "services"; + protected final String userRemarks = "commentTest"; + + protected ServiceReqDetails serviceDetails11 = null; + protected ServiceReqDetails serviceDetails22 = null; + protected ServiceReqDetails serviceDetails33 = null; + + @BeforeMethod + public void initBeforeTest() throws Exception { + DbUtils.deleteFromEsDbByPattern("_all"); + Resource resourceObj = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resourceDetails1 = new ResourceReqDetails(resourceObj); + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + createThreeServices(sdncDesignerDetails1); + } + + protected void createThreeServices(User user) throws Exception { + + String checkinComment = "good checkin"; + String checkinComentJson = "{\"userRemarks\": \"" + checkinComment + "\"}"; + + RestResponse addInformationalArtifactToResource = ArtifactRestUtils.addInformationalArtifactToResource( + heatArtifactDetails, sdncDesignerDetails1, resourceDetails1.getUniqueId()); + RestResponse certifyResource = LifecycleRestUtils.certifyResource(resourceDetails1); + componentInstanceReqDetails = ElementFactory.getDefaultComponentInstance("defaultInstance", resourceDetails1); + + serviceDetails11 = ElementFactory.getDefaultService(); + serviceDetails22 = ElementFactory.getDefaultService(); + serviceDetails33 = ElementFactory.getDefaultService(); + + serviceDetails11.setName(serviceDetails11.getName() + "1"); + List tags = serviceDetails11.getTags(); + tags.add(serviceDetails11.getName()); + serviceDetails11.setTags(tags); + + serviceDetails22.setName(serviceDetails11.getName() + "2"); + tags = serviceDetails22.getTags(); + tags.add(serviceDetails22.getName()); + serviceDetails22.setTags(tags); + + serviceDetails33.setName(serviceDetails11.getName() + "3"); + tags = serviceDetails33.getTags(); + tags.add(serviceDetails33.getName()); + serviceDetails33.setTags(tags); + // + // serviceUtils.deleteService_allVersions(serviceDetails11, designer1); + // serviceUtils.deleteService_allVersions(serviceDetails22, designer1); + // serviceUtils.deleteService_allVersions(serviceDetails33, designer1); + + RestResponse createServiceResponse1 = createService(user, serviceDetails11); + RestResponse createServiceResponse2 = createService(user, serviceDetails22); + RestResponse createServiceResponse3 = createService(user, serviceDetails33); + + // addResourceWithHeatArt(); + // + // serviceUtils.addServiceMandatoryArtifacts(user, + // createServiceResponse1); + // + // + // RestResponse createServiceResponse2 = + // serviceUtils.createServiceTowardsCatalogBe(serviceDetails22, user); + // assertNotNull("check response object is not null after creating + // service", createServiceResponse2); + // assertNotNull("check if error code exists in response after creating + // service", createServiceResponse2.getErrorCode()); + // assertEquals("Check response code after creating service", 201, + // createServiceResponse2.getErrorCode().intValue()); + // serviceDetails22.setUniqueId(serviceUtils.getServiceUniqueId(createServiceResponse2)); + // logger.debug("Created service2 = {}", serviceDetails22); + // serviceUtils.addServiceMandatoryArtifacts(user, + // createServiceResponse2); + // + // RestResponse createServiceResponse3 = + // serviceUtils.createServiceTowardsCatalogBe(serviceDetails33, user); + // assertNotNull("check response object is not null after creating + // service", createServiceResponse3); + // assertNotNull("check if error code exists in response after creating + // service", createServiceResponse3.getErrorCode()); + // assertEquals("Check response code after creating service", 201, + // createServiceResponse3.getErrorCode().intValue()); + // serviceDetails33.setUniqueId(serviceUtils.getServiceUniqueId(createServiceResponse3)); + // logger.debug("Created service3 = {}", serviceDetails33); + // serviceUtils.addServiceMandatoryArtifacts(user, + // createServiceResponse3); + + } + + protected RestResponse createService(User user, ServiceReqDetails serviceDetails) throws Exception, IOException { + RestResponse createServiceResponse1 = ServiceRestUtils.createService(serviceDetails, user); + assertNotNull("check response object is not null after creating service", createServiceResponse1); + assertNotNull("check if error code exists in response after creating service", + createServiceResponse1.getErrorCode()); + assertEquals("Check response code after creating service", 201, + createServiceResponse1.getErrorCode().intValue()); + Service convertServiceResponseToJavaObject = ResponseParser + .convertServiceResponseToJavaObject(createServiceResponse1.getResponse()); + serviceDetails.setUniqueId(convertServiceResponseToJavaObject.getUniqueId()); + logger.debug("Created service1 = {}", serviceDetails); + addResourceWithHeatArt(serviceDetails); + return createServiceResponse1; + } + + protected void addResourceWithHeatArt(ServiceReqDetails serviceDetails) throws Exception { + + RestResponse createResourceInstance = ComponentInstanceRestUtils.createComponentInstance( + componentInstanceReqDetails, sdncDesignerDetails1, serviceDetails.getUniqueId(), + ComponentTypeEnum.SERVICE); + // System.out.println("serviceUID --->" + serviceDetails.getUniqueId()); + assertEquals("Check response code ", 201, createResourceInstance.getErrorCode().intValue()); + } + + protected void certifyAllServices() throws Exception { + LifecycleRestUtils.certifyService(serviceDetails11); + LifecycleRestUtils.certifyService(serviceDetails22); + LifecycleRestUtils.certifyService(serviceDetails33); + } + + protected boolean isElementInArray(String elementId, JSONArray jsonArray) throws Exception { + for (int i = 0; i < jsonArray.size(); i++) { + JSONObject jobject = (JSONObject) jsonArray.get(i); + + if (jobject.get("uniqueId").toString().equals(elementId)) { + return true; + } + } + return false; + } + + protected void approveDistributionStatusOfCertifiedService(ServiceReqDetails serviceDetails, User user) + throws Exception { + approveDistributionStatusOfService(serviceDetails, user, "1.0"); + } + + protected void approveDistributionStatusOfService(ServiceReqDetails serviceDetails, User user, String version) + throws Exception { + RestResponse res = LifecycleRestUtils.sendApproveDistribution(user, serviceDetails.getUniqueId(), userRemarks); + assertEquals(200, res.getErrorCode().intValue()); + ServiceValidationUtils.validateDistrubtionStatusValue(res, DistributionStatusEnum.DISTRIBUTION_APPROVED); + } + + protected void rejectDistributionStatusOfService(ServiceReqDetails serviceDetails, User user) throws Exception { + rejectDistributionStatusOfService(serviceDetails, user, "1.0"); + } + + protected void rejectDistributionStatusOfService(ServiceReqDetails serviceDetails, User user, String version) + throws Exception { + RestResponse res = LifecycleRestUtils.rejectDistribution(serviceDetails, version, user, userRemarks); + assertEquals(200, res.getErrorCode().intValue()); + ServiceValidationUtils.validateDistrubtionStatusValue(res, DistributionStatusEnum.DISTRIBUTION_REJECTED); + } + + protected JSONArray getFollowedListAsJsonArray(User user) throws Exception { + RestResponse getGovernorFollowed = ServiceRestUtils.getFollowed(user); + assertNotNull(getGovernorFollowed); + assertNotNull(getGovernorFollowed.getErrorCode()); + assertEquals(200, getGovernorFollowed.getErrorCode().intValue()); + + JSONArray listArrayFromRestResponse = ServiceRestUtils.getListArrayFromRestResponse(getGovernorFollowed); + + return listArrayFromRestResponse; + } + + protected void changeDistributionStatusOfAllService(boolean approved, User user) throws Exception { + if (approved) { + approveDistributionStatusOfCertifiedService(serviceDetails11, user); + approveDistributionStatusOfCertifiedService(serviceDetails22, user); + approveDistributionStatusOfCertifiedService(serviceDetails33, user); + } else { + rejectDistributionStatusOfService(serviceDetails11, user); + rejectDistributionStatusOfService(serviceDetails22, user); + rejectDistributionStatusOfService(serviceDetails33, user); + } + + } + + protected JSONArray checkFollowed(User user) throws Exception { + JSONArray getFollowedList = getFollowedListAsJsonArray(user); + assertFalse(getFollowedList.isEmpty()); + assertTrue(isElementInArray(serviceDetails11.getUniqueId(), getFollowedList)); + assertTrue(isElementInArray(serviceDetails22.getUniqueId(), getFollowedList)); + assertTrue(isElementInArray(serviceDetails33.getUniqueId(), getFollowedList)); + + return getFollowedList; + } + + // -------------------------------------T E S T + // S------------------------------------------------------// + + @Test + public void governorList_AllCertifiedVersionsOfService() throws Exception { + certifyAllServices(); + String serviceUniqueIdCertified1 = serviceDetails11.getUniqueId(); + RestResponse res = LifecycleRestUtils.changeServiceState(serviceDetails11, sdncDesignerDetails1, "1.0", + LifeCycleStatesEnum.CHECKOUT); + assertEquals(200, res.getErrorCode().intValue()); + + JSONArray getFollowedList = getFollowedListAsJsonArray(governor); + assertFalse(getFollowedList.isEmpty()); + assertFalse(isElementInArray(serviceDetails11.getUniqueId(), getFollowedList)); + assertTrue(isElementInArray(serviceDetails22.getUniqueId(), getFollowedList)); + assertTrue(isElementInArray(serviceDetails33.getUniqueId(), getFollowedList)); + assertTrue(isElementInArray(serviceUniqueIdCertified1, getFollowedList)); + assertEquals(3, getFollowedList.size()); + + // certifyService(serviceDetails11, "1.1"); + LifecycleRestUtils.certifyService(serviceDetails11); + + JSONArray governorFollowedList2 = checkFollowed(governor); + assertEquals(4, governorFollowedList2.size()); + assertTrue(isElementInArray(serviceDetails11.getUniqueId(), governorFollowedList2)); + assertTrue(isElementInArray(serviceUniqueIdCertified1, governorFollowedList2)); + + } + + // -------------------------------------T E S T + // S------------------------------------------------------// + + @Test + public void governorList_distributionNotApproved() throws Exception { + certifyAllServices(); + + JSONArray checkFollowed = checkFollowed(governor); + assertEquals(3, checkFollowed.size()); + } + + @Test + public void governorGetEmptyListTest_notCertifiedServices() throws Exception { + JSONArray governorFollowedList = getFollowedListAsJsonArray(governor); + + assertTrue(governorFollowedList.isEmpty()); + } + + @Test + public void governorList_distributionApproved() throws Exception { + certifyAllServices(); + boolean approved = true; + changeDistributionStatusOfAllService(approved, governor); + + JSONArray checkFollowed = checkFollowed(governor); + assertEquals(3, checkFollowed.size()); + } + + @Test(enabled = false) + public void governorList_distributed() throws Exception { + certifyAllServices(); + + LifecycleRestUtils.changeDistributionStatus(serviceDetails11, "1.0", governor, userRemarks, + DistributionStatusEnum.DISTRIBUTED); + LifecycleRestUtils.changeDistributionStatus(serviceDetails22, "1.0", governor, userRemarks, + DistributionStatusEnum.DISTRIBUTED); + LifecycleRestUtils.changeDistributionStatus(serviceDetails33, "1.0", governor, userRemarks, + DistributionStatusEnum.DISTRIBUTED); + + JSONArray governorFollowedList = getFollowedListAsJsonArray(governor); + assertFalse(governorFollowedList.isEmpty()); + assertTrue(isElementInArray(serviceDetails11.getUniqueId(), governorFollowedList)); + assertTrue(isElementInArray(serviceDetails22.getUniqueId(), governorFollowedList)); + assertTrue(isElementInArray(serviceDetails33.getUniqueId(), governorFollowedList)); + } + + @Test + public void governorList_distributionRejected() throws Exception { + certifyAllServices(); + boolean distributionRejected = false; + changeDistributionStatusOfAllService(distributionRejected, governor); + + JSONArray checkFollowed = checkFollowed(governor); + assertEquals(3, checkFollowed.size()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/executeOnUGN/distributionClient/ClientConfiguration.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/executeOnUGN/distributionClient/ClientConfiguration.java new file mode 100644 index 0000000000..c80f6c612d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/executeOnUGN/distributionClient/ClientConfiguration.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.executeOnUGN.distributionClient; + +import java.util.ArrayList; +import java.util.List; + +public class ClientConfiguration { + + private String asdcAddress; + private String user; + private String password; + private Integer pollingInterval; + private Integer pollingTimeout; + private List relevantArtifactTypes; + private String consumerGroup; + private String environmentName; + private String consumerID; + + public ClientConfiguration() { + + super(); + + this.asdcAddress = "localhost:8443"; + this.consumerID = "mso-123456"; + this.consumerGroup = "mso-group"; + this.environmentName = "PROD"; + this.password = "password"; + this.pollingInterval = 20; + this.pollingTimeout = 20; + this.relevantArtifactTypes = new ArrayList(); + this.relevantArtifactTypes.add("SHELL"); + this.user = "mso-user"; + } + + public String getAsdcAddress() { + return asdcAddress; + } + + public void setAsdcAddress(String asdcAddress) { + this.asdcAddress = asdcAddress; + } + + public String getUser() { + return user; + } + + public void setUser(String user) { + this.user = user; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public int getPollingInterval() { + return pollingInterval; + } + + public void setPollingInterval(Integer pollingInterval) { + this.pollingInterval = pollingInterval; + } + + public int getPollingTimeout() { + return pollingTimeout; + } + + public void setPollingTimeout(Integer pollingTimeout) { + this.pollingTimeout = pollingTimeout; + } + + public List getRelevantArtifactTypes() { + return relevantArtifactTypes; + } + + public void setRelevantArtifactTypes(List relevantArtifactTypes) { + this.relevantArtifactTypes = relevantArtifactTypes; + } + + public String getConsumerGroup() { + return consumerGroup; + } + + public void setConsumerGroup(String consumerGroup) { + this.consumerGroup = consumerGroup; + } + + public String getEnvironmentName() { + return environmentName; + } + + public void setEnvironmentName(String environmentName) { + this.environmentName = environmentName; + } + + public String getComsumerID() { + return consumerID; + } + + public void setComsumerID(String comsumerID) { + this.consumerID = comsumerID; + } + + public ClientConfiguration(String asdcAddress, String user, String password, Integer pollingInterval, + Integer pollingTimeout, List relevantArtifactTypes, String consumerGroup, String environmentName, + String comsumerID) { + super(); + this.asdcAddress = asdcAddress; + this.user = user; + this.password = password; + this.pollingInterval = pollingInterval; + this.pollingTimeout = pollingTimeout; + this.relevantArtifactTypes = relevantArtifactTypes; + this.consumerGroup = consumerGroup; + this.environmentName = environmentName; + this.consumerID = comsumerID; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/ComplexResourceBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/ComplexResourceBaseTest.java new file mode 100644 index 0000000000..14c7a37101 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/ComplexResourceBaseTest.java @@ -0,0 +1,177 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.preRequisites; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.lifecycle.LCSbaseTest; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.annotations.BeforeMethod; + +public class ComplexResourceBaseTest extends ComponentBaseTest { + + protected ServiceReqDetails serviceDetails; + protected ResourceReqDetails resourceDetailsVFC; + protected ResourceReqDetails resourceDetailsVL; + protected ResourceReqDetails resourceDetailsVF; + protected ResourceReqDetails resourceDetailsCP; + protected ComponentInstanceReqDetails resourceInstanceReqDetailsVF; + protected ComponentInstanceReqDetails resourceInstanceReqDetailsVFC; + protected ComponentInstanceReqDetails resourceInstanceReqDetailsVL; + protected ComponentInstanceReqDetails resourceInstanceReqDetailsCP; + protected User sdncDesignerDetails1; + protected User sdncTesterDeatails1; + protected User sdncAdminDetails1; + protected ArtifactReqDetails heatArtifactDetails; + + protected ArtifactReqDetails defaultArtifactDetails; + protected int maxLength = 50; + protected Resource resourceVF = null; + + @Rule + public static TestName name = new TestName(); + + public ComplexResourceBaseTest() { + super(name, ComplexResourceBaseTest.class.getName()); + } + + @BeforeMethod + public void before() throws Exception { + + initializeMembers(); + + createComponents(); + + } + + public void initializeMembers() throws IOException, Exception { + + serviceDetails = ElementFactory.getDefaultService(); + resourceDetailsVFC = ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VFC, "resourceVFC"); + resourceDetailsVF = ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VF, "resourceVF3"); + resourceDetailsVL = ElementFactory.getDefaultResourceByType(ResourceTypeEnum.VL, "resourceVL"); + resourceDetailsCP = ElementFactory.getDefaultResourceByType(ResourceTypeEnum.CP, "resourceCP"); + sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncTesterDeatails1 = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + sdncAdminDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + + } + + protected void createComponents() throws Exception { + + RestResponse response = ServiceRestUtils.createService(serviceDetails, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("service uniqueId is null:", serviceDetails.getUniqueId()); + + response = ResourceRestUtils.createResource(resourceDetailsVFC, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetailsVFC.getUniqueId()); + response = LifecycleRestUtils.changeResourceState(resourceDetailsVFC, sdncDesignerDetails1, + resourceDetailsVFC.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertTrue("change LS state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + response = ResourceRestUtils.createResource(resourceDetailsVF, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetailsVF.getUniqueId()); + + response = ResourceRestUtils.createResource(resourceDetailsCP, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetailsCP.getUniqueId()); + response = LifecycleRestUtils.changeResourceState(resourceDetailsCP, sdncDesignerDetails1, + resourceDetailsCP.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertTrue("change LS state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + response = ResourceRestUtils.createResource(resourceDetailsVL, sdncDesignerDetails1); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + assertNotNull("resource uniqueId is null:", resourceDetailsVL.getUniqueId()); + response = LifecycleRestUtils.changeResourceState(resourceDetailsVL, sdncDesignerDetails1, + resourceDetailsVL.getVersion(), LifeCycleStatesEnum.CHECKIN); + assertTrue("change LS state to CHECKIN, returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + resourceInstanceReqDetailsVFC = ElementFactory.getDefaultComponentInstance("VFC", resourceDetailsVFC); + resourceInstanceReqDetailsVF = ElementFactory.getDefaultComponentInstance("VF", resourceDetailsVF); + resourceInstanceReqDetailsVL = ElementFactory.getDefaultComponentInstance("VL", resourceDetailsVL); + resourceInstanceReqDetailsCP = ElementFactory.getDefaultComponentInstance("CP", resourceDetailsCP); + + } + + protected void createVFWithCertifiedResourceInstance(ResourceReqDetails resourceDetails, + ComponentInstanceReqDetails resourceInstanceReqDetails) throws Exception { + + RestResponse response = LifecycleRestUtils.changeResourceState(resourceDetails, sdncDesignerDetails1, + resourceDetails.getVersion(), LifeCycleStatesEnum.CHECKOUT); + assertEquals("Check response code after CHECKOUT", 200, response.getErrorCode().intValue()); + + // add heat artifact to resource and certify + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncDesignerDetails1, + resourceDetails.getUniqueId()); + assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + response = LCSbaseTest.certifyResource(resourceDetails, sdncDesignerDetails1); + assertEquals("Check response code after CERTIFY request", 200, response.getErrorCode().intValue()); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + + resourceInstanceReqDetails.setComponentUid(resourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncDesignerDetails1, + resourceVF); + assertEquals("Check response code after create RI", 201, response.getErrorCode().intValue()); + + resourceVF = convertResourceGetResponseToJavaObject(resourceDetailsVF); + } + + protected Resource convertResourceGetResponseToJavaObject(ResourceReqDetails resourceDetails) throws IOException { + RestResponse response = ResourceRestUtils.getResource(resourceDetails, sdncDesignerDetails1); + assertEquals("Check response code after get resource", 200, response.getErrorCode().intValue()); + return ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/DownloadArtifactBaseTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/DownloadArtifactBaseTest.java new file mode 100644 index 0000000000..bde68528bf --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/DownloadArtifactBaseTest.java @@ -0,0 +1,125 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.preRequisites; + +import java.io.IOException; + +import org.apache.log4j.lf5.util.ResourceUtils; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.execute.lifecycle.LCSbaseTest; +import org.openecomp.sdc.ci.tests.utils.ArtifactUtils; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.AssertJUnit; +import org.testng.annotations.BeforeMethod; + +public class DownloadArtifactBaseTest extends ComponentBaseTest { + + protected ResourceReqDetails downloadResourceDetails; + protected ServiceReqDetails serviceDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected User sdncUserDetails; + protected User sdncDesignerDetails1; + protected ArtifactReqDetails heatArtifactDetails; + + protected ArtifactReqDetails defaultArtifactDetails; + protected ResourceUtils resourceUtils; + protected ArtifactUtils artifactUtils; + protected Service service; + + public DownloadArtifactBaseTest(TestName testName, String className) { + super(testName, className); + } + + @BeforeMethod + public void before() throws Exception { + + initializeMembers(); + createComponents(); + + } + + public void initializeMembers() throws IOException, Exception { + downloadResourceDetails = ElementFactory.getDefaultResource(); + serviceDetails = ElementFactory.getDefaultService(); + sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + sdncDesignerDetails1 = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + heatArtifactDetails = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + resourceInstanceReqDetails = ElementFactory.getDefaultComponentInstance(); + + } + + protected void createComponents() throws Exception { + + RestResponse response = ResourceRestUtils.createResource(downloadResourceDetails, sdncUserDetails); + AssertJUnit.assertTrue("create request returned status:" + response.getErrorCode(), + response.getErrorCode() == 201); + AssertJUnit.assertNotNull("resource uniqueId is null:", downloadResourceDetails.getUniqueId()); + + ArtifactReqDetails heatArtifactDetails = ElementFactory + .getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + response = ArtifactRestUtils.addInformationalArtifactToResource(heatArtifactDetails, sdncUserDetails, + downloadResourceDetails.getUniqueId()); + AssertJUnit.assertTrue("add HEAT artifact to resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + // certified resource + response = LCSbaseTest.certifyResource(downloadResourceDetails, sdncDesignerDetails1); + AssertJUnit.assertTrue("certify resource request returned status:" + response.getErrorCode(), + response.getErrorCode() == 200); + + response = ServiceRestUtils.createService(serviceDetails, sdncUserDetails); + AssertJUnit.assertTrue("create request returned status:" + response.getErrorCode(), + response.getErrorCode() == 201); + AssertJUnit.assertNotNull("service uniqueId is null:", serviceDetails.getUniqueId()); + + // add resource instance with HEAT deployment artifact to the service + resourceInstanceReqDetails.setComponentUid(downloadResourceDetails.getUniqueId()); + response = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, sdncUserDetails, + serviceDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + AssertJUnit.assertTrue("response code is not 201, returned: " + response.getErrorCode(), + response.getErrorCode() == 201); + + response = ServiceRestUtils.getService(serviceDetails, sdncUserDetails); + AssertJUnit.assertTrue("response code is not 200, returned: " + response.getErrorCode(), + response.getErrorCode() == 200); + service = ResponseParser.convertServiceResponseToJavaObject(response.getResponse()); + + DbUtils.cleanAllAudits(); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/SimpleOneRsrcOneServiceTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/SimpleOneRsrcOneServiceTest.java new file mode 100644 index 0000000000..add06a587c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/preRequisites/SimpleOneRsrcOneServiceTest.java @@ -0,0 +1,96 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.preRequisites; + +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; + +import org.apache.log4j.lf5.util.ResourceUtils; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.ArtifactUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.annotations.BeforeMethod; + +public abstract class SimpleOneRsrcOneServiceTest extends ComponentBaseTest { + + protected ResourceReqDetails resourceDetails; + protected ServiceReqDetails serviceDetails; + protected ComponentInstanceReqDetails resourceInstanceReqDetails; + protected ArtifactReqDetails heatArtifactDetails1; + + private static final String heatExtension = "yaml"; + private static final String yangXmlExtension = "xml"; + private static final String muranoPkgExtension = "zip"; + private static final String extension = null; + private final String folderName = "heatEnv"; + + protected User sdncDesignerDetails; + protected ArtifactReqDetails defaultArtifactDetails; + protected ResourceUtils resourceUtils; + protected ArtifactUtils artifactUtils; + protected Utils utils; + + private static RestResponse createServiceResponse; + + public SimpleOneRsrcOneServiceTest(TestName testName, String className) { + super(testName, className); + } + + @BeforeMethod + public void before() throws Exception { + + initializeMembers(); + createComponents(); + + } + + public void initializeMembers() throws IOException, Exception { + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + resourceDetails = ElementFactory.getDefaultResource(); + serviceDetails = ElementFactory.getDefaultService(); + heatArtifactDetails1 = ElementFactory.getDefaultDeploymentArtifactForType(ArtifactTypeEnum.HEAT.getType()); + resourceInstanceReqDetails = ElementFactory.getDefaultComponentInstance("resourceInstanceReqDetails"); + } + + protected void createComponents() throws Exception { + + RestResponse response = ResourceRestUtils.createResource(resourceDetails, sdncDesignerDetails); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + + response = ServiceRestUtils.createService(serviceDetails, sdncDesignerDetails); + assertTrue("create request returned status:" + response.getErrorCode(), response.getErrorCode() == 201); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/rules/MyTestWatcher.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/rules/MyTestWatcher.java new file mode 100644 index 0000000000..aa6131c8ff --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/rules/MyTestWatcher.java @@ -0,0 +1,82 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.rules; + +import org.junit.rules.TestWatcher; +import org.junit.runner.Description; +import org.openecomp.sdc.ci.tests.api.SdcTest; + +public class MyTestWatcher extends TestWatcher { + + SdcTest odlTest; + + public MyTestWatcher(SdcTest odlTest) { + this.odlTest = odlTest; + } + + /** + * Invoked when a test succeeds + * + * @param description + */ + @Override + protected void succeeded(Description description) { + String testName = description.getMethodName(); + odlTest.addTestSummary(testName, true); + + } + + /** + * Invoked when a test fails + * + * @param e + * @param description + */ + @Override + protected void failed(Throwable e, Description description) { + String testName = description.getMethodName(); + odlTest.addTestSummary(testName, false, e); + } + + /** + * Invoked when a test is about to start + * + * @param description + */ + @Override + protected void starting(Description description) { + // System.out.println("protected void starting(Description description) + // {"); + this.odlTest.getLogger().debug("Start running test {}", description.getMethodName()); + } + + /** + * Invoked when a test method finishes (whether passing or failing) + * + * @param description + */ + @Override + protected void finished(Description description) { + // System.out.println("protected void finished(Description description) + // {"); + this.odlTest.getLogger().debug("Finish running test {}", description.getMethodName()); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/ExtentReporterNG.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/ExtentReporterNG.java new file mode 100644 index 0000000000..5119263032 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/ExtentReporterNG.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.run; + +import java.io.File; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import org.testng.IReporter; +import org.testng.IResultMap; +import org.testng.ISuite; +import org.testng.ISuiteResult; +import org.testng.ITestContext; +import org.testng.ITestResult; +import org.testng.xml.XmlSuite; + +import com.relevantcodes.extentreports.ExtentReports; +import com.relevantcodes.extentreports.ExtentTest; +import com.relevantcodes.extentreports.LogStatus; + +public class ExtentReporterNG implements IReporter { + private ExtentReports extent; + + @Override + public void generateReport(List xmlSuites, List suites, String outputDirectory) { + extent = new ExtentReports(outputDirectory + File.separator + "ExtentReportsTestNG.html", true); + + for (ISuite suite : suites) { + Map result = suite.getResults(); + + for (ISuiteResult r : result.values()) { + ITestContext context = r.getTestContext(); + + buildTestNodes(context.getPassedTests(), LogStatus.PASS); + buildTestNodes(context.getFailedTests(), LogStatus.FAIL); + buildTestNodes(context.getSkippedTests(), LogStatus.SKIP); + } + } + + extent.flush(); + extent.close(); + } + + private void buildTestNodes(IResultMap tests, LogStatus status) { + ExtentTest test; + + if (tests.size() > 0) { + for (ITestResult result : tests.getAllResults()) { + test = extent.startTest(result.getMethod().getMethodName()); + + test.getTest().setStartedTime(getTime(result.getStartMillis())); + test.getTest().setEndedTime(getTime(result.getEndMillis())); + + for (String group : result.getMethod().getGroups()) + test.assignCategory(group); + + String message = "Test " + status.toString().toLowerCase() + "ed"; + + if (result.getThrowable() != null) + message = result.getThrowable().getMessage(); + + test.log(status, message); + + extent.endTest(test); + } + } + } + + private Date getTime(long millis) { + Calendar calendar = Calendar.getInstance(); + calendar.setTimeInMillis(millis); + return calendar.getTime(); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest.java new file mode 100644 index 0000000000..3f895a3780 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest.java @@ -0,0 +1,293 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.run; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.net.URISyntaxException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.testng.TestNG; + +public class StartTest { + + public static long timeOfTest = 0; + + public static boolean debug = false; + + public static AtomicBoolean loggerInitialized = new AtomicBoolean(false); + + protected static Logger logger = null; + + public static void main(String[] args) { + + String debugEnabled = System.getProperty("debug"); + if (debugEnabled != null && debugEnabled.equalsIgnoreCase("true")) { + debug = true; + } + System.out.println("Debug mode is " + (debug ? "enabled" : "disabled")); + + enableLogger(); + + Config config = null; + try { + config = Utils.getConfig(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (config == null) { + logger.error("Failed to configuration file of ci tests."); + System.exit(1); + } + + // need to update + // List packagesToRun = config.getPackages(); + // if (packagesToRun == null || true == packagesToRun.isEmpty()) { + // logger.error("No package was configured to be executed."); + // System.exit(2); + // } + // StartTest tests = new StartTest(); + + // stop on error logic + // boolean stopOnClassFailure = false; + // String stopOnClassFailureStr = + // System.getProperty("stopOnClassFailure"); + // if (stopOnClassFailureStr != null && + // stopOnClassFailureStr.equalsIgnoreCase("true")) { + // stopOnClassFailure = true; + // } else { + // Boolean stopOnClassFailureObj = config.isStopOnClassFailure(); + // if (stopOnClassFailureObj != null) { + // stopOnClassFailure = stopOnClassFailureObj.booleanValue(); + // } + // } + // + + // tests.start(packagesToRun, stopOnClassFailure); + + // TestListenerAdapter tla = new TestListenerAdapter(); + // + // TestHTMLReporter report = new TestHTMLReporter(); + //// report. + + TestNG testng = new TestNG(); + + List suites = new ArrayList(); + suites.add("testSuites/" + args[0]); + testng.setTestSuites(suites); + // testng.addListener(tla); + testng.setUseDefaultListeners(true); + testng.setOutputDirectory("target/"); + + StartTest tests = new StartTest(); + // testng.setPreserveOrder(true); + // testng.setVerbose(2); + // testng.setSuiteThreadPoolSize(1); + // testng.setThreadCount(1); + testng.run(); + + } + + public StartTest() { + logger = Logger.getLogger(StartTest.class.getName()); + } + + public static void enableLogger() { + + if (false == loggerInitialized.get()) { + + loggerInitialized.set(true); + + String log4jPropsFile = System.getProperty("log4j.configuration"); + if (System.getProperty("os.name").contains("Windows")) { + String logProps = "src/main/resources/ci/conf/log4j.properties"; + if (log4jPropsFile == null) { + System.setProperty("targetlog", "target/"); + log4jPropsFile = logProps; + } + + } + PropertyConfigurator.configureAndWatch(log4jPropsFile); + + } + } + + // logger.debug("Going to run test class {}", testClass.getName()); + // logger.debug("Test class {} finished {}", testClass.getName(), (result.wasSuccessful() ? "OK." : " WITH ERROR.")); + // logger.debug("class {} failed tests: {}", testClass.getName(), (failuresPerClass * 1.0) / runsPerClass * 100 + " %"); + // logger.debug("class {} ignored tests: {}", testClass.getName(), (ignoredPerClass * 1.0) / runsPerClass * 100 + " %"); + private List getClassesForPackage(String pkgname) { + + List classes = new ArrayList(); + + // Get a File object for the package + File directory = null; + String fullPath; + String relPath = pkgname.replace('.', '/'); + + // System.out.println("ClassDiscovery: Package: " + pkgname + + // " becomes Path:" + relPath); + + URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); + + // System.out.println("ClassDiscovery: Resource = " + resource); + if (resource == null) { + throw new RuntimeException("No resource for " + relPath); + } + fullPath = resource.getFile(); + // System.out.println("ClassDiscovery: FullPath = " + resource); + + if (debug) { + System.out.println("fullPath is " + fullPath); + } + + try { + directory = new File(resource.toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException( + pkgname + " (" + resource + + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", + e); + } catch (IllegalArgumentException e) { + directory = null; + } + // System.out.println("ClassDiscovery: Directory = " + directory); + + if (directory != null && directory.exists()) { + + // Get the list of the files contained in the package + String[] files = directory.list(); + for (int i = 0; i < files.length; i++) { + + // we are only interested in .class files + if (files[i].endsWith(".class") && false == files[i].contains("$")) { + + // removes the .class extension + String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6); + + // System.out.println("ClassDiscovery: className = " + + // className); + + if (debug) { + System.out.println("ClassDiscovery: className = " + className); + } + + try { + Class clas = Class.forName(className); + boolean isAddToRun = false; + Method[] methods = clas.getMethods(); + for (Method method : methods) { + Annotation[] anns = method.getAnnotations(); + for (Annotation an : anns) { + if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) { + isAddToRun = true; + break; + } + } + } + if (isAddToRun) + classes.add(clas); + } catch (ClassNotFoundException e) { + throw new RuntimeException("ClassNotFoundException loading " + className); + } + } + } + } else { + try { + String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + if (debug) { + System.out.println("jarPath is " + jarPath); + } + + JarFile jarFile = new JarFile(jarPath); + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + if (entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { + + // System.out.println("ClassDiscovery: JarEntry: " + + // entryName); + String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + + // System.out.println("ClassDiscovery: className = " + + // className); + + if (false == className.contains("$")) { + + if (debug) { + System.out.println("ClassDiscovery: className = " + className); + } + + try { + Class clas = Class.forName(className); + boolean isAddToRun = false; + Method[] methods = clas.getMethods(); + for (Method method : methods) { + Annotation[] anns = method.getAnnotations(); + for (Annotation an : anns) { + if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) { + isAddToRun = true; + break; + } + } + } + if (isAddToRun) + classes.add(clas); + } catch (ClassNotFoundException e) { + throw new RuntimeException("ClassNotFoundException loading " + className); + } + } + } + } + jarFile.close(); + + } catch (IOException e) { + throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e); + } + } + return classes; + } + + private void addTableHead(StringBuilder results) { + results.append("
"); + results.append(""); + results.append(""); + results.append(""); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest2backup.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest2backup.java new file mode 100644 index 0000000000..bab5afaa08 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/run/StartTest2backup.java @@ -0,0 +1,410 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.run; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.lang.annotation.Annotation; +import java.lang.reflect.Method; +import java.net.URISyntaxException; +import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Enumeration; +import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +import org.apache.log4j.PropertyConfigurator; +import org.junit.runner.JUnitCore; +import org.junit.runner.Result; +import org.junit.runner.notification.Failure; +import org.openecomp.sdc.ci.tests.api.SdcTest; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class StartTest2backup { + + private List> testClasses = new ArrayList>(); + public static long timeOfTest = 0; + + public static boolean debug = false; + + public static AtomicBoolean loggerInitialized = new AtomicBoolean(false); + + protected static Logger logger = null; + + public static void main(String[] args) { + + String debugEnabled = System.getProperty("debug"); + if (debugEnabled != null && debugEnabled.equalsIgnoreCase("true")) { + debug = true; + } + System.out.println("Debug mode is " + (debug ? "enabled" : "disabled")); + + enableLogger(); + + Config config = null; + try { + config = Utils.getConfig(); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + if (config == null) { + logger.error("Failed to configuration file of ci tests."); + System.exit(1); + } + + List packagesToRun = config.getPackages(); + if (packagesToRun == null || true == packagesToRun.isEmpty()) { + logger.error("No package was configured to be executed."); + System.exit(2); + } + StartTest2backup tests = new StartTest2backup(); + + boolean stopOnClassFailure = false; + String stopOnClassFailureStr = System.getProperty("stopOnClassFailure"); + if (stopOnClassFailureStr != null && stopOnClassFailureStr.equalsIgnoreCase("true")) { + stopOnClassFailure = true; + } else { + Boolean stopOnClassFailureObj = config.isStopOnClassFailure(); + if (stopOnClassFailureObj != null) { + stopOnClassFailure = stopOnClassFailureObj.booleanValue(); + } + } + + tests.start(packagesToRun, stopOnClassFailure); + } + + public StartTest2backup() { + logger = LoggerFactory.getLogger(StartTest2backup.class.getName()); + } + + public static void enableLogger() { + + if (false == loggerInitialized.get()) { + + loggerInitialized.set(true); + + String log4jPropsFile = System.getProperty("log4j.configuration"); + if (System.getProperty("os.name").contains("Windows")) { + String logProps = "src/main/resources/ci/conf/log4j.properties"; + if (log4jPropsFile == null) { + System.setProperty("targetlog", "target/"); + log4jPropsFile = logProps; + } + + } + PropertyConfigurator.configureAndWatch(log4jPropsFile); + + } + } + + public void start(List packages, boolean exitOnFailure) { + + boolean success = true; + StringBuilder results = new StringBuilder(); + Result result; + + if (packages == null) { + return; + } + + for (String packageName : packages) { + // List classesForPackage = + // getClassesForPackage("org.openecomp.sdc.ci.tests.execute"); + List classesForPackage = getClassesForPackage(packageName); + if (classesForPackage != null && false == classesForPackage.isEmpty()) { + for (Class testUnit : classesForPackage) { + testClasses.add(testUnit); + } + } + } + + System.out.println(testClasses); + + // tsetClasses.add(LogValidatorTest.class); + // tsetClasses.add(AttNorthboundTest.class); + + results.append( + ""); + + Calendar calendar = Calendar.getInstance(); + timeOfTest = calendar.getTimeInMillis(); + SimpleDateFormat date_format = new SimpleDateFormat("MMM dd yyyy HH:mm:ss"); + results.append("

This report generated on " + date_format.format(calendar.getTime()) + "


"); + + results.append("
").append(testName).append("").append(result).append("").append(message).append("").append(convertExceptionToString(exception)).append(""); + + doc.append(""); + doc.append("
"); + + doc.append(convertExceptionToString(exception)); + + doc.append("
"); + doc.append("
").append("Unit Test").append("").append("Result").append("
"); + addTableHead(results); + + int size = testClasses.size(); + int index = 0; + + int totalRunTests = 0; + int totalFailureTests = 0; + int totalIgnoreTests = 0; + int numOfFailureClasses = 0; + for (Class testClass : testClasses) { + + index++; + + StringBuilder builder = new StringBuilder(); + String str = "***************************************************************************"; + builder.append(str + "\n"); + String current = "class " + index + "/" + size + " failure(" + numOfFailureClasses + ") + RUNS(" + + totalRunTests + ")" + " FAILURES(" + totalFailureTests + ") IGNORED(" + totalIgnoreTests + ")"; + int interval = ((str.length() - current.length() - 2) / 2); + String substring = str.substring(0, interval); + builder.append(substring + " " + current + " " + substring + "\n"); + builder.append(str + "\n"); + + System.out.println(builder.toString()); + + logger.debug(builder.toString()); + logger.debug("Going to run test class {}", testClass.getName()); + + result = JUnitCore.runClasses(testClass); + if (result.wasSuccessful() == false) { + numOfFailureClasses++; + } + logger.debug("Test class {} finished {}", testClass.getName(), (result.wasSuccessful() ? "OK." : " WITH ERROR.")); + List failures = result.getFailures(); + if (failures != null) { + for (Failure failure : failures) { + logger.error("Test class " + testClass.getName() + " failure test " + failure.getTestHeader() + "-" + + failure.getTrace()); + } + } + int runsPerClass = result.getRunCount(); + int failuresPerClass = result.getFailureCount(); + int ignoredPerClass = result.getIgnoreCount(); + + totalRunTests += runsPerClass; + totalFailureTests += failuresPerClass; + totalIgnoreTests += ignoredPerClass; + + logger.debug("class {} failed tests: {}", testClass.getName(), (failuresPerClass * 1.0) / runsPerClass * 100 + " %"); + logger.debug("class {} ignored tests: {}", testClass.getName(), (ignoredPerClass * 1.0) / runsPerClass * 100 + " %"); + + // List failures = result.getFailures(); + // if (failures != null) { + // for (Failure failure : failures) { + // System.err.println("9999999999" + failure.getTestHeader()); + // } + // } + + addUnitTestResult(results, testClass, result); + success &= result.wasSuccessful(); + + if (numOfFailureClasses > 0) { + // if (exitOnFailure) { + if (exitOnFailure) { + break; + } + } + } + + results.append("
"); + results.append("

Tests Summary:


"); + results.append("Total Runs : " + totalRunTests + "
"); + results.append("Total Failure : " + totalFailureTests + "
"); + results.append("Total: " + totalFailureTests + "/" + totalRunTests + "
"); + results.append(""); + + FileUtils.writeToFile(Config.instance().getOutputFolder() + File.separator + Config.instance().getReportName(), + results.toString()); + + if (!success) { + System.out.println("FAILURE"); + logger.error("Failure tests : " + + ((totalFailureTests + totalIgnoreTests) * 1.0) / (totalRunTests + totalIgnoreTests) + " %"); + logger.error("Ignored tests : " + (totalIgnoreTests * 1.0) / (totalRunTests + totalIgnoreTests) + " %"); + System.exit(1); + } + + System.out.println("SUCCESS"); + } + + private List getClassesForPackage(String pkgname) { + + List classes = new ArrayList(); + + // Get a File object for the package + File directory = null; + String fullPath; + String relPath = pkgname.replace('.', '/'); + + // System.out.println("ClassDiscovery: Package: " + pkgname + + // " becomes Path:" + relPath); + + URL resource = ClassLoader.getSystemClassLoader().getResource(relPath); + + // System.out.println("ClassDiscovery: Resource = " + resource); + if (resource == null) { + throw new RuntimeException("No resource for " + relPath); + } + fullPath = resource.getFile(); + // System.out.println("ClassDiscovery: FullPath = " + resource); + + if (debug) { + System.out.println("fullPath is " + fullPath); + } + + try { + directory = new File(resource.toURI()); + } catch (URISyntaxException e) { + throw new RuntimeException( + pkgname + " (" + resource + + ") does not appear to be a valid URL / URI. Strange, since we got it from the system...", + e); + } catch (IllegalArgumentException e) { + directory = null; + } + // System.out.println("ClassDiscovery: Directory = " + directory); + + if (directory != null && directory.exists()) { + + // Get the list of the files contained in the package + String[] files = directory.list(); + for (int i = 0; i < files.length; i++) { + + // we are only interested in .class files + if (files[i].endsWith(".class") && false == files[i].contains("$")) { + + // removes the .class extension + String className = pkgname + '.' + files[i].substring(0, files[i].length() - 6); + + // System.out.println("ClassDiscovery: className = " + + // className); + + if (debug) { + System.out.println("ClassDiscovery: className = " + className); + } + + try { + Class clas = Class.forName(className); + boolean isAddToRun = false; + Method[] methods = clas.getMethods(); + for (Method method : methods) { + Annotation[] anns = method.getAnnotations(); + for (Annotation an : anns) { + if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) { + isAddToRun = true; + break; + } + } + } + if (isAddToRun) + classes.add(clas); + } catch (ClassNotFoundException e) { + throw new RuntimeException("ClassNotFoundException loading " + className); + } + } + } + } else { + try { + String jarPath = fullPath.replaceFirst("[.]jar[!].*", ".jar").replaceFirst("file:", ""); + + if (debug) { + System.out.println("jarPath is " + jarPath); + } + + JarFile jarFile = new JarFile(jarPath); + Enumeration entries = jarFile.entries(); + while (entries.hasMoreElements()) { + JarEntry entry = entries.nextElement(); + String entryName = entry.getName(); + if (entryName.startsWith(relPath) && entryName.length() > (relPath.length() + "/".length())) { + + // System.out.println("ClassDiscovery: JarEntry: " + + // entryName); + String className = entryName.replace('/', '.').replace('\\', '.').replace(".class", ""); + + // System.out.println("ClassDiscovery: className = " + + // className); + + if (false == className.contains("$")) { + + if (debug) { + System.out.println("ClassDiscovery: className = " + className); + } + + try { + Class clas = Class.forName(className); + boolean isAddToRun = false; + Method[] methods = clas.getMethods(); + for (Method method : methods) { + Annotation[] anns = method.getAnnotations(); + for (Annotation an : anns) { + if (an.annotationType().getSimpleName().equalsIgnoreCase("Test")) { + isAddToRun = true; + break; + } + } + } + if (isAddToRun) + classes.add(clas); + } catch (ClassNotFoundException e) { + throw new RuntimeException("ClassNotFoundException loading " + className); + } + } + } + } + jarFile.close(); + + } catch (IOException e) { + throw new RuntimeException(pkgname + " (" + directory + ") does not appear to be a valid package", e); + } + } + return classes; + } + + private void addTableHead(StringBuilder results) { + results.append(""); + results.append("").append("Unit Test").append(""); + results.append("").append("Result").append(""); + results.append(""); + } + + private void addUnitTestResult(StringBuilder results, Class testClass, + Result unitTestResult) { + + boolean isSuccess = unitTestResult.wasSuccessful(); + + String result = (isSuccess) ? "success" : "fail"; + String fileName = FileUtils.getFileName(testClass.getName()); + results.append(""); + // results.append("").append(FileUtils.getFileName(testClass.getName())).append(""); + results.append("") + .append("" + fileName + "").append(""); + results.append("").append(result).append(""); + results.append(""); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/CrudE2E.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/CrudE2E.java new file mode 100644 index 0000000000..00ff48e887 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/CrudE2E.java @@ -0,0 +1,220 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.sanity; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.Pair; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.AssocType; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.Assert; +import org.testng.annotations.Test; + +import fj.data.Either; + +public class CrudE2E extends ComponentBaseTest { + private static Logger log = LoggerFactory.getLogger(CrudE2E.class.getName()); + + public Component resourceDetailsVFCcomp_01; + public Component resourceDetailsVFCsoft_01; + public Component resourceDetailsCP_01; + public Component resourceDetailsVL_01; + public Component resourceDetailsVF_01; + public Component resourceDetailsVF_02; + + public ComponentInstance resourceDetailsVFC1compIns1; + public ComponentInstance resourceDetailsVFC1softIns1; + public ComponentInstance resourceDetailsCP1ins_01; + public ComponentInstance resourceDetailsVL1ins_01; + public ComponentInstance resourceDetailsVF1ins_01; + public Component defaultService1; + private List variablesAsList = new ArrayList(); + + @Rule + public static TestName name = new TestName(); + + public CrudE2E() { + super(name, CrudE2E.class.getName()); + } + + @Test + public void complexScenario() throws Exception { + + User designer = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + + //////// create defaultService1 /////////////////////// + Either createDefaultService1e = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true); + defaultService1 = createDefaultService1e.left().value(); + + //////// create VFC1 (resourceDetailsVFCcomp_01) DerivedFrom COMPUTE + //////// type add all possible informational artifacts and change state + //////// to CERTIFY//////// + Either resourceDetailsVFCcompE = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, NormativeTypesEnum.COMPUTE,ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, UserRoleEnum.DESIGNER, true); + resourceDetailsVFCcomp_01 = resourceDetailsVFCcompE.left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.CHEF, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.PUPPET, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG_XML, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.DG_XML, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MURANO_PKG, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsVFCcomp_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.changeComponentState(resourceDetailsVFCcomp_01, UserRoleEnum.DESIGNER,LifeCycleStatesEnum.CERTIFY, true); + + //////// create VFC2 (resourceDetailsVFCsoft_01) DerivedFrom SOFTWARE + //////// type and change state to CERTIFY//////// + Either resourceDetailsVFCsoftE = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VFC, NormativeTypesEnum.SOFTWARE_COMPONENT,ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true); + resourceDetailsVFCsoft_01 = resourceDetailsVFCsoftE.left().value(); + AtomicOperationUtils.changeComponentState(resourceDetailsVFCsoft_01, UserRoleEnum.DESIGNER,LifeCycleStatesEnum.CERTIFY, true); + + //////// create CP1 (resourceDetailsVFCsoft_01) DerivedFrom PORT type + //////// and change state to CHECKIN//////// + Either resourceDetailsCP_01e = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, NormativeTypesEnum.PORT,ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true); + resourceDetailsCP_01 = resourceDetailsCP_01e.left().value(); + AtomicOperationUtils.changeComponentState(resourceDetailsCP_01, UserRoleEnum.DESIGNER,LifeCycleStatesEnum.CHECKIN, true); + + //////// create VL1 (resourceDetailsVFCsoft_01) DerivedFrom NETWORK type + //////// and change state to CERTIFY//////// + Either resourceDetailsVL_01e = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VL, NormativeTypesEnum.NETWORK,ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, UserRoleEnum.DESIGNER, true); + resourceDetailsVL_01 = resourceDetailsVL_01e.left().value(); + AtomicOperationUtils.changeComponentState(resourceDetailsVL_01, UserRoleEnum.DESIGNER,LifeCycleStatesEnum.CERTIFY, true); + + //////// create VF1 (resourceDetailsVFCcomp_01) DerivedFrom COMPUTE type + //////// add all possible deployment and informational artifacts + //////// ////////// + Either resourceDetailsVF_01e = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.ROOT,ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, UserRoleEnum.DESIGNER, true); + resourceDetailsVF_01 = resourceDetailsVF_01e.left().value(); + ArtifactDefinition heatArtifact = AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT, resourceDetailsVF_01, UserRoleEnum.DESIGNER, true, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_VOL, resourceDetailsVF_01,UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.HEAT_NET, resourceDetailsVF_01,UserRoleEnum.DESIGNER, true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsVF_01, UserRoleEnum.DESIGNER,true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.CHEF, resourceDetailsVF_01, UserRoleEnum.DESIGNER,false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.PUPPET, resourceDetailsVF_01, UserRoleEnum.DESIGNER,false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG, resourceDetailsVF_01, UserRoleEnum.DESIGNER,false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.YANG_XML, resourceDetailsVF_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.DG_XML, resourceDetailsVF_01, UserRoleEnum.DESIGNER,false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MURANO_PKG, resourceDetailsVF_01,UserRoleEnum.DESIGNER, false, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.OTHER, resourceDetailsVF_01, UserRoleEnum.DESIGNER,false, true); + + //////// Add VFC1 VFC2 CP and VL to VF container ///////////// + resourceDetailsVFC1compIns1 = AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCcomp_01, resourceDetailsVF_01,UserRoleEnum.DESIGNER, true).left().value(); + resourceDetailsVFC1softIns1 = AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVFCsoft_01, resourceDetailsVF_01,UserRoleEnum.DESIGNER, true).left().value(); + resourceDetailsCP1ins_01 = AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsCP_01,resourceDetailsVF_01, UserRoleEnum.DESIGNER, true).left().value(); + resourceDetailsVL1ins_01 = AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVL_01,resourceDetailsVF_01, UserRoleEnum.DESIGNER, true).left().value(); + + //////// associate cp-vl vl-vfcComp and vfcComp-vfcSoft//////// + resourceDetailsVF_01 = AtomicOperationUtils.getResourceObject(resourceDetailsVF_01, UserRoleEnum.DESIGNER); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF_01, resourceDetailsCP1ins_01,resourceDetailsVL1ins_01, AssocType.LINKABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF_01, resourceDetailsCP1ins_01,resourceDetailsVFC1compIns1, AssocType.BINDABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF_01, resourceDetailsVFC1compIns1,resourceDetailsVFC1softIns1, AssocType.NODE.getAssocType(), UserRoleEnum.DESIGNER, true); + + //////// download all VF1 artifacts//////// + Collection artifacts = resourceDetailsVF_01.getDeploymentArtifacts().values(); + List collect = artifacts.stream().filter(p -> p.checkEsIdExist() == true).map(p -> p.getUniqueId()).collect(Collectors.toList()); + artifacts.stream().filter(p -> p.checkEsIdExist() == true).map(p -> p.getUniqueId()).forEach(item -> log.debug(item)); + + //////// get all VF1 artifacts//////// + + Collection> componentInstancesProperties = resourceDetailsVF_01.getComponentInstancesProperties().values(); + List collect2 = componentInstancesProperties.stream().filter(p -> p.isEmpty() == false).flatMap(l -> l.stream()).collect(Collectors.toList()).stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + + //////// certify VF1 - failed due to uncertified CP instance //////// + RestResponse changeVfStateFailed = LifecycleRestUtils.changeComponentState(resourceDetailsVF_01, designer,LifeCycleStatesEnum.CERTIFICATIONREQUEST); + Resource resResourceDetailsVF_01 = (Resource) resourceDetailsVF_01; + variablesAsList = Arrays.asList(resResourceDetailsVF_01.getResourceType().toString(),resourceDetailsCP_01.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.VALIDATED_RESOURCE_NOT_FOUND.name(), variablesAsList,changeVfStateFailed.getResponse()); + + //////// certify resources CP1 //////// + resourceDetailsCP_01 = AtomicOperationUtils.changeComponentState(resourceDetailsCP_01, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + //////// replace VF1 instances with new certified instances (CP1 + //////// replaced) //////// + Either, RestResponse> changeComponentInstanceVersion = AtomicOperationUtils.changeComponentInstanceVersion(resourceDetailsVF_01, resourceDetailsCP1ins_01, resourceDetailsCP_01,UserRoleEnum.DESIGNER, true); + resourceDetailsVF_01 = changeComponentInstanceVersion.left().value().getLeft(); + resourceDetailsCP1ins_01 = changeComponentInstanceVersion.left().value().getRight(); + + //////// associate cp-vl and cp-vfc1,//////// + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF_01, resourceDetailsCP1ins_01,resourceDetailsVL1ins_01, AssocType.LINKABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.associate2ResourceInstances(resourceDetailsVF_01, resourceDetailsCP1ins_01,resourceDetailsVFC1compIns1, AssocType.BINDABLE.getAssocType(), UserRoleEnum.DESIGNER, true); + + /////// change VF1 state to CHECK-IN and add it as instance to service1 + /////// container + resourceDetailsVF_01 = AtomicOperationUtils.changeComponentState(resourceDetailsVF_01, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resourceDetailsVF1ins_01 = AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceDetailsVF_01,defaultService1, UserRoleEnum.DESIGNER, true).left().value(); + + //////// distribute service1 - failed due to incorrect LifeCyclestatus + //////// //////// + RestResponse distributeService = AtomicOperationUtils.distributeService(defaultService1, false); + Assert.assertEquals(distributeService, null, "verification failed"); + + //////// certify service1 - failed due to uncertified instances //////// + designer = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + RestResponse changeServicetStateFailed = LifecycleRestUtils.changeComponentState(defaultService1, designer,LifeCycleStatesEnum.CERTIFICATIONREQUEST); + variablesAsList = Arrays.asList(defaultService1.getComponentType().toString().toLowerCase(),resourceDetailsVF_01.getName()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.VALIDATED_RESOURCE_NOT_FOUND.name(), variablesAsList,changeServicetStateFailed.getResponse()); + + ////// change VF1 state to CERTIFIED + resourceDetailsVF_01 = AtomicOperationUtils.changeComponentState(resourceDetailsVF_01, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + //////// replace VF1 instances with new certified instances //////// + changeComponentInstanceVersion = AtomicOperationUtils.changeComponentInstanceVersion(defaultService1,resourceDetailsVF1ins_01, resourceDetailsVF_01, UserRoleEnum.DESIGNER, true); + resourceDetailsVF_01 = changeComponentInstanceVersion.left().value().getLeft(); + resourceDetailsVFC1compIns1 = changeComponentInstanceVersion.left().value().getRight(); + + /////// certify service1 //////// + defaultService1 = AtomicOperationUtils.changeComponentState(defaultService1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + //////// distribute service1 - successfully //////// + AtomicOperationUtils.distributeService(defaultService1, true); + + /////// create VF2 //////// + Either resourceDetailsVF_02e = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.ROOT,ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, UserRoleEnum.DESIGNER, true); + resourceDetailsVF_02 = resourceDetailsVF_02e.left().value(); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/MultipleResourceUpdate.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/MultipleResourceUpdate.java new file mode 100644 index 0000000000..8b8a793bc6 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/sanity/MultipleResourceUpdate.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.sanity; + +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.AssocType; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.testng.annotations.Test; + +public class MultipleResourceUpdate extends ComponentBaseTest { + + @Rule + public static TestName name = new TestName(); + + public MultipleResourceUpdate() { + super(name, MultipleResourceUpdate.class.getName()); + } + + @Test + public void simpleScenario() throws Exception { + + // Creating VF and Resource instances + Resource vf = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource cp1 = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.CP, NormativeTypesEnum.PORT, + ResourceCategoryEnum.NETWORK_CONNECTIVITY_CON_POINT, UserRoleEnum.DESIGNER, true).left().value(); + Resource cp2 = AtomicOperationUtils.createResourceByType(ResourceTypeEnum.CP, UserRoleEnum.DESIGNER, true).left().value(); + Resource vl = AtomicOperationUtils + .createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VL, NormativeTypesEnum.NETWORK, + ResourceCategoryEnum.NETWORK_CONNECTIVITY_VIRTUAL_LINK, UserRoleEnum.DESIGNER, true).left().value(); + + vf.getCreatorUserId(); + + // Check In Resources + AtomicOperationUtils.changeComponentState(cp1, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + AtomicOperationUtils.changeComponentState(cp2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + AtomicOperationUtils.changeComponentState(vl, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true); + + // CheckIn all other except VF + ComponentInstance instanceCP1 = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp1, vf, UserRoleEnum.DESIGNER, true).left().value(); + ComponentInstance instanceVL = AtomicOperationUtils + .addComponentInstanceToComponentContainer(vl, vf, UserRoleEnum.DESIGNER, true).left().value(); + ComponentInstance instanceCP2 = AtomicOperationUtils + .addComponentInstanceToComponentContainer(cp2, vf, UserRoleEnum.DESIGNER, true).left().value(); + + vf = (Resource) AtomicOperationUtils.getCompoenntObject(vf, UserRoleEnum.DESIGNER); + + // Create Vertex(Link/Associate 2 Resource Instances on Canvas) + AtomicOperationUtils.associate2ResourceInstances(vf, instanceCP1, instanceVL, AssocType.LINKABLE.getAssocType(), + UserRoleEnum.DESIGNER, true); + + List componentInstanceReqDetailsList = new ArrayList<>(); + componentInstanceReqDetailsList.add(new ComponentInstanceReqDetails(instanceCP1)); + componentInstanceReqDetailsList.add(new ComponentInstanceReqDetails(instanceCP2)); + componentInstanceReqDetailsList.add(new ComponentInstanceReqDetails(instanceVL)); + + ComponentInstanceReqDetails compInstDet = componentInstanceReqDetailsList.get(0); + compInstDet.setPosX("150"); + compInstDet.setPosY("150"); + compInstDet = componentInstanceReqDetailsList.get(1); + compInstDet.setPosX("400"); + compInstDet.setPosY("150"); + compInstDet = componentInstanceReqDetailsList.get(2); + compInstDet.setPosX("150"); + compInstDet.setPosY("300"); + + RestResponse response = ComponentInstanceRestUtils.updateMultipleComponentInstance( + componentInstanceReqDetailsList, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), vf.getUniqueId(), + vf.getComponentType()); + assertTrue("response code is not 200, returned: " + response.getErrorCode(), + response.getErrorCode() == ProductRestUtils.STATUS_CODE_SUCCESS); + + compInstDet = componentInstanceReqDetailsList.get(0); + compInstDet.setPosX("350"); + compInstDet.setPosY("350"); + compInstDet = componentInstanceReqDetailsList.get(1); + compInstDet.setPosX("600"); + compInstDet.setPosY("350"); + compInstDet = componentInstanceReqDetailsList.get(2); + compInstDet.setPosX("350"); + compInstDet.setPosY("500"); + + response = ComponentInstanceRestUtils.updateMultipleComponentInstance(componentInstanceReqDetailsList, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), vf.getUniqueId(), vf.getComponentType()); + assertTrue("response code is not 200, returned: " + response.getErrorCode(), + response.getErrorCode() == ProductRestUtils.STATUS_CODE_SUCCESS); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaCapabilitiesNodeTemplatesDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaCapabilitiesNodeTemplatesDefinition.java new file mode 100644 index 0000000000..76c0c86680 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaCapabilitiesNodeTemplatesDefinition.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +public class ToscaCapabilitiesNodeTemplatesDefinition { + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaDefinition.java new file mode 100644 index 0000000000..5ce4b8c618 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaDefinition.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +import java.util.List; + +public class ToscaDefinition { + + String toscaDefinitionVersion; + List toscaImports; + List toscaNodeTypes; + ToscaTopologyTemplateDefinition toscaTopologyTemplate; + + public ToscaDefinition() { + super(); + } + + public String getToscaDefinitionVersion() { + return toscaDefinitionVersion; + } + + public void setToscaDefinitionVersion(String toscaDefinitionVersion) { + this.toscaDefinitionVersion = toscaDefinitionVersion; + } + + public List getToscaImports() { + return toscaImports; + } + + public void setToscaImports(List toscaImports) { + this.toscaImports = toscaImports; + } + + public List getToscaNodeTypes() { + return toscaNodeTypes; + } + + public void setToscaNodeTypes(List toscaNodeTypes) { + this.toscaNodeTypes = toscaNodeTypes; + } + + public ToscaTopologyTemplateDefinition getToscaTopologyTemplate() { + return toscaTopologyTemplate; + } + + public void setToscaTopologyTemplate(ToscaTopologyTemplateDefinition toscaTopologyTemplate) { + this.toscaTopologyTemplate = toscaTopologyTemplate; + } + + @Override + public String toString() { + return "ToscaDefinition [toscaDefinitionVersion=" + toscaDefinitionVersion + ", toscaImports=" + toscaImports + + ", toscaNodeTypes=" + toscaNodeTypes + ", toscaTopologyTemplate=" + toscaTopologyTemplate + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaGroupsTopologyTemplateDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaGroupsTopologyTemplateDefinition.java new file mode 100644 index 0000000000..e19fcb3aba --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaGroupsTopologyTemplateDefinition.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +import java.util.List; + +// spec page 102 +public class ToscaGroupsTopologyTemplateDefinition { + + String type; // required + String description; + // List toscaGroupsProperiesDefinition; + List targets; // required + // List toscaGroupsInterfacesDefinition; + List members; + + public ToscaGroupsTopologyTemplateDefinition() { + super(); + // TODO Auto-generated constructor stub + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getTargets() { + return targets; + } + + public void setTargets(List targets) { + this.targets = targets; + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + @Override + public String toString() { + return "ToscaGroupsTopologyTemplateDefinition [type=" + type + ", description=" + description + ", targets=" + + targets + ", members=" + members + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaImportsDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaImportsDefinition.java new file mode 100644 index 0000000000..5363223c38 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaImportsDefinition.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +import java.util.List; + +import org.openecomp.sdc.ci.tests.datatypes.GroupHeatMetaDefinition; + +public class ToscaImportsDefinition { + + String typeName; + + List groupHeatMetaDefinition; + + public ToscaImportsDefinition() { + super(); + } + + public String getTypeName() { + return typeName; + } + + public void setTypeName(String typeName) { + this.typeName = typeName; + } + + public List getGroupHeatMetaDefinition() { + return groupHeatMetaDefinition; + } + + public void setGroupHeatMetaDefinition(List groupHeatMetaDefinition) { + this.groupHeatMetaDefinition = groupHeatMetaDefinition; + } + + @Override + public String toString() { + return "TypeHeatMetaDefinition [typeName=" + typeName + ", groupHeatMetaDefinition=" + groupHeatMetaDefinition + + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaInputsTopologyTemplateDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaInputsTopologyTemplateDefinition.java new file mode 100644 index 0000000000..62f859c567 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaInputsTopologyTemplateDefinition.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +public class ToscaInputsTopologyTemplateDefinition { + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTemplatesTopologyTemplateDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTemplatesTopologyTemplateDefinition.java new file mode 100644 index 0000000000..8970467e9c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTemplatesTopologyTemplateDefinition.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +import java.util.List; + +public class ToscaNodeTemplatesTopologyTemplateDefinition { + + String name; + String type; + List properties; + List requirements; + List capabilities; + + public ToscaNodeTemplatesTopologyTemplateDefinition() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } + + public List getRequirements() { + return requirements; + } + + public void setRequirements(List requirements) { + this.requirements = requirements; + } + + public List getCapabilities() { + return capabilities; + } + + public void setCapabilities(List capabilities) { + this.capabilities = capabilities; + } + + @Override + public String toString() { + return "ToscaNodeTemplatesTopologyTemplateDefinition [name=" + name + ", type=" + type + ", properties=" + + properties + ", requirements=" + requirements + ", capabilities=" + capabilities + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTypesDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTypesDefinition.java new file mode 100644 index 0000000000..148e99c58c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaNodeTypesDefinition.java @@ -0,0 +1,54 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +// spec page 88 +public class ToscaNodeTypesDefinition { + + String name; + String derivedFrom; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDerivedFrom() { + return derivedFrom; + } + + public void setDerivedFrom(String derivedFrom) { + this.derivedFrom = derivedFrom; + } + + public ToscaNodeTypesDefinition() { + super(); + } + + @Override + public String toString() { + return "CsarNodeTypesDefinition [name=" + name + ", derivedFrom=" + derivedFrom + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaPropertiesNodeTemplatesDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaPropertiesNodeTemplatesDefinition.java new file mode 100644 index 0000000000..cf0add050d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaPropertiesNodeTemplatesDefinition.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +public class ToscaPropertiesNodeTemplatesDefinition { + + String name; + Object value; + + public ToscaPropertiesNodeTemplatesDefinition() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Object getValue() { + return value; + } + + public void setValue(Object value) { + this.value = value; + } + + @Override + public String toString() { + return "ToscaPropertyNodeTemplatesTopologyTemplateDefinition [name=" + name + ", value=" + value + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaRequirementsNodeTemplatesDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaRequirementsNodeTemplatesDefinition.java new file mode 100644 index 0000000000..bd9f0f0f5e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaRequirementsNodeTemplatesDefinition.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +public class ToscaRequirementsNodeTemplatesDefinition { + + String name; + String capability; + String node; + String relationship; + + public ToscaRequirementsNodeTemplatesDefinition() { + super(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getCapability() { + return capability; + } + + public void setCapability(String capability) { + this.capability = capability; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public String getRelationship() { + return relationship; + } + + public void setRelationship(String relationship) { + this.relationship = relationship; + } + + @Override + public String toString() { + return "ToscaRequirementsDefinition [name=" + name + ", capability=" + capability + ", node=" + node + + ", relationship=" + relationship + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaTopologyTemplateDefinition.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaTopologyTemplateDefinition.java new file mode 100644 index 0000000000..549867a562 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/tosca/datatypes/ToscaTopologyTemplateDefinition.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.tosca.datatypes; + +import java.util.List; + +// spec page 104 +public class ToscaTopologyTemplateDefinition { + + String description; + List toscaInputsTopologyTemplateDefinition; + List toscaNodeTemplatesTopologyTemplateDefinition; + // List + List toscaGroupsTopologyTemplateDefinition; + // List + // toscaPolociesTopologyTemplateDefinition; + // List + // toscaOutputsTopologyTemplateDefinition; + + public ToscaTopologyTemplateDefinition() { + super(); + } + + public List getToscaInputsTopologyTemplateDefinition() { + return toscaInputsTopologyTemplateDefinition; + } + + public void setToscaInputsTopologyTemplateDefinition( + List toscaInputsTopologyTemplateDefinition) { + this.toscaInputsTopologyTemplateDefinition = toscaInputsTopologyTemplateDefinition; + } + + public List getToscaNodeTemplatesTopologyTemplateDefinition() { + return toscaNodeTemplatesTopologyTemplateDefinition; + } + + public void setToscaNodeTemplatesTopologyTemplateDefinition( + List toscaNodeTemplatesTopologyTemplateDefinition) { + this.toscaNodeTemplatesTopologyTemplateDefinition = toscaNodeTemplatesTopologyTemplateDefinition; + } + + public List getToscaGroupsTopologyTemplateDefinition() { + return toscaGroupsTopologyTemplateDefinition; + } + + public void setToscaGroupsTopologyTemplateDefinition( + List toscaGroupsTopologyTemplateDefinition) { + this.toscaGroupsTopologyTemplateDefinition = toscaGroupsTopologyTemplateDefinition; + } + + @Override + public String toString() { + return "ToscaTopologyTemplateDefinition [toscaInputsTopologyTemplateDefinition=" + + toscaInputsTopologyTemplateDefinition + ", toscaNodeTemplatesTopologyTemplateDefinition=" + + toscaNodeTemplatesTopologyTemplateDefinition + ", toscaGroupsTopologyTemplateDefinition=" + + toscaGroupsTopologyTemplateDefinition + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/AddUserAuditMessageInfo.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/AddUserAuditMessageInfo.java new file mode 100644 index 0000000000..9ca8adee53 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/AddUserAuditMessageInfo.java @@ -0,0 +1,113 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.users; + +public class AddUserAuditMessageInfo { + + String TIMESTAMP; + String ACTION; + // String MODIFIER_NAME; + String MODIFIER; + // String USER_UID; + // String USER_NAME; + // String USER_EMAIL; + // String USER_ROLE; + String USER; + String STATUS; + String DESC; + + public AddUserAuditMessageInfo(String timestamp, String action, String modifierName, String modifierUid, + String user, String status, String desc) { + super(); + this.TIMESTAMP = timestamp; + this.ACTION = action; + // this.MODIFIER_NAME = modifierName; + this.MODIFIER = modifierUid; + this.USER = user; + this.STATUS = status; + this.DESC = desc; + } + + public AddUserAuditMessageInfo() { + super(); + } + + public String getTIMESTAMP() { + return TIMESTAMP; + } + + public void setTIMESTAMP(String tIMESTAMP) { + TIMESTAMP = tIMESTAMP; + } + + public String getACTION() { + return ACTION; + } + + public void setACTION(String aCTION) { + ACTION = aCTION; + } + + // public String getMODIFIER_NAME() { + // return MODIFIER_NAME; + // } + // public void setMODIFIER_NAME(String mODIFIER_NAME) { + // MODIFIER_NAME = mODIFIER_NAME; + // } + public String getMODIFIER() { + return MODIFIER; + } + + public void setMODIFIER(String mODIFIER_UID) { + MODIFIER = mODIFIER_UID; + } + + public String getUSER() { + return USER; + } + + public void setUSER(String uSER) { + USER = uSER; + } + + public String getSTATUS() { + return STATUS; + } + + public void setSTATUS(String sTATUS) { + STATUS = sTATUS; + } + + public String getDESC() { + return DESC; + } + + public void setDESC(String dESC) { + DESC = dESC; + } + + @Override + public String toString() { + return "AddUserAuditMessageInfo [timestamp=" + TIMESTAMP + ", action=" + ACTION + ", modifierUid=" + MODIFIER + + ", user=" + USER + ", status=" + STATUS + ", desc=" + DESC + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserAuditJavaObject.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserAuditJavaObject.java new file mode 100644 index 0000000000..b34d474cf0 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserAuditJavaObject.java @@ -0,0 +1,133 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.users; + +public class UserAuditJavaObject { + + String TIMESTAMP; + String ACTION; + // String MODIFIER_NAME; + String MODIFIER; + String USER; + // String USER_NAME; + // String USER_EMAIL; + // String USER_ROLE; + String STATUS; + String DESC; + + public UserAuditJavaObject(String timestamp, String action, String modifier, String user, String status, + String desc) { + super(); + this.TIMESTAMP = timestamp; + this.ACTION = action; + // this.MODIFIER_NAME = modifierName; + this.MODIFIER = modifier; + this.USER = user; + // this.USER_NAME = userName; + // this.USER_EMAIL = userEmail; + // this.USER_ROLE = userRole; + this.STATUS = status; + this.DESC = desc; + } + + public UserAuditJavaObject() { + super(); + } + + public String getTIMESTAMP() { + return TIMESTAMP; + } + + public void setTIMESTAMP(String tIMESTAMP) { + TIMESTAMP = tIMESTAMP; + } + + public String getACTION() { + return ACTION; + } + + public void setACTION(String aCTION) { + ACTION = aCTION; + } + + // public String getMODIFIER_NAME() { + // return MODIFIER_NAME; + // } + // public void setMODIFIER_NAME(String mODIFIER_NAME) { + // MODIFIER_NAME = mODIFIER_NAME; + // } + public String getMODIFIER() { + return MODIFIER; + } + + public void setMODIFIER(String mODIFIER_UID) { + MODIFIER = mODIFIER_UID; + } + + public String getUSER() { + return USER; + } + + public void setUSER(String uSER) { + USER = uSER; + } + + // public String getUSER_NAME() { + // return USER_NAME; + // } + // public void setUSER_NAME(String uSER_NAME) { + // USER_NAME = uSER_NAME; + // } + // public String getUSER_EMAIL() { + // return USER_EMAIL; + // } + // public void setUSER_EMAIL(String uSER_EMAIL) { + // USER_EMAIL = uSER_EMAIL; + // } + // public String getUSER_ROLE() { + // return USER_ROLE; + // } + // public void setUSER_ROLE(String uSER_ROLE) { + // USER_ROLE = uSER_ROLE; + // } + public String getSTATUS() { + return STATUS; + } + + public void setSTATUS(String sTATUS) { + STATUS = sTATUS; + } + + public String getDESC() { + return DESC; + } + + public void setDESC(String dESC) { + DESC = dESC; + } + + @Override + public String toString() { + return "UserAuditJavaObject [timestamp=" + TIMESTAMP + ", action=" + ACTION + ", modifier=" + MODIFIER + + ", user=" + USER + ", status=" + STATUS + ", desc=" + DESC + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserHeaderData.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserHeaderData.java new file mode 100644 index 0000000000..06320bcb5f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserHeaderData.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.users; + +public class UserHeaderData { + String contentType; + String httpCspUserId; + String accept; + + public UserHeaderData(String contentType, String httpCspUserId, String accept) { + super(); + this.contentType = contentType; + this.httpCspUserId = httpCspUserId; + this.accept = accept; + } + + public String getContentType() { + return contentType; + } + + public void setContentType(String contentType) { + this.contentType = contentType; + } + + public String getHttpCspUserId() { + return httpCspUserId; + } + + public void setHttpCspUserId(String httpCspUserId) { + this.httpCspUserId = httpCspUserId; + } + + public String getAccept() { + return accept; + } + + public void setAccept(String accept) { + this.accept = accept; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserResponseMessageEnum.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserResponseMessageEnum.java new file mode 100644 index 0000000000..4db52c2886 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/UserResponseMessageEnum.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.users; + +public enum UserResponseMessageEnum { + + SUCCESS_MESSAGE("OK"), + MISSING_INFORMATION("Error: Missing information"), + METHOD_NOT_ALLOWED("Error: Method not allowed"), + RESTRICTED_OPERATION("Error: Restricted operation"), + USER_ALREADY_EXISTS("Error: User with %s ID already exists"), + INVALID_EMAIL("Error: Invalid Content. Invalid e-mail address %s"), + INVALID_ROLE("Error: Invalid Content. Invalid role %s"), + INVALID_CONTENT("Error: Invalid content"), + USER_NOT_FOUND("Error: User with %s ID is not found"), + INTERNAL_SERVER_ERROR("Error: Internal Server Error. Try later again"), + ADMINISTARTOR_CAN_BE_DELETED("Error: Administrator can be deleted by other administrator only"), + RESTRICTED_ACCESS("Error: Restricted access"); + + String value; + + private UserResponseMessageEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/WebSealUserDetails.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/WebSealUserDetails.java new file mode 100644 index 0000000000..609ebf22b7 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/users/WebSealUserDetails.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.users; + +public class WebSealUserDetails { + String firstName; + String lastName; + String userId; + String email; + + public WebSealUserDetails() { + super(); + } + + public WebSealUserDetails(String firstName, String lastName, String userId, String emailAddress) { + super(); + this.firstName = firstName; + this.lastName = lastName; + this.userId = userId; + this.email = emailAddress; + + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getEmailAddress() { + return email; + } + + public void setEmailAddress(String emailAddress) { + this.email = emailAddress; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ArtifactUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ArtifactUtils.java new file mode 100644 index 0000000000..12f8ffe984 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ArtifactUtils.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; + +public class ArtifactUtils { + + public static ArtifactDefinition convertArtifactReqToDefinition(ArtifactReqDetails artifactReq) { + ArtifactDefinition artifact = new ArtifactDefinition(); + artifact.setArtifactLabel(artifactReq.getArtifactLabel()); + artifact.setArtifactDisplayName(artifactReq.getArtifactDisplayName()); + artifact.setArtifactGroupType(ArtifactGroupTypeEnum.findType(artifactReq.getArtifactGroupType())); + artifact.setArtifactType(artifactReq.getArtifactType().toUpperCase()); + artifact.setArtifactName(artifactReq.getArtifactName()); + artifact.setDescription(artifactReq.getDescription()); + artifact.setUniqueId(artifactReq.getUniqueId()); + artifact.setTimeout(artifactReq.getTimeout()); + artifact.setEsId(artifactReq.getUniqueId()); + + return artifact; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/DbUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/DbUtils.java new file mode 100644 index 0000000000..22295cb451 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/DbUtils.java @@ -0,0 +1,306 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.users.UserAuditJavaObject; +import org.openecomp.sdc.ci.tests.utils.cassandra.CassandraUtils; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public class DbUtils { + + private static String titanConfigFilePath; + private static TitanGraph titanGraph; + + public static void cleanAllAudits() throws IOException { + // utils.deleteFromEsDbByPattern("_all"); + // deleteFromEsDbByPattern("auditingevents-*"); + CassandraUtils.truncateAllTables("sdcaudit"); + + // List auditIdArray = new + // ArrayList(); + // auditIdArray = buildObjectArrayListByTypesIndex("auditingevents*", + // "useraccessevent"); + // + // logger.info("Starting to delete all service topologies from ES"); + // for (int i = 0; i < auditIdArray.size(); i ++){ + // EsIndexTypeIdToDelete esIndexTypeIdToDelete = auditIdArray.get(i); + // utils.deleteFromEsDbByPattern(esIndexTypeIdToDelete.getIndex()+"/"+esIndexTypeIdToDelete.getType()+"/"+esIndexTypeIdToDelete.getId()); + // + // } + } + + public static RestResponse deleteFromEsDbByPattern(String patternToDelete) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SEARCH_DATA_FROM_ES, config.getEsHost(), config.getEsPort(), + patternToDelete); + HttpRequest httpRequest = new HttpRequest(); + RestResponse restResponse = httpRequest.httpSendDelete(url, null); + restResponse.getErrorCode(); + // System.out.println("URL to delete" + url); + // System.out.println("response code" + restResponse.getErrorCode()); + cleanAllAudits(); + + return restResponse; + } + + public static RestResponse getFromEsByPattern(String patternToGet) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SEARCH_DATA_FROM_ES, config.getEsHost(), config.getEsPort(), patternToGet); + HttpRequest httpRequest = new HttpRequest(); + RestResponse restResponse = httpRequest.httpSendGet(url, null); + restResponse.getErrorCode(); + // System.out.println("URL to get" + url); + // System.out.println("response code" + restResponse.getErrorCode()); + + return restResponse; + } + + public Either getVertexByUId(String uid) { + TitanGraph titanGraph = getTitanGraph(); + Either result = Either.right(false); + // Iterator vertexItr = titanGraph.getVertices().iterator(); + + Iterator vertexItr = titanGraph.query().vertices().iterator(); + while (vertexItr.hasNext()) { + Vertex vertex = vertexItr.next(); + // String uidFoundVal = vertex.getProperty("uid"); + String uidFoundVal = vertex.value("uid"); + if (uid.equals(uidFoundVal)) { + result = Either.left(vertex); + } + } + return result; + } + + public static TitanState getCurrentTitanState() { + TitanGraph titanGraph = getTitanGraph(); + List vertices = new ArrayList<>(); + List edges = new ArrayList<>(); + // Iterator edgesItr = titanGraph.getEdges().iterator(); + Iterator edgesItr = titanGraph.query().edges().iterator(); + // Iterator verticesItr = titanGraph.getVertices().iterator(); + Iterator verticesItr = titanGraph.query().vertices().iterator(); + while (edgesItr.hasNext()) { + edges.add(edgesItr.next()); + } + while (verticesItr.hasNext()) { + vertices.add(verticesItr.next()); + } + + TitanState currState = new TitanState(edges, vertices); + return currState; + + } + + // + private static TitanGraph getTitanGraph() { + if (titanGraph == null) { + titanGraph = TitanFactory.open(titanConfigFilePath); + } + return titanGraph; + } + + public void restoreToTitanState(TitanState titanStateToRestoreTo) { + List verticesToRemove = new ArrayList<>(), verticesToAdd = new ArrayList<>(); + List edgesToRemove = new ArrayList<>(), edgesToAdd = new ArrayList<>(); + + TitanState currentTitanState = getCurrentTitanState(); + + List joinedEdges = new ArrayList<>(); + joinedEdges.addAll(titanStateToRestoreTo.edges); + joinedEdges.retainAll(currentTitanState.edges); + + List joinedVertices = new ArrayList<>(); + joinedVertices.addAll(titanStateToRestoreTo.vertices); + joinedVertices.retainAll(currentTitanState.vertices); + + edgesToRemove.addAll(currentTitanState.edges); + edgesToRemove.removeAll(joinedEdges); + + verticesToRemove.addAll(currentTitanState.vertices); + verticesToRemove.removeAll(joinedVertices); + + edgesToAdd.addAll(titanStateToRestoreTo.edges); + edgesToAdd.removeAll(joinedEdges); + + verticesToAdd.addAll(titanStateToRestoreTo.vertices); + verticesToAdd.removeAll(joinedVertices); + + modifyGraphAccordingToDelta(verticesToRemove, verticesToAdd, edgesToRemove, edgesToAdd); + + } + + private void modifyGraphAccordingToDelta(List verticesToRemove, List verticesToAdd, + List edgesToRemove, List edgesToAdd) { + + TitanGraph titanGraph = getTitanGraph(); + + for (Vertex vertex : verticesToRemove) { + // titanGraph.removeVertex(vertex); + vertex.remove(); + } + for (Vertex vertex : verticesToAdd) { + TitanVertex titanVertex = titanGraph.addVertex(); + copyProperties(vertex, titanVertex); + } + + for (Edge edge : edgesToRemove) { + // titanGraph.removeEdge(edge); + edge.remove(); + } + + for (Edge edge : edgesToAdd) { + // Element addedEdge = titanGraph.addEdge(edge.getId(), + // edge.getVertex(Direction.OUT), edge.getVertex(Direction.IN), + // edge.getLabel()); + + // Edge edge = tGraph.addEdge(null, fromV.left().value(), + // toV.left().value(), type); + + Element addedEdge = edge.outVertex().addEdge(edge.label(), edge.inVertex()); + + copyProperties(edge, addedEdge); + + } + + // titanGraph.commit(); + titanGraph.tx().commit(); + + } + + private void copyProperties(Element copyFrom, Element copyTo) { + // Set properties = copyFrom.getPropertyKeys(); + Set properties = copyFrom.keys(); + for (String propertyKey : properties) { + // copyTo.setProperty(propertyKey, + // copyFrom.getProperty(propertyKey)); + copyTo.property(propertyKey, copyFrom.value(propertyKey)); + } + + } + + public static class TitanState { + private List edges; + private List vertices; + + private TitanState(List edges, List vertices) { + this.edges = edges; + this.vertices = vertices; + } + + @Override + public String toString() { + return "TitanState [edges=" + edges.size() + ", vertices=" + vertices.size() + "]"; + } + + } + + public void shutDowntitan() { + if (titanGraph != null) { + // titanGraph.shutdown(); + titanGraph.close(); + } + } + + public static void setProperties(Element element, Map properties) { + + if (properties != null && false == properties.isEmpty()) { + + Object[] propertyKeyValues = new Object[properties.size() * 2]; + int i = 0; + for (Entry entry : properties.entrySet()) { + propertyKeyValues[i++] = entry.getKey(); + propertyKeyValues[i++] = entry.getValue(); + } + + ElementHelper.attachProperties(element, propertyKeyValues); + + } + + } + + public static UserAuditJavaObject parseAuditRespByAction(String action) throws Exception { + + // String index = "auditingevents*"; + // String type = "useradminevent"; + // String pattern = "/_search?q=action:\""+action+"\""; + // String auditingMessage = retrieveAuditMessageByIndexType(index, type, + // pattern); + UserAuditJavaObject auditParsedResp = new UserAuditJavaObject(); + Gson gson = new Gson(); + + String pattern = "/_search?q=ACTION:\"" + action + "\""; + String auditingMessage = retrieveAuditMessagesByPattern(pattern); + JsonElement jElement = new JsonParser().parse(auditingMessage); + JsonObject jObject = jElement.getAsJsonObject(); + JsonObject hitsObject = (JsonObject) jObject.get("hits"); + JsonArray hitsArray = (JsonArray) hitsObject.get("hits"); + // for (int i = 0; i < hitsArray.size();){ + if (hitsArray.size() == 0) { + return auditParsedResp; + } + JsonObject jHitObject = (JsonObject) hitsArray.get(0); + JsonObject jSourceObject = (JsonObject) jHitObject.get("_source"); + + auditParsedResp = gson.fromJson(jSourceObject, UserAuditJavaObject.class); + // logger.debug("auditParsedResp: {}", auditParsedResp); + + return auditParsedResp; + + } + + public static String retrieveAuditMessagesByPattern(String pattern) throws IOException { + + Config config = Utils.getConfig(); + HttpRequest getAuditingMessage = new HttpRequest(); + String url = String.format(Urls.GET_SEARCH_DATA_FROM_ES, config.getEsHost(), config.getEsPort(), pattern); + RestResponse restResponse = getAuditingMessage.httpSendGet(url, null); + + return restResponse.getResponse(); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Decoder.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Decoder.java new file mode 100644 index 0000000000..7d90eb0b6d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Decoder.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import java.io.BufferedReader; +import java.io.FileReader; +import java.io.IOException; + +import org.apache.commons.codec.binary.Base64; + +public class Decoder { + + public static String encode(byte[] byteArrayToEncode) { + + byte[] bytesEncoded = Base64.encodeBase64(byteArrayToEncode); + String strEncoded = new String(bytesEncoded); + return strEncoded; + } + + public static String decode(String strEncoded) throws IOException { + + byte[] byteDecoded = Base64.decodeBase64(strEncoded); + String decoded = new String(byteDecoded); + + return decoded; + + } + + public static String readFileToString(String file) throws IOException { + + BufferedReader reader = new BufferedReader(new FileReader(file)); + String line = null; + StringBuilder stringBuilder = new StringBuilder(); + String ls = System.getProperty("line.separator"); + + while ((line = reader.readLine()) != null) { + stringBuilder.append(line); + stringBuilder.append(ls); + } + reader.close(); + return stringBuilder.toString(); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ReqCap.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ReqCap.java new file mode 100644 index 0000000000..66d2a8450c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ReqCap.java @@ -0,0 +1,630 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.testng.Assert; + +public class ReqCap { + + public static Map> expectedContainerCapabilities; + public static Map> expectedContainerRequirements; + public static Map removedRequirements; + public static Map>, Map>>> expectedContInstReqCap; + + public static void verifyVFReqCap(String componentId) throws Exception { + RestResponse restResponse = ResourceRestUtils.getResource(componentId); + Resource resource = ResponseParser.parseToObject(restResponse.getResponse(), Resource.class); + verifyReqCap(resource); + } + + public static void verifyServiceReqCap(String componentId, User sdncDesignerDetails) throws Exception { + RestResponse restResponse = ServiceRestUtils.getService(componentId, sdncDesignerDetails); + Service service = ResponseParser.parseToObject(restResponse.getResponse(), Service.class); + verifyReqCap(service); + } + + public static void verifyProductReqCap(String componentId, User sdncPsDetails1) throws Exception { + RestResponse restResponse = ProductRestUtils.getProduct(componentId, sdncPsDetails1.getUserId()); + Product product = ResponseParser.parseToObject(restResponse.getResponse(), Product.class); + verifyReqCap(product); + } + + public static void verifyReqCap(Component actualComponent) { + verifyContainerReqCap(actualComponent); + verifyCompInstReqCap(actualComponent); + } + + public RestResponse changeServiceInstanceVersion(String componentUniqueId, String serviceInstanceToReplaceUniqueId, + String serviceUniqueId, User sdncModifierDetails, ComponentTypeEnum componentType, boolean isHighestLevel) + throws Exception { + RestResponse changeResourceInstanceVersion = ProductRestUtils.changeServiceInstanceVersion(componentUniqueId, + serviceInstanceToReplaceUniqueId, serviceUniqueId, sdncModifierDetails, componentType); + if (changeResourceInstanceVersion.getErrorCode().equals(BaseRestUtils.STATUS_CODE_SUCCESS) && isHighestLevel) { + /* + * // Add RI Capabilities and Requirements to expected MAP --> + * expectedVfCapabilities and expectedVfRequirements + * + * ComponentInstance componentInstance = + * ResponseParser.parseToObjectUsingMapper( + * changeResourceInstanceVersion.getResponse(), + * ComponentInstance.class); + * addCompInstReqCapToExpected(componentInstance, componentType); + */ + } + return changeResourceInstanceVersion; + } + + public static void updateExpectedReqCapAfterChangeLifecycleState(String oldContainerUniqueIdToReplace, + String newContainerUniqueId) { + + // Update of container req/cap + + Set compInstKeysToChange = new HashSet<>(); + + for (String expKey : expectedContainerCapabilities.keySet()) { + List expCapList = expectedContainerCapabilities.get(expKey); + for (CapabilityDefinition cap : expCapList) { + String ownerId = cap.getOwnerId(); + + if (ownerId.contains(oldContainerUniqueIdToReplace)) { + compInstKeysToChange.add(ownerId); + cap.setOwnerId(cap.getOwnerId().replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + } + } + } + + for (String expKey : expectedContainerRequirements.keySet()) { + List expCapList = expectedContainerRequirements.get(expKey); + for (RequirementDefinition cap : expCapList) { + String ownerId = cap.getOwnerId(); + if (ownerId.contains(oldContainerUniqueIdToReplace)) { + compInstKeysToChange.add(ownerId); + cap.setOwnerId(cap.getOwnerId().replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId)); + } + } + } + + // Update of internal comp instances req/cap + for (String oldKey : compInstKeysToChange) { + ImmutablePair>, Map>> immutablePair = expectedContInstReqCap + .get(oldKey); + if (immutablePair != null) { + expectedContInstReqCap.remove(oldKey); + String newKey = oldKey.replaceAll(oldContainerUniqueIdToReplace, newContainerUniqueId); + expectedContInstReqCap.put(newKey, immutablePair); + } + } + } + + private static void verifyCompInstReqCap(Component actualComponent) { + List componentInstances = actualComponent.getComponentInstances(); + if (componentInstances != null) { + assertEquals(expectedContInstReqCap.size(), componentInstances.size()); + for (ComponentInstance compInst : componentInstances) { + String uniqueId = compInst.getUniqueId(); + // System.out.println("Verifying req/cap of component instance + // "+ uniqueId); + Map> actualCompInstReq = compInst.getRequirements(); + if (actualCompInstReq == null) { + actualCompInstReq = new HashMap<>(); + } + Map> actualCompInstCap = compInst.getCapabilities(); + if (actualCompInstCap == null) { + actualCompInstCap = new HashMap<>(); + } + ImmutablePair>, Map>> expReqCap = expectedContInstReqCap + .get(uniqueId); + assertNotNull(expReqCap); + // System.out.println("expected instance requirements: + // "+expReqCap.right); + // System.out.println("expected instance capabilities: + // "+expReqCap.left); + // System.out.println("actual instance requirements: + // "+actualCompInstReq); + // System.out.println("actual instance capabilities: + // "+actualCompInstCap); + + // REQ comparison + compareReqCapMaps(expReqCap.right, actualCompInstReq); + + // CAP comparison + compareReqCapMaps(expReqCap.left, actualCompInstCap); + } + + } else { + assertTrue(expectedContInstReqCap.isEmpty()); + } + } + + private static void verifyContainerReqCap(Component actualComponent) { + Map> actualContainerRequirements = actualComponent.getRequirements(); + if (actualContainerRequirements == null) { + actualContainerRequirements = new HashMap<>(); + } + Map> actualContainerCapabilities = actualComponent.getCapabilities(); + if (actualContainerCapabilities == null) { + actualContainerCapabilities = new HashMap<>(); + } + // System.out.println("Verifying req/cap of container component "+ + // actualComponent.getUniqueId()); + // System.out.println("expected container requirements: + // "+expectedContainerRequirements); + // System.out.println("expected container capabilities: + // "+expectedContainerCapabilities); + // System.out.println("actual container requirements: + // "+actualContainerRequirements); + // System.out.println("actual container capabilities: + // "+actualContainerCapabilities); + + // REQ comparison + compareReqCapMaps(expectedContainerRequirements, actualContainerRequirements); + + // CAP comparison + compareReqCapMaps(expectedContainerCapabilities, actualContainerCapabilities); + } + + private static void compareReqCapMaps(Map> expectedMap, Map> actualMap) { + assertEquals(expectedMap.size(), actualMap.size()); + for (String expKey : expectedMap.keySet()) { + List expCapList = expectedMap.get(expKey); + List actCapList = actualMap.get(expKey); + assertEquals(expCapList.size(), actCapList.size()); + assertEquals(new HashSet<>(expCapList), new HashSet<>(actCapList)); + } + } + + public static void addCompInstReqCapToExpected(ComponentInstance componentInstance, + ComponentTypeEnum containerComponentType, User sdncDesignerDetails) throws Exception { + + sdncDesignerDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + String uniqueId = componentInstance.getUniqueId(); + String name = componentInstance.getName(); + String originComponentId = componentInstance.getComponentUid(); + RestResponse getResponse = null; + ComponentTypeEnum compInstType = getCompInstTypeByContainerType(containerComponentType); + Component component = null; + if (compInstType == ComponentTypeEnum.RESOURCE) { + getResponse = ResourceRestUtils.getResource(sdncDesignerDetails, originComponentId); + ResourceRestUtils.checkSuccess(getResponse); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Resource.class); + } else if (compInstType == ComponentTypeEnum.SERVICE) { + getResponse = ServiceRestUtils.getService(originComponentId, sdncDesignerDetails); + ResourceRestUtils.checkSuccess(getResponse); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Service.class); + } else { + Assert.fail("Unsupported type - " + containerComponentType); + } + + Map> resourceRequirements = component.getRequirements(); + if (resourceRequirements == null) { + resourceRequirements = new HashMap<>(); + } + + Function>, List> requirementDefinitionMapper = e -> new ArrayList<>(e.getValue().stream().map(item -> new RequirementDefinition(item)).collect(Collectors.toList())); + Map> reqCopy = resourceRequirements.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), requirementDefinitionMapper)); + + Map> resourceCapabilities = component.getCapabilities(); + if (resourceCapabilities == null) { + resourceCapabilities = new HashMap<>(); + } + + Function>, List> capabilityDefinitionMapper = e -> new ArrayList<>(e.getValue().stream().map(item -> new CapabilityDefinition(item)).collect(Collectors.toList())); + Map> capCopy = resourceCapabilities.entrySet().stream().collect(Collectors.toMap(e -> e.getKey(), capabilityDefinitionMapper)); + + setupContainerExpectedReqCap(uniqueId, name, resourceRequirements, resourceCapabilities); + if (component.getComponentType().equals(ComponentTypeEnum.RESOURCE) + && ((Resource) component).getResourceType() != ResourceTypeEnum.VF) { + setupConstInstExpectedReqCap(uniqueId, name, reqCopy, capCopy); + } + + // adding entry for expected componentInstance + ImmutablePair>, Map>> compInstReqCapPair = new ImmutablePair>, Map>>( + capCopy, reqCopy); + expectedContInstReqCap.put(uniqueId, compInstReqCapPair); + } + + private static void setupContainerExpectedReqCap(String uniqueId, String name, + Map> componentRequirements, + Map> componentCapabilities) { + for (Entry> resReq : componentRequirements.entrySet()) { + List reqListToAdd = resReq.getValue(); + for (RequirementDefinition requirementDefinition : reqListToAdd) { + requirementDefinition.setOwnerId(uniqueId); + requirementDefinition.setOwnerName(name); + } + List expectedReqList = expectedContainerRequirements.get(resReq.getKey()); + if (expectedReqList == null) { + expectedReqList = reqListToAdd; + } else { + expectedReqList.addAll(reqListToAdd); + } + expectedContainerRequirements.put(resReq.getKey(), expectedReqList); + } + + for (Entry> resCap : componentCapabilities.entrySet()) { + List capListToAdd = resCap.getValue(); + for (CapabilityDefinition capDefinition : capListToAdd) { + capDefinition.setOwnerId(uniqueId); + capDefinition.setOwnerName(name); + } + List expectedCapList = expectedContainerCapabilities.get(resCap.getKey()); + if (expectedCapList == null) { + expectedCapList = capListToAdd; + } else { + expectedCapList.addAll(capListToAdd); + } + expectedContainerCapabilities.put(resCap.getKey(), expectedCapList); + } + } + + private static void setupConstInstExpectedReqCap(String uniqueId, String name, + Map> componentRequirements, + Map> componentCapabilities) { + for (Entry> resReq : componentRequirements.entrySet()) { + List reqListToAdd = resReq.getValue(); + for (RequirementDefinition requirementDefinition : reqListToAdd) { + requirementDefinition.setOwnerId(uniqueId); + requirementDefinition.setOwnerName(name); + } + } + + for (Entry> resCap : componentCapabilities.entrySet()) { + List capListToAdd = resCap.getValue(); + for (CapabilityDefinition capDefinition : capListToAdd) { + capDefinition.setOwnerId(uniqueId); + capDefinition.setOwnerName(name); + } + } + } + + private static ComponentTypeEnum getCompInstTypeByContainerType(ComponentTypeEnum componentType) { + switch (componentType) { + case RESOURCE: + return ComponentTypeEnum.RESOURCE; + case SERVICE: + return ComponentTypeEnum.RESOURCE; + case PRODUCT: + return ComponentTypeEnum.SERVICE; + default: + break; + } + return null; + } + + public static void deleteCompInstReqCapFromExpected(String componentInstanceId) { + List entriesRequirementsToRemove = new ArrayList<>(); + List entriesCapabilitiesToRemove = new ArrayList<>(); + for (Entry> reqEntry : expectedContainerRequirements.entrySet()) { + List reqList = reqEntry.getValue(); + List reqListToDelete = new ArrayList<>(); + for (RequirementDefinition requirementDefinition : reqList) { + if (requirementDefinition.getOwnerId().equals(componentInstanceId)) { + reqListToDelete.add(requirementDefinition); + } + } + reqList.removeAll(reqListToDelete); + if (reqList.isEmpty()) { + entriesRequirementsToRemove.add(reqEntry.getKey()); + } + } + + for (String ekey : entriesRequirementsToRemove) { + expectedContainerRequirements.remove(ekey); + } + + for (Entry> capEntry : expectedContainerCapabilities.entrySet()) { + List capList = capEntry.getValue(); + List capListToDelete = new ArrayList<>(); + for (CapabilityDefinition capabilityDefinition : capList) { + if (capabilityDefinition.getOwnerId().equals(componentInstanceId)) { + capListToDelete.add(capabilityDefinition); + } + } + capList.removeAll(capListToDelete); + if (capList.isEmpty()) { + entriesCapabilitiesToRemove.add(capEntry.getKey()); + } + } + for (String ekey : entriesCapabilitiesToRemove) { + expectedContainerCapabilities.remove(ekey); + } + + expectedContInstReqCap.remove(componentInstanceId); + + } + + // Automatically updates the expected req/cap of the container + public static RestResponse createAtomicInstanceForVF(Resource containerDetails, Resource compInstOriginDetails, + User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.RESOURCE, + true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse createAtomicInstanceForService(Service containerDetails, Resource compInstOriginDetails, + User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, + true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse createVFInstance(Service containerDetails, Resource compInstOriginDetails, User modifier) + throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, + true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse createServiceInstance(Product containerDetails, Service compInstOriginDetails, + User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.PRODUCT, + true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse deleteAtomicInstanceForVF(String compInstUniqueId, Resource containerDetails, + User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.RESOURCE, true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse deleteAtomicInstanceForService(String compInstUniqueId, Service containerDetails, + User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, true); + } + + // Automatically updates the expected req/cap of the container + public static RestResponse deleteVFInstance(String compInstUniqueId, Service containerDetails, User modifier) + throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, true); + + } + + // Automatically updates the expected req/cap of the container + public static RestResponse deleteServiceInstance(String compInstUniqueId, Product containerDetails, User modifier) + throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.PRODUCT, true); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse createAtomicInstanceForVFDuringSetup(Resource containerDetails, + Resource compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.RESOURCE, + false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse createAtomicInstanceForServiceDuringSetup(Service containerDetails, + Resource compInstOriginDetails, User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, + false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse createVFInstanceDuringSetup(Service containerDetails, Resource compInstOriginDetails, + User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.SERVICE, + false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse createServiceInstanceDuringSetup(Product containerDetails, Service compInstOriginDetails, + User modifier) throws Exception { + return createComponentInstance(containerDetails, compInstOriginDetails, modifier, ComponentTypeEnum.PRODUCT, + false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse deleteAtomicInstanceForVFDuringSetup(String compInstUniqueId, Resource containerDetails, + User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.RESOURCE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse deleteAtomicInstanceForServiceDuringSetup(String compInstUniqueId, + Service containerDetails, User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, false); + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse deleteVFInstanceDuringSetup(String compInstUniqueId, Service containerDetails, + User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.SERVICE, false); + + } + + // Setup of lower components - Doesn't affect req/cap of the container (for + // example, setup of VF for testing a Product) + public static RestResponse deleteServiceInstanceDuringSetup(String compInstUniqueId, Product containerDetails, + User modifier) throws IOException, Exception { + return deleteComponentInstance(compInstUniqueId, containerDetails, modifier, ComponentTypeEnum.PRODUCT, false); + } + + public static Component getComponentAndValidateRIs(Component componentDetails, int numberOfRIs, + int numberOfRelations, User sdncAdminDetails) throws IOException, Exception { + + RestResponse getResponse = null; + Component component = null; + if (componentDetails instanceof Resource) { + getResponse = ResourceRestUtils.getResource(sdncAdminDetails, componentDetails.getUniqueId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Resource.class); + } else if (componentDetails instanceof Service) { + getResponse = ServiceRestUtils.getService((componentDetails.getUniqueId()), sdncAdminDetails); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Service.class); + } else if (componentDetails instanceof Product) { + getResponse = ProductRestUtils.getProduct(componentDetails.getUniqueId(), sdncAdminDetails.getUserId()); + component = ResponseParser.parseToObjectUsingMapper(getResponse.getResponse(), Product.class); + } else { + Assert.fail("Unsupported type of componentDetails - " + componentDetails.getClass().getSimpleName()); + } + ResourceRestUtils.checkSuccess(getResponse); + int numberOfActualRIs = component.getComponentInstances() != null ? component.getComponentInstances().size() + : 0; + int numberOfActualRelations = component.getComponentInstancesRelations() != null + ? component.getComponentInstancesRelations().size() : 0; + assertEquals("Check number of RIs meet the expected number", numberOfRIs, numberOfActualRIs); + assertEquals("Check number of RI relations meet the expected number", numberOfRelations, + numberOfActualRelations); + verifyReqCap(component); + + return component; + } + + public static void getComponentAndValidateRIsAfterChangeLifecycleState(String oldComponentUniqueIdToReplace, + Component componentDetails, int numOfRIs, int numOfRelations, User sdncAdminDetails) + throws IOException, Exception { + updateExpectedReqCapAfterChangeLifecycleState(oldComponentUniqueIdToReplace, componentDetails.getUniqueId()); + getComponentAndValidateRIs(componentDetails, numOfRIs, numOfRelations, sdncAdminDetails); + } + + private static RestResponse createComponentInstance(Component containerDetails, Component compInstOriginDetails, + User modifier, ComponentTypeEnum containerComponentTypeEnum, boolean isHighestLevel) + throws IOException, Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory + .getComponentInstance(compInstOriginDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance( + resourceInstanceReqDetails, modifier, containerDetails.getUniqueId(), containerComponentTypeEnum); + if (createResourceInstanceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_CREATED) && isHighestLevel) { + // Add RI Capabilities and Requirements to expected MAP --> + // expectedVfCapabilities and expectedVfRequirements + ComponentInstance componentInstance = ResponseParser + .parseToObjectUsingMapper(createResourceInstanceResponse.getResponse(), ComponentInstance.class); + addCompInstReqCapToExpected(componentInstance, containerComponentTypeEnum, modifier); + } + return createResourceInstanceResponse; + } + + private static RestResponse deleteComponentInstance(String compInstUniqueId, Component containerDetails, + User modifier, ComponentTypeEnum componentTypeEnum, boolean isHighestLevel) throws Exception { + RestResponse deleteResourceInstanceResponse = ComponentInstanceRestUtils.deleteComponentInstance(modifier, + containerDetails.getUniqueId(), compInstUniqueId, componentTypeEnum); + if (deleteResourceInstanceResponse.getErrorCode().equals(BaseRestUtils.STATUS_CODE_DELETE) && isHighestLevel) { + deleteCompInstReqCapFromExpected(compInstUniqueId); + } + return deleteResourceInstanceResponse; + } + + public static RestResponse associateComponentInstancesForService(RequirementCapabilityRelDef requirementDef, + ComponentReqDetails containerDetails, User user) throws IOException { + + RestResponse associateInstances = ComponentInstanceRestUtils.associateInstances(requirementDef, user, + containerDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(associateInstances); + deleteAssociatedFromExpected(requirementDef); + return associateInstances; + } + + private static void deleteAssociatedFromExpected(RequirementCapabilityRelDef requirementDef) { + // removing from requirements + RequirementAndRelationshipPair relationship = requirementDef.getRelationships().get(0); + String type = relationship.getRelationship().getType(); + String fromId = requirementDef.getFromNode(); + List reqList = expectedContainerRequirements.get(type); + RequirementDefinition toDelete = null; + if (reqList != null) { + for (RequirementDefinition reqDef : reqList) { + if (reqDef.getOwnerId().equals(fromId)) { + toDelete = reqDef; + } + } + if (toDelete != null) { + reqList.remove(toDelete); + if (reqList.isEmpty()) { + expectedContainerRequirements.remove(type); + } + removedRequirements.put(toDelete.getCapability() + " " + toDelete.getOwnerId(), toDelete); + } + } + } + + public static void dissociateComponentInstancesForService(RequirementCapabilityRelDef requirementDef, + ComponentReqDetails containerDetails, User user) throws IOException { + + RestResponse dissociateInstances = ComponentInstanceRestUtils.dissociateInstances(requirementDef, user, + containerDetails.getUniqueId(), ComponentTypeEnum.SERVICE); + ResourceRestUtils.checkSuccess(dissociateInstances); + addDissociatedToExpected(requirementDef); + } + + private static void addDissociatedToExpected(RequirementCapabilityRelDef requirementDef) { + // adding to requirements + RequirementAndRelationshipPair relationship = requirementDef.getRelationships().get(0); + String type = relationship.getRelationship().getType(); + String fromId = requirementDef.getFromNode(); + String key = type + " " + fromId; + RequirementDefinition requirementDefinition = removedRequirements.get(key); + if (requirementDefinition != null) { + List reqList = expectedContainerRequirements.get(type); + if (reqList == null) { + reqList = new ArrayList<>(); + expectedContainerRequirements.put(type, reqList); + } + reqList.add(requirementDefinition); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ToscaParserUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ToscaParserUtils.java new file mode 100644 index 0000000000..e5928b327f --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/ToscaParserUtils.java @@ -0,0 +1,267 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import org.openecomp.sdc.ci.tests.datatypes.enums.ToscaKeysEnum; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaNodeTemplatesTopologyTemplateDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaNodeTypesDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaPropertiesNodeTemplatesDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaRequirementsNodeTemplatesDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaTopologyTemplateDefinition; +import org.openecomp.sdc.ci.tests.utils.validation.CsarValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +public class ToscaParserUtils { + + private static Logger log = LoggerFactory.getLogger(ToscaParserUtils.class.getName()); + + public static Map getToscaYamlMap(String csarUUID, String fileLocation) throws Exception { + String csarPayload = CsarValidationUtils.getCsarPayload(csarUUID, fileLocation); + if (csarPayload != null) { + Yaml yaml = new Yaml(); + Map map = (Map) yaml.load(csarPayload); + return map; + } + return null; + } + + public static ToscaDefinition getToscaDefinitionObjectByCsarUuid(String csarUUID) throws Exception { + + String TOSCAMetaLocation = "TOSCA-Metadata/TOSCA.meta"; + Map map = getToscaYamlMap(csarUUID, TOSCAMetaLocation); + assertNotNull("Tosca Entry-Definitions is null", map); + if (map != null) { + String definitionYamlLocation = (String) map.get("Entry-Definitions"); + Map toscaMap = getToscaYamlMap(csarUUID, definitionYamlLocation); + assertNotNull("Tosca definition is null", toscaMap); + if (toscaMap != null) { + ToscaDefinition toscaDefinition = new ToscaDefinition(); + Set keySet = toscaMap.keySet(); + for (Object key : keySet) { + ToscaKeysEnum toscaKey = ToscaKeysEnum.findToscaKey((String) key); + switch (toscaKey) { + case TOSCA_DEFINITION_VERSION: + getToscaDefinitionVersion(toscaMap, toscaDefinition); + break; + case NODE_TYPES: + getToscaNodeTypes(toscaMap, toscaDefinition); + break; + case TOPOLOGY_TEMPLATE: + getToscaTopologyTemplate(toscaMap, toscaDefinition); + break; + case IMPORTS: + // toscaMap.get("imports"); + break; + default: + break; + } + } + return toscaDefinition; + } + } + return null; + + } + + public static void getToscaDefinitionVersion(Map toscaMap, ToscaDefinition toscaDefinition) { + if (toscaMap.get("tosca_definitions_version") != null) { + toscaDefinition.setToscaDefinitionVersion((String) toscaMap.get("tosca_definitions_version")); + } + } + + // spec 90 page + public static void getToscaNodeTypes(Map toscaMap, ToscaDefinition toscaDefinition) { + @SuppressWarnings("unchecked") + Map> nodeTypes = (Map>) toscaMap.get("node_types"); + List listToscaNodeTypes = new ArrayList<>(); + if (nodeTypes != null) { + for (Map.Entry> entry : nodeTypes.entrySet()) { + ToscaNodeTypesDefinition toscaNodeTypes = new ToscaNodeTypesDefinition(); + String toscaNodeName = entry.getKey(); + toscaNodeTypes.setName(toscaNodeName); + + Map toscaNodeType = entry.getValue(); + if (toscaNodeType != null) { + Set> entrySet = toscaNodeType.entrySet(); + if (entrySet != null) { + // boolean found = false; + for (Entry toscaNodeTypeMap : entrySet) { + String key = toscaNodeTypeMap.getKey(); + if (key.equals("derived_from")) { + String derivedFrom = toscaNodeTypeMap.getValue(); + toscaNodeTypes.setDerivedFrom(derivedFrom); + // found = true; + break; + } else { + continue; + } + + } + // if (found == false) { + // System.out.println("Tosca file not valid, + // derived_from not found"); + // } + } + + } + listToscaNodeTypes.add(toscaNodeTypes); + } + toscaDefinition.setToscaNodeTypes(listToscaNodeTypes); + } + } + + public static void getToscaTopologyTemplate(Map toscaMap, ToscaDefinition toscaDefinition) { + ToscaTopologyTemplateDefinition toscaTopologyTemplate = new ToscaTopologyTemplateDefinition(); + @SuppressWarnings("unchecked") + Map> topologyTemplateMap = (Map>) toscaMap + .get("topology_template"); + List listToscaNodeTemplates = new ArrayList<>(); + + if (topologyTemplateMap != null) { + getToscaNodeTemplates(topologyTemplateMap, listToscaNodeTemplates); + } + toscaTopologyTemplate.setToscaNodeTemplatesTopologyTemplateDefinition(listToscaNodeTemplates); + toscaDefinition.setToscaTopologyTemplate(toscaTopologyTemplate); + } + + public static void getToscaNodeTemplates(Map> topologyTemplateMap, + List listToscaNodeTemplates) { + Map nodeTemplatesMap = topologyTemplateMap.get("node_templates"); + if (nodeTemplatesMap != null) { + + for (Entry nodeTemplates : nodeTemplatesMap.entrySet()) { + ToscaNodeTemplatesTopologyTemplateDefinition toscaNodeTemplates = new ToscaNodeTemplatesTopologyTemplateDefinition(); + getToscaNodeTemplatesName(nodeTemplates, toscaNodeTemplates); + + @SuppressWarnings("unchecked") + Map node = (Map) nodeTemplates.getValue(); + getNodeTemplatesType(toscaNodeTemplates, node); + getToscaNodeTemplateProperties(toscaNodeTemplates, node); + getToscaNodeTemplateRequirements(toscaNodeTemplates, node); + listToscaNodeTemplates.add(toscaNodeTemplates); + } + } + } + + public static void getToscaNodeTemplateRequirements(ToscaNodeTemplatesTopologyTemplateDefinition toscaNodeTemplates, + Map node) { + List toscaRequirements = new ArrayList<>(); + if (node.get("requirements") != null) { + @SuppressWarnings("unchecked") + List> requirementList = (List>) node.get("requirements"); + for (int i = 0; i < requirementList.size(); i++) { + for (Map.Entry requirement : requirementList.get(i).entrySet()) { + ToscaRequirementsNodeTemplatesDefinition toscaRequirement = new ToscaRequirementsNodeTemplatesDefinition(); + if (requirement.getKey() != null) { + String requirementName = requirement.getKey(); + toscaRequirement.setName(requirementName); + } else { + log.debug("Tosca file not valid, requirements should contain name"); + } + + @SuppressWarnings("unchecked") + Map requirementMap = (Map) requirement.getValue(); + Set> entrySet = requirementMap.entrySet(); + if (entrySet != null) { + for (Entry requirementField : entrySet) { + String key = requirementField.getKey(); + switch (key) { + case "capability": + if (requirementMap.get(key) != null) { + String capability = (String) requirementMap.get(key); + toscaRequirement.setCapability(capability); + break; + } else { + continue; + } + case "node": + if (requirementMap.get(key) != null) { + String requirementNode = (String) requirementMap.get(key); + toscaRequirement.setNode(requirementNode); + break; + } else { + continue; + } + case "relationship": + if (requirementMap.get(key) != null) { + String relationship = (String) requirementMap.get(key); + toscaRequirement.setRelationship(relationship); + break; + } else { + continue; + } + default: + break; + } + } + } + toscaRequirements.add(toscaRequirement); + } + } + } + toscaNodeTemplates.setRequirements(toscaRequirements); + } + + public static void getToscaNodeTemplateProperties(ToscaNodeTemplatesTopologyTemplateDefinition toscaNodeTemplates, + Map node) { + List listToscaProperties = new ArrayList<>(); + if (node.get("properties") != null) { + @SuppressWarnings("unchecked") + Map properties = (Map) node.get("properties"); + for (Map.Entry property : properties.entrySet()) { + ToscaPropertiesNodeTemplatesDefinition toscaProperty = new ToscaPropertiesNodeTemplatesDefinition(); + String propertyName = property.getKey(); + Object propertyValue = property.getValue(); + toscaProperty.setName(propertyName); + toscaProperty.setValue(propertyValue); + listToscaProperties.add(toscaProperty); + } + } + toscaNodeTemplates.setProperties(listToscaProperties); + } + + protected static void getNodeTemplatesType(ToscaNodeTemplatesTopologyTemplateDefinition toscaNodeTemplates, + Map node) { + if (node.get("type") != null) { + String type = (String) node.get("type"); + toscaNodeTemplates.setType(type); + } else { + log.debug("Tosca file not valid, nodeTemplate should contain type"); + } + } + + protected static void getToscaNodeTemplatesName(Entry nodeTemplates, + ToscaNodeTemplatesTopologyTemplateDefinition toscaNodeTemplates) { + String name = nodeTemplates.getKey(); + toscaNodeTemplates.setName(name); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Utils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Utils.java new file mode 100644 index 0000000000..962f140dbd --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/Utils.java @@ -0,0 +1,233 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.lang3.StringUtils; +import org.apache.log4j.Logger; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.ToscaNodeTypeInfo; +import org.openecomp.sdc.common.api.YamlConstants; +import org.yaml.snakeyaml.Yaml; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public final class Utils { + + Gson gson = new Gson(); + + static Logger logger = Logger.getLogger(Utils.class.getName()); + + String contentTypeHeaderData = "application/json"; + String acceptHeaderDate = "application/json"; + + public Utils() { + + } + + @SuppressWarnings("unchecked") + public ToscaNodeTypeInfo parseToscaNodeYaml(String fileContent) { + + ToscaNodeTypeInfo result = new ToscaNodeTypeInfo(); + Object templateVersion = null; + Object templateName = null; + + if (fileContent != null) { + Yaml yaml = new Yaml(); + + Map yamlObject = (Map) yaml.load(fileContent); + + templateVersion = yamlObject.get(YamlConstants.TEMPLATE_VERSION); + if (templateVersion != null) { + result.setTemplateVersion(templateVersion.toString()); + } + templateName = yamlObject.get(YamlConstants.TEMPLATE_NAME); + if (templateName != null) { + result.setTemplateName(templateName.toString()); + } + Object nodeTypes = yamlObject.get(YamlConstants.NODE_TYPES); + + if (nodeTypes != null) { + Map nodeTypesMap = (Map) nodeTypes; + for (Entry entry : nodeTypesMap.entrySet()) { + + String nodeName = entry.getKey(); + if (nodeName != null) { + result.setNodeName(nodeName); + } + + break; + + } + } + + } + + return result; + } + + public static String getJsonObjectValueByKey(String metadata, String key) { + JsonElement jelement = new JsonParser().parse(metadata); + + JsonObject jobject = jelement.getAsJsonObject(); + Object obj = jobject.get(key); + if (obj == null) { + return null; + } else { + String value; + value = (String) jobject.get(key).getAsString(); + return value; + } + } + + public static Config getConfig() throws FileNotFoundException { + Config config = Config.instance(); + return config; + } + + public static void compareArrayLists(List actualArraylList, List expectedArrayList, + String message) { + + ArrayList actual = new ArrayList(actualArraylList); + ArrayList expected = new ArrayList(expectedArrayList); + assertEquals(message + " count got by rest API not match to " + message + " expected count", expected.size(), + actual.size()); + actual.removeAll(expected); + assertEquals(message + " content got by rest API not match to " + message + " expected content", 0, + actual.size()); + } + + public static Object parseYamlConfig(String pattern) throws FileNotFoundException { + + Yaml yaml = new Yaml(); + Config config = getConfig(); + String configurationFile = config.getConfigurationFile(); + File file = new File(configurationFile); + // File file = new + // File("../catalog-be/src/main/resources/config/configuration.yaml"); + InputStream inputStream = new FileInputStream(file); + Map map = (Map) yaml.load(inputStream); + Object patternMap = (Object) map.get(pattern); + + return patternMap; + } + + public static String getDepArtLabelFromConfig(ArtifactTypeEnum artifactTypeEnum) throws FileNotFoundException { + + @SuppressWarnings("unchecked") + Map mapOfDepResArtTypesObjects = (Map) parseYamlConfig( + "deploymentResourceArtifacts"); + for (Map.Entry iter : mapOfDepResArtTypesObjects.entrySet()) { + if (iter.getValue().toString().contains(artifactTypeEnum.getType())) { + return iter.getKey().toLowerCase(); + } + } + + return "defaultLabelName"; + } + + public static String multipleChar(String ch, int repeat) { + return StringUtils.repeat(ch, repeat); + } + + public static List getListOfDepResArtLabels(Boolean isLowerCase) throws FileNotFoundException { + + List listOfResDepArtTypesFromConfig = new ArrayList(); + @SuppressWarnings("unchecked") + Map resourceDeploymentArtifacts = (Map) parseYamlConfig( + "deploymentResourceArtifacts"); + if (resourceDeploymentArtifacts != null) { + + if (isLowerCase) { + for (Map.Entry iter : resourceDeploymentArtifacts.entrySet()) { + listOfResDepArtTypesFromConfig.add(iter.getKey().toLowerCase()); + } + } else { + + for (Map.Entry iter : resourceDeploymentArtifacts.entrySet()) { + listOfResDepArtTypesFromConfig.add(iter.getKey()); + } + } + } + return listOfResDepArtTypesFromConfig; + } + + public static List getListOfToscaArtLabels(Boolean isLowerCase) throws FileNotFoundException { + + List listOfToscaArtTypesFromConfig = new ArrayList(); + @SuppressWarnings("unchecked") + Map toscaArtifacts = (Map) parseYamlConfig("toscaArtifacts"); + if (toscaArtifacts != null) { + + if (isLowerCase) { + for (Map.Entry iter : toscaArtifacts.entrySet()) { + listOfToscaArtTypesFromConfig.add(iter.getKey().toLowerCase()); + } + } else { + for (Map.Entry iter : toscaArtifacts.entrySet()) { + listOfToscaArtTypesFromConfig.add(iter.getKey()); + } + } + } + return listOfToscaArtTypesFromConfig; + } + + public static List getListOfResPlaceHoldersDepArtTypes() throws FileNotFoundException { + List listResDepArtTypesFromConfig = new ArrayList(); + List listOfResDepArtLabelsFromConfig = getListOfDepResArtLabels(false); + assertNotNull("deployment artifact types list is null", listOfResDepArtLabelsFromConfig); + Object parseYamlConfig = Utils.parseYamlConfig("deploymentResourceArtifacts"); + Map mapOfDepResArtTypesObjects = (Map) Utils + .parseYamlConfig("deploymentResourceArtifacts"); + + // assertNotNull("deployment artifact types list is null", + // mapOfDepResArtTypesObjects); + if (listOfResDepArtLabelsFromConfig != null) { + for (String resDepArtType : listOfResDepArtLabelsFromConfig) { + Object object = mapOfDepResArtTypesObjects.get(resDepArtType); + if (object instanceof Map) { + Map map = (Map) object; + listResDepArtTypesFromConfig.add((String) map.get("type")); + } else { + assertTrue("return object does not instance of map", false); + } + } + } + return listResDepArtTypesFromConfig; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils.java new file mode 100644 index 0000000000..51b68d4d56 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils.java @@ -0,0 +1,213 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.cassandra; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.javatuples.Pair; +import org.openecomp.sdc.be.resources.data.auditing.AuditingTypesConstants; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.TableMetadata; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.querybuilder.Select.Where; + +public final class CassandraUtils { + private static Logger logger = LoggerFactory.getLogger(CassandraUtils.class.getName()); + + protected static Cluster cluster = null; + protected static Session session; + + protected static void initConnection(String keyspace) throws FileNotFoundException { + + String cassandraHost = Utils.getConfig().getCassandraHost(); + Boolean cassandraAuthenticate = Utils.getConfig().getCassandraAuthenticate(); + String cassandraUsername = Utils.getConfig().getCassandraUsername(); + String cassandraPassword = Utils.getConfig().getCassandraPassword(); + Boolean cassandraSsl = Utils.getConfig().getCassandraSsl(); + String cassandraTruststorePath = Utils.getConfig().getCassandraTruststorePath(); + String cassandraTruststorePassword = Utils.getConfig().getCassandraTruststorePassword(); + /* + * String cassandraAuditKeySpace= + * Utils.getConfig().getCassandraAuditKeySpace(); String + * cassandraArtifactKeySpace= + * Utils.getConfig().getCassandraArtifactKeySpace(); + */ + + Cluster.Builder clusterBuilder = Cluster.builder().addContactPoint(cassandraHost); + if (cassandraAuthenticate) { + // authantication + clusterBuilder.withCredentials(cassandraUsername, cassandraPassword); + } + + if (cassandraSsl) { + // ssl + System.setProperty("javax.net.ssl.trustStore", cassandraTruststorePath); + System.setProperty("javax.net.ssl.trustStorePassword", cassandraTruststorePassword); + clusterBuilder.withSSL(); + } + + cluster = clusterBuilder.build(); + session = cluster.connect(keyspace); + + } + + public static void truncateTable(String keyspace, String tableName) throws FileNotFoundException { + + if (session == null || session.isClosed()) { + initConnection(keyspace); + } + + try { + + if (session != null) { + session.execute(QueryBuilder.truncate(keyspace, tableName)); + logger.debug("The table {}. {} was cleaned", keyspace, tableName); + } else { + throw new RuntimeException("Keyspace " + keyspace + " not connected"); + } + } finally { + // if (cluster != null) { + // cluster.close(); + // } + } + } + + public static void close() { + if (cluster != null) { + cluster.close(); + } + } + + public static void truncateAllKeyspaces() throws FileNotFoundException { + // truncateAllTables(AuditingTypesConstants.ARTIFACT_KEYSPACE); + truncateAllTables(AuditingTypesConstants.AUDIT_KEYSPACE); + } + + public static void truncateAllTables(String keyspace) throws FileNotFoundException { + + if (session == null || session.isClosed()) { + initConnection(keyspace); + } + try { + + if (session != null) { + Metadata metadata = cluster.getMetadata(); + KeyspaceMetadata keyspaceMetadata = metadata.getKeyspace(keyspace); + if (keyspaceMetadata != null) { + Collection tables = keyspaceMetadata.getTables(); + tables.forEach(table -> { + session.execute(QueryBuilder.truncate(table)); + logger.debug("Table trunceted - {}", table.getName()); + }); + } + } else { + throw new RuntimeException("Keyspace " + keyspace + " not connected"); + } + + } finally { + // if (cluster != null) { + // cluster.close(); + // } + } + } + + public static List fetchFromTable(String keyspace, String tableName, + List> fields) throws FileNotFoundException { + + List> fieldsConverted = new ArrayList<>(); + + fields.forEach(pair -> { + Pair newPair = new Pair(pair.getValue0().getDisplayName(), pair.getValue1()); + fieldsConverted.add(newPair); + }); + + return fetchFromTableQuery(keyspace, tableName, fieldsConverted); + } + + public static List fetchFromTableQuery(String keyspace, String tableName, List> fields) + throws FileNotFoundException { + + if (session == null || session.isClosed()) { + initConnection(keyspace); + } + try { + + if (session != null) { + Select select = QueryBuilder.select().all().from(keyspace, tableName); + if (fields != null) { + // Set> entrySet = + // fields.entrySet(); + // fields. + boolean multiple = (fields.size() > 1) ? true : false; + Where where = null; + int size = 0; + + for (Pair pair : fields) { + ++size; + if (size == 1) { + where = select.where(QueryBuilder.eq(pair.getValue0(), pair.getValue1())); + } else { + where.and(QueryBuilder.eq(pair.getValue0(), pair.getValue1())); + } + } + if (multiple) { + select.allowFiltering(); + } + + } + + List rows = session.execute(select).all(); + for (Row row : rows) { + logger.debug("{}", row); + } + return rows; + } + } finally { + // if (cluster != null) { + // cluster.close(); + // } + } + return null; + } + // + // public static void main(String[] args) throws FileNotFoundException { + // Map map = new HashMap<>(); + // map.put(AuditingFieldsKeysEnum.AUDIT_ACTION, "Access"); + // map.put(AuditingFieldsKeysEnum.AUDIT_STATUS, "200"); + // // CassandraUtils.truncateTable("sdcArtifact", "resources"); + //// CassandraUtils.truncateAllTables("sdcAudit"); + // CassandraUtils.fetchFromTable("sdcAudit", "useraccessevent", map ); + // } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils2.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils2.java new file mode 100644 index 0000000000..414ca2334e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/cassandra/CassandraUtils2.java @@ -0,0 +1,172 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.cassandra; + +import java.io.FileNotFoundException; +import java.util.Collection; +import java.util.List; + +import org.javatuples.Pair; +import org.openecomp.sdc.be.resources.data.auditing.AuditingTypesConstants; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.datastax.driver.core.Cluster; +import com.datastax.driver.core.KeyspaceMetadata; +import com.datastax.driver.core.Metadata; +import com.datastax.driver.core.Row; +import com.datastax.driver.core.Session; +import com.datastax.driver.core.TableMetadata; +import com.datastax.driver.core.querybuilder.QueryBuilder; +import com.datastax.driver.core.querybuilder.Select; +import com.datastax.driver.core.querybuilder.Select.Where; + +public final class CassandraUtils2 { + private static Logger logger = LoggerFactory.getLogger(CassandraUtils2.class.getName()); + + public static void truncateTable(String keyspace, String tableName) throws FileNotFoundException { + + String cassandraHost = Utils.getConfig().getCassandraHost(); + + Cluster cluster = null; + Session session; + + try { + Cluster.Builder clusterBuilder = Cluster.builder().addContactPoint(cassandraHost); + // authantication + // clusterBuilder.withCredentials(username,password); + // ssl + // System.setProperty("javax.net.ssl.trustStore",truststorePath); + // System.setProperty("javax.net.ssl.trustStorePassword",truststorePassword); + // clusterBuilder.withSSL(); + cluster = clusterBuilder.build(); + session = cluster.connect(keyspace); + if (session != null) { + session.execute(QueryBuilder.truncate(keyspace, tableName)); + logger.debug("The table {}. {} was cleaned", keyspace, tableName); + } else { + throw new RuntimeException("Keyspace " + keyspace + " not connected"); + } + } finally { + if (cluster != null) { + cluster.close(); + } + } + } + + public static void truncateAllKeyspaces() throws FileNotFoundException { + truncateAllTables(AuditingTypesConstants.ARTIFACT_KEYSPACE); + truncateAllTables(AuditingTypesConstants.AUDIT_KEYSPACE); + } + + public static void truncateAllTables(String keyspace) throws FileNotFoundException { + String cassandraHost = Utils.getConfig().getCassandraHost(); + + Cluster cluster = null; + Session session; + + try { + cluster = Cluster.builder().addContactPoint(cassandraHost).build(); + session = cluster.connect(keyspace); + if (session != null) { + Metadata metadata = cluster.getMetadata(); + KeyspaceMetadata keyspaceMetadata = metadata.getKeyspace(keyspace); + if (keyspaceMetadata != null) { + Collection tables = keyspaceMetadata.getTables(); + tables.forEach(table -> { + session.execute(QueryBuilder.truncate(table)); + logger.debug("Table trunceted - {}", table.getName()); + }); + } + } else { + throw new RuntimeException("Keyspace " + keyspace + " not connected"); + } + + } finally { + if (cluster != null) { + cluster.close(); + } + } + } + + public static List fetchFromTable(String keyspace, String tableName, + List> fields) throws FileNotFoundException { + + // List> + // Map + + Cluster cluster = null; + Session session; + String cassandraHost = Utils.getConfig().getCassandraHost(); + + try { + cluster = Cluster.builder().addContactPoint(cassandraHost).build(); + session = cluster.connect(keyspace); + if (session != null) { + Select select = QueryBuilder.select().all().from(keyspace, tableName); + if (fields != null) { + // Set> entrySet = + // fields.entrySet(); + // fields. + boolean multiple = (fields.size() > 1) ? true : false; + Where where = null; + int size = 0; + + for (Pair pair : fields) { + ++size; + if (size == 1) { + where = select.where(QueryBuilder.eq(pair.getValue0().getDisplayName(), pair.getValue1())); + } else { + where.and(QueryBuilder.eq(pair.getValue0().getDisplayName(), pair.getValue1())); + } + } + if (multiple) { + select.allowFiltering(); + } + + } + + List rows = session.execute(select).all(); + for (Row row : rows) { + logger.debug("{}", row); + } + return rows; + } + } finally { + if (cluster != null) { + cluster.close(); + } + } + return null; + } + // + // public static void main(String[] args) throws FileNotFoundException { + // Map map = new HashMap<>(); + // map.put(AuditingFieldsKeysEnum.AUDIT_ACTION, "Access"); + // map.put(AuditingFieldsKeysEnum.AUDIT_STATUS, "200"); + // // CassandraUtils.truncateTable("sdcArtifact", "resources"); + //// CassandraUtils.truncateAllTables("sdcAudit"); + // CassandraUtils.fetchFromTable("sdcAudit", "useraccessevent", map ); + // } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/AtomicOperationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/AtomicOperationUtils.java new file mode 100644 index 0000000000..0456b2c121 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/AtomicOperationUtils.java @@ -0,0 +1,627 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.general; + +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.Pair; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.PropertyTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ComponentInstanceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.PropertyRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; + +import com.google.gson.Gson; + +import fj.data.Either; + +public final class AtomicOperationUtils { + + private AtomicOperationUtils() { + throw new UnsupportedOperationException(); + } + + // *********** RESOURCE **************** + /** + * Import a vfc From tosca file + * + * @param filePath + * @param fileName + * @return + * @throws IOException + * @throws JSONException + */ + public static Either importResource(String filePath, String fileName) { + try { + User designer = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + ImportReqDetails importReqDetails = ElementFactory.getDefaultImportResource("ciTmpVFC"); + importReqDetails = ImportUtils.getImportResourceDetailsByPathAndName(importReqDetails, filePath, fileName); + RestResponse importResourceResponse = ResourceRestUtils.createImportResource(importReqDetails, designer, null); + return buildResourceFromResponse(importResourceResponse); + } catch (Exception e) { + throw new AtomicOperationException(e); + } + } + + public static Either createResourceByType(ResourceTypeEnum resourceType, UserRoleEnum userRole, Boolean validateState) { + try { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ResourceReqDetails defaultResource = ElementFactory.getDefaultResourceByType(resourceType, defaultUser); + RestResponse resourceResp = ResourceRestUtils.createResource(defaultResource, defaultUser); + + if (validateState) { + assertTrue(resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED); + } + + if (resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + Resource resourceResponseObject = ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + return Either.left(resourceResponseObject); + } + return Either.right(resourceResp); + } catch (Exception e) { + throw new AtomicOperationException(e); + } + } + + public static Either createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum resourceType, NormativeTypesEnum normativeTypes, ResourceCategoryEnum resourceCategory, UserRoleEnum userRole, Boolean validateState) + throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ResourceReqDetails defaultResource = ElementFactory.getDefaultResourceByTypeNormTypeAndCatregory(resourceType, normativeTypes, resourceCategory, defaultUser); + RestResponse resourceResp = ResourceRestUtils.createResource(defaultResource, defaultUser); + + if (validateState) { + assertTrue(resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED); + } + + if (resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + // Resource resourceResponseObject = ResponseParser + // .convertResourceResponseToJavaObject(resourceResp.getResponse()); + Resource resourceResponseObject = ResponseParser.parseToObjectUsingMapper(resourceResp.getResponse(), Resource.class); + return Either.left(resourceResponseObject); + } + return Either.right(resourceResp); + } + + public static Either createResourcesByCustomNormativeTypeAndCatregory(ResourceTypeEnum resourceType, Resource resourceNormativeType, ResourceCategoryEnum resourceCategory, UserRoleEnum userRole, Boolean validateState) + throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ResourceReqDetails defaultResource = ElementFactory.getDefaultResourceByTypeNormTypeAndCatregory(resourceType, resourceNormativeType, resourceCategory, defaultUser); + RestResponse resourceResp = ResourceRestUtils.createResource(defaultResource, defaultUser); + + if (validateState) { + assertTrue("actual result: " + resourceResp.getResponseMessage(), resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED); + } + + if (resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + // Resource resourceResponseObject = ResponseParser + // .convertResourceResponseToJavaObject(resourceResp.getResponse()); + Resource resourceResponseObject = ResponseParser.parseToObjectUsingMapper(resourceResp.getResponse(), Resource.class); + return Either.left(resourceResponseObject); + } + return Either.right(resourceResp); + } + + // *********** SERVICE **************** + + public static Either createDefaultService(UserRoleEnum userRole, Boolean validateState) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(defaultUser); + RestResponse createServiceResp = ServiceRestUtils.createService(serviceDetails, defaultUser); + + if (validateState) { + assertTrue(createServiceResp.getErrorCode() == ServiceRestUtils.STATUS_CODE_CREATED); + } + + if (createServiceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + Service serviceResponseObject = ResponseParser.convertServiceResponseToJavaObject(createServiceResp.getResponse()); + return Either.left(serviceResponseObject); + } + return Either.right(createServiceResp); + } + + public static Either createServiceByCategory(ServiceCategoriesEnum category, UserRoleEnum userRole, Boolean validateState) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(category, defaultUser); + RestResponse createServiceResp = ServiceRestUtils.createService(serviceDetails, defaultUser); + + if (validateState) { + assertTrue(createServiceResp.getErrorCode() == ServiceRestUtils.STATUS_CODE_CREATED); + } + + if (createServiceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + Service serviceResponseObject = ResponseParser.convertServiceResponseToJavaObject(createServiceResp.getResponse()); + return Either.left(serviceResponseObject); + } + return Either.right(createServiceResp); + } + + // *********** PRODUCT **************** + + public static Either createDefaultProduct(UserRoleEnum userRole, Boolean validateState) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ProductReqDetails defaultProduct = ElementFactory.getDefaultProduct(); + RestResponse createProductResp = ProductRestUtils.createProduct(defaultProduct, defaultUser); + + if (validateState) { + assertTrue(createProductResp.getErrorCode() == ProductRestUtils.STATUS_CODE_CREATED); + } + + if (createProductResp.getErrorCode() == ProductRestUtils.STATUS_CODE_CREATED) { + Product productResponseJavaObject = ResponseParser.convertProductResponseToJavaObject(createProductResp.getResponse()); + return Either.left(productResponseJavaObject); + } + return Either.right(createProductResp); + } + + // *********** LIFECYCLE *************** + + public static Pair changeComponentState(Component component, UserRoleEnum userRole, LifeCycleStatesEnum targetState, Boolean validateState) throws Exception { + + Boolean isValidationFailed = false; + RestResponse lifeCycleStatesResponse = null; + User defaultUser = ElementFactory.getDefaultUser(userRole); + + LifeCycleStatesEnum curentCompState = LifeCycleStatesEnum.findByCompState(component.getLifecycleState().toString()); + + if (curentCompState == targetState) { + return Pair.of(component, null); + } + // List lifeCycleStatesEnumOrigList = new + // ArrayList(EnumSet.allOf(LifeCycleStatesEnum.class)); + + ArrayList lifeCycleStatesEnumList = new ArrayList(); + if (curentCompState.equals(LifeCycleStatesEnum.CHECKIN) && targetState.equals(LifeCycleStatesEnum.CHECKOUT)) { + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CHECKIN.toString()); + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CHECKOUT.toString()); + } else { + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CHECKOUT.toString()); + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CHECKIN.toString()); + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CERTIFICATIONREQUEST.toString()); + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.STARTCERTIFICATION.toString()); + lifeCycleStatesEnumList.add(LifeCycleStatesEnum.CERTIFY.toString()); + } + for (int i = 0; i < lifeCycleStatesEnumList.size(); i++) { + if (lifeCycleStatesEnumList.get(i).equals(curentCompState.name())) { + int a; + a = (i == lifeCycleStatesEnumList.size() - 1) ? 0 : i + 1; + + for (int n = a; n < lifeCycleStatesEnumList.size(); n++) { + if (lifeCycleStatesEnumList.get(n).equals(LifeCycleStatesEnum.STARTCERTIFICATION.name()) || lifeCycleStatesEnumList.get(n).equals(LifeCycleStatesEnum.CERTIFY.name())) { + defaultUser = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + } else + defaultUser = ElementFactory.getDefaultUser(userRole); + + lifeCycleStatesResponse = LifecycleRestUtils.changeComponentState(component, defaultUser, LifeCycleStatesEnum.findByState(lifeCycleStatesEnumList.get(n))); + if (lifeCycleStatesResponse.getErrorCode() != LifecycleRestUtils.STATUS_CODE_SUCCESS) + isValidationFailed = true; + if (lifeCycleStatesEnumList.get(n).equals(targetState.toString()) || isValidationFailed == true) { + break; + } + } + } + + } + component = getCompoenntObject(component, userRole); + Component componentJavaObject = convertReposnseToComponentObject(component, lifeCycleStatesResponse); + + if (validateState == true && isValidationFailed == true) { + assertTrue("change state failed" + lifeCycleStatesResponse.getResponse(), false); + + return Pair.of(componentJavaObject, lifeCycleStatesResponse); + } + + if (isValidationFailed == true) { + return Pair.of(componentJavaObject, lifeCycleStatesResponse); + } + + return Pair.of(componentJavaObject, lifeCycleStatesResponse); + } + + public static RestResponse distributeService(Component component, Boolean validateState) throws Exception { + + Service service = (Service) component; + + User opsUser = ElementFactory.getDefaultUser(UserRoleEnum.OPS); + User governotUser = ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR); + + ServiceReqDetails serviceDetails = new ServiceReqDetails(service); + RestResponse distributionService = null; + + RestResponse approveDistribution = LifecycleRestUtils.changeDistributionStatus(serviceDetails, null, governotUser, "approveService", DistributionStatusEnum.DISTRIBUTION_APPROVED); + if (approveDistribution.getErrorCode() == 200) { + distributionService = LifecycleRestUtils.changeDistributionStatus(serviceDetails, null, opsUser, "approveService", DistributionStatusEnum.DISTRIBUTED); + } + + if (validateState) { + assertTrue(approveDistribution.getErrorCode() == ProductRestUtils.STATUS_CODE_SUCCESS); + assertTrue(distributionService.getErrorCode() == ProductRestUtils.STATUS_CODE_SUCCESS); + return distributionService; + } + + return distributionService; + + } + + // *********** ARTIFACTS ***************** + + public static Either uploadArtifactByType(ArtifactTypeEnum artifactType, Component component, UserRoleEnum userRole, Boolean deploymentTrue, Boolean validateState) throws Exception { + + User defaultUser = ElementFactory.getDefaultUser(userRole); + ArtifactReqDetails artifactDetails = ElementFactory.getArtifactByType(null, artifactType, deploymentTrue); + if (deploymentTrue == false) + artifactDetails.setArtifactGroupType(ArtifactGroupTypeEnum.INFORMATIONAL.getType()); + RestResponse uploadArtifactResp = ArtifactRestUtils.uploadArtifact(artifactDetails, component, defaultUser); + + if (validateState) { + assertTrue("artifact upload failed: " + artifactDetails.getArtifactName(), uploadArtifactResp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + if (uploadArtifactResp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS) { + ArtifactDefinition artifactJavaObject = ResponseParser.convertArtifactDefinitionResponseToJavaObject(uploadArtifactResp.getResponse()); + return Either.left(artifactJavaObject); + } + return Either.right(uploadArtifactResp); + } + + // *********** CONTAINERS ***************** + /** + * Adds Component instance to Component + * + * @param compInstParent + * @param compContainer + * @return + */ + public static Either addComponentInstanceToComponentContainer(Component compInstParent, Component compContainer) { + return addComponentInstanceToComponentContainer(compInstParent, compContainer, UserRoleEnum.DESIGNER, false); + } + + public static Either addComponentInstanceToComponentContainer(Component compInstParent, Component compContainer, UserRoleEnum userRole, Boolean validateState) { + try { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ComponentInstanceReqDetails componentInstanceDetails = ElementFactory.getComponentInstance(compInstParent); + RestResponse createComponentInstance = ComponentInstanceRestUtils.createComponentInstance(componentInstanceDetails, defaultUser, compContainer); + + if (validateState) { + assertTrue(createComponentInstance.getErrorCode() == ServiceRestUtils.STATUS_CODE_CREATED); + } + + if (createComponentInstance.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + ComponentInstance componentInstance = ResponseParser.convertComponentInstanceResponseToJavaObject(createComponentInstance.getResponse()); + return Either.left(componentInstance); + } + return Either.right(createComponentInstance); + } catch (Exception e) { + throw new AtomicOperationException(e); + } + } + + public static Resource getResourceObject(Component containerDetails, UserRoleEnum userRole) throws Exception { + // User defaultUser = ElementFactory.getDefaultUser(userRole); + RestResponse restResponse = ResourceRestUtils.getResource(containerDetails.getUniqueId()); + Resource container = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + return container; + } + + public static Service getServiceObject(Component containerDetails, UserRoleEnum userRole) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + RestResponse serviceResponse = ServiceRestUtils.getService(containerDetails.getUniqueId(), defaultUser); + Service container = ResponseParser.convertServiceResponseToJavaObject(serviceResponse.getResponse()); + return container; + } + + public static Product getProductObject(Component containerDetails, UserRoleEnum userRole) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + RestResponse productRest = ProductRestUtils.getProduct(containerDetails.getUniqueId(), defaultUser.getUserId()); + Product container = ResponseParser.convertProductResponseToJavaObject(productRest.getResponse()); + return container; + } + + public static Component getCompoenntObject(Component containerDetails, UserRoleEnum userRole) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + + switch (containerDetails.getComponentType()) { + case RESOURCE: + RestResponse restResponse = ResourceRestUtils.getResource(containerDetails.getUniqueId()); + containerDetails = ResponseParser.convertResourceResponseToJavaObject(restResponse.getResponse()); + break; + case SERVICE: + RestResponse serviceResponse = ServiceRestUtils.getService(containerDetails.getUniqueId(), defaultUser); + containerDetails = ResponseParser.convertServiceResponseToJavaObject(serviceResponse.getResponse()); + break; + case PRODUCT: + RestResponse productRest = ProductRestUtils.getProduct(containerDetails.getUniqueId(), defaultUser.getUserId()); + containerDetails = ResponseParser.convertProductResponseToJavaObject(productRest.getResponse()); + break; + default: + break; + } + return containerDetails; + } + + public static Component convertReposnseToComponentObject(Component containerDetails, RestResponse restresponse) throws Exception { + + switch (containerDetails.getComponentType()) { + case RESOURCE: + containerDetails = ResponseParser.convertResourceResponseToJavaObject(restresponse.getResponse()); + break; + case SERVICE: + containerDetails = ResponseParser.convertServiceResponseToJavaObject(restresponse.getResponse()); + break; + case PRODUCT: + containerDetails = ResponseParser.convertProductResponseToJavaObject(restresponse.getResponse()); + break; + default: + break; + } + return containerDetails; + } + + public static RestResponse associate2ResourceInstances(Component containerDetails, ComponentInstance fromNode, ComponentInstance toNode, String assocType, UserRoleEnum userRole, Boolean validateState) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + RestResponse associate2ResourceInstancesResponse = ResourceRestUtils.associate2ResourceInstances(containerDetails, fromNode, toNode, assocType, defaultUser); + + if (validateState) { + assertTrue(associate2ResourceInstancesResponse.getErrorCode() == ServiceRestUtils.STATUS_CODE_SUCCESS); + } + + return associate2ResourceInstancesResponse; + } + + public static Either, RestResponse> changeComponentInstanceVersion(Component containerDetails, ComponentInstance componentInstanceToReplace, Component newInstance, UserRoleEnum userRole, Boolean validateState) + throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + + RestResponse changeComponentInstanceVersionResp = ComponentInstanceRestUtils.changeComponentInstanceVersion(containerDetails, componentInstanceToReplace, newInstance, defaultUser); + if (validateState) { + assertTrue("change ComponentInstance version failed: " + changeComponentInstanceVersionResp.getResponseMessage(), changeComponentInstanceVersionResp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + if (changeComponentInstanceVersionResp.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS) { + + Component compoenntObject = AtomicOperationUtils.getCompoenntObject(containerDetails, userRole); + ComponentInstance componentInstanceJavaObject = ResponseParser.convertComponentInstanceResponseToJavaObject(changeComponentInstanceVersionResp.getResponse()); + + return Either.left(Pair.of(compoenntObject, componentInstanceJavaObject)); + } + + return Either.right(changeComponentInstanceVersionResp); + } + + // *********** PROPERTIES ***************** + + public static Either addCustomPropertyToResource(PropertyReqDetails propDetails, Resource resourceDetails, UserRoleEnum userRole, Boolean validateState) throws Exception { + + User defaultUser = ElementFactory.getDefaultUser(userRole); + Map propertyToSend = new HashMap(); + propertyToSend.put(propDetails.getName(), propDetails); + Gson gson = new Gson(); + RestResponse addPropertyResponse = PropertyRestUtils.createProperty(resourceDetails.getUniqueId(), gson.toJson(propertyToSend), defaultUser); + + if (validateState) { + assertTrue("add property to resource failed: " + addPropertyResponse.getErrorCode(), addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_CREATED); + } + + if (addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_CREATED) { + ComponentInstanceProperty compInstProp = null; + String property = ResponseParser.getJsonObjectValueByKey(addPropertyResponse.getResponse(), propDetails.getName()); + compInstProp = (ResponseParser.convertPropertyResponseToJavaObject(property)); + return Either.left(compInstProp); + } + return Either.right(addPropertyResponse); + } + + // Benny + public static Either updatePropertyOfResource(PropertyReqDetails propDetails, Resource resourceDetails, String propertyUniqueId, UserRoleEnum userRole, Boolean validateState) throws Exception { + + User defaultUser = ElementFactory.getDefaultUser(userRole); + Map propertyToSend = new HashMap(); + propertyToSend.put(propDetails.getName(), propDetails); + Gson gson = new Gson(); + RestResponse addPropertyResponse = PropertyRestUtils.updateProperty(resourceDetails.getUniqueId(), propertyUniqueId, gson.toJson(propertyToSend), defaultUser); + + if (validateState) { + assertTrue("add property to resource failed: " + addPropertyResponse.getResponseMessage(), addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + } + + if (addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_SUCCESS) { + ComponentInstanceProperty compInstProp = null; + String property = ResponseParser.getJsonObjectValueByKey(addPropertyResponse.getResponse(), propDetails.getName()); + compInstProp = (ResponseParser.convertPropertyResponseToJavaObject(property)); + return Either.left(compInstProp); + } + return Either.right(addPropertyResponse); + } + + public static RestResponse deletePropertyOfResource(String resourceId, String propertyId, UserRoleEnum userRole) throws Exception { + User defaultUser = ElementFactory.getDefaultUser(userRole); + return PropertyRestUtils.deleteProperty(resourceId, propertyId, defaultUser); + } + + public static Either addDefaultPropertyToResource(PropertyTypeEnum propertyType, Resource resourceDetails, UserRoleEnum userRole, Boolean validateState) throws Exception { + + User defaultUser = ElementFactory.getDefaultUser(userRole); + PropertyReqDetails propDetails = ElementFactory.getPropertyDetails(propertyType); + Map propertyToSend = new HashMap(); + propertyToSend.put(propDetails.getName(), propDetails); + Gson gson = new Gson(); + RestResponse addPropertyResponse = PropertyRestUtils.createProperty(resourceDetails.getUniqueId(), gson.toJson(propertyToSend), defaultUser); + + if (validateState) { + assertTrue("add property to resource failed: " + addPropertyResponse.getResponseMessage(), addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_CREATED); + } + + if (addPropertyResponse.getErrorCode() == BaseRestUtils.STATUS_CODE_CREATED) { + ComponentInstanceProperty compInstProp = null; + String property = ResponseParser.getJsonObjectValueByKey(addPropertyResponse.getResponse(), propDetails.getName()); + compInstProp = (ResponseParser.convertPropertyResponseToJavaObject(property)); + + return Either.left(compInstProp); + } + return Either.right(addPropertyResponse); + } + + public static RestResponse createDefaultConsumer(Boolean validateState) { + try { + ConsumerDataDefinition defaultConsumerDefinition = ElementFactory.getDefaultConsumerDetails(); + RestResponse createResponse = ConsumerRestUtils.createConsumer(defaultConsumerDefinition, ElementFactory.getDefaultUser(UserRoleEnum.ADMIN)); + BaseRestUtils.checkCreateResponse(createResponse); + + if (validateState) { + assertTrue(createResponse.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED); + } + return createResponse; + } catch (Exception e) { + throw new AtomicOperationException(e); + } + } + + /** + * Builds Resource From rest response + * + * @param resourceResp + * @return + */ + public static Either buildResourceFromResponse(RestResponse resourceResp) { + Either result; + if (resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + Resource resourceResponseObject = ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + result = Either.left(resourceResponseObject); + } else { + result = Either.right(resourceResp); + } + return result; + } + + private static class AtomicOperationException extends RuntimeException { + private AtomicOperationException(Exception e) { + super(e); + } + + private static final long serialVersionUID = 1L; + }; + + /** + * Import resource from CSAR + * + * @param resourceType + * @param userRole + * @param fileName + * @param filePath + * @return Resource + * @throws Exception + */ + public static Resource importResourceFromCSAR(ResourceTypeEnum resourceType, UserRoleEnum userRole, String fileName, String... filePath) throws Exception { + // Get the CSARs path + String realFilePath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "test" + File.separator + "resources" + File.separator + "CI" + File.separator + "csars"; + if (filePath != null && filePath.length > 0) { + realFilePath = filePath.toString(); + } + + // Create default import resource & user + ImportReqDetails resourceDetails = ElementFactory.getDefaultImportResource(); + User sdncModifierDetails = ElementFactory.getDefaultUser(userRole); + + byte[] data = null; + Path path = Paths.get(realFilePath + File.separator + fileName); + data = Files.readAllBytes(path); + String payloadName = fileName; + String payloadData = Base64.encodeBase64String(data); + resourceDetails.setPayloadData(payloadData); + resourceDetails.setCsarUUID(payloadName); + resourceDetails.setPayloadName(payloadName); + resourceDetails.setResourceType(resourceType.name()); + + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncModifierDetails); + BaseRestUtils.checkCreateResponse(createResource); + return ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + }; + + public static Either importResourceByFileName(ResourceTypeEnum resourceType, UserRoleEnum userRole, String fileName, Boolean validateState, String... filePath) throws IOException { + + String realFilePath = System.getProperty("user.dir") + File.separator + "src" + File.separator + "test" + File.separator + "resources" + File.separator + "CI" + File.separator + "csars"; + if (filePath != null && filePath.length > 0) { + realFilePath = filePath.toString(); + } + + try { + User defaultUser = ElementFactory.getDefaultUser(userRole); + ResourceReqDetails defaultResource = ElementFactory.getDefaultResource(defaultUser); + ImportReqDetails defaultImportResource = ElementFactory.getDefaultImportResource(defaultResource); + ImportUtils.getImportResourceDetailsByPathAndName(defaultImportResource, realFilePath, fileName); + RestResponse resourceResp = ResourceRestUtils.createResource(defaultImportResource, defaultUser); + + if (validateState) { + assertTrue(resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED); + } + + if (resourceResp.getErrorCode() == ResourceRestUtils.STATUS_CODE_CREATED) { + Resource resourceResponseObject = ResponseParser.convertResourceResponseToJavaObject(resourceResp.getResponse()); + return Either.left(resourceResponseObject); + } + return Either.right(resourceResp); + } catch (Exception e) { + throw new AtomicOperationException(e); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/Convertor.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/Convertor.java new file mode 100644 index 0000000000..4aa13b48e4 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/Convertor.java @@ -0,0 +1,309 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.general; + +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_CREATED; +import static org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils.STATUS_CODE_SUCCESS; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.lang3.StringUtils; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedUserCRUDAudit; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.api.Constants; + +public class Convertor { + // ***** resource ***** + public static ResourceRespJavaObject constructFieldsForRespValidation(ResourceReqDetails resourceDetails, + String resourceVersion) { + return convertToRespObject(resourceDetails, resourceVersion, UserRoleEnum.ADMIN.getUserId(), + UserRoleEnum.ADMIN.getUserName()); + + } + + public static ResourceRespJavaObject constructFieldsForRespValidation(ResourceReqDetails resourceDetails) { + return convertToRespObject(resourceDetails, resourceDetails.getVersion(), UserRoleEnum.ADMIN.getUserId(), + UserRoleEnum.ADMIN.getUserName()); + + } + + public static ResourceRespJavaObject constructFieldsForRespValidation(ResourceReqDetails resourceDetails, + String resourceVersion, User user) { + return convertToRespObject(resourceDetails, resourceVersion, user.getUserId(), user.getFullName()); + + } + + private static ResourceRespJavaObject convertToRespObject(ResourceReqDetails resourceDetails, + String resourceVersion, String userId, String userName) { + ResourceRespJavaObject resourceRespJavaObject = new ResourceRespJavaObject(); + + resourceRespJavaObject.setUniqueId(resourceDetails.getUniqueId()); + resourceRespJavaObject.setName(resourceDetails.getName()); + resourceRespJavaObject.setCreatorUserId(resourceDetails.getCreatorUserId()); + resourceRespJavaObject.setCreatorFullName(resourceDetails.getCreatorFullName()); + resourceRespJavaObject.setLastUpdaterUserId(userId); + resourceRespJavaObject.setLastUpdaterFullName(userName); + resourceRespJavaObject.setDescription(resourceDetails.getDescription()); + resourceRespJavaObject.setIcon(resourceDetails.getIcon()); + resourceRespJavaObject.setTags(resourceDetails.getTags()); + resourceRespJavaObject.setIsHighestVersion("true"); + resourceRespJavaObject.setCategories(resourceDetails.getCategories()); + resourceRespJavaObject.setLifecycleState( + resourceDetails.getLifecycleState() != null ? resourceDetails.getLifecycleState().toString() + : LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + // resourceRespJavaObject.setLifecycleState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + resourceRespJavaObject.setDerivedFrom(resourceDetails.getDerivedFrom()); + resourceRespJavaObject.setVendorName(resourceDetails.getVendorName()); + resourceRespJavaObject.setVendorRelease(resourceDetails.getVendorRelease()); + resourceRespJavaObject.setContactId(resourceDetails.getContactId()); + resourceRespJavaObject.setAbstractt("false"); + resourceRespJavaObject.setVersion(resourceVersion); + resourceRespJavaObject.setCost(resourceDetails.getCost()); + resourceRespJavaObject.setLicenseType(resourceDetails.getLicenseType()); + resourceRespJavaObject.setResourceType(resourceDetails.getResourceType()); + + return resourceRespJavaObject; + + } + + // ********** product ************** + + public static Product constructFieldsForRespValidation(ProductReqDetails productDetails, String productVersion, + User user) { + return convertToRespObject(productDetails, productVersion, user.getUserId(), user.getFullName()); + } + + private static Product convertToRespObject(ProductReqDetails productDetails, String productVersion, String userId, + String userName) { + Product expectedProduct = new Product(); + + expectedProduct.setUniqueId(productDetails.getUniqueId()); + expectedProduct.setName(productDetails.getName()); + expectedProduct.setFullName(productDetails.getFullName()); + expectedProduct.setCreatorUserId(productDetails.getCreatorUserId()); + expectedProduct.setCreatorFullName(productDetails.getCreatorFullName()); + expectedProduct.setLastUpdaterUserId(userId); + expectedProduct.setLastUpdaterFullName(userName); + expectedProduct.setDescription(productDetails.getDescription()); + // expectedProduct.setIcon(resourceDetails.getIcon()); + expectedProduct.setTags(productDetails.getTags()); + expectedProduct.setHighestVersion(true); + List categories = productDetails.getCategories(); + if (categories == null) { + categories = new ArrayList<>(); + } + expectedProduct.setCategories(categories); + expectedProduct.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + expectedProduct.setVersion(productVersion); + expectedProduct.setContacts(productDetails.getContacts()); + return expectedProduct; + } + + // ***** audit ***** + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ResourceReqDetails resourceDetails, + String resourceVersion) { + return convertToAuditObject(resourceDetails, resourceVersion, UserRoleEnum.ADMIN.getUserId(), + UserRoleEnum.ADMIN.getUserName()); + } + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation( + ResourceReqDetails resourceDetails) { + return convertToAuditObject(resourceDetails, resourceDetails.getVersion(), UserRoleEnum.ADMIN.getUserId(), + UserRoleEnum.ADMIN.getUserName()); + } + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ResourceReqDetails resourceDetails, + String resourceVersion, User user) { + return convertToAuditObject(resourceDetails, resourceVersion, user.getUserId(), user.getFullName()); + } + + private static ExpectedResourceAuditJavaObject convertToAuditObject(ResourceReqDetails resourceDetails, + String resourceVersion, String userId, String userName) { + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + + expectedResourceAuditJavaObject.setAction("Checkout"); + expectedResourceAuditJavaObject.setModifierName(userName); + expectedResourceAuditJavaObject.setModifierUid(userId); + expectedResourceAuditJavaObject.setStatus("200.0"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setResourceName(resourceDetails.getName()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(String.valueOf(Float.parseFloat(resourceVersion) - 0.1f)); + expectedResourceAuditJavaObject.setCurrVersion(resourceVersion); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setComment(null); + + return expectedResourceAuditJavaObject; + } + + public static ExpectedProductAudit constructFieldsForAuditValidation(Product productDetails, String action, + User user, ActionStatus actionStatus, String prevVersion, String currVersion, LifecycleStateEnum prevState, + LifecycleStateEnum currState, String uuid, String... errorMessageParams) throws FileNotFoundException { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + return convertToAuditObject(productDetails, action, user, errorInfo, prevVersion, currVersion, prevState, + currState, uuid, errorMessageParams); + } + + private static ExpectedProductAudit convertToAuditObject(Product productDetails, String action, User user, + ErrorInfo errorInfo, String prevVersion, String currVersion, LifecycleStateEnum prevState, + LifecycleStateEnum currState, String uuid, String... errorMessageParams) { + ExpectedProductAudit expectedProductAudit = new ExpectedProductAudit(); + + expectedProductAudit.setACTION(action); + String userId = user.getUserId(); + String userFullName; + if (StringUtils.isEmpty(user.getFirstName()) && StringUtils.isEmpty(user.getLastName())) { + userFullName = ""; + } else { + userFullName = user.getFullName(); + } + if (StringUtils.isEmpty(userId)) { + userId = "UNKNOWN"; + } + expectedProductAudit.setMODIFIER( + !StringUtils.isEmpty(userFullName) ? userFullName + "(" + userId + ")" : "(" + userId + ")"); + expectedProductAudit.setSTATUS(Integer.toString(errorInfo.getCode())); + expectedProductAudit.setDESC(errorInfo.getAuditDesc((Object[]) (errorMessageParams))); + expectedProductAudit + .setRESOURCE_NAME(productDetails != null ? productDetails.getName() : Constants.EMPTY_STRING); + expectedProductAudit.setRESOURCE_TYPE("Product"); + expectedProductAudit.setPREV_VERSION(prevVersion); + expectedProductAudit.setCURR_VERSION(currVersion); + expectedProductAudit.setPREV_STATE(prevState != null ? prevState.name() : Constants.EMPTY_STRING); + expectedProductAudit.setCURR_STATE(currState != null ? currState.name() : Constants.EMPTY_STRING); + expectedProductAudit.setSERVICE_INSTANCE_ID(uuid); + return expectedProductAudit; + } + + //////////////// + // Convertor.constructFieldsForAuditValidationSuccess(addUser, + //////////////// sdncAdminUser, mechIdUser, null, STATUS_CODE_CREATED); + public static ExpectedUserCRUDAudit constructFieldsForAuditValidation(String action, User userModifier, + ActionStatus actionStatus, User userAfter, User userBefore, Object... variables) throws Exception { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + ExpectedUserCRUDAudit expectedAddUserAuditJavaObject = new ExpectedUserCRUDAudit(); + expectedAddUserAuditJavaObject.setAction(action); + expectedAddUserAuditJavaObject.setModifier( + userModifier.getFirstName() != null ? userModifier.getFullName() + "(" + userModifier.getUserId() + ")" + : "(" + userModifier.getUserId() + ")"); + String status = Integer.toString(errorInfo.getCode()); + expectedAddUserAuditJavaObject.setStatus(status); + if (errorInfo.getCode() == STATUS_CODE_SUCCESS || errorInfo.getCode() == STATUS_CODE_CREATED) { + expectedAddUserAuditJavaObject.setDesc("OK"); + } else { + expectedAddUserAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + } + expectedAddUserAuditJavaObject.setUserBefore(userBefore != null + ? userBefore.getUserId() + ", " + userBefore.getFirstName() + " " + userBefore.getLastName() + ", " + + userBefore.getEmail() + ", " + userBefore.getRole() + : Constants.EMPTY_STRING); + expectedAddUserAuditJavaObject.setUserAfter(userAfter != null + ? userAfter.getUserId() + ", " + userAfter.getFirstName() + " " + userAfter.getLastName() + ", " + + userAfter.getEmail() + ", " + userAfter.getRole() + : Constants.EMPTY_STRING); + return expectedAddUserAuditJavaObject; + } + + // For RESOURCE and SERVICE same Audit + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation( + ComponentReqDetails componentDetails, String action, User userModifier, ActionStatus actionStatus, + String currVersion, String prevVersion, String curState, String prevState, String uuid, String comment, + Object... variables) throws Exception { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(action); + expectedResourceAuditJavaObject.setMODIFIER( + userModifier.getFirstName() != null ? userModifier.getFullName() + "(" + userModifier.getUserId() + ")" + : "(" + userModifier.getUserId() + ")"); + String status = Integer.toString(errorInfo.getCode()); + expectedResourceAuditJavaObject.setStatus(status); + if (errorInfo.getCode() == STATUS_CODE_SUCCESS || errorInfo.getCode() == STATUS_CODE_CREATED) { + expectedResourceAuditJavaObject.setDesc("OK"); + } else { + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + } + expectedResourceAuditJavaObject.setCurrState(curState); + expectedResourceAuditJavaObject.setPrevState(prevState); + expectedResourceAuditJavaObject.setCurrVersion(currVersion); + expectedResourceAuditJavaObject.setPrevVersion(prevVersion); + expectedResourceAuditJavaObject.setComment(comment); + expectedResourceAuditJavaObject.setSERVICE_INSTANCE_ID(uuid); + if (componentDetails instanceof ServiceReqDetails) { + expectedResourceAuditJavaObject.setResourceName(((ServiceReqDetails) componentDetails).getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + } + if (componentDetails instanceof ResourceReqDetails) { + expectedResourceAuditJavaObject.setResourceName(((ResourceReqDetails) componentDetails).getName()); + expectedResourceAuditJavaObject.setResourceType("Resource"); + } + return expectedResourceAuditJavaObject; + } + + // Distribution Service Audit + public static ExpectedResourceAuditJavaObject constructFieldsForDistributionAuditValidation( + ComponentReqDetails componentDetails, String action, User userModifier, ActionStatus actionStatus, + String currVersion, String distCurrStatus, String distProvStatus, String curState, String uuid, + String comment, Object... variables) throws Exception { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(action); + expectedResourceAuditJavaObject.setMODIFIER( + userModifier.getFirstName() != null ? userModifier.getFullName() + "(" + userModifier.getUserId() + ")" + : "(" + userModifier.getUserId() + ")"); + String status = Integer.toString(errorInfo.getCode()); + expectedResourceAuditJavaObject.setStatus(status); + if (errorInfo.getCode() == STATUS_CODE_SUCCESS || errorInfo.getCode() == STATUS_CODE_CREATED) { + expectedResourceAuditJavaObject.setDesc("OK"); + } else { + expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + } + expectedResourceAuditJavaObject.setCurrState(curState); + expectedResourceAuditJavaObject.setCurrVersion(currVersion); + expectedResourceAuditJavaObject.setDcurrStatus(distCurrStatus); + expectedResourceAuditJavaObject.setDprevStatus(distProvStatus); + expectedResourceAuditJavaObject.setComment(comment); + expectedResourceAuditJavaObject.setSERVICE_INSTANCE_ID(uuid); + if (componentDetails instanceof ServiceReqDetails) { + expectedResourceAuditJavaObject.setResourceName(((ServiceReqDetails) componentDetails).getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + } + return expectedResourceAuditJavaObject; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java new file mode 100644 index 0000000000..ba2ebd9b4e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ElementFactory.java @@ -0,0 +1,873 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.general; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.RelationshipImpl; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.PropertyReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.PropertyTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.ValidationUtils; + +public class ElementFactory { + + private static String DEFAULT_ARTIFACT_LABEL = "artifact1"; + private static final String RESOURCE_INSTANCE_POS_X = "20"; + private static final String RESOURCE_INSTANCE_POS_Y = "20"; + private static final String RESOURCE_INSTANCE_DESCRIPTION = "description"; + + // *** RESOURCE *** + + public static ResourceReqDetails getDefaultResource() { + return getDefaultResource("ciRes", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, "jh0003"); + } + + public static ResourceReqDetails getDefaultResource(ResourceCategoryEnum category) { + return getDefaultResource("ciRes", NormativeTypesEnum.ROOT, category, "jh0003"); + } + + public static ResourceReqDetails getDefaultResource(String contactId) { + return getDefaultResource("ciRes", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, contactId); + } + + public static ResourceReqDetails getDefaultResource(User modifier) { + return getDefaultResource("ciRes", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, modifier.getUserId()); + } + + public static ResourceReqDetails getDefaultResource(NormativeTypesEnum derivedFrom, ResourceCategoryEnum category) { + return getDefaultResource("ciRes", derivedFrom, category, "jh0003"); + } + + public static ResourceReqDetails getDefaultResource(NormativeTypesEnum derivedFrom) { + return getDefaultResource("ciRes", derivedFrom, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, "jh0003"); + } + + public static ResourceReqDetails getDefaultResource(String resourceName, NormativeTypesEnum derivedFrom) { + return getDefaultResource(resourceName, derivedFrom, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, "jh0003"); + } + + public static ResourceReqDetails getDefaultResource(NormativeTypesEnum derivedFrom, String contactId) { + return getDefaultResource("ciRes", derivedFrom, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, contactId); + } + + // New + public static ResourceReqDetails getDefaultResourceByType(ResourceTypeEnum ResourceType, String resourceName) { + return getDefaultResourceByType(resourceName, NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, "jh0003", ResourceType.toString()); + } + + public static ResourceReqDetails getDefaultResourceByType(ResourceTypeEnum ResourceType, User user) { + return getDefaultResourceByType("ciRes", NormativeTypesEnum.ROOT, ResourceCategoryEnum.GENERIC_INFRASTRUCTURE, user.getUserId(), ResourceType.toString()); + } + + public static ResourceReqDetails getDefaultResourceByTypeNormTypeAndCatregory(ResourceTypeEnum resourceType, NormativeTypesEnum normativeTypes, ResourceCategoryEnum resourceCategory, User user) { + return getDefaultResourceByType("ciRes", normativeTypes, resourceCategory, user.getUserId(), resourceType.toString()); + } + + public static PropertyReqDetails getDefaultMapProperty(PropertyTypeEnum innerType) { + return getPropertyDetails(innerType); + } + + public static PropertyReqDetails getDefaultMapProperty() { + return getPropertyDetails(PropertyTypeEnum.STRING_MAP); + } + + public static ResourceReqDetails getDefaultResource(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId) { + resourceName = (resourceName + generateUUIDforSufix()); + String description = "Represents a generic software component that can be managed and run by a Compute Node Type."; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(derived.normativeName); + String vendorName = "ATT (Tosca)"; + String vendorRelease = "1.0.0.wd03"; + String icon = "defaulticon"; + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(category.getCategory(), category.getSubCategory()); + + return resourceDetails; + + } + + public static ResourceReqDetails getDefaultResourceByTypeNormTypeAndCatregory(ResourceTypeEnum resourceType, Resource normativeTypes, ResourceCategoryEnum resourceCategory, User user) { + return getDefaultResource("ciRes" + resourceType, normativeTypes, resourceCategory, user.getUserId()); + } + + public static ResourceReqDetails getDefaultResource(String resourceName, Resource derived, ResourceCategoryEnum category, String contactId) { + resourceName = (resourceName + generateUUIDforSufix()); + String description = "Represents a generic software component that can be managed and run by a Compute Node Type."; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + + ArrayList derivedFrom = new ArrayList(); + derivedFrom.add(derived.getToscaResourceName()); + String vendorName = "ATT (Tosca)"; + String vendorRelease = "1.0.0.wd03"; + String icon = "defaulticon"; + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(category.getCategory(), category.getSubCategory()); + + return resourceDetails; + + } + + public static ResourceReqDetails getDefaultResourceByType(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId, ResourceTypeEnum resourceType) { + return getDefaultResourceByType(resourceName, derived, category, contactId, resourceType.toString()); + } + + // New + public static ResourceReqDetails getDefaultResourceByType(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId, String resourceType) { + resourceName = (resourceName + resourceType + generateUUIDforSufix()); + String description = "Represents a generic software component that can be managed and run by a Compute Node Type."; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + ArrayList derivedFrom = null; + if (derived != null) { + derivedFrom = new ArrayList(); + derivedFrom.add(derived.normativeName); + } + String vendorName = "ATT (Tosca)"; + String vendorRelease = "1.0.0.wd03"; + String icon = "defaulticon"; + ResourceReqDetails resourceDetails = new ResourceReqDetails(resourceName, description, resourceTags, null, derivedFrom, vendorName, vendorRelease, contactId, icon, resourceType.toString()); + resourceDetails.addCategoryChain(category.getCategory(), category.getSubCategory()); + return resourceDetails; + } + + // New + public static ImportReqDetails getDefaultImportResourceByType(String resourceName, NormativeTypesEnum derived, ResourceCategoryEnum category, String contactId, String resourceType) { + resourceName = (resourceName + resourceType + generateUUIDforSufix()); + String description = "Represents a generic software component that can be managed and run by a Compute Node Type."; + ArrayList resourceTags = new ArrayList(); + resourceTags.add(resourceName); + ArrayList derivedFrom = null; + if (derived != null) { + derivedFrom = new ArrayList(); + derivedFrom.add(derived.normativeName); + } + String vendorName = "ATT (Tosca)"; + String vendorRelease = "1.0.0.wd03"; + String icon = "defaulticon"; + ImportReqDetails resourceDetails = new ImportReqDetails(resourceName, description, resourceTags, derivedFrom, vendorName, vendorRelease, contactId, icon); + resourceDetails.addCategoryChain(category.getCategory(), category.getSubCategory()); + return resourceDetails; + } + //// + + public static ImportReqDetails getDefaultImportResource(ResourceReqDetails resourceReqDetails) { + ImportReqDetails importReqDetails = new ImportReqDetails(resourceReqDetails.getName(), resourceReqDetails.getDescription(), resourceReqDetails.getTags(), resourceReqDetails.getDerivedFrom(), resourceReqDetails.getVendorName(), + resourceReqDetails.getVendorRelease(), resourceReqDetails.getContactId(), resourceReqDetails.getIcon()); + importReqDetails.setPayloadName("myCompute.yaml"); + importReqDetails.setCategories(resourceReqDetails.getCategories()); + importReqDetails.setPayloadData( + "dG9zY2FfZGVmaW5pdGlvbnNfdmVyc2lvbjogdG9zY2Ffc2ltcGxlX3lhbWxfMV8wXzANCm5vZGVfdHlwZXM6IA0KICBvcmcub3BlbmVjb21wLnJlc291cmNlLk15Q29tcHV0ZToNCiAgICBkZXJpdmVkX2Zyb206IHRvc2NhLm5vZGVzLlJvb3QNCiAgICBhdHRyaWJ1dGVzOg0KICAgICAgcHJpdmF0ZV9hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIHB1YmxpY19hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIG5ldHdvcmtzOg0KICAgICAgICB0eXBlOiBtYXANCiAgICAgICAgZW50cnlfc2NoZW1hOg0KICAgICAgICAgIHR5cGU6IHRvc2NhLmRhdGF0eXBlcy5uZXR3b3JrLk5ldHdvcmtJbmZvDQogICAgICBwb3J0czoNCiAgICAgICAgdHlwZTogbWFwDQogICAgICAgIGVudHJ5X3NjaGVtYToNCiAgICAgICAgICB0eXBlOiB0b3NjYS5kYXRhdHlwZXMubmV0d29yay5Qb3J0SW5mbw0KICAgIHJlcXVpcmVtZW50czoNCiAgICAgIC0gbG9jYWxfc3RvcmFnZTogDQogICAgICAgICAgY2FwYWJpbGl0eTogdG9zY2EuY2FwYWJpbGl0aWVzLkF0dGFjaG1lbnQNCiAgICAgICAgICBub2RlOiB0b3NjYS5ub2Rlcy5CbG9ja1N0b3JhZ2UNCiAgICAgICAgICByZWxhdGlvbnNoaXA6IHRvc2NhLnJlbGF0aW9uc2hpcHMuQXR0YWNoZXNUbw0KICAgICAgICAgIG9jY3VycmVuY2VzOiBbMCwgVU5CT1VOREVEXSAgDQogICAgY2FwYWJpbGl0aWVzOg0KICAgICAgaG9zdDogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5Db250YWluZXINCiAgICAgICAgdmFsaWRfc291cmNlX3R5cGVzOiBbdG9zY2Eubm9kZXMuU29mdHdhcmVDb21wb25lbnRdIA0KICAgICAgZW5kcG9pbnQgOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuRW5kcG9pbnQuQWRtaW4gDQogICAgICBvczogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5PcGVyYXRpbmdTeXN0ZW0NCiAgICAgIHNjYWxhYmxlOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuU2NhbGFibGUNCiAgICAgIGJpbmRpbmc6DQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5uZXR3b3JrLkJpbmRhYmxlDQo="); + return importReqDetails; + } + + public static ImportReqDetails getDefaultImportResource() { + ResourceReqDetails resourceReqDetails = getDefaultResource(); + ImportReqDetails importReqDetails = new ImportReqDetails(resourceReqDetails.getName(), resourceReqDetails.getDescription(), resourceReqDetails.getTags(), resourceReqDetails.getDerivedFrom(), resourceReqDetails.getVendorName(), + resourceReqDetails.getVendorRelease(), resourceReqDetails.getContactId(), resourceReqDetails.getIcon()); + importReqDetails.setPayloadName("myCompute.yaml"); + importReqDetails.setCategories(resourceReqDetails.getCategories()); + importReqDetails.setPayloadData( + "dG9zY2FfZGVmaW5pdGlvbnNfdmVyc2lvbjogdG9zY2Ffc2ltcGxlX3lhbWxfMV8wXzANCm5vZGVfdHlwZXM6IA0KICBvcmcub3BlbmVjb21wLnJlc291cmNlLk15Q29tcHV0ZToNCiAgICBkZXJpdmVkX2Zyb206IHRvc2NhLm5vZGVzLlJvb3QNCiAgICBhdHRyaWJ1dGVzOg0KICAgICAgcHJpdmF0ZV9hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIHB1YmxpY19hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIG5ldHdvcmtzOg0KICAgICAgICB0eXBlOiBtYXANCiAgICAgICAgZW50cnlfc2NoZW1hOg0KICAgICAgICAgIHR5cGU6IHRvc2NhLmRhdGF0eXBlcy5uZXR3b3JrLk5ldHdvcmtJbmZvDQogICAgICBwb3J0czoNCiAgICAgICAgdHlwZTogbWFwDQogICAgICAgIGVudHJ5X3NjaGVtYToNCiAgICAgICAgICB0eXBlOiB0b3NjYS5kYXRhdHlwZXMubmV0d29yay5Qb3J0SW5mbw0KICAgIHJlcXVpcmVtZW50czoNCiAgICAgIC0gbG9jYWxfc3RvcmFnZTogDQogICAgICAgICAgY2FwYWJpbGl0eTogdG9zY2EuY2FwYWJpbGl0aWVzLkF0dGFjaG1lbnQNCiAgICAgICAgICBub2RlOiB0b3NjYS5ub2Rlcy5CbG9ja1N0b3JhZ2UNCiAgICAgICAgICByZWxhdGlvbnNoaXA6IHRvc2NhLnJlbGF0aW9uc2hpcHMuQXR0YWNoZXNUbw0KICAgICAgICAgIG9jY3VycmVuY2VzOiBbMCwgVU5CT1VOREVEXSAgDQogICAgY2FwYWJpbGl0aWVzOg0KICAgICAgaG9zdDogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5Db250YWluZXINCiAgICAgICAgdmFsaWRfc291cmNlX3R5cGVzOiBbdG9zY2Eubm9kZXMuU29mdHdhcmVDb21wb25lbnRdIA0KICAgICAgZW5kcG9pbnQgOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuRW5kcG9pbnQuQWRtaW4gDQogICAgICBvczogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5PcGVyYXRpbmdTeXN0ZW0NCiAgICAgIHNjYWxhYmxlOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuU2NhbGFibGUNCiAgICAgIGJpbmRpbmc6DQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5uZXR3b3JrLkJpbmRhYmxlDQo="); + return importReqDetails; + } + + public static ImportReqDetails getDefaultImportResource(String name) { + ResourceReqDetails resourceReqDetails = getDefaultResourceByType(ResourceTypeEnum.VFC, name); + ImportReqDetails importReqDetails = new ImportReqDetails(resourceReqDetails.getName(), resourceReqDetails.getDescription(), resourceReqDetails.getTags(), resourceReqDetails.getDerivedFrom(), resourceReqDetails.getVendorName(), + resourceReqDetails.getVendorRelease(), resourceReqDetails.getContactId(), resourceReqDetails.getIcon()); + importReqDetails.setPayloadName("myCompute.yaml"); + importReqDetails.setCategories(resourceReqDetails.getCategories()); + importReqDetails.setPayloadData( + "dG9zY2FfZGVmaW5pdGlvbnNfdmVyc2lvbjogdG9zY2Ffc2ltcGxlX3lhbWxfMV8wXzANCm5vZGVfdHlwZXM6IA0KICBvcmcub3BlbmVjb21wLnJlc291cmNlLk15Q29tcHV0ZToNCiAgICBkZXJpdmVkX2Zyb206IHRvc2NhLm5vZGVzLlJvb3QNCiAgICBhdHRyaWJ1dGVzOg0KICAgICAgcHJpdmF0ZV9hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIHB1YmxpY19hZGRyZXNzOg0KICAgICAgICB0eXBlOiBzdHJpbmcNCiAgICAgIG5ldHdvcmtzOg0KICAgICAgICB0eXBlOiBtYXANCiAgICAgICAgZW50cnlfc2NoZW1hOg0KICAgICAgICAgIHR5cGU6IHRvc2NhLmRhdGF0eXBlcy5uZXR3b3JrLk5ldHdvcmtJbmZvDQogICAgICBwb3J0czoNCiAgICAgICAgdHlwZTogbWFwDQogICAgICAgIGVudHJ5X3NjaGVtYToNCiAgICAgICAgICB0eXBlOiB0b3NjYS5kYXRhdHlwZXMubmV0d29yay5Qb3J0SW5mbw0KICAgIHJlcXVpcmVtZW50czoNCiAgICAgIC0gbG9jYWxfc3RvcmFnZTogDQogICAgICAgICAgY2FwYWJpbGl0eTogdG9zY2EuY2FwYWJpbGl0aWVzLkF0dGFjaG1lbnQNCiAgICAgICAgICBub2RlOiB0b3NjYS5ub2Rlcy5CbG9ja1N0b3JhZ2UNCiAgICAgICAgICByZWxhdGlvbnNoaXA6IHRvc2NhLnJlbGF0aW9uc2hpcHMuQXR0YWNoZXNUbw0KICAgICAgICAgIG9jY3VycmVuY2VzOiBbMCwgVU5CT1VOREVEXSAgDQogICAgY2FwYWJpbGl0aWVzOg0KICAgICAgaG9zdDogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5Db250YWluZXINCiAgICAgICAgdmFsaWRfc291cmNlX3R5cGVzOiBbdG9zY2Eubm9kZXMuU29mdHdhcmVDb21wb25lbnRdIA0KICAgICAgZW5kcG9pbnQgOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuRW5kcG9pbnQuQWRtaW4gDQogICAgICBvczogDQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5PcGVyYXRpbmdTeXN0ZW0NCiAgICAgIHNjYWxhYmxlOg0KICAgICAgICB0eXBlOiB0b3NjYS5jYXBhYmlsaXRpZXMuU2NhbGFibGUNCiAgICAgIGJpbmRpbmc6DQogICAgICAgIHR5cGU6IHRvc2NhLmNhcGFiaWxpdGllcy5uZXR3b3JrLkJpbmRhYmxlDQo="); + return importReqDetails; + } + + // *** SERVICE *** + public static ServiceReqDetails getDefaultService() { + return getDefaultService("ciService", ServiceCategoriesEnum.MOBILITY, "al1976"); + } + + public static ServiceReqDetails getDefaultService(String contactId) { + return getDefaultService("ciService", ServiceCategoriesEnum.MOBILITY, contactId); + } + + public static ServiceReqDetails getDefaultService(User user) { + return getDefaultService("ciService", ServiceCategoriesEnum.MOBILITY, user.getUserId()); + } + + public static ServiceReqDetails getService(ServiceCategoriesEnum category) { + return getDefaultService("ciService", category, "al1976"); + } + + public static ServiceReqDetails getDefaultService(ServiceCategoriesEnum category, User user) { + return getDefaultService("ciService", category, user.getUserId()); + } + + public static ServiceReqDetails getDefaultService(String serviceName, ServiceCategoriesEnum category, String contactId) { + serviceName = (serviceName + generateUUIDforSufix()); + ArrayList tags = new ArrayList(); + tags.add("serviceTag"); + tags.add("serviceTag1"); + tags.add(serviceName); + String description = "service Description"; + String icon = "myIcon"; + + ServiceReqDetails serviceDetails = new ServiceReqDetails(serviceName, category.getValue(), tags, description, contactId, icon); + + return serviceDetails; + } + + // ***** PROPERTY *** + + public static PropertyReqDetails getDefaultProperty() { + return getDefaultProperty("disk_size"); + } + + public static PropertyReqDetails getDefaultProperty(String propertyName) { + PropertyReqDetails property = new PropertyReqDetails(); + property.setName(propertyName); + property.setPropertyType("integer"); + property.setPropertyRequired(false); + property.setPropertyDefaultValue("12345"); + property.setPropertyDescription("test property"); + property.setPropertyRangeMax("500"); + property.setPropertyRangeMin("100"); + property.setPropertyPassword(false); + return property; + } + + public static PropertyReqDetails getDefaultIntegerProperty() { + return getPropertyDetails(PropertyTypeEnum.INTEGER); + } + + public static PropertyReqDetails getDefaultStringProperty() { + return getPropertyDetails(PropertyTypeEnum.STRING); + } + + public static PropertyReqDetails getDefaultBooleanProperty() { + return getPropertyDetails(PropertyTypeEnum.BOOLEAN); + } + + public static PropertyReqDetails getDefaultListProperty() { + return getPropertyDetails(PropertyTypeEnum.STRING_LIST); + } + + public static PropertyReqDetails getDefaultListProperty(PropertyTypeEnum innerType) { + return getPropertyDetails(innerType); + } + + public static PropertyReqDetails getPropertyDetails(PropertyTypeEnum propType) { + return new PropertyReqDetails(propType.getName(), propType.getType(), propType.getValue(), propType.getDescription(), propType.getSchemaDefinition()); + } + + // ***** RESOURCE INSTANCE *** + public static ComponentInstanceReqDetails getDefaultComponentInstance() { + return getDefaultComponentInstance("resourceInstanceName"); + } + + public static ComponentInstanceReqDetails getDefaultComponentInstance(String name) { + String resourceUid = "resourceId"; + ComponentInstanceReqDetails resourceInstanceDetails = new ComponentInstanceReqDetails(resourceUid, RESOURCE_INSTANCE_DESCRIPTION, RESOURCE_INSTANCE_POS_X, RESOURCE_INSTANCE_POS_Y, name); + + return resourceInstanceDetails; + + } + + public static ComponentInstanceReqDetails getDefaultComponentInstance(String name, ComponentReqDetails componentReqDetails) { + String resourceUid = componentReqDetails.getUniqueId(); + ComponentInstanceReqDetails resourceInstanceDetails = new ComponentInstanceReqDetails(resourceUid, RESOURCE_INSTANCE_DESCRIPTION, RESOURCE_INSTANCE_POS_X, RESOURCE_INSTANCE_POS_Y, name); + + return resourceInstanceDetails; + + } + + public static ComponentInstanceReqDetails getComponentResourceInstance(ComponentReqDetails compInstOriginDetails) { + String compInstName = (compInstOriginDetails.getName() != null ? compInstOriginDetails.getName() : "resourceInstanceName"); + String resourceUid = compInstOriginDetails.getUniqueId(); + ComponentInstanceReqDetails resourceInstanceDetails = new ComponentInstanceReqDetails(resourceUid, RESOURCE_INSTANCE_DESCRIPTION, RESOURCE_INSTANCE_POS_X, RESOURCE_INSTANCE_POS_Y, compInstName); + return resourceInstanceDetails; + + } + + public static ComponentInstanceReqDetails getComponentInstance(Component compInstOriginDetails) { + String compInstName = (compInstOriginDetails.getName() != null ? compInstOriginDetails.getName() : "componentInstanceName"); + String compInsUid = compInstOriginDetails.getUniqueId(); + ComponentInstanceReqDetails componentInstanceDetails = new ComponentInstanceReqDetails(compInsUid, RESOURCE_INSTANCE_DESCRIPTION, RESOURCE_INSTANCE_POS_X, RESOURCE_INSTANCE_POS_Y, compInstName); + return componentInstanceDetails; + + } + + // ******* USER ********************** + public static User getDefaultUser(UserRoleEnum userRole) { + User sdncModifierDetails = new User(); + sdncModifierDetails.setUserId(userRole.getUserId()); + sdncModifierDetails.setFirstName(userRole.getFirstName()); + sdncModifierDetails.setLastName(userRole.getLastName()); + return sdncModifierDetails; + } + + public static User getDefaultMechUser() { + User sdncMechUserDetails = new User(); + sdncMechUserDetails.setUserId("m12345"); + sdncMechUserDetails.setFirstName("Shay"); + sdncMechUserDetails.setLastName("Sponder"); + sdncMechUserDetails.setEmail("mechId@intl.sdc.com"); + sdncMechUserDetails.setRole("DESIGNER"); + return sdncMechUserDetails; + } + + // ******* CONSUMER ********************** + + public static ConsumerDataDefinition getDefaultConsumerDetails() { + ConsumerDataDefinition consumer = new ConsumerDataDefinition(); + consumer.setConsumerName("ci"); + consumer.setConsumerSalt("2a1f887d607d4515d4066fe0f5452a50"); + consumer.setConsumerPassword("0a0dc557c3bf594b1a48030e3e99227580168b21f44e285c69740b8d5b13e33b"); + return consumer; + } + + // *** ARTIFACT *** + public static ArtifactReqDetails getDefaultArtifact() throws IOException, Exception { + return getDefaultArtifact(DEFAULT_ARTIFACT_LABEL); + } + + public static ArtifactReqDetails getDefaultArtifact(String artifactLabel) throws IOException, Exception { + List artifactTypes = ResponseParser.getValuesFromJsonArray(ArtifactRestUtils.getArtifactTypesList()); + String artifactType = artifactTypes.get(0); + + return getDefaultArtifact(artifactLabel, artifactType); + } + + public static ArtifactReqDetails getDefaultArtifact(String artifactLabel, String artifactType) throws IOException, Exception { + + String artifactName = "testArtifact.sh"; + String artifactDescription = "descriptionTest"; + String payloadData = "dGVzdA=="; // content of file + + ArtifactReqDetails artifactDetails = new ArtifactReqDetails(artifactName, artifactType, artifactDescription, payloadData, artifactLabel); + artifactDetails.setUrl(""); + artifactDetails.setArtifactDisplayName(artifactLabel); + return artifactDetails; + } + + public static ArtifactReqDetails getServiceApiArtifactDetails(String artifactLabel) throws IOException, Exception { + ArtifactReqDetails defaultArtifact = getDefaultArtifact(artifactLabel, "OTHER"); + defaultArtifact.setUrl("http://www.apple.com"); + defaultArtifact.setServiceApi(true); + defaultArtifact.setArtifactDisplayName(StringUtils.capitalize(defaultArtifact.getArtifactLabel())); + return defaultArtifact; + } + + public static ArtifactReqDetails getDefaultDeploymentArtifactForType(String artifactType) throws IOException, Exception { + return getArtifactByType(DEFAULT_ARTIFACT_LABEL, artifactType, true); + } + + public static ArtifactReqDetails getArtifactByType(ArtifactTypeEnum artifactLabel, ArtifactTypeEnum artifactType, Boolean deploymentTrue) throws IOException, Exception { + return getArtifactByType(DEFAULT_ARTIFACT_LABEL, artifactType.toString(), deploymentTrue); + + } + + public static ArtifactReqDetails getArtifactByType(String artifactLabel, String artifactType, Boolean deploymentTrue) throws IOException, Exception { + String artifactName; + String payloadData = null; + Integer timeout = null; + String url = ""; + String artifactDescription = "descriptionTest"; + + // PLEASE NOTE!!! + // The non-default payloads here are real ones according to various + // types validations, + // Please don't change them unless you know what you are doing! + + ArtifactTypeEnum artifactTypeEnum = ArtifactTypeEnum.findType(artifactType); + + /* + * Missing file type: DCAE_JSON + */ + switch (artifactTypeEnum) { + case DCAE_EVENT: + case APPC_CONFIG: + case DCAE_DOC: + case DCAE_TOSCA: + case HEAT: + case HEAT_NET: + case HEAT_VOL: { + artifactName = generateUUIDforSufix() + artifactType + "_install_apache2.yaml"; + payloadData = "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + timeout = 60; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + case DCAE_INVENTORY_TOSCA: + case DCAE_INVENTORY_JSON: + case DCAE_INVENTORY_POLICY: + case DCAE_INVENTORY_DOC: + case DCAE_INVENTORY_BLUEPRINT: + case DCAE_INVENTORY_EVENT: { + artifactName = getDcaeArtifactName(artifactTypeEnum, artifactType); + payloadData = "will be override later"; + timeout = 60; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + case MURANO_PKG: { + artifactName = artifactType + "org.openstack.Rally.zip"; + payloadData = "ODM4MTRjNzkxZjcwYTlkMjk4ZGQ2ODE4MThmNjg0N2Y="; + break; + } + case DCAE_POLICY: { + artifactName = artifactType + "dcae_policy.emf"; + payloadData = "will be override later"; + break; + } + case DCAE_JSON: { + artifactName = artifactType + "dcae_policy.json"; + payloadData = "e30="; + break; + } + case PUPPET: + case CHEF: + case DG_XML: + case YANG: { + artifactName = generateUUIDforSufix() + artifactType + "yangXml.xml"; + payloadData = "PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8ZGF0YT4NCiAgPHNwb3J0cz4NCiAgICA8cGVyc29uPg0KICAgICAgPG5hbWU+TGlvbmVsIEFuZHJlcyBNZXNzaTwvbmFtZT4NCiAgICAgIDxiaXJ0aGRheT4xOTg3LTA2LTI0VDAwOjAwOjAwLTAwOjAwPC9iaXJ0aGRheT4NCiAgICA8L3BlcnNvbj4NCiAgICA8cGVyc29uPg0KICAgICAgPG5hbWU+Q3Jpc3RpYW5vIFJvbmFsZG88L25hbWU+DQogICAgICA8YmlydGhkYXk+MTk4NS0wMi0wNVQwMDowMDowMC0wMDowMDwvYmlydGhkYXk+DQogICAgPC9wZXJzb24+DQogICAgPHRlYW0+DQogICAgICA8bmFtZT5GQyBCYXJjZWxvbmE8L25hbWU+DQogICAgICA8cGxheWVyPg0KICAgICAgICA8bmFtZT5MaW9uZWwgQW5kcmVzIE1lc3NpPC9uYW1lPg0KICAgICAgICA8c2Vhc29uPkNoYW1waW9ucyBMZWFndWUgMjAxNC0yMDE1PC9zZWFzb24+DQogICAgICAgIDxudW1iZXI+MTA8L251bWJlcj4NCiAgICAgICAgPHNjb3Jlcz40Mzwvc2NvcmVzPg0KICAgICAgPC9wbGF5ZXI+DQogICAgPC90ZWFtPg0KICAgIDx0ZWFtPg0KICAgICAgPG5hbWU+UmVhbCBNYWRyaWQ8L25hbWU+DQogICAgICA8cGxheWVyPg0KICAgICAgICA8bmFtZT5DcmlzdGlhbm8gUm9uYWxkbzwvbmFtZT4NCiAgICAgICAgPHNlYXNvbj5DaGFtcGlvbnMgTGVhZ3VlIDIwMTQtMjAxNTwvc2Vhc29uPg0KICAgICAgICA8bnVtYmVyPjc8L251bWJlcj4NCiAgICAgICAgPHNjb3Jlcz40ODwvc2NvcmVzPg0KICAgICAgPC9wbGF5ZXI+DQogICAgPC90ZWFtPg0KICA8L3Nwb3J0cz4NCg0KPC9kYXRhPg=="; + timeout = 15; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + case VF_LICENSE: + case VENDOR_LICENSE: + case MODEL_INVENTORY_PROFILE: + case MODEL_QUERY_SPEC: + case VNF_CATALOG: + case YANG_XML: { + artifactName = generateUUIDforSufix() + artifactType + "yangXml.xml"; + payloadData = "PD94bWwgdmVyc2lvbj0iMS4wIj8+DQo8ZGF0YT4NCiAgPHNwb3J0cz4NCiAgICA8cGVyc29uPg0KICAgICAgPG5hbWU+TGlvbmVsIEFuZHJlcyBNZXNzaTwvbmFtZT4NCiAgICAgIDxiaXJ0aGRheT4xOTg3LTA2LTI0VDAwOjAwOjAwLTAwOjAwPC9iaXJ0aGRheT4NCiAgICA8L3BlcnNvbj4NCiAgICA8cGVyc29uPg0KICAgICAgPG5hbWU+Q3Jpc3RpYW5vIFJvbmFsZG88L25hbWU+DQogICAgICA8YmlydGhkYXk+MTk4NS0wMi0wNVQwMDowMDowMC0wMDowMDwvYmlydGhkYXk+DQogICAgPC9wZXJzb24+DQogICAgPHRlYW0+DQogICAgICA8bmFtZT5GQyBCYXJjZWxvbmE8L25hbWU+DQogICAgICA8cGxheWVyPg0KICAgICAgICA8bmFtZT5MaW9uZWwgQW5kcmVzIE1lc3NpPC9uYW1lPg0KICAgICAgICA8c2Vhc29uPkNoYW1waW9ucyBMZWFndWUgMjAxNC0yMDE1PC9zZWFzb24+DQogICAgICAgIDxudW1iZXI+MTA8L251bWJlcj4NCiAgICAgICAgPHNjb3Jlcz40Mzwvc2NvcmVzPg0KICAgICAgPC9wbGF5ZXI+DQogICAgPC90ZWFtPg0KICAgIDx0ZWFtPg0KICAgICAgPG5hbWU+UmVhbCBNYWRyaWQ8L25hbWU+DQogICAgICA8cGxheWVyPg0KICAgICAgICA8bmFtZT5DcmlzdGlhbm8gUm9uYWxkbzwvbmFtZT4NCiAgICAgICAgPHNlYXNvbj5DaGFtcGlvbnMgTGVhZ3VlIDIwMTQtMjAxNTwvc2Vhc29uPg0KICAgICAgICA8bnVtYmVyPjc8L251bWJlcj4NCiAgICAgICAgPHNjb3Jlcz40ODwvc2NvcmVzPg0KICAgICAgPC9wbGF5ZXI+DQogICAgPC90ZWFtPg0KICA8L3Nwb3J0cz4NCg0KPC9kYXRhPg=="; + timeout = 0; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + case OTHER: { + artifactName = generateUUIDforSufix() + artifactType + "other.pdf"; + payloadData = "aGVhdF90ZW1wbGF0ZV92ZXJzaW9uOiAyMDEzLTA1LTIzDQoNCmRlc2NyaXB0aW9uOiBTaW1wbGUgdGVtcGxhdGUgdG8gZGVwbG95IGEgc3RhY2sgd2l0aCB0d28gdmlydHVhbCBtYWNoaW5lIGluc3RhbmNlcw0KDQpwYXJhbWV0ZXJzOg0KICBpbWFnZV9uYW1lXzE6DQogICAgdHlwZTogc3RyaW5nDQogICAgbGFiZWw6IEltYWdlIE5hbWUNCiAgICBkZXNjcmlwdGlvbjogU0NPSU1BR0UgU3BlY2lmeSBhbiBpbWFnZSBuYW1lIGZvciBpbnN0YW5jZTENCiAgICBkZWZhdWx0OiBjaXJyb3MtMC4zLjEteDg2XzY0DQogIGltYWdlX25hbWVfMjoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogSW1hZ2UgTmFtZQ0KICAgIGRlc2NyaXB0aW9uOiBTQ09JTUFHRSBTcGVjaWZ5IGFuIGltYWdlIG5hbWUgZm9yIGluc3RhbmNlMg0KICAgIGRlZmF1bHQ6IGNpcnJvcy0wLjMuMS14ODZfNjQNCiAgbmV0d29ya19pZDoNCiAgICB0eXBlOiBzdHJpbmcNCiAgICBsYWJlbDogTmV0d29yayBJRA0KICAgIGRlc2NyaXB0aW9uOiBTQ09ORVRXT1JLIE5ldHdvcmsgdG8gYmUgdXNlZCBmb3IgdGhlIGNvbXB1dGUgaW5zdGFuY2UNCiAgICBoaWRkZW46IHRydWUNCiAgICBjb25zdHJhaW50czoNCiAgICAgIC0gbGVuZ3RoOiB7IG1pbjogNiwgbWF4OiA4IH0NCiAgICAgICAgZGVzY3JpcHRpb246IFBhc3N3b3JkIGxlbmd0aCBtdXN0IGJlIGJldHdlZW4gNiBhbmQgOCBjaGFyYWN0ZXJzLg0KICAgICAgLSByYW5nZTogeyBtaW46IDYsIG1heDogOCB9DQogICAgICAgIGRlc2NyaXB0aW9uOiBSYW5nZSBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3ZhbHVlczoNCiAgICAgICAgLSBtMS5zbWFsbA0KICAgICAgICAtIG0xLm1lZGl1bQ0KICAgICAgICAtIG0xLmxhcmdlDQogICAgICAgIGRlc2NyaXB0aW9uOiBBbGxvd2VkIHZhbHVlcyBkZXNjcmlwdGlvbg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbYS16QS1aMC05XSsiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IGNvbnNpc3Qgb2YgY2hhcmFjdGVycyBhbmQgbnVtYmVycyBvbmx5Lg0KICAgICAgLSBhbGxvd2VkX3BhdHRlcm46ICJbQS1aXStbYS16QS1aMC05XSoiDQogICAgICAgIGRlc2NyaXB0aW9uOiBQYXNzd29yZCBtdXN0IHN0YXJ0IHdpdGggYW4gdXBwZXJjYXNlIGNoYXJhY3Rlci4NCiAgICAgIC0gY3VzdG9tX2NvbnN0cmFpbnQ6IG5vdmEua2V5cGFpcg0KICAgICAgICBkZXNjcmlwdGlvbjogQ3VzdG9tIGRlc2NyaXB0aW9uDQoNCnJlc291cmNlczoNCiAgbXlfaW5zdGFuY2UxOg0KICAgIHR5cGU6IE9TOjpOb3ZhOjpTZXJ2ZXINCiAgICBwcm9wZXJ0aWVzOg0KICAgICAgaW1hZ2U6IHsgZ2V0X3BhcmFtOiBpbWFnZV9uYW1lXzEgfQ0KICAgICAgZmxhdm9yOiBtMS5zbWFsbA0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9DQogIG15X2luc3RhbmNlMjoNCiAgICB0eXBlOiBPUzo6Tm92YTo6U2VydmVyDQogICAgcHJvcGVydGllczoNCiAgICAgIGltYWdlOiB7IGdldF9wYXJhbTogaW1hZ2VfbmFtZV8yIH0NCiAgICAgIGZsYXZvcjogbTEudGlueQ0KICAgICAgbmV0d29ya3M6DQogICAgICAgIC0gbmV0d29yayA6IHsgZ2V0X3BhcmFtIDogbmV0d29ya19pZCB9"; + timeout = 0; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + case SHELL_SCRIPT: + default: {// dummy + artifactName = generateUUIDforSufix() + "testArtifact.sh"; + payloadData = "dGVzdA=="; + artifactLabel = normalizeArtifactLabel(artifactName); + break; + } + } + + ArtifactReqDetails artifactDetails = new ArtifactReqDetails(artifactName, artifactType, artifactDescription, payloadData, artifactLabel); + artifactDetails.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + artifactDetails.setUrl(url); + artifactDetails.setTimeout(timeout); + artifactDetails.setArtifactDisplayName(artifactLabel); + return artifactDetails; + } + + private static String getDcaeArtifactName(ArtifactTypeEnum artifactTypeEnum, String artifactType) { + String artifactName = null; + switch (artifactTypeEnum) { + case DCAE_INVENTORY_TOSCA: { + artifactName = generateUUIDforSufix() + artifactType + "_toscaSampleArtifact.yml"; + break; + } + case DCAE_INVENTORY_JSON: { + artifactName = generateUUIDforSufix() + artifactType + "_jsonSampleArtifact.json"; + break; + } + case DCAE_INVENTORY_POLICY: { + artifactName = generateUUIDforSufix() + artifactType + "_emfSampleArtifact.emf"; + break; + } + case DCAE_INVENTORY_DOC: { + artifactName = generateUUIDforSufix() + artifactType + "_docSampleArtifact.doc"; + break; + } + case DCAE_INVENTORY_BLUEPRINT: { + artifactName = generateUUIDforSufix() + artifactType + "_bluePrintSampleArtifact.xml"; + break; + } + case DCAE_INVENTORY_EVENT: { + artifactName = generateUUIDforSufix() + artifactType + "_eventSampleArtifact.xml"; + break; + } + } + return artifactName; + } + + // ---------------------Audit message------------------ + public static ExpectedResourceAuditJavaObject getDefaultImportResourceAuditMsgSuccess() { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(AuditingActionEnum.IMPORT_RESOURCE.getName()); + expectedResourceAuditJavaObject.setResourceName("defaultImportResourceName.yaml"); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion("0.1"); + expectedResourceAuditJavaObject.setModifierName(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getFullName()); + expectedResourceAuditJavaObject.setModifierUid(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + expectedResourceAuditJavaObject.setStatus("201"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setToscaNodeType(""); + return expectedResourceAuditJavaObject; + + } + + public static ExpectedResourceAuditJavaObject getDefaultImportResourceAuditMsgFailure(ErrorInfo errorInfo, List variables) { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(AuditingActionEnum.IMPORT_RESOURCE.getName()); + expectedResourceAuditJavaObject.setResourceName(""); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion(""); + expectedResourceAuditJavaObject.setModifierName(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getFullName()); + expectedResourceAuditJavaObject.setModifierUid(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(""); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + expectedResourceAuditJavaObject.setToscaNodeType(""); + return expectedResourceAuditJavaObject; + + } + + public static ExpectedResourceAuditJavaObject getDefaultCertificationRequestAuditMsgSuccess() { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(AuditingActionEnum.CERTIFICATION_REQUEST_RESOURCE.getName()); + expectedResourceAuditJavaObject.setResourceName("defaultResourceName"); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion(""); + expectedResourceAuditJavaObject.setCurrVersion("0.1"); + expectedResourceAuditJavaObject.setModifierName(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getFullName()); + expectedResourceAuditJavaObject.setModifierUid(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + expectedResourceAuditJavaObject.setPrevState(""); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setComment(""); + return expectedResourceAuditJavaObject; + + } + + public static ExpectedResourceAuditJavaObject getDefaultCertificationRequestAuditMsgFailure(ErrorInfo errorInfo, List variables) { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + expectedResourceAuditJavaObject.setAction(AuditingActionEnum.CERTIFICATION_REQUEST_RESOURCE.getName()); + expectedResourceAuditJavaObject.setResourceName(""); + expectedResourceAuditJavaObject.setResourceType("Resource"); + expectedResourceAuditJavaObject.setPrevVersion("0.1"); + expectedResourceAuditJavaObject.setCurrVersion("0.1"); + expectedResourceAuditJavaObject.setModifierName(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getFullName()); + expectedResourceAuditJavaObject.setModifierUid(ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + expectedResourceAuditJavaObject.setPrevState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + expectedResourceAuditJavaObject.setCurrState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.toString()); + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedResourceAuditJavaObject.setDesc(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + expectedResourceAuditJavaObject.setComment(""); + return expectedResourceAuditJavaObject; + + } + + public static ExpectedExternalAudit getDefaultExternalAuditObject(AssetTypeEnum assetType, AuditingActionEnum action, String query) { + + ExpectedExternalAudit expectedExternalAudit = new ExpectedExternalAudit(); + expectedExternalAudit.setACTION(action.getName()); + expectedExternalAudit.setCONSUMER_ID("ci"); + expectedExternalAudit.setRESOURCE_URL("/asdc/v1/catalog/" + assetType.getValue() + (query == null ? "" : query)); + expectedExternalAudit.setSTATUS("200"); + expectedExternalAudit.setDESC("OK"); + return expectedExternalAudit; + + } + + public static ExpectedExternalAudit getDefaultAssetListAudit(AssetTypeEnum assetType, AuditingActionEnum auditAction) { + + // ExpectedExternalAudit expectedAssetListAuditJavaObject = new + // ExpectedExternalAudit(); + ExpectedExternalAudit expectedAssetListAuditJavaObject = getDefaultExternalAuditObject(assetType, auditAction, null); + return expectedAssetListAuditJavaObject; + + } + + public static ExpectedExternalAudit getDefaultFilteredAssetListAudit(AssetTypeEnum assetType, String query) { + + // ExpectedExternalAudit expectedAssetListAuditJavaObject = new + // ExpectedExternalAudit(); + ExpectedExternalAudit expectedAssetListAuditJavaObject = getDefaultExternalAuditObject(assetType, AuditingActionEnum.GET_FILTERED_ASSET_LIST, query); + return expectedAssetListAuditJavaObject; + + } + + public static ExpectedExternalAudit getDefaultExternalArtifactAuditSuccess(AssetTypeEnum assetType, AuditingActionEnum action, ArtifactDefinition artifactDefinition, String componentUUID) { + + // ExpectedExternalAudit expectedExternalArtifactAudit = new + // ExpectedExternalAudit(); + + ExpectedExternalAudit expectedExternalArtifactAudit = getDefaultExternalAuditObject(assetType, action, null); + expectedExternalArtifactAudit.setMODIFIER(AuditValidationUtils.getModifierString(artifactDefinition.getUpdaterFullName(), artifactDefinition.getUserIdLastUpdater())); + expectedExternalArtifactAudit.setPREV_ARTIFACT_UUID(""); + expectedExternalArtifactAudit.setCURR_ARTIFACT_UUID(artifactDefinition.getArtifactUUID()); + expectedExternalArtifactAudit.setARTIFACT_DATA(AuditValidationUtils.buildArtifactDataAudit(artifactDefinition)); + expectedExternalArtifactAudit.setRESOURCE_URL(expectedExternalArtifactAudit.getRESOURCE_URL() + "/" + componentUUID + "/artifacts"); + return expectedExternalArtifactAudit; + + } + + public static ExpectedExternalAudit getDefaultExternalArtifactAuditSuccess(AssetTypeEnum assetType, AuditingActionEnum action, ArtifactDefinition artifactDefinition, String componentUUID, String resourceInstanceName) { + + ExpectedExternalAudit expectedExternalArtifactAudit = getDefaultExternalArtifactAuditSuccess(assetType, action, artifactDefinition, componentUUID); + expectedExternalArtifactAudit.setRESOURCE_URL("/asdc/v1/catalog/" + assetType.getValue() + "/" + componentUUID + "/resourceInstances/" + resourceInstanceName + "/artifacts"); + return expectedExternalArtifactAudit; + } + + public static ExpectedExternalAudit getDefaultExternalArtifactAuditFailure(AssetTypeEnum assetType, AuditingActionEnum action, ArtifactDefinition artifactDefinition, String componentUUID, ErrorInfo errorInfo, List variables) { + + // ExpectedExternalAudit expectedExternalArtifactAudit = new + // ExpectedExternalAudit(); + + ExpectedExternalAudit expectedExternalArtifactAudit = getDefaultExternalAuditObject(assetType, action, null); + expectedExternalArtifactAudit.setMODIFIER(AuditValidationUtils.getModifierString(artifactDefinition.getUpdaterFullName(), artifactDefinition.getUserIdLastUpdater())); + expectedExternalArtifactAudit.setPREV_ARTIFACT_UUID(""); + expectedExternalArtifactAudit.setCURR_ARTIFACT_UUID(artifactDefinition.getArtifactUUID()); + expectedExternalArtifactAudit.setARTIFACT_DATA(AuditValidationUtils.buildArtifactDataAudit(artifactDefinition)); + expectedExternalArtifactAudit.setRESOURCE_URL(expectedExternalArtifactAudit.getRESOURCE_URL() + "/" + componentUUID + "/artifacts"); + expectedExternalArtifactAudit.setSTATUS(errorInfo.getCode().toString()); + expectedExternalArtifactAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + return expectedExternalArtifactAudit; + + } + + public static ExpectedExternalAudit getDefaultExternalArtifactAuditFailure(AssetTypeEnum assetType, AuditingActionEnum action, ArtifactDefinition artifactDefinition, String componentUUID, ErrorInfo errorInfo, List variables, + String resourceInstanceName) { + + ExpectedExternalAudit expectedExternalArtifactAudit = getDefaultExternalArtifactAuditFailure(assetType, action, artifactDefinition, componentUUID, errorInfo, variables); + expectedExternalArtifactAudit.setRESOURCE_URL("/asdc/v1/catalog/" + assetType.getValue() + "/" + componentUUID + "/resourceInstances/" + resourceInstanceName + "/artifacts"); + return expectedExternalArtifactAudit; + } + + public static ExpectedExternalAudit getFilteredAssetListAuditCategoryNotFound(AssetTypeEnum assetType, String query, String category) { + + // ExpectedExternalAudit expectedAssetListAuditJavaObject = new + // ExpectedExternalAudit(); + ExpectedExternalAudit expectedAssetListAuditJavaObject = getDefaultExternalAuditObject(assetType, AuditingActionEnum.GET_FILTERED_ASSET_LIST, query); + expectedAssetListAuditJavaObject.setSTATUS("404"); + ErrorInfo errorInfo = null; + try { + errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + } catch (FileNotFoundException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + String desc = (errorInfo.getMessageId() + ": " + errorInfo.getMessage()).replace("%2", "category").replace("%3", category).replace("%1", "resource"); + expectedAssetListAuditJavaObject.setDESC(desc); + + return expectedAssetListAuditJavaObject; + + } + + public static ExpectedExternalAudit getDefaultAssetMetadataAudit(AssetTypeEnum assetType, Component component) { + + ExpectedExternalAudit expectedAssetListAuditJavaObject = new ExpectedExternalAudit(); + expectedAssetListAuditJavaObject = getDefaultExternalAuditObject(assetType, AuditingActionEnum.GET_ASSET_METADATA, null); + expectedAssetListAuditJavaObject.setRESOURCE_URL(expectedAssetListAuditJavaObject.getRESOURCE_URL() + "/" + component.getUUID() + "/metadata"); + expectedAssetListAuditJavaObject.setRESOURCE_NAME(component.getName()); + expectedAssetListAuditJavaObject.setRESOURCE_TYPE(component.getComponentType().getValue()); + expectedAssetListAuditJavaObject.setSERVICE_INSTANCE_ID(component.getUUID()); + return expectedAssetListAuditJavaObject; + + } + + public static ExpectedExternalAudit getDefaultAssetMetadataAuditFailure(AssetTypeEnum assetType, String serviceUuid, String resourceType) { + + ExpectedExternalAudit expectedAssetListAuditJavaObject = new ExpectedExternalAudit(); + expectedAssetListAuditJavaObject = getDefaultExternalAuditObject(assetType, AuditingActionEnum.GET_ASSET_METADATA, null); + expectedAssetListAuditJavaObject.setSTATUS("404"); + expectedAssetListAuditJavaObject.setDESC("OK"); + expectedAssetListAuditJavaObject.setRESOURCE_URL(expectedAssetListAuditJavaObject.getRESOURCE_URL() + "/" + serviceUuid + "/metadata"); + expectedAssetListAuditJavaObject.setRESOURCE_TYPE(resourceType); + expectedAssetListAuditJavaObject.setSERVICE_INSTANCE_ID(serviceUuid); + return expectedAssetListAuditJavaObject; + + } + + // Category/Subcategory/Group + public static CategoryDefinition getDefaultCategory() { + CategoryDefinition productCategoryDefinition = new CategoryDefinition(); + productCategoryDefinition.setName("Category1"); + return productCategoryDefinition; + } + + public static SubCategoryDefinition getDefaultSubCategory() { + SubCategoryDefinition productSubCategoryDefinition = new SubCategoryDefinition(); + productSubCategoryDefinition.setName("SubCategory1"); + return productSubCategoryDefinition; + } + + public static GroupingDefinition getDefaultGroup() { + GroupingDefinition productGroupDefinition = new GroupingDefinition(); + productGroupDefinition.setName("Grouping1"); + return productGroupDefinition; + } + + // Product + + public static ProductReqDetails getDefaultProduct() { + return createDefaultProductReqDetails("Product1", null); + } + + public static ProductReqDetails getDefaultProduct(String name) { + return createDefaultProductReqDetails(name, null); + } + + public static ProductReqDetails getDefaultProduct(CategoryDefinition category) { + List categories = new ArrayList<>(); + categories.add(category); + return createDefaultProductReqDetails("CiProduct1", categories); + } + + public static ProductReqDetails getDefaultProduct(String name, CategoryDefinition category) { + List categories = new ArrayList<>(); + categories.add(category); + return createDefaultProductReqDetails(name, categories); + } + + public static ProductReqDetails getDefaultProduct(List categories) { + return createDefaultProductReqDetails("CiProduct1", categories); + } + + public static ProductReqDetails getDefaultProduct(String name, List categories) { + return createDefaultProductReqDetails(name, categories); + } + + private static ProductReqDetails createDefaultProductReqDetails(String name, List categories) { + ProductReqDetails product = new ProductReqDetails(name); + ArrayList tags = new ArrayList(); + tags.add(name); + product.setTags(tags); + product.setProjectCode("12345"); + product.setIcon("myIcon"); + ArrayList contacts = new ArrayList(); + // contacts.add(ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST1).getUserId()); + // contacts.add(ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_STRATEGIST2).getUserId()); + contacts.add(ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER1).getUserId()); + // contacts.add(ElementFactory.getDefaultUser(UserRoleEnum.PRODUCT_MANAGER2).getUserId()); + product.setContacts(contacts); + product.setCategories(categories); + String fullName = "This is my full name: " + name; + product.setFullName(fullName); + String description = "This is product description"; + product.setDescription(description); + return product; + } + + public static RequirementCapabilityRelDef getReqCapRelation(String fromCompInstId, String toCompInstId, String reqOwnerId, String capOwnerId, String capType, String reqCapName, List capList, + List reqList) { + RequirementCapabilityRelDef requirementDef = new RequirementCapabilityRelDef(); + requirementDef.setFromNode(fromCompInstId); + requirementDef.setToNode(toCompInstId); + RequirementAndRelationshipPair pair = new RequirementAndRelationshipPair(); + pair.setRequirementOwnerId(reqOwnerId); + pair.setCapabilityOwnerId(capOwnerId); + pair.setRequirement(reqCapName); + RelationshipImpl relationship = new RelationshipImpl(); + relationship.setType(capType); + pair.setRelationships(relationship); + pair.setCapabilityUid(capList.get(0).getUniqueId()); + pair.setRequirementUid(reqList.get(0).getUniqueId()); + List relationships = new ArrayList<>(); + relationships.add(pair); + requirementDef.setRelationships(relationships); + return requirementDef; + } + + private static String generateUUIDforSufix() { + + String uniqueSufix = UUID.randomUUID().toString(); + String[] split = uniqueSufix.split("-"); + return uniqueSufix = split[4]; + } + + private static String normalizeArtifactLabel(String label) { + + label = label.substring(0, label.indexOf(".")); + String normalizedLabel = ValidationUtils.normalizeArtifactLabel(label); + return normalizedLabel.substring(0, Math.min(25, normalizedLabel.length())); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/FileUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/FileUtils.java new file mode 100644 index 0000000000..b785563a4d --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/FileUtils.java @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.general; + +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class FileUtils { + + static Logger logger = LoggerFactory.getLogger(Utils.class.getName()); + + public static void writeToFile(String filePath, String content) { + try { + Files.write(Paths.get(filePath), content.getBytes()); + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static String getFileName(String fullyQualified) { + String fileName = fullyQualified; + + int i = fullyQualified.lastIndexOf('.'); + if (i > 0) { + fileName = fullyQualified.substring(i + 1); + } + return fileName; + + } + + public static Either getFileContentUTF8(String filePath) { + Either eitherResult; + try { + String content = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); + eitherResult = Either.left(content); + } catch (Exception e) { + eitherResult = Either.right(e); + } + return eitherResult; + } + + public static List getFileListFromBaseDirectoryByTestName(String testResourcesPath) { + + File file = new File(testResourcesPath); + File[] listFiles = file.listFiles(); + if (listFiles != null) { + List listFileName = new ArrayList(); + for (File newFile : listFiles) { + if (newFile.isFile()) { + listFileName.add(newFile.getPath()); + } + } + return listFileName; + } + assertTrue("directory " + testResourcesPath + " is empty", false); + return null; + } + + public static String getFilePathFromListByPattern(List fileList, String pattern) { + + for (String filePath : fileList) { + if (filePath.contains(pattern)) { + return filePath; + } + } + return null; + } + + public static String loadPayloadFileFromListUsingPosition(List listFileName, String pattern, Boolean isBase64, int positionInList) throws IOException { + List newList = new ArrayList(Arrays.asList(listFileName.get(positionInList))); + return loadPayloadFile(newList, pattern, isBase64); + } + + public static String loadPayloadFile(List listFileName, String pattern, Boolean isBase64) throws IOException { + String fileName; + String payload = null; + fileName = FileUtils.getFilePathFromListByPattern(listFileName, pattern); + logger.debug("fileName: {}", fileName); + + if (fileName != null) { + payload = Decoder.readFileToString(fileName); + if (isBase64) { + payload = Decoder.encode(payload.getBytes()); + } + } else { + assertTrue("file to upload not found", false); + } + return payload; + } + + public static String getFileNameFromPath(String testResourcesPath) { + + File file = new File(testResourcesPath); + String fileName = null; + if (file.exists()) { + return file.getName(); + } else { + assertTrue("file to upload not found", false); + } + return fileName; + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ImportUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ImportUtils.java new file mode 100644 index 0000000000..040cdba444 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/general/ImportUtils.java @@ -0,0 +1,56 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.general; + +import java.io.IOException; +import java.util.List; + +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; + +public class ImportUtils { + + public static ImportReqDetails getImportResourceDetailsByPathAndName(ImportReqDetails importReqDetails, String filePath, String fileName) throws IOException { + + // ImportReqDetails importReqDetails; + // User sdncUserDetails; + // String testResourcesPath; + // ResourceReqDetails resourceDetails; + // Config config; + // config = Utils.getConfig(); + // + // importReqDetails = ElementFactory.getDefaultImportResource(); + // User sdncUserDetails = + // ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + // ResourceReqDetails resourceDetails = + // ElementFactory.getDefaultResource(); + // String sourceDir = config.getResourceConfigDir(); + // String testResourcesPath = sourceDir + File.separator + workDir; + // final String workDir = "importToscaResourceByCreateUrl"; + + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(filePath); + importReqDetails.setPayloadName(fileName); + String payloadData = FileUtils.loadPayloadFile(listFileName, fileName, true); + importReqDetails.setPayloadData(payloadData); + + return importReqDetails; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ArtifactRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ArtifactRestUtils.java new file mode 100644 index 0000000000..4360621364 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ArtifactRestUtils.java @@ -0,0 +1,689 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.AssertJUnit; + +import com.google.gson.Gson; + +public class ArtifactRestUtils extends BaseRestUtils { + private static Logger logger = LoggerFactory.getLogger(ArtifactRestUtils.class.getName()); + + // External API + // Upload Artifact of the asset + public static RestResponse externalAPIUploadArtifactOfTheAsset(Component component, User user, ArtifactReqDetails artifactReqDetails) throws IOException { + Config config = Utils.getConfig(); + String resourceType = null; + String resourceUUID = component.getUUID(); + + System.out.println(component.getComponentType()); + + if (component.getComponentType().toString().toLowerCase().equals("resource")) { + resourceType = "resources"; + } else { + resourceType = "services"; + } + + String url = String.format(Urls.POST_EXTERNAL_API_UPLOAD_ARTIFACT_OF_ASSET, config.getCatalogBeHost(), config.getCatalogBePort(), resourceType, resourceUUID); + + return uploadInformationalArtifact(artifactReqDetails, user, calculateChecksum(artifactReqDetails), url); + } + + // + // Testing + // + public static RestResponse getResourceDeploymentArtifactExternalAPI(String resourceUUID, String artifactUUID, User sdncModifierDetails, String resourceType) throws IOException { + Config config = Utils.getConfig(); + String url = null; + + if (resourceType.equals("Service")) { + url = String.format(Urls.GET_DOWNLOAD_SERVICE_ARTIFACT_OF_ASSET, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUUID, artifactUUID); + + } else { + url = String.format(Urls.GET_DOWNLOAD_RESOURCE_ARTIFACT_OF_ASSET, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUUID, artifactUUID); + } + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + headersMap.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + HttpRequest http = new HttpRequest(); + + logger.debug("Send GET request to get Resource Assets: {}", url); + System.out.println("Send GET request to get Resource Assets: " + url); + + logger.debug("Request headers: {}", headersMap); + System.out.println("Request headers: " + headersMap); + + RestResponse sendGetResourceAssets = http.httpSendGet(url, headersMap); + + return sendGetResourceAssets; + + } + + public static RestResponse getComponentInstanceDeploymentArtifactExternalAPI(String resourceUUID, String componentInstanceUID, String artifactUUID, User sdncModifierDetails, String resourceType) throws IOException { + Config config = Utils.getConfig(); + String url = null; + + if (resourceType.equals("Service")) { + url = String.format(Urls.GET_DOWNLOAD_SERVICE_ARTIFACT_OF_COMPONENT_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUUID, componentInstanceUID, artifactUUID); + + } else { + url = String.format(Urls.GET_DOWNLOAD_RESOURCE_ARTIFACT_OF_COMPONENT_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUUID, componentInstanceUID, artifactUUID); + } + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + headersMap.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + HttpRequest http = new HttpRequest(); + + logger.debug("Send GET request to get Resource Assets: {}", url); + System.out.println("Send GET request to get Resource Assets: " + url); + + logger.debug("Request headers: {}", headersMap); + System.out.println("Request headers: " + headersMap); + + RestResponse sendGetResourceAssets = http.httpSendGet(url, headersMap); + + return sendGetResourceAssets; + + } + + // *********** SERVICE **************** + public static RestResponse getArtifactTypesList() throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_ARTIFACTS, config.getCatalogBeHost(), config.getCatalogBePort()); + + return sendGet(url, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + } + + public static RestResponse addInformationalArtifactToService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid) throws IOException { + return addInformationalArtifactToService(artifactDetails, sdncModifierDetails, serviceUid, calculateChecksum(artifactDetails)); + } + + public static RestResponse addInformationalArtifactToService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String checksum) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.ADD_ARTIFACT_TO_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceUid); + + return uploadInformationalArtifact(artifactDetails, sdncModifierDetails, checksum, url); + } + + public static RestResponse downloadServiceArtifact(ServiceReqDetails service, ArtifactReqDetails artifact, User user, Map addionalHeaders) throws Exception { + + return downloadServiceArtifact(service, artifact, user, addionalHeaders, true); + } + + public static RestResponse downloadServiceArtifact(ServiceReqDetails service, ArtifactReqDetails artifact, User user, Map addionalHeaders, boolean addEcompHeader) throws Exception { + Config config = Utils.getConfig(); + String relativeUrl = encodeUrlForDownload( + String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, ValidationUtils.convertToSystemName(service.getName()), service.getVersion(), ValidationUtils.normalizeFileName(artifact.getArtifactName()))); + String fullUrl = String.format(Urls.DOWNLOAD_SERVICE_ARTIFACT_FULL_URL, config.getCatalogBeHost(), config.getCatalogBePort(), relativeUrl); + + return downloadArtifact(fullUrl, user, addionalHeaders, addEcompHeader); + } + + public static RestResponse downloadResourceArtifact(ServiceReqDetails service, ResourceReqDetails resource, ArtifactReqDetails artifact, User user, Map addionalHeaders) throws Exception { + return downloadResourceArtifact(service, resource, artifact, user, addionalHeaders, true); + } + + public static RestResponse downloadResourceArtifact(ServiceReqDetails service, ResourceReqDetails resource, ArtifactReqDetails artifact, User user, Map addionalHeaders, boolean addEcompHeader) throws Exception { + Config config = Utils.getConfig(); + String relativeUrl = encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_RESOURCE_ARTIFACT_RELATIVE_URL, ValidationUtils.convertToSystemName(service.getName()), service.getVersion(), + ValidationUtils.convertToSystemName(resource.getName()), resource.getVersion(), ValidationUtils.normalizeFileName(artifact.getArtifactName()))); + String fullUrl = String.format(Urls.DOWNLOAD_RESOURCE_ARTIFACT_FULL_URL, config.getCatalogBeHost(), config.getCatalogBePort(), relativeUrl); + + return downloadArtifact(fullUrl, user, addionalHeaders, addEcompHeader); + } + + public static RestResponse downloadResourceInstanceArtifact(String serviceUniqueId, String resourceInstanceId, User user, String artifactUniqeId) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.DOWNLOAD_COMPONENT_INSTANCE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), serviceUniqueId, resourceInstanceId, artifactUniqeId); + RestResponse res = sendGet(url, user.getUserId(), null); + return res; + } + + //// + + // update + + public static RestResponse updateInformationalArtifactOfServiceByMethod(ArtifactReqDetails artifactReqDetails, String serviceUid, String artifactUid, User sdncModifierDetails, String httpMethod) throws IOException { + // TODO Auto-generated method stub + return updateInformationalArtifactOfServiceByMethod(artifactReqDetails, serviceUid, artifactUid, sdncModifierDetails, httpMethod, calculateChecksum(artifactReqDetails)); + } + + public static RestResponse updateInformationalArtifactOfServiceByMethod(ArtifactReqDetails artifactReqDetails, String serviceUid, User sdncModifierDetails, String httpMethod) throws IOException { + // TODO Auto-generated method stub + return updateInformationalArtifactOfServiceByMethod(artifactReqDetails, serviceUid, artifactReqDetails.getUniqueId(), sdncModifierDetails, httpMethod, calculateChecksum(artifactReqDetails)); + } + + public static RestResponse downloadResourceArtifactInternalApi(String resourceId, User user, String artifactUniqeId) throws Exception { + return downloadComponentArtifactInternalApi(resourceId, user, artifactUniqeId, Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT); + } + + public static RestResponse downloadServiceArtifactInternalApi(String componentId, User user, String artifactUniqeId) throws Exception { + return downloadComponentArtifactInternalApi(componentId, user, artifactUniqeId, Urls.UI_DOWNLOAD_SERVICE_ARTIFACT); + } + + public static RestResponse downloadComponentArtifactInternalApi(String componentId, User user, String artifactUniqeId, String urlTemplate) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(urlTemplate, config.getCatalogBeHost(), config.getCatalogBePort(), componentId, artifactUniqeId); + RestResponse res = sendGet(url, user.getUserId(), null); + return res; + } + + /* + * public static RestResponse updateInformationalArtifactPayloadOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid, String checksum) throws IOException { return + * updateInformationalArtifactOfService(artifactDetails, sdncModifierDetails, serviceUid, artifactUid, checksum, true); } + * + * public static RestResponse updateInformationalArtifactMetadataOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid) throws IOException { return + * updateInformationalArtifactOfService(artifactDetails, sdncModifierDetails, serviceUid, artifactUid, calculateChecksum(artifactDetails), false); } + * + * public static RestResponse updateInformationalArtifactOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid, String checksum, boolean isPayloadUpdate) throws IOException { Config config = + * Utils.getConfig(); Map headersMap = getHeadersMap(sdncModifierDetails); + * + * if (isPayloadUpdate){ headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); } + * + * Gson gson = new Gson(); String jsonBody = gson.toJson(artifactDetails); + * + * HttpRequest http = new HttpRequest(); + * + * String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE, config.getCatalogBeHost(),config.getCatalogBePort(), serviceUid, artifactUid); RestResponse res = http.httpSendPost(url, jsonBody, headersMap); + * System.out.println("update artifact was finished with response: "+ res.getErrorCode()); return res; } + */ + + public static RestResponse updateInformationalArtifactOfServiceByMethod(ArtifactReqDetails artifactReqDetails, String serviceUid, String artifactUid, User sdncModifierDetails, String httpMethod, String checksum) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = getHeadersMap(sdncModifierDetails); + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(artifactReqDetails); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceUid, artifactUid); + RestResponse updateResourceResponse = http.httpSendByMethod(url, httpMethod, userBodyJson, headersMap); + // System.out.println("update artifact was finished with response: "+ + // updateResourceResponse.getErrorCode()); + + return updateResourceResponse; + } + + public static Map getHeadersMap(User sdncModifierDetails) { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptJsonHeader); + + try { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + } catch (Exception e) { + + } + + return headersMap; + } + + // *********** RESOURCE **************** + // add + public static RestResponse addInformationalArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid) throws IOException { + return addInformationalArtifactToResource(artifactDetails, sdncModifierDetails, resourceUid, calculateChecksum(artifactDetails)); + } + + public static RestResponse explicitAddInformationalArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid) throws IOException { + Config config = Utils.getConfig(); + + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid); + + return uploadInformationalArtifact(artifactDetails, sdncModifierDetails, calculateChecksum(artifactDetails), url); + } + + public static RestResponse addInformationalArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid, String checksum) throws IOException { + Config config = Utils.getConfig(); + + if (artifactDetails.getArtifactGroupType() != null && artifactDetails.getArtifactGroupType().equals(ArtifactGroupTypeEnum.DEPLOYMENT.getType())) { + // YANG_XML and OTHER deployment artifact should be added through + // this API, not updated + String artifactType = artifactDetails.getArtifactType(); + if (!(ArtifactTypeEnum.YANG_XML.getType().equals(artifactType) || ArtifactTypeEnum.OTHER.getType().equals(artifactType) || ArtifactTypeEnum.VNF_CATALOG.getType().equals(artifactType) + || ArtifactTypeEnum.VF_LICENSE.getType().equals(artifactType) || ArtifactTypeEnum.VENDOR_LICENSE.getType().equals(artifactType) || ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.getType().equals(artifactType) + || ArtifactTypeEnum.MODEL_QUERY_SPEC.getType().equals(artifactType) || ArtifactTypeEnum.APPC_CONFIG.getType().equals(artifactType))) { + // return updateInformationalArtifactToResource(artifactDetails, + // sdncModifierDetails, resourceUid); + } + } + String url = String.format(Urls.ADD_ARTIFACT_TO_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid); + + return uploadInformationalArtifact(artifactDetails, sdncModifierDetails, checksum, url); + } + + // update + public static RestResponse updateInformationalArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid) throws IOException { + return updateInformationalArtifactToResource(artifactDetails, sdncModifierDetails, resourceUid, calculateChecksum(artifactDetails)); + } + + public static RestResponse updateInformationalArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid, String checksum) throws IOException { + Config config = Utils.getConfig(); + if (artifactDetails.getArtifactGroupType() != null && artifactDetails.getArtifactGroupType().equals("DEPLOYMENT")) { + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceUid); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + ArtifactDefinition artifactDefinition = deploymentArtifacts.get(artifactDetails.getArtifactLabel()); + artifactDetails.setUniqueId(artifactDefinition.getUniqueId()); + artifactDetails.setArtifactLabel(artifactDefinition.getArtifactLabel()); + + } + + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid, artifactDetails.getUniqueId()); + + return uploadInformationalArtifact(artifactDetails, sdncModifierDetails, calculateChecksum(artifactDetails), url); + } + + public static RestResponse uploadArtifactToPlaceholderOnResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid, String placeHolderLabel) throws IOException { + Config config = Utils.getConfig(); + if (artifactDetails.getArtifactLabel() != null && !artifactDetails.getArtifactLabel().isEmpty()) { + RestResponse resourceGetResponse = ResourceRestUtils.getResource(sdncModifierDetails, resourceUid); + Resource resourceRespJavaObject = ResponseParser.convertResourceResponseToJavaObject(resourceGetResponse.getResponse()); + Map deploymentArtifacts = resourceRespJavaObject.getDeploymentArtifacts(); + ArtifactDefinition artifactDefinition = deploymentArtifacts.get(artifactDetails.getArtifactLabel()); + AssertJUnit.assertNotNull(artifactDefinition); + artifactDetails.setUniqueId(artifactDefinition.getUniqueId()); + artifactDetails.setArtifactLabel(artifactDefinition.getArtifactLabel()); + + } + + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid, artifactDetails.getUniqueId()); + + return uploadInformationalArtifact(artifactDetails, sdncModifierDetails, calculateChecksum(artifactDetails), url); + } + + public static RestResponse updateDeploymentArtifactToResource(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceUid) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid, artifactDetails.getUniqueId()); + + return updateDeploymentArtifact(artifactDetails, sdncModifierDetails, url); + } + + public static RestResponse updateArtifactToResourceInstance(ArtifactDefinition artifactDefinition, User sdncModifierDetails, String resourceInstanceId, String serviceId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE_INSTANCE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId, resourceInstanceId, artifactDefinition.getUniqueId()); + return updateDeploymentArtifact(artifactDefinition, sdncModifierDetails, url); + } + + public static RestResponse updateDeploymentArtifactToRI(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceInstanceId, String serviceId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE_INSTANCE_HEAT_ENV_PARAMS, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId, resourceInstanceId, artifactDetails.getUniqueId()); + return updateDeploymentArtifact(artifactDetails, sdncModifierDetails, url); + } + + // delete + public static RestResponse deleteArtifactFromResourceInstance(ArtifactDefinition artifactDefinition, User sdncModifierDetails, String resourceUid, String serviceId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_RESOURCE_INSTANCE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId, resourceUid, artifactDefinition.getUniqueId()); + return sendDelete(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse deleteInformationalArtifactFromResource(String resourceUid, ArtifactReqDetails artifactDetails, User sdncModifierDetails) throws IOException { + return deleteInformationalArtifactFromResource(resourceUid, artifactDetails.getUniqueId(), sdncModifierDetails); + } + + public static RestResponse deleteInformationalArtifactFromResource(String resourceUid, String artifactId, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceUid, artifactId); + return sendDelete(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse deleteServiceApiArtifact(ArtifactReqDetails artifactDetails, String serviceUniqueId, User user) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_DELETE_SERVICE_API_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), serviceUniqueId, artifactDetails.getUniqueId()); + RestResponse res = sendDelete(url, user.getUserId()); + logger.debug("Deleting api artifact was finished with response: {}", res.getErrorCode()); + logger.debug("Response body: {}", res.getResponseMessage()); + return res; + } + + // *************** RESOURCE INSTANCE ************** + /** + * Add DCAE artifacts to resource instance. + * + * @param artifactDetails + * @param sdncModifierDetails + * @param resourceInstanceId + * @param serviceId + * @return + * @throws IOException + */ + public static RestResponse addArtifactToResourceInstance(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String resourceInstanceId, String serviceId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.ADD_RESOURCE_INSTANCE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId, resourceInstanceId, artifactDetails.getUniqueId()); + return addArtifactToInstance(artifactDetails, sdncModifierDetails, calculateChecksum(artifactDetails), url); + } + + // *************** COMPONENT ************** + + public static RestResponse uploadDeploymentArtifact(ArtifactReqDetails artifactDetails, Component component, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + Map additionalHeaders = null; + String checksum = ResponseParser.calculateMD5Header(artifactDetails); + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + + ComponentTypeEnum componentType = component.getComponentType(); + + String url = null; + + switch (componentType) { + + case RESOURCE: { + url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), component.getUniqueId(), artifactDetails.getUniqueId()); + + break; + } + case SERVICE: { + + break; + } + + case PRODUCT: { + + break; + } + + default: {// dummy + assertTrue("failed on enum selection", false); + + break; + } + } + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + // System.out.println("ArtifactDetails: "+ jsonBody); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), acceptHeaderData, additionalHeaders); + if (res.getErrorCode() == STATUS_CODE_SUCCESS) { + artifactDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + } + // System.out.println("Add artifact was finished with response: "+ + // res.getErrorCode()); + return res; + } + + public static RestResponse uploadArtifact(ArtifactReqDetails artifactDetails, Component component, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + List placeHolderlst = Utils.getListOfResPlaceHoldersDepArtTypes(); + Map additionalHeaders = null; + String checksum = null; + String url = null; + // + // + // if (artifactDetails.getArtifactGroupType() != null + // && artifactDetails.getArtifactGroupType().equals("DEPLOYMENT") + // && placeHolderlst.contains(artifactDetails.getArtifactType())) { + // Map deploymentArtifacts = + // component.getDeploymentArtifacts(); + // ArtifactDefinition artifactDefinition = + // deploymentArtifacts.get(artifactDetails.getArtifactLabel()); + // artifactDetails.setUniqueId(artifactDefinition.getUniqueId()); + // artifactDetails.setArtifactLabel(artifactDefinition.getArtifactLabel()); + // checksum = ResponseParser.calculateMD5Header(artifactDetails); + // additionalHeaders = new HashMap(); + // additionalHeaders.put(HttpHeaderEnum.Content_MD5.getValue(), + // checksum); + // url = String.format(Urls.UPDATE_ARTIFACT_OF_COMPONENT, + // config.getCatalogBeHost(), + // config.getCatalogBePort(), + // ComponentTypeEnum.findParamByType(component.getComponentType()), + // component.getUniqueId(), artifactDetails.getUniqueId()); + // } + // + // else { + checksum = ResponseParser.calculateMD5Header(artifactDetails); + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + url = String.format(Urls.UPLOAD_DELETE_ARTIFACT_OF_COMPONENT, config.getCatalogBeHost(), config.getCatalogBePort(), ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId(), artifactDetails.getUniqueId()); + // } + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + // System.out.println("ArtifactDetails: "+ jsonBody); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), acceptHeaderData, additionalHeaders); + if (res.getErrorCode() == STATUS_CODE_SUCCESS) { + artifactDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + } + // System.out.println("Add artifact was finished with response: "+ + // res.getErrorCode()); + return res; + } + + // *************** PRIVATE ************** + private static RestResponse uploadInformationalArtifact(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String checksum, String url) throws IOException { + Map additionalHeaders = null; + if (checksum != null && !checksum.isEmpty()) { + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + } + + additionalHeaders.put(HttpHeaderEnum.AUTHORIZATION.getValue(), authorizationHeader); + additionalHeaders.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + Gson gson = new Gson(); + // System.out.println("ArtifactDetails: "+ jsonBody); + String jsonBody = gson.toJson(artifactDetails); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), acceptHeaderData, additionalHeaders); + if ((res.getErrorCode() == STATUS_CODE_SUCCESS) || (res.getErrorCode() == STATUS_CODE_CREATED)) { + artifactDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + } + // System.out.println("Add artifact was finished with response: "+ + // res.getErrorCode()); + return res; + } + + private static RestResponse addArtifactToInstance(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String checksum, String url) throws IOException { + Map additionalHeaders = null; + additionalHeaders = new HashMap(); + if (checksum != null && !checksum.isEmpty()) { + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + } + additionalHeaders.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json, text/plain, */*"); + additionalHeaders.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json;charset=UTF-8"); + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), "application/json, text/plain, */*", additionalHeaders); + if (res.getErrorCode() == STATUS_CODE_SUCCESS) { + artifactDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + } + return res; + } + + private static RestResponse updateDeploymentArtifact(ArtifactDefinition artifactDefinition, User sdncModifierDetails, String url) throws IOException { + Map additionalHeaders = null; + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json, text/plain, */*"); + additionalHeaders.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json;charset=UTF-8"); + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDefinition); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), "application/json, text/plain, */*", additionalHeaders); + return res; + } + + private static RestResponse updateDeploymentArtifact(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String url) throws IOException { + Map additionalHeaders = null; + + additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json, text/plain, */*"); + additionalHeaders.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json;charset=UTF-8"); + // additionalHeaders.put(HttpHeaderEnum..getValue(), + // "application/json;charset=UTF-8"); + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + // System.out.println("ArtifactDetails: "+ jsonBody); + + RestResponse res = sendPost(url, jsonBody, sdncModifierDetails.getUserId(), "application/json, text/plain, */*", additionalHeaders); + if (res.getErrorCode() == STATUS_CODE_SUCCESS) { + artifactDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + } + // System.out.println("Add artifact was finished with response: "+ + // res.getErrorCode()); + return res; + } + + private static RestResponse downloadArtifact(String url, User user, Map addionalHeaders, boolean addEcompHeader) throws IOException { + if (addEcompHeader) { + addionalHeaders.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), ecomp); + } + return downloadArtifact(url, user, addionalHeaders, acceptOctetStream); + } + + private static RestResponse downloadArtifact(String url, User user, Map addionalHeaders, String accept) throws IOException { + addionalHeaders.put(HttpHeaderEnum.ACCEPT.getValue(), accept); + + RestResponse res = sendGet(url, user.getUserId(), addionalHeaders); + // System.out.println("download artifact was finished with response: "+ + // res.getErrorCode()); + // System.out.println("response is: " + res.getResponse()); + return res; + } + + private static Map> getArtifactsListFromResponse(String jsonResponse, String fieldOfArtifactList) { + JSONObject object = (JSONObject) JSONValue.parse(jsonResponse); + Map> map = (Map>) object.get(fieldOfArtifactList); + return map; + } + + public static String calculateChecksum(ArtifactReqDetails artifactDetails) { + String checksum = null; + if (artifactDetails.getPayload() != null) { + checksum = ResponseParser.calculateMD5Header(artifactDetails); + } + return checksum; + } + + public static String encodeUrlForDownload(String url) { + + return url.replaceAll(" ", "%20"); + } + + public static String getPartialUrlByArtifactName(ServiceReqDetails serviceDetails, String serviceVersion, String artifactName) { + return encodeUrlForDownload(String.format(Urls.DISTRIB_DOWNLOAD_SERVICE_ARTIFACT_RELATIVE_URL, ValidationUtils.convertToSystemName(serviceDetails.getName()), serviceVersion, artifactName)); + } + + public static String getUniqueIdOfArtifact(RestResponse createResponse, String artifactField, String requieredArtifactLabel) throws Exception { + Map artifact = getArtifactFromRestResponse(createResponse, artifactField, requieredArtifactLabel); + assertNotNull(artifact); + return artifact.get("uniqueId").toString(); + } + + public static Map getArtifactFromRestResponse(RestResponse response, String artifactField, String requieredArtifactLabel) { + Map> map = getArtifactsListFromResponse(response.getResponse(), artifactField); + return map.get(requieredArtifactLabel); + } + + public static RestResponse updateInformationalArtifactPayloadOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid) throws IOException { + return updateInformationalArtifactPayloadOfService(artifactDetails, sdncModifierDetails, serviceUid, artifactUid, calculateMD5Header(artifactDetails)); + } + + private static RestResponse updateInformationalArtifactPayloadOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid, String checksum) throws IOException { + return updateInformationalArtifactOfService(artifactDetails, sdncModifierDetails, serviceUid, artifactUid, checksum, true); + } + + private static RestResponse updateInformationalArtifactOfService(ArtifactReqDetails artifactDetails, User sdncModifierDetails, String serviceUid, String artifactUid, String checksum, boolean isPayloadUpdate) throws IOException { + Config config = Utils.getConfig(); + Map headersMap = prepareHeadersMap(sdncModifierDetails.getUserId()); + + if (isPayloadUpdate) { + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), checksum); + } + + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + + HttpRequest http = new HttpRequest(); + + String url = String.format(Urls.UPDATE_OR_DELETE_ARTIFACT_OF_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceUid, artifactUid); + RestResponse res = http.httpSendPost(url, jsonBody, headersMap); + // System.out.println("update artifact was finished with response: "+ + // res.getErrorCode()); + return res; + } + + public static String calculateMD5Header(ArtifactReqDetails artifactDetails) { + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + // calculate MD5 for json body + return calculateMD5(jsonBody); + + } + + public static String calculateMD5(String data) { + String calculatedMd5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(data); + // encode base-64 result + byte[] encodeBase64 = Base64.encodeBase64(calculatedMd5.getBytes()); + String encodeBase64Str = new String(encodeBase64); + return encodeBase64Str; + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/AssetRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/AssetRestUtils.java new file mode 100644 index 0000000000..51bd2162c0 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/AssetRestUtils.java @@ -0,0 +1,510 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.AssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceDetailedAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceInstanceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceDetailedAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class AssetRestUtils extends BaseRestUtils { + static Gson gson = new Gson(); + static ObjectMapper objectMapper = new ObjectMapper(); + + static Logger logger = LoggerFactory.getLogger(UserRestUtils.class.getName()); + static final String contentTypeHeaderData = "application/json"; + static final String acceptHeaderDate = "application/json"; + static final String basicAuthentication = "Basic Y2k6MTIzNDU2"; + // /asdc/v1/catalog/{services/resources}/{componentUUID}/artifacts/{artifactUUID} + static final String COMPONENT_ARTIFACT_URL = "/asdc/v1/catalog/%s/%s/artifacts/%s"; + // /asdc/v1/catalog/{services/resources}/{componentUUID}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID} + static final String RESOURCE_INSTANCE_ARTIFACT_URL = "/asdc/v1/catalog/%s/%s/resourceInstances/%s/artifacts/%s"; + + public static HttpResponse getComponentToscaModel(AssetTypeEnum assetType, String uuid) throws IOException { + Config config = Utils.getConfig(); + CloseableHttpClient httpclient = HttpClients.createDefault(); + String url = String.format(Urls.GET_TOSCA_MODEL, config.getCatalogBeHost(), config.getCatalogBePort(), + assetType.getValue(), uuid); + HttpGet httpGet = new HttpGet(url); + + httpGet.addHeader(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + httpGet.addHeader(HttpHeaderEnum.AUTHORIZATION.getValue(), basicAuthentication); + + logger.debug("Send GET request to get Tosca model: {}", url); + + return httpclient.execute(httpGet); + } + + public static RestResponse getComponentListByAssetType(boolean isBasicAuthentication, AssetTypeEnum assetType, + String... filterArrayString) throws IOException { + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + if (isBasicAuthentication) { + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), basicAuthentication); + } + headersMap.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ASSET_LIST, config.getCatalogBeHost(), config.getCatalogBePort(), + assetType.getValue()); + if (filterArrayString != null && filterArrayString.length > 0) { + url = buildUrlWithFilter(url, filterArrayString); + } + + RestResponse sendGetResourceAssets = http.httpSendGet(url, headersMap); + + return sendGetResourceAssets; + } + + public static RestResponse getFilteredComponentList(AssetTypeEnum assetType, String query) throws IOException { + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), basicAuthentication); + headersMap.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + HttpRequest http = new HttpRequest(); + + String url = String.format(Urls.GET_FILTERED_ASSET_LIST, config.getCatalogBeHost(), config.getCatalogBePort(), + assetType.getValue(), query); + + logger.debug("Send GET request to get Resource Assets: {}", url); + logger.debug("Request headers: {}", headersMap); + + RestResponse sendGetResourceAssets = http.httpSendGet(url, headersMap); + + return sendGetResourceAssets; + } + + public static String buildUrlWithFilter(String url, String[] filterArrayString) { + StringBuilder sb = new StringBuilder(); + int length = filterArrayString.length; + int count = 0; + for (String filterString : filterArrayString) { + sb.append(filterString); + count++; + if (length != count) { + sb.append("&"); + } + } + return url + "?" + sb; + } + + public static RestResponse getAssetMetadataByAssetTypeAndUuid(boolean isBasicAuthentication, + AssetTypeEnum assetType, String uuid) throws IOException { + + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + if (isBasicAuthentication) { + headersMap.put(HttpHeaderEnum.AUTHORIZATION.getValue(), basicAuthentication); + } + headersMap.put(HttpHeaderEnum.X_ECOMP_INSTANCE_ID.getValue(), "ci"); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ASSET_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), + assetType.getValue(), uuid); + + logger.debug("Send GET request to get Resource Assets: {}", url); + logger.debug("Request headers: {} ", headersMap); + + RestResponse sendGetResourceAssets = http.httpSendGet(url, headersMap); + + return sendGetResourceAssets; + } + + public static List getResourceAssetList(RestResponse assetResponse) { + List resourceAssetList = new ArrayList<>(); + + JsonElement jelement = new JsonParser().parse(assetResponse.getResponse()); + JsonArray componenetArray = (JsonArray) jelement; + for (JsonElement jElement : componenetArray) { + ResourceAssetStructure resource = gson.fromJson(jElement, ResourceAssetStructure.class); + resourceAssetList.add(resource); + } + return resourceAssetList; + } + + public static ResourceDetailedAssetStructure getResourceAssetMetadata(RestResponse assetResponse) { + + List resourcesList = new ArrayList<>(); + List artifactsList = new ArrayList<>(); + ResourceDetailedAssetStructure resourceAssetMetadata = new ResourceDetailedAssetStructure(); + String response = assetResponse.getResponse(); + + JsonObject jObject = (JsonObject) new JsonParser().parse(response); + resourceAssetMetadata = gson.fromJson(jObject, ResourceDetailedAssetStructure.class); + + setResourceInstanceAssetList(resourcesList, jObject); + resourceAssetMetadata.setResources(resourcesList); + + setArtifactAssetList(artifactsList, jObject); + resourceAssetMetadata.setArtifacts(artifactsList); + + return resourceAssetMetadata; + } + + public static void generalMetadataFieldsValidatior(AssetStructure assetMetadata, Component component) { + + assertTrue("Expected resourceUuid is " + component.getUUID() + " actual: " + assetMetadata.getUuid(), + assetMetadata.getUuid().equals(component.getUUID())); + assertTrue( + "Expected resourceInvariantUuid is " + component.getInvariantUUID() + " actual: " + + assetMetadata.getInvariantUUID(), + assetMetadata.getInvariantUUID().equals(component.getInvariantUUID())); + assertTrue("Expected asset name is " + component.getName() + " actual: " + assetMetadata.getName(), + assetMetadata.getName().equals(component.getName())); + assertTrue("Expected asset version is " + component.getVersion() + " actual: " + assetMetadata.getVersion(), + assetMetadata.getVersion().equals(component.getVersion())); + assertTrue( + "Expected asset lastUpdaterUserId is " + component.getLastUpdaterUserId() + " actual: " + + assetMetadata.getLastUpdaterUserId(), + assetMetadata.getLastUpdaterUserId().equals(component.getLastUpdaterUserId())); + assertNotNull("Expected asset toscaModel is null", assetMetadata.getToscaModelURL()); + assertTrue( + "Expected asset category is " + component.getCategories().get(0).getName() + " actual: " + + assetMetadata.getCategory(), + assetMetadata.getCategory().equals(component.getCategories().get(0).getName())); + assertTrue( + "Expected asset lifeCycleState is " + component.getLifecycleState() + " actual: " + + assetMetadata.getLifecycleState(), + assetMetadata.getLifecycleState().equals(component.getLifecycleState().toString())); + + } + + public static void resourceMetadataValidatior(ResourceDetailedAssetStructure resourceAssetMetadata, + Resource resource, AssetTypeEnum assetType) { + + generalMetadataFieldsValidatior(resourceAssetMetadata, resource); + assertTrue( + "Expected asset lastUpdaterFullName is " + resource.getLastUpdaterFullName() + " actual: " + + resourceAssetMetadata.getLastUpdaterFullName(), + resourceAssetMetadata.getLastUpdaterFullName().equals(resource.getLastUpdaterFullName())); + assertTrue( + "Expected asset subCategory is " + resource.getCategories().get(0).getSubcategories().get(0).getName() + + " actual: " + resourceAssetMetadata.getSubCategory(), + resourceAssetMetadata.getSubCategory() + .equals(resource.getCategories().get(0).getSubcategories().get(0).getName())); + assertTrue( + "Expected asset toscaResourceName is " + resource.getToscaResourceName() + " actual: " + + resourceAssetMetadata.getToscaResourceName(), + resourceAssetMetadata.getToscaResourceName().equals(resource.getToscaResourceName())); + assertTrue( + "Expected asset resourceType is " + resource.getResourceType() + " actual: " + + resourceAssetMetadata.getResourceType(), + resourceAssetMetadata.getResourceType().equals(resource.getResourceType().toString())); + resourceInstanceAssetValidator(resourceAssetMetadata.getResources(), resource, assetType); + // resourceInstanceAssetValidator(resourceAssetMetadata.getResources(), + // resource); + artifactAssetValidator(resourceAssetMetadata.getArtifacts(), resource, assetType); + + } + + public static void serviceMetadataValidatior(ServiceDetailedAssetStructure serviceAssetMetadata, Service service, + AssetTypeEnum assetType) { + + generalMetadataFieldsValidatior(serviceAssetMetadata, service); + assertTrue( + "Expected asset lastUpdaterFullName is " + service.getLastUpdaterFullName() + " actual: " + + serviceAssetMetadata.getLastUpdaterFullName(), + serviceAssetMetadata.getLastUpdaterFullName().equals(service.getLastUpdaterFullName())); + assertTrue( + "Expected asset distributionStatus is " + service.getDistributionStatus() + " actual: " + + serviceAssetMetadata.getDistributionStatus(), + serviceAssetMetadata.getDistributionStatus().equals(service.getDistributionStatus().toString())); + resourceInstanceAssetValidator(serviceAssetMetadata.getResources(), service, assetType); + // resourceInstanceAssetValidator(serviceAssetMetadata.getResources(), + // service); + artifactAssetValidator(serviceAssetMetadata.getArtifacts(), service, assetType); + + } + + private static void artifactAssetValidator(List artifactAssetStructureList, + Component component, AssetTypeEnum assetType) { + Map componentDeploymentArtifacts = component.getDeploymentArtifacts(); + validateArtifactMetadata(componentDeploymentArtifacts, artifactAssetStructureList, component.getUUID(), + assetType, null); + } + + private static void validateArtifactMetadata(Map componentDeploymentArtifacts, + List artifactAssetStructureList, String componentUuid, AssetTypeEnum assetType, + String resourceInstanceName) { + + for (Entry componentDeploymentArtifact : componentDeploymentArtifacts.entrySet()) { + ArtifactAssetStructure artifactAssetStructure = getArtifactMetadata(artifactAssetStructureList, + componentDeploymentArtifact.getValue().getArtifactUUID()); + ArtifactDefinition componentDeploymentArtifactValue = componentDeploymentArtifact.getValue(); + if (artifactAssetStructure != null) { + assertTrue( + "Expected artifact asset artifactName is " + componentDeploymentArtifactValue.getArtifactName() + + " actual: " + artifactAssetStructure.getArtifactName(), + componentDeploymentArtifactValue.getArtifactName() + .equals(artifactAssetStructure.getArtifactName())); + assertTrue( + "Expected artifact asset Type is " + componentDeploymentArtifactValue.getArtifactType() + + " actual: " + artifactAssetStructure.getArtifactType(), + componentDeploymentArtifactValue.getArtifactType() + .equals(artifactAssetStructure.getArtifactType())); + // assertNotNull("Expected artifact asset resourceInvariantUUID + // is null", + // resourceInstanceAssetStructure.getResourceInvariantUUID()); + // String expectedArtifactUrl = "/asdc/v1/catalog/" + + // assetType.getValue() + "/" + componentUuid + "/artifacts/" + + // componentDeploymentArtifactValue.getArtifactUUID(); + String expectedArtifactUrl = ""; + if (resourceInstanceName == null) { + expectedArtifactUrl = String.format(COMPONENT_ARTIFACT_URL, assetType.getValue(), componentUuid, + componentDeploymentArtifactValue.getArtifactUUID()); + } else { + expectedArtifactUrl = String.format(RESOURCE_INSTANCE_ARTIFACT_URL, assetType.getValue(), + componentUuid, resourceInstanceName, componentDeploymentArtifactValue.getArtifactUUID()); + } + + assertTrue( + "Expected artifact asset URL is " + expectedArtifactUrl + " actual: " + + artifactAssetStructure.getArtifactURL(), + artifactAssetStructure.getArtifactURL().equals(expectedArtifactUrl)); + assertTrue( + "Expected artifact asset description is " + componentDeploymentArtifactValue.getDescription() + + " actual: " + artifactAssetStructure.getArtifactDescription(), + componentDeploymentArtifactValue.getDescription().toString() + .equals(artifactAssetStructure.getArtifactDescription())); + assertTrue( + "Expected artifact asset checkSum is " + componentDeploymentArtifactValue.getArtifactChecksum() + + " actual: " + artifactAssetStructure.getArtifactChecksum(), + componentDeploymentArtifactValue.getArtifactChecksum() + .equals(artifactAssetStructure.getArtifactChecksum())); + assertTrue( + "Expected artifact asset version is " + componentDeploymentArtifactValue.getArtifactVersion() + + " actual: " + artifactAssetStructure.getArtifactVersion(), + componentDeploymentArtifactValue.getArtifactVersion() + .equals(artifactAssetStructure.getArtifactVersion())); + if (componentDeploymentArtifactValue.getTimeout() > 0) { + assertTrue( + "Expected artifact asset timeout is " + componentDeploymentArtifactValue.getTimeout() + + " actual: " + artifactAssetStructure.getArtifactTimeout(), + componentDeploymentArtifactValue.getTimeout() + .equals(artifactAssetStructure.getArtifactTimeout())); + } + + } else { + assertTrue("artifact asset with UUID" + componentDeploymentArtifact.getValue().getArtifactUUID() + + " not found in get Metadata response", false); + } + } + + } + + private static ArtifactAssetStructure getArtifactMetadata(List artifactAssetStructureList, + String artifactUUID) { + for (ArtifactAssetStructure artifactAssetStructure : artifactAssetStructureList) { + if (artifactAssetStructure.getArtifactUUID().equals(artifactUUID)) { + return artifactAssetStructure; + } + } + return null; + } + + private static void resourceInstanceAssetValidator( + List resourceInstanceAssetStructures, Component component, + AssetTypeEnum assetType) { + + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + for (ComponentInstance componentInstance : componentInstances) { + ResourceInstanceAssetStructure resourceInstanceAssetStructure = getResourceInstanceMetadata( + resourceInstanceAssetStructures, componentInstance.getName()); + if (resourceInstanceAssetStructure != null) { + assertTrue( + "Expected RI asset resourceName is " + componentInstance.getComponentName() + " actual: " + + resourceInstanceAssetStructure.getResourceName(), + componentInstance.getComponentName() + .equals(resourceInstanceAssetStructure.getResourceName())); + assertTrue( + "Expected RI asset Name is " + componentInstance.getName() + " actual: " + + resourceInstanceAssetStructure.getResourceInstanceName(), + componentInstance.getName() + .equals(resourceInstanceAssetStructure.getResourceInstanceName())); + assertNotNull("Expected RI asset resourceInvariantUUID is null", + resourceInstanceAssetStructure.getResourceInvariantUUID()); + assertTrue( + "Expected RI asset resourceVersion is " + componentInstance.getComponentVersion() + + " actual: " + resourceInstanceAssetStructure.getResourceVersion(), + componentInstance.getComponentVersion() + .equals(resourceInstanceAssetStructure.getResourceVersion())); + assertTrue( + "Expected RI asset resourceType is " + componentInstance.getOriginType() + " actual: " + + resourceInstanceAssetStructure.getResoucreType(), + componentInstance.getOriginType().toString() + .equals(resourceInstanceAssetStructure.getResoucreType())); + assertTrue( + "Expected RI asset resourceUUID is " + componentInstance.getComponentUid() + " actual: " + + resourceInstanceAssetStructure.getResourceUUID(), + componentInstance.getComponentUid() + .equals(resourceInstanceAssetStructure.getResourceUUID())); + validateArtifactMetadata(componentInstance.getDeploymentArtifacts(), + resourceInstanceAssetStructure.getArtifacts(), component.getUUID(), assetType, + componentInstance.getNormalizedName()); + // validateArtifactMetadata(componentInstance.getDeploymentArtifacts(), + // resourceInstanceAssetStructure.getArtifacts(), + // component.getUUID(), AssetTypeEnum.RESOURCES); + } else { + assertTrue("resourceInstance asset with UUID" + componentInstance.getComponentUid() + + " not found in get Metadata response", false); + } + } + } + + } + + // private static ResourceInstanceAssetStructure + // getResourceInstanceMetadata(List + // resourceInstanceAssetStructures, String componentUid) { + private static ResourceInstanceAssetStructure getResourceInstanceMetadata( + List resourceInstanceAssetStructures, String name) { + for (ResourceInstanceAssetStructure resourceInstanceAssetStructure : resourceInstanceAssetStructures) { + if (resourceInstanceAssetStructure.getResourceInstanceName().equals(name)) { + return resourceInstanceAssetStructure; + } + } + return null; + } + + public static ServiceDetailedAssetStructure getServiceAssetMetadata(RestResponse assetResponse) { + + List resourcesList = new ArrayList<>(); + List artifactsList = new ArrayList<>(); + ServiceDetailedAssetStructure serviceAssetMetadata; + + JsonObject jObject = (JsonObject) new JsonParser().parse(assetResponse.getResponse()); + serviceAssetMetadata = gson.fromJson(jObject, ServiceDetailedAssetStructure.class); + + setResourceInstanceAssetList(resourcesList, jObject); + serviceAssetMetadata.setResources(resourcesList); + + setArtifactAssetList(artifactsList, jObject); + serviceAssetMetadata.setArtifacts(artifactsList); + + return serviceAssetMetadata; + } + + public static void setArtifactAssetList(List artifactsList, JsonObject jObject) { + JsonArray artifactsArray = jObject.getAsJsonArray("artifacts"); + if (artifactsArray != null) { + for (JsonElement jElement : artifactsArray) { + ArtifactAssetStructure artifact = gson.fromJson(jElement, ArtifactAssetStructure.class); + artifactsList.add(artifact); + } + } + } + + public static void setResourceInstanceAssetList(List resourcesList, + JsonObject jObject) { + JsonArray resourcesArray = jObject.getAsJsonArray("resources"); + if (resourcesArray != null) { + for (JsonElement jElement : resourcesArray) { + ResourceInstanceAssetStructure resource = gson.fromJson(jElement, ResourceInstanceAssetStructure.class); + resourcesList.add(resource); + } + } + } + + public static List getServiceAssetList(RestResponse assetResponse) { + List serviceAssetList = new ArrayList<>(); + + JsonElement jelement = new JsonParser().parse(assetResponse.getResponse()); + JsonArray componenetArray = (JsonArray) jelement; + for (JsonElement jElement : componenetArray) { + ServiceAssetStructure service = gson.fromJson(jElement, ServiceAssetStructure.class); + serviceAssetList.add(service); + } + return serviceAssetList; + } + + public static List getResourceNamesList(List resourceAssetList) { + List assetNamesList = new ArrayList<>(); + for (ResourceAssetStructure resourceAsset : resourceAssetList) { + assetNamesList.add(resourceAsset.getName()); + } + return assetNamesList; + } + + public static List getServiceNamesList(List serviceAssetList) { + List assetNamesList = new ArrayList<>(); + for (ServiceAssetStructure serviceAsset : serviceAssetList) { + assetNamesList.add(serviceAsset.getName()); + } + return assetNamesList; + } + + public static void checkResourceTypeInObjectList(List resourceAssetList, + ResourceTypeEnum resourceType) { + for (ResourceAssetStructure resourceAsset : resourceAssetList) { + assertTrue( + "Expected resourceType is " + resourceType.toString() + " actual: " + + resourceAsset.getResourceType(), + resourceAsset.getResourceType().equals(resourceType.toString())); + } + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/BaseRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/BaseRestUtils.java new file mode 100644 index 0000000000..9ffe5782e7 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/BaseRestUtils.java @@ -0,0 +1,256 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.apache.http.HttpEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.validation.BaseValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BaseRestUtils extends BaseValidationUtils { + public static final String contentTypeHeaderData = "application/json"; + public static final String acceptHeaderData = "application/json"; + public static final String acceptJsonHeader = "application/json"; + public static final String acceptOctetHeader = "application/octet-stream"; + public static final String authorizationHeader = "Basic " + Base64.encodeBase64String("ci:123456".getBytes()); + public static final String acceptOctetStream = "application/octet-stream"; + public static final String ecomp = "ecomp"; + public static final String authorizationPrefixString = "Basic "; + + public static final String RESOURCE_COMPONENT_TYPE = "resources"; + public static final String PRODUCT_COMPONENT_TYPE = "products"; + public static final String SERVICE_COMPONENT_TYPE = "services"; + + public static final int STATUS_CODE_SUCCESS = 200; + public static final int STATUS_CODE_CREATED = 201; + public static final int STATUS_CODE_DELETE = 204; + public static final int STATUS_CODE_NOT_FOUND = 404; + public static final int STATUS_CODE_SUCCESS_NO_CONTENT = 204; + public static final int STATUS_CODE_SUCCESS_DELETE = 204; + public static final int STATUS_CODE_INVALID_CONTENT = 400; + public static final int STATUS_CODE_MISSING_DATA = 400; + public static final int STATUS_CODE_MISSING_INFORMATION = 403; + public static final int STATUS_CODE_RESTRICTED_ACCESS = 403; + public static final int STATUS_CODE_ALREADY_EXISTS = 409; + public static final int STATUS_CODE_RESTRICTED_OPERATION = 409; + public static final int STATUS_CODE_COMPONENT_NAME_EXCEEDS_LIMIT = 400; + public static final int STATUS_CODE_MISSING_COMPONENT_NAME = 400; + public static final int STATUS_CODE_UNSUPPORTED_ERROR = 400; + public static final int STATUS_CODE_IMPORT_SUCCESS = 201; + public static final int STATUS_CODE_UPDATE_SUCCESS = 200; + public static final int RESTRICTED_OPERATION = 409; + public static final int STATUS_CODE_GET_SUCCESS = 200; + + public static final String SUCCESS_MESSAGE = "OK"; + private static Logger logger = LoggerFactory.getLogger(BaseRestUtils.class.getName()); + + private static byte[] encodeBase64; + + // ************* PRIVATE METHODS ************************ + + protected static Map prepareHeadersMap(String userId) { + return prepareHeadersMap(userId, acceptHeaderData); + } + + protected static Map prepareHeadersMap(String userId, String accept) { + Map headersMap = new HashMap(); + if (contentTypeHeaderData != null) { + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + } + if (accept != null) { + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), accept); + } + if (userId != null) { + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), userId); + } + + return headersMap; + } + + // send request + // GET + protected static RestResponse sendGet(String url, String userId) throws IOException { + return sendGet(url, userId, null); + } + + protected static RestResponse sendGet(String url, String userId, Map additionalHeaders) + throws IOException { + Map headersMap = prepareHeadersMap(userId); + if (additionalHeaders != null) { + headersMap.putAll(additionalHeaders); + } + + HttpRequest http = new HttpRequest(); + RestResponse getResourceResponse = http.httpSendGet(url, headersMap); + return getResourceResponse; + } + + public static RestResponse sendGetAndRemoveHeaders(String url, String userId, List headersToRemove) + throws IOException { + Map headersMap = prepareHeadersMap(userId); + if (headersToRemove != null) { + for (String header : headersToRemove) { + headersMap.remove(header); + } + } + + HttpRequest http = new HttpRequest(); + RestResponse getResourceResponse = http.httpSendGet(url, headersMap); + return getResourceResponse; + } + + // PUT + protected static RestResponse sendPut(String url, String userBodyJson, String userId, String cont) + throws IOException { + Map headersMap = prepareHeadersMap(userId, cont); + + HttpRequest http = new HttpRequest(); + RestResponse updateResourceResponse = http.httpSendByMethod(url, "PUT", userBodyJson, headersMap); + return updateResourceResponse; + } + + // POST + public static RestResponse sendPost(String url, String userBodyJson, String userId, String accept) + throws IOException { + return sendPost(url, userBodyJson, userId, accept, null); + } + + protected static RestResponse sendPost(String url, String userBodyJson, String userId, String accept, + Map additionalHeaders) throws IOException { + Map headersMap = prepareHeadersMap(userId, accept); + if (additionalHeaders != null) { + headersMap.putAll(additionalHeaders); + } + HttpRequest http = new HttpRequest(); + RestResponse postResourceResponse = http.httpSendPost(url, userBodyJson, headersMap); + return postResourceResponse; + } + + // used form complex requests like import categories.. + protected static RestResponse sendPost(String url, HttpEntity entity, String userId, String accept) + throws IOException { + RestResponse postResponse = new RestResponse(); + CloseableHttpResponse response = null; + CloseableHttpClient client = null; + try { + client = HttpClients.createDefault(); + HttpPost httpPost = new HttpPost(url); + + httpPost.addHeader("USER_ID", userId); + httpPost.setEntity(entity); + response = client.execute(httpPost); + HttpEntity responseEntity = response.getEntity(); + int statusCode = response.getStatusLine().getStatusCode(); + + postResponse.setErrorCode(statusCode); + StringBuffer sb = new StringBuffer(); + try { + BufferedReader in = new BufferedReader(new InputStreamReader(responseEntity.getContent())); + String inputLine; + while ((inputLine = in.readLine()) != null) { + sb.append(inputLine); + } + in.close(); + } catch (Exception e) { + logger.debug("response body is null"); + } + postResponse.setResponse(sb.toString()); + } finally { + try { + if (response != null) { + response.close(); + } + + } catch (IOException e) { + logger.debug("failed to close client or response: ", e); + } + try { + if (client != null) { + client.close(); + } + } catch (IOException e) { + logger.debug("failed to close client or response: ", e); + } + } + return postResponse; + } + + // DELETE + protected static RestResponse sendDelete(String url, String userId) throws IOException { + Map headersMap = prepareHeadersMap(userId); + + HttpRequest http = new HttpRequest(); + RestResponse deleteResourceResponse = http.httpSendDelete(url, headersMap); + return deleteResourceResponse; + } + + /* + * // ------ protected static Boolean checkErrorCode(RestResponse + * deleteResponse) { if (deleteResponse.getErrorCode() == + * STATUS_CODE_SUCCESS || deleteResponse.getErrorCode() == + * STATUS_CODE_DELETE) { return true; } return false; } + * + * // *** STATUS CODE VALIDATION UTIITIES **** public static void + * checkStatusCode(RestResponse response, String assertMessage, boolean AND, + * int... statuses) { int statusCode = response.getErrorCode(); for (int + * status : statuses) { if (AND && statusCode != status) { + * Assert.fail(assertMessage + " status: " + statusCode); } else if + * (statusCode == status) { return; } } if (!AND) { + * Assert.fail(assertMessage + " status: " + statusCode); } } + * + * public static void checkDeleteResponse(RestResponse response) { + * checkStatusCode(response,"delete request failed",false,STATUS_CODE_DELETE + * ,STATUS_CODE_NOT_FOUND, STATUS_CODE_SUCCESS); // STATUS_CODE_SUCCESS for + * deActivate user } + * + * public static void checkCreateResponse(RestResponse response) { + * checkStatusCode(response, "create request failed", false, + * STATUS_CODE_CREATED); } + */ + public static String encodeUrlForDownload(String url) { + return url.replaceAll(" ", "%20"); + } + + public static Map addAuthorizeHeader(String userName, String password) { + String userCredentials = userName + ":" + password; + encodeBase64 = Base64.encodeBase64(userCredentials.getBytes()); + String encodedUserCredentials = authorizationPrefixString + new String(encodeBase64); + Map authorizationHeader = new HashMap(); + authorizationHeader.put(HttpHeaderEnum.AUTHORIZATION.getValue(), encodedUserCredentials); + return authorizationHeader; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CatalogRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CatalogRestUtils.java new file mode 100644 index 0000000000..a265639804 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CatalogRestUtils.java @@ -0,0 +1,75 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +public class CatalogRestUtils extends BaseRestUtils { + + public static RestResponse getAbstractResources() throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_ABSTRACT_RESOURCES, config.getCatalogBeHost(), + config.getCatalogBePort()); + + return sendGet(url, UserRoleEnum.DESIGNER.getUserId()); + } + + public static RestResponse getCatalog() throws IOException { + return getCatalog(UserRoleEnum.DESIGNER.getUserId()); + } + + public static RestResponse getCatalog(String userId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_CATALOG_DATA, config.getCatalogBeHost(), config.getCatalogBePort()); + return sendGet(url, userId); + } + + public static RestResponse getAllCategoriesTowardsCatalogBe() throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES, config.getCatalogBeHost(), config.getCatalogBePort(), + BaseRestUtils.RESOURCE_COMPONENT_TYPE); + + return sendGet(url, UserRoleEnum.DESIGNER.getUserId()); + } + + public static RestResponse getAllCategoriesTowardsCatalogFeWithUuid(String uuid) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES_FE, config.getCatalogFeHost(), config.getCatalogFePort(), + BaseRestUtils.RESOURCE_COMPONENT_TYPE); + + Map additionalHeaders = new HashMap(); + additionalHeaders.put(HttpHeaderEnum.X_ECOMP_REQUEST_ID_HEADER.getValue(), uuid); + + return sendGet(url, UserRoleEnum.DESIGNER.getUserId(), additionalHeaders); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CategoryRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CategoryRestUtils.java new file mode 100644 index 0000000000..d9ae91b955 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/CategoryRestUtils.java @@ -0,0 +1,298 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; + +public class CategoryRestUtils extends BaseRestUtils { + + private static final int STATUS_CODE_CREATED = 201; + + private static Gson gson = new Gson(); + + public static RestResponse createCategory(CategoryDefinition categoryDefinition, User sdncModifierDetails, + String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), + categoryType); + String bodyJson = gson.toJson(categoryDefinition); + RestResponse addCategoryResponse = BaseRestUtils.sendPost(url, bodyJson, sdncModifierDetails.getUserId(), + acceptHeaderData); + if (addCategoryResponse.getErrorCode().intValue() == STATUS_CODE_CREATED) + categoryDefinition.setUniqueId( + ResponseParser.getValueFromJsonResponse(addCategoryResponse.getResponse(), "uniqueId")); + return addCategoryResponse; + } + + // GET categories + public static RestResponse getAllCategories(User sdncModifierDetails, String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES, config.getCatalogBeHost(), config.getCatalogBePort(), categoryType); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + RestResponse getCategotyResponse = http.httpSendGet(url, headersMap); + return getCategotyResponse; + } + + public static RestResponse getAllCategoriesTowardsFe(User sdncModifierDetails, String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES_FE, config.getCatalogFeHost(), config.getCatalogFePort(), categoryType); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + RestResponse getCategotyResponse = http.httpSendGet(url, headersMap); + return getCategotyResponse; + } + + // Delete Category + public static RestResponse deleteCategory(String categoryId, String psUserId, String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), categoryType, categoryId); + url = url.replace("#", "%23"); // HEX + url = url.replace(" ", "%20"); // HEX + RestResponse deleteCategoryResponse = sendDelete(url, psUserId); + return deleteCategoryResponse; + } + + public static RestResponse createSubCategory(SubCategoryDefinition subCategory, CategoryDefinition parentCategory, + User sdncModifierDetails, String categoryType) throws Exception { + // categoryType = service/resource/product + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_SUB_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), + categoryType, parentCategory.getUniqueId()); + String bodyJson = gson.toJson(subCategory); + RestResponse createSubCategoryPost = BaseRestUtils.sendPost(url, bodyJson, sdncModifierDetails.getUserId(), + acceptHeaderData); + if (createSubCategoryPost.getErrorCode().intValue() == STATUS_CODE_CREATED) + subCategory.setUniqueId( + ResponseParser.getValueFromJsonResponse(createSubCategoryPost.getResponse(), "uniqueId")); + + return createSubCategoryPost; + } + + public static RestResponse deleteSubCategory(String subCategoryId, String categoryId, String psUserId, + String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_SUB_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), + categoryType, categoryId, subCategoryId); + url = url.replace("#", "%23"); // HEX + url = url.replace(" ", "%20"); // HEX + RestResponse deleteSubCategoryResponse = sendDelete(url, psUserId); + return deleteSubCategoryResponse; + } + + public static RestResponse deleteGrouping(String groupId, String subCategoryId, String categoryId, String psUserId, + String categoryType) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_GROUPING, config.getCatalogBeHost(), config.getCatalogBePort(), + categoryType, categoryId, subCategoryId, groupId); + url = url.replace("#", "%23"); // HEX + url = url.replace(" ", "%20"); // HEX + RestResponse deleteGroupResponse = sendDelete(url, psUserId); + return deleteGroupResponse; + } + + public static RestResponse createServiceCategoryHttpCspAtuUidIsMissing(CategoryDefinition categoryDataDefinition, + User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), + SERVICE_COMPONENT_TYPE); + + Map headersMap = prepareHeadersMap(sdncModifierDetails.getUserId()); + headersMap.remove("USER_ID"); + Gson gson = new Gson(); + String userBodyJson = gson.toJson(categoryDataDefinition); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse createCatergoryResponse = http.httpSendPost(url, userBodyJson, headersMap); + return createCatergoryResponse; + } + + public static RestResponse createSubCategoryHttpCspAtuUidIsMissing(SubCategoryDefinition subCategory, + CategoryDefinition parentCategory, User sdncModifierDetails, String categoryType) throws Exception { + // categoryType = service/resource/product + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_SUB_CATEGORY, config.getCatalogBeHost(), config.getCatalogBePort(), + categoryType, parentCategory.getUniqueId()); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + headersMap.remove("USER_ID"); + Gson gson = new Gson(); + String subCatJson = gson.toJson(subCategory); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(subCatJson); + RestResponse addCategoryResponse = http.httpSendPost(url, subCatJson, headersMap); + return addCategoryResponse; + } + + public static RestResponse deleteCatergoryHttpCspAtuUidIsMissing(CategoryDefinition categoryDataDefinition, User sdncModifierDetails) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort(), categoryDataDefinition.getName()); + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + headersMap.remove("USER_ID"); + Gson gson = new Gson(); + String userBodyJson = gson.toJson(categoryDataDefinition); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse deleteCategotyResponse = http.httpSendDelete(url, headersMap); + return deleteCategotyResponse; + } + + public static RestResponse createGrouping(GroupingDefinition grouping, SubCategoryDefinition subCategory, + CategoryDefinition parentCategory, User sdncModifierDetails, String categoryType) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_GROUPING, config.getCatalogBeHost(), config.getCatalogBePort(), categoryType, parentCategory.getUniqueId(), subCategory.getUniqueId()); + String bodyJson = gson.toJson(grouping); + RestResponse addGroupingResponse = BaseRestUtils.sendPost(url, bodyJson, sdncModifierDetails.getUserId(), acceptHeaderData); + return addGroupingResponse; + } + + public static RestResponse importCategories(MultipartEntityBuilder mpBuilder, String userId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.IMPORT_CATEGORIES, config.getCatalogBeHost(), config.getCatalogBePort()); + + RestResponse importResponse = BaseRestUtils.sendPost(url, mpBuilder.build(), userId, acceptHeaderData); + return importResponse; + } + + public static int getMatchingCategoriesNum(RestResponse getAllCategoryRest, CategoryDefinition categoryDefinition) { + String response = getAllCategoryRest.getResponse(); + Gson gson = new Gson(); + List categoryDefinitions = gson.fromJson(response, + new TypeToken>() { + }.getType()); + int categoriesNum = 0; + String catName = categoryDefinition.getName(); + for (CategoryDefinition elem : categoryDefinitions) { + if (elem.getName().equals(catName)) { + categoryDefinition.setUniqueId(elem.getUniqueId()); + categoriesNum++; + } + } + + return categoriesNum; + } + + public static int getMatchingSubCategoriesNum(RestResponse getAllCategoryRest, String parentCategoryId, + SubCategoryDefinition expectedSubCategoryDefinition) { + + String response = getAllCategoryRest.getResponse(); + Gson gson = new Gson(); + List categoryDefinitions = gson.fromJson(response, + new TypeToken>() { + }.getType()); + int subCatNum = 0; + String subCatName = expectedSubCategoryDefinition.getName(); + for (CategoryDefinition elem : categoryDefinitions) { + if (elem.getUniqueId().equals(parentCategoryId)) { + List subCategories = elem.getSubcategories(); + if (subCategories != null) { + for (SubCategoryDefinition subCategoryDataDefinition : subCategories) { + if (subCatName.equals(subCategoryDataDefinition.getName())) { + expectedSubCategoryDefinition.setUniqueId(subCategoryDataDefinition.getUniqueId()); + subCatNum++; + } + } + } + + } + } + return subCatNum; + } + + public static int getMatchingGroupingNum(RestResponse getAllCategoryRest, String parentCategoryId, + String subCategoryId, GroupingDefinition expectedGroupingDefinition) { + + String response = getAllCategoryRest.getResponse(); + Gson gson = new Gson(); + List categoryDefinitions = gson.fromJson(response, + new TypeToken>() { + }.getType()); + int groupingNum = 0; + String groupingName = expectedGroupingDefinition.getName(); + for (CategoryDefinition elem : categoryDefinitions) { + if (elem.getUniqueId().equals(parentCategoryId)) { + List subCategories = elem.getSubcategories(); + if (subCategories != null) { + for (SubCategoryDefinition subCategoryDataDefinition : subCategories) { + // if + // (subCategoryId.equals(subCategoryDataDefinition.getUniqueId())) + // { + if (subCategoryId.equals(subCategoryDataDefinition.getUniqueId()) + && subCategoryDataDefinition.getGroupings() != null) { + List grouping = subCategoryDataDefinition.getGroupings(); + for (GroupingDefinition groupingDataDefinition : grouping) { + if (groupingName.equals(groupingDataDefinition.getName())) { + expectedGroupingDefinition.setUniqueId(groupingDataDefinition.getUniqueId()); + groupingNum++; + } + } + + } + } + } + + } + } + return groupingNum; + } + + public enum CategoryAuditJsonKeysEnum { + ACTION("ACTION"), MODIFIER("MODIFIER"), CATEGORY_NAME("CATEGORY_NAME"), SUB_CATEGORY_NAME("SUB_CATEGORY_NAME"), GROUPING_NAME("GROUPING_NAME"), RESOURCE_TYPE("RESOURCE_TYPE"), ECOMP_USER("ECOMP_USER"), STATUS("STATUS"), + DESCRIPTION("DESCRIPTION"), DETAILS("DETAILS"); + + private String auditJsonKeyName; + + private CategoryAuditJsonKeysEnum(String auditJsonKeyName) { + this.auditJsonKeyName = auditJsonKeyName; + } + + public String getAuditJsonKeyName() { + return auditJsonKeyName.toLowerCase(); + } + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentInstanceRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentInstanceRestUtils.java new file mode 100644 index 0000000000..10587390f2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentInstanceRestUtils.java @@ -0,0 +1,276 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.Assert.assertTrue; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +import com.google.gson.Gson; + +public class ComponentInstanceRestUtils extends BaseRestUtils { + public static String acceptHeaderDate = "application/json"; + static Config config = Config.instance(); + public static Gson gson = new Gson(); + + // 'componentType' can be 'services' or 'resources' + + public static RestResponse createComponentInstance(ComponentInstanceReqDetails componentInstanceReqDetails, + User sdncModifierDetails, Component component) throws Exception { + return createComponentInstance(componentInstanceReqDetails, sdncModifierDetails, component.getUniqueId(), + component.getComponentType()); + } + + public static RestResponse createComponentInstance(ComponentInstanceReqDetails componentInstanceReqDetails, + User sdncModifierDetails, String componentId, ComponentTypeEnum componentType) throws Exception { + + return createComponentInstance(componentInstanceReqDetails, sdncModifierDetails, componentId, + ComponentTypeEnum.findParamByType(componentType)); + } + + public static RestResponse createComponentInstance(ComponentInstanceReqDetails componentInstanceReqDetails, + User sdncModifierDetails, String componentId, String componentType) throws Exception { + Config config = Utils.getConfig(); + String userId = sdncModifierDetails.getUserId(); + String serviceBodyJson = gson.toJson(componentInstanceReqDetails); + String url = String.format(Urls.CREATE_COMPONENT_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), + componentType, componentId); + RestResponse createResourceInstance = sendPost(url, serviceBodyJson, userId, acceptHeaderData); + if (createResourceInstance.getErrorCode().equals(BaseRestUtils.STATUS_CODE_CREATED)) { + String uniqueId = ResponseParser.getValueFromJsonResponse(createResourceInstance.getResponse(), "uniqueId"); + componentInstanceReqDetails.setUniqueId(uniqueId); + // Gson gson = new Gson(); + // ResourceInstanceReqDetails fromJson = + // gson.fromJson(createResourceInstance.getResponse(), + // ResourceInstanceReqDetails.class); + // componentInstanceReqDetails.setUniqueId(fromJson.getUniqueId()); + } + return createResourceInstance; + } + + public static RestResponse getComponentInstances(ComponentTypeEnum type, String componentId, User user) + throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), user.getUserId()); + + String url = String.format(Urls.GET_COMPONENT_INSTANCES, config.getCatalogBeHost(), config.getCatalogBePort(), + ComponentTypeEnum.findParamByType(type), componentId); + + RestResponse sendGetServerRequest = sendGet(url, user.getUserId(), headersMap); + + return sendGetServerRequest; + + } + + public static RestResponse deleteComponentInstance(User sdncModifierDetails, String componentId, + String resourceInstanceId, ComponentTypeEnum componentType) throws Exception { + + return deleteComponentInstance(sdncModifierDetails, componentId, resourceInstanceId, + ComponentTypeEnum.findParamByType(componentType)); + } + + public static RestResponse deleteComponentInstance(User sdncModifierDetails, String componentId, + String resourceInstanceId, String componentTypeString) throws Exception { + Config config = Utils.getConfig(); + String userId = sdncModifierDetails.getUserId(); + String url = String.format(Urls.DELETE_COMPONENT_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), + componentTypeString, componentId, resourceInstanceId); + RestResponse sendCreateUserRequest = sendDelete(url, userId); + return sendCreateUserRequest; + } + + public static RestResponse updateComponentInstance(ComponentInstanceReqDetails componentInstanceReqDetails, + User sdncModifierDetails, String componentId, ComponentTypeEnum componentType) throws IOException { + + Config config = Utils.getConfig(); + String userId = sdncModifierDetails.getUserId(); + String serviceBodyJson = gson.toJson(componentInstanceReqDetails); + String url = String.format(Urls.UPDATE_COMPONENT_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), + ComponentTypeEnum.findParamByType(componentType), componentId, + componentInstanceReqDetails.getUniqueId()); + RestResponse updateResourceInstance = sendPost(url, serviceBodyJson, userId, acceptHeaderData); + return updateResourceInstance; + } + + // TODO Tal CI for New API Multiple Instance Update + public static RestResponse updateMultipleComponentInstance( + List componentInstanceReqDetailsList, User sdncModifierDetails, + String componentId, ComponentTypeEnum componentType) throws IOException { + Config config = Utils.getConfig(); + String userId = sdncModifierDetails.getUserId(); + String serviceBodyJson = gson.toJson(componentInstanceReqDetailsList.toArray()); + String url = String.format(Urls.UPDATE_MULTIPLE_COMPONENT_INSTANCE, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(componentType), componentId); + RestResponse updateResourceInstance = sendPost(url, serviceBodyJson, userId, acceptHeaderData); + return updateResourceInstance; + } + + public static RestResponse associateInstances(RequirementCapabilityRelDef relation, User sdncModifierDetails, + String componentId, ComponentTypeEnum componentTypeEnum) throws IOException { + + Config config = Utils.getConfig(); + + String componentType = ""; + switch (componentTypeEnum) { + case RESOURCE: + componentType = ComponentTypeEnum.RESOURCE_PARAM_NAME; + break; + case SERVICE: + componentType = ComponentTypeEnum.SERVICE_PARAM_NAME; + break; + default: + break; + } + String serviceBodyJson = gson.toJson(relation); + String url = String.format(Urls.ASSOCIATE__RESOURCE_INSTANCE, config.getCatalogBeHost(), + config.getCatalogBePort(), componentType, componentId); + + RestResponse associateInstance = sendPost(url, serviceBodyJson, sdncModifierDetails.getUserId(), + acceptHeaderData); + return associateInstance; + + } + + public static RestResponse dissociateInstances(RequirementCapabilityRelDef relation, User sdncModifierDetails, + String componentId, ComponentTypeEnum componentTypeEnum) throws IOException { + + Config config = Utils.getConfig(); + + String componentType = ""; + switch (componentTypeEnum) { + case RESOURCE: + componentType = ComponentTypeEnum.RESOURCE_PARAM_NAME; + break; + case SERVICE: + componentType = ComponentTypeEnum.SERVICE_PARAM_NAME; + break; + default: + break; + } + String serviceBodyJson = gson.toJson(relation); + String url = String.format(Urls.DISSOCIATE__RESOURCE_INSTANCE, config.getCatalogBeHost(), + config.getCatalogBePort(), componentType, componentId); + + RestResponse associateInstance = sendPut(url, serviceBodyJson, sdncModifierDetails.getUserId(), + acceptHeaderData); + return associateInstance; + + } + + public static void checkComponentInstanceType(RestResponse response, String expectedComponentType) { + String actualComponentType = ResponseParser.getComponentTypeFromResponse(response); + assertTrue(expectedComponentType.equals(actualComponentType), + "Failed. expected: " + expectedComponentType + ", actual: " + actualComponentType + "/"); + } + + public static RestResponse updatePropertyValueOnResourceInstance(Component component, ComponentInstance instDetails, + User user, ComponentInstanceProperty updatedInstanceProperty) throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), user.getUserId()); + + String url = String.format(Urls.UPDATE_PROPERTY_TO_RESOURCE_INSTANCE, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(component.getComponentType()), + component.getUniqueId(), instDetails.getUniqueId()); + String body = gson.toJson(updatedInstanceProperty); + + RestResponse sendGetServerRequest = sendPost(url, body, user.getUserId(), acceptHeaderData); + return sendGetServerRequest; + + } + + public static RestResponse changeComponentInstanceVersion(Component container, + ComponentInstance componentInstanceToReplace, Component newInstance, User sdncModifierDetails) + throws Exception { + + return changeComponentInstanceVersion(container.getUniqueId(), componentInstanceToReplace, newInstance, + sdncModifierDetails, container.getComponentType()); + } + + public static RestResponse changeComponentInstanceVersion(String containerUID, + ComponentInstance componentInstanceToReplace, Component component, User sdncModifierDetails, + ComponentTypeEnum componentType) throws IOException { + + Config config = Utils.getConfig(); + String resourceUid = ("{\"componentUid\":\"" + component.getUniqueId() + "\"}"); + String url = String.format(Urls.CHANGE__RESOURCE_INSTANCE_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(componentType), containerUID, + componentInstanceToReplace.getUniqueId()); + RestResponse changeResourceInstanceVersion = sendPost(url, resourceUid, sdncModifierDetails.getUserId(), + acceptHeaderData); + + if (changeResourceInstanceVersion.getErrorCode() == 200 + || changeResourceInstanceVersion.getErrorCode() == 201) { + Gson gson = new Gson(); + // ResourceInstanceReqDetails + // convertResourceInstanceResponseToJavaObject = + // ResponseParser.convertResourceInstanceResponseToJavaObject(createResourceInstance.getResponse()); + ComponentInstanceReqDetails fromJson = gson.fromJson(changeResourceInstanceVersion.getResponse(), + ComponentInstanceReqDetails.class); + + componentInstanceToReplace.setUniqueId(fromJson.getUniqueId()); + + } + + return changeResourceInstanceVersion; + + } + + public static RestResponse changeComponentInstanceVersion(String componentUniqueId, + String serviceInstanceToReplaceUniqueId, String serviceUniqueId, User sdncModifierDetails, + ComponentTypeEnum componentType) throws IOException { + Config config = Utils.getConfig(); + String resourceUid = ("{\"componentUid\":\"" + serviceUniqueId + "\"}"); + String url = String.format(Urls.CHANGE__RESOURCE_INSTANCE_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(componentType), componentUniqueId, + serviceInstanceToReplaceUniqueId); + RestResponse changeResourceInstanceVersion = sendPost(url, resourceUid, sdncModifierDetails.getUserId(), + acceptHeaderData); + return changeResourceInstanceVersion; + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentRestUtils.java new file mode 100644 index 0000000000..dcebe4afa8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ComponentRestUtils.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ComponentReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +public class ComponentRestUtils extends BaseRestUtils { + public static RestResponse getComponentRequirmentsCapabilities(User sdncModifierDetails, + ComponentReqDetails componentReqDetails) throws IOException { + Config config = Utils.getConfig(); + ComponentTypeEnum componentType = null; + if (componentReqDetails instanceof ResourceReqDetails) { + componentType = ComponentTypeEnum.RESOURCE; + } else if (componentReqDetails instanceof ServiceReqDetails) { + componentType = ComponentTypeEnum.SERVICE; + } else if (componentReqDetails instanceof ProductReqDetails) { + componentType = ComponentTypeEnum.PRODUCT; + } + String url = String.format(Urls.GET_COMPONENT_REQUIRMENTS_CAPABILITIES, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(componentType), + componentReqDetails.getUniqueId()); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static CapReqDef getAndParseComponentRequirmentsCapabilities(User user, ComponentReqDetails componentDetails) + throws IOException { + RestResponse getComponentReqCap = getComponentRequirmentsCapabilities(user, componentDetails); + ResourceRestUtils.checkSuccess(getComponentReqCap); + CapReqDef capReqDef = ResponseParser.parseToObject(getComponentReqCap.getResponse(), CapReqDef.class); + return capReqDef; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ConsumerRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ConsumerRestUtils.java new file mode 100644 index 0000000000..1b93d8d778 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ConsumerRestUtils.java @@ -0,0 +1,206 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertEquals; + +import java.util.Map; + +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +import com.google.gson.Gson; + +public class ConsumerRestUtils extends BaseRestUtils { + + public static final int STATUS_CODE_SUCCESS = 200; + public static final int STATUS_CODE_CREATED = 201; + public static final int STATUS_CODE_DELETE = 204; + public static final int STATUS_CODE_NOT_FOUND = 404; + Utils utils = new Utils(); + private static Long expectedsLastupdatedtime; + private static Long expectedLastAuthenticationTime; + + public static RestResponse createConsumer(ConsumerDataDefinition consumerDataDefinition, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort()); + + String userId = sdncModifierDetails.getUserId(); + + Map headersMap = prepareHeadersMap(userId); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(consumerDataDefinition); + + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse createConsumerResponse = http.httpSendPost(url, userBodyJson, headersMap); + if (createConsumerResponse.getErrorCode() == STATUS_CODE_CREATED) { + ConsumerDataDefinition getConsumerDataObject = parseComsumerResp(createConsumerResponse); + consumerDataDefinition.setConsumerDetailsLastupdatedtime(getConsumerDataObject.getConsumerDetailsLastupdatedtime()); + consumerDataDefinition.setConsumerLastAuthenticationTime(getConsumerDataObject.getConsumerLastAuthenticationTime()); + consumerDataDefinition.setLastModfierAtuid(getConsumerDataObject.getLastModfierAtuid()); + } + return createConsumerResponse; + } + + public static RestResponse createConsumerHttpCspAtuUidIsMissing(ConsumerDataDefinition consumerDataDefinition, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort()); + + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + headersMap.remove("USER_ID"); + Gson gson = new Gson(); + String userBodyJson = gson.toJson(consumerDataDefinition); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse createConsumerResponse = http.httpSendPost(url, userBodyJson, headersMap); + if (createConsumerResponse.getErrorCode() == STATUS_CODE_CREATED) { + ConsumerDataDefinition getConsumerDataObject = parseComsumerResp(createConsumerResponse); + consumerDataDefinition.setConsumerDetailsLastupdatedtime(getConsumerDataObject.getConsumerDetailsLastupdatedtime()); + consumerDataDefinition.setConsumerLastAuthenticationTime(getConsumerDataObject.getConsumerLastAuthenticationTime()); + consumerDataDefinition.setLastModfierAtuid(getConsumerDataObject.getLastModfierAtuid()); + } + return createConsumerResponse; + } + + public static RestResponse deleteConsumerHttpCspAtuUidIsMissing(ConsumerDataDefinition consumerDataDefinition, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort(), consumerDataDefinition.getConsumerName()); + + String userId = sdncModifierDetails.getUserId(); + Map headersMap = prepareHeadersMap(userId); + headersMap.remove("USER_ID"); + Gson gson = new Gson(); + String userBodyJson = gson.toJson(consumerDataDefinition); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse deleteConsumerResponse = http.httpSendDelete(url, headersMap); + return deleteConsumerResponse; + } + + public static ConsumerDataDefinition parseComsumerResp(RestResponse restResponse) throws Exception { + + String bodyToParse = restResponse.getResponse(); + ObjectMapper mapper = new ObjectMapper(); + try { + ConsumerDataDefinition component = mapper.readValue(bodyToParse, ConsumerDataDefinition.class); + return component; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + public static RestResponse deleteConsumer(ConsumerDataDefinition consumerDataDefinition, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort(), consumerDataDefinition.getConsumerName()); + + String userId = sdncModifierDetails.getUserId(); + + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + RestResponse deleteConsumerResponse = http.httpSendDelete(url, headersMap); + return deleteConsumerResponse; + } + + public static RestResponse getConsumer(ConsumerDataDefinition consumerDataDefinition, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_CONSUMER, config.getCatalogBeHost(), config.getCatalogBePort(), consumerDataDefinition.getConsumerName()); + + String userId = sdncModifierDetails.getUserId(); + + Map headersMap = prepareHeadersMap(userId); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + RestResponse getConsumerResponse = http.httpSendGet(url, headersMap); + return getConsumerResponse; + } + + public static void validateConsumerReqVsResp(ConsumerDataDefinition consumerDefinition, ConsumerDataDefinition getConsumerDataObject) { + + String expected; + + expected = consumerDefinition.getConsumerName(); + assertEquals("consumer name - ", expected, getConsumerDataObject.getConsumerName()); + + expected = consumerDefinition.getConsumerPassword().toLowerCase(); + assertEquals("consumer password - ", expected, getConsumerDataObject.getConsumerPassword()); + + expected = consumerDefinition.getLastModfierAtuid(); + assertEquals("consumer Last Modfier Atuid - ", expected, getConsumerDataObject.getLastModfierAtuid()); + + expected = consumerDefinition.getConsumerSalt(); + assertEquals("consumer Salt - ", expected, getConsumerDataObject.getConsumerSalt()); + + expectedsLastupdatedtime = consumerDefinition.getConsumerDetailsLastupdatedtime(); + assertEquals("consumer Last updated time - ", expectedsLastupdatedtime, getConsumerDataObject.getConsumerDetailsLastupdatedtime()); + + expectedLastAuthenticationTime = consumerDefinition.getConsumerLastAuthenticationTime(); + assertEquals("consumer Last authentication time - ", expectedLastAuthenticationTime, getConsumerDataObject.getConsumerLastAuthenticationTime()); + } + + ///// New + public enum EcompConsumerAuditJsonKeysEnum { + ACTION("ACTION"), MODIFIER("MODIFIER"), ECOMP_USER("ECOMP_USER"), STATUS("STATUS"), DESC("DESCRIPTION"); + private String auditJsonKeyName; + + private EcompConsumerAuditJsonKeysEnum(String auditJsonKeyName) { + this.auditJsonKeyName = auditJsonKeyName; + } + + public String getAuditJsonKeyName() { + return auditJsonKeyName.toLowerCase(); + } + } + + /* + * protected void resourceArtifatAuditSuccess(String action, ArtifactReqDetails artifact, ResourceReqDetails resourceDetails , User user) throws Exception { ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = + * Convertor.constructFieldsForAuditValidation(resourceDetails, resourceDetails.getVersion(), user); String auditAction = action; expectedResourceAuditJavaObject.setAction(auditAction); expectedResourceAuditJavaObject.setPrevState(""); + * expectedResourceAuditJavaObject.setPrevVersion(""); expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum. NOT_CERTIFIED_CHECKOUT).toString()); expectedResourceAuditJavaObject.setStatus("200"); + * expectedResourceAuditJavaObject.setDesc("OK"); expectedResourceAuditJavaObject.setArtifactName(artifact.getArtifactName( )); AuditUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null); } + */ + + /* + * protected void resourceArtifatValidateAuditWithErrorMessage(String actionStatus, ResourceReqDetails resourceDetails, String auditAction, String setCurrState, Object ... variables)throws Exception { ErrorInfo errorInfo = + * utils.parseYaml(actionStatus); ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = Convertor.constructFieldsForAuditValidation(resourceDetails, resourceDetails.getVersion(), sdncUserDetails); + * expectedResourceAuditJavaObject.setAction(auditAction); expectedResourceAuditJavaObject.setPrevState(""); expectedResourceAuditJavaObject.setPrevVersion(""); expectedResourceAuditJavaObject.setCurrState(setCurrState); + * expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()) ; expectedResourceAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables) ); expectedResourceAuditJavaObject.setArtifactName(""); + * AuditUtils.validateAudit(expectedResourceAuditJavaObject, auditAction, null); } + */ +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/EcompUserRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/EcompUserRestUtils.java new file mode 100644 index 0000000000..a71711dde6 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/EcompUserRestUtils.java @@ -0,0 +1,255 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.run.StartTest; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +public class EcompUserRestUtils extends BaseRestUtils { + + static Gson gson = new Gson(); + + static Logger logger = LoggerFactory.getLogger(UserRestUtils.class.getName()); + static String contentTypeHeaderData = "application/json"; + static String acceptHeaderDate = "application/json"; + static String ecompUsername = "12345"; + static String ecompPassword = "12345"; + + public EcompUserRestUtils() { + super(); + + StartTest.enableLogger(); + } + + public static RestResponse pushUser(EcompUser ecompUser) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + String userBodyJson = gson.toJson(ecompUser); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_PUSH_USER, config.getCatalogBeHost(), config.getCatalogBePort()); + + logger.debug("Send POST request to create user: {}", url); + logger.debug("User body: {}", userBodyJson); + logger.debug("User headers: {}", headersMap); + + RestResponse sendPushUserResponse = http.httpSendPost(url, userBodyJson, headersMap); + + return sendPushUserResponse; + } + + /* + * loginId - equals to userId + */ + public static RestResponse editUser(String loginId, EcompUser ecompUser) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + String userBodyJson = gson.toJson(ecompUser); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_EDIT_USER, config.getCatalogBeHost(), config.getCatalogBePort(), loginId); + + logger.debug("Send POST request to edit user: {}", url); + logger.debug("User body: {}", userBodyJson); + logger.debug("User headers: {}", headersMap); + + RestResponse sendEditUserResponse = http.httpSendPost(url, userBodyJson, headersMap); + + return sendEditUserResponse; + } + + /* + * loginId - equals to userId + */ + public static RestResponse getUser(String loginId) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_GET_USER, config.getCatalogBeHost(), config.getCatalogBePort(), loginId); + + logger.debug("Send GET request to get user: {}", url); + logger.debug("User headers: {}", headersMap); + + RestResponse sendGetUserRequest = http.httpSendGet(url, headersMap); + + return sendGetUserRequest; + } + + public static RestResponse getAllUsers() throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_GET_ALL_USERS, config.getCatalogBeHost(), config.getCatalogBePort()); + + logger.debug("Send POST request to get all users: {}", url); + logger.debug("User headers: {}" , headersMap); + + RestResponse sendGetAllUsersRequest = http.httpSendGet(url, headersMap); + + return sendGetAllUsersRequest; + } + + public static RestResponse getAllAvailableRoles() throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_GET_ALL_AVAILABLE_ROLES, config.getCatalogBeHost(), + config.getCatalogBePort()); + + logger.debug("Send GET request to get all available roles: {}", url); + logger.debug("User headers: {}", headersMap); + + RestResponse sendUpdateUserRequest = http.httpSendGet(url, headersMap); + + return sendUpdateUserRequest; + } + + /* + * loginId - equals to userId + */ + public static RestResponse pushUserRoles(String loginId, List roles) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + String roleBodyJson = gson.toJson(roles); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_PUSH_USER_ROLES, config.getCatalogBeHost(), config.getCatalogBePort(), + loginId); + + logger.debug("Send POST request to push user role: {}", url); + logger.debug("Roles body: {}", roleBodyJson); + logger.debug("Request headers: {}", headersMap); + + RestResponse sendpushUserRolesResponse = http.httpSendPost(url, roleBodyJson, headersMap); + + return sendpushUserRolesResponse; + } + + /* + * loginId - equals to userId + */ + public static RestResponse getUserRoles(String loginId) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.ECOMP_USERNAME.getValue(), ecompUsername); + headersMap.put(HttpHeaderEnum.ECOMP_PASSWORD.getValue(), ecompPassword); + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.ECOMP_GET_USER_ROLES, config.getCatalogBeHost(), config.getCatalogBePort(), + loginId); + + logger.debug("Send GET request to get user roles: {}", url); + logger.debug("User headers: {}", headersMap); + + RestResponse sendGetUserRolesRequest = http.httpSendGet(url, headersMap); + + return sendGetUserRolesRequest; + } + + // TODO !!!!!!!!!!!!!! + /* + * Ask Eli if implementation of users is needed DELETE ECOMP USER + */ + + /* + * public static void main(String[] args) { EcompUser ecompUser = new + * EcompUser(); ecompUser.setFirstName("Test"); + * ecompUser.setLastName("Testovich"); + * ecompUser.setEmail("ttes@intl.sdc.com"); ecompUser.setLoginId("tt0004"); + * ecompUser.setActive(true); + * + * EcompRole roleToUpdate = new EcompRole(); roleToUpdate.setId(new + * Long(6)); roleToUpdate.setName("PRODUCT_STRATEGIST"); List + * listOfRoles = new LinkedList<>(); listOfRoles.add(roleToUpdate); + * + * try { + * System.out.println("\n-----------------------------\n Testing pushUser"); + * System.out.println(pushUser(ecompUser)); + * System.out.println("\n-----------------------------\n Testing editUser"); + * // System.out.println(editUser("tt0001", ecompUser)); + * System.out.println("\n-----------------------------\n Testing getUser"); + * // System.out.println(getUser(ecompUser.getLoginId())); System.out. + * println("\n-----------------------------\n Testing getAllUsers"); // + * System.out.println(getAllUsers()); System.out. + * println("\n-----------------------------\n Testing getAllAvailableRoles" + * ); // System.out.println(getAllAvailableRoles().toString()); System.out. + * println("\n-----------------------------\n Testing pushUserRoles"); // + * System.out.println(pushUserRoles("tt0001", listOfRoles)); System.out. + * println("\n-----------------------------\n Testing getUserRoles"); // + * System.out.println(getUserRoles("tt0001")); } catch (IOException e) { // + * TODO Auto-generated catch block e.printStackTrace(); } } + */ +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/GroupRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/GroupRestUtils.java new file mode 100644 index 0000000000..d79c8e002c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/GroupRestUtils.java @@ -0,0 +1,61 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; + +import com.google.gson.Gson; + +public class GroupRestUtils extends BaseRestUtils { + public static String acceptHeaderDate = "application/json"; + static Config config = Config.instance(); + public static Gson gson = new Gson(); + + public static RestResponse getGroupById(Component component, String groupId, User user) throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), user.getUserId()); + + String url = String.format(Urls.GET_GROUP_BY_ID, config.getCatalogBeHost(), config.getCatalogBePort(), + ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId(), groupId); + + RestResponse sendGetServerRequest = sendGet(url, user.getUserId(), headersMap); + + return sendGetServerRequest; + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ImportRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ImportRestUtils.java new file mode 100644 index 0000000000..3ce48962fd --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ImportRestUtils.java @@ -0,0 +1,339 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.nio.file.FileSystems; +import java.nio.file.Files; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.ContentType; +import org.apache.http.entity.mime.MultipartEntityBuilder; +import org.apache.http.entity.mime.content.FileBody; +import org.apache.http.entity.mime.content.StringBody; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.codehaus.jettison.json.JSONException; +import org.openecomp.sdc.be.dao.rest.HttpRestClient; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.ImportTestTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.openecomp.sdc.common.rest.api.RestResponseAsByteArray; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ImportRestUtils extends BaseRestUtils { + + private static Logger log = LoggerFactory.getLogger(ImportRestUtils.class.getName()); + private static Properties downloadCsarHeaders = new Properties(); + + static { + downloadCsarHeaders.put("Accept", "application/octet-stream"); + } + + @SuppressWarnings("unused") + private static Integer importNormativeResource(NormativeTypesEnum resource, UserRoleEnum userRole) throws IOException { + Config config = Utils.getConfig(); + CloseableHttpResponse response = null; + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getTestZipFile(resource.getFolderName()))); + mpBuilder.addPart("resourceMetadata", new StringBody(getTestJsonStringOfFile(resource.getFolderName(), resource.getFolderName() + ".json"), ContentType.APPLICATION_JSON)); + + String url = String.format(Urls.IMPORT_RESOURCE_NORMATIVE, config.getCatalogBeHost(), config.getCatalogBePort()); + + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + httpPost.addHeader("USER_ID", userRole.getUserId()); + httpPost.setEntity(mpBuilder.build()); + response = client.execute(httpPost); + return response.getStatusLine().getStatusCode(); + } finally { + closeResponse(response); + closeHttpClient(client); + + } + } + + public static RestResponse importResourceByName(ResourceReqDetails resourceDetails, User importer) throws Exception { + Config config = Utils.getConfig(); + CloseableHttpResponse response = null; + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getTestZipFile(resourceDetails.getName()))); + mpBuilder.addPart("resourceMetadata", new StringBody(getTestJsonStringOfFile(resourceDetails.getName(), resourceDetails.getName() + ".json"), ContentType.APPLICATION_JSON)); + + String url = String.format(Urls.IMPORT_RESOURCE_NORMATIVE, config.getCatalogBeHost(), config.getCatalogBePort()); + + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + RestResponse restResponse = new RestResponse(); + httpPost.addHeader("USER_ID", importer.getUserId()); + httpPost.setEntity(mpBuilder.build()); + response = client.execute(httpPost); + HttpEntity entity = response.getEntity(); + String responseBody = null; + if (entity != null) { + InputStream instream = entity.getContent(); + StringWriter writer = new StringWriter(); + IOUtils.copy(instream, writer); + responseBody = writer.toString(); + try { + + } finally { + instream.close(); + } + } + + restResponse.setErrorCode(response.getStatusLine().getStatusCode()); + restResponse.setResponse(responseBody); + + if (restResponse.getErrorCode() == STATUS_CODE_CREATED) { + resourceDetails.setUUID(ResponseParser.getUuidFromResponse(restResponse)); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(restResponse)); + resourceDetails.setVersion(ResponseParser.getVersionFromResponse(restResponse)); + resourceDetails.setCreatorUserId(importer.getUserId()); + resourceDetails.setCreatorFullName(importer.getFullName()); + } + + return restResponse; + + } finally { + closeResponse(response); + closeHttpClient(client); + + } + + } + + public static RestResponse importNewResourceByName(String resourceName, UserRoleEnum userRole) throws IOException { + Config config = Utils.getConfig(); + + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getTestZipFile(resourceName))); + mpBuilder.addPart("resourceMetadata", new StringBody(getTestJsonStringOfFile(resourceName, resourceName + ".json"), ContentType.APPLICATION_JSON)); + HttpEntity requestEntity = mpBuilder.build(); + String url = String.format(Urls.IMPORT_USER_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + Map headers = new HashMap(); + headers.put("USER_ID", userRole.getUserId()); + + return HttpRequest.sendHttpPostWithEntity(requestEntity, url, headers); + } + + public static RestResponse importNormativeResourceByName(String resourceName, UserRoleEnum userRole) throws IOException { + Config config = Utils.getConfig(); + + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getTestZipFile(resourceName))); + mpBuilder.addPart("resourceMetadata", new StringBody(getTestJsonStringOfFile(resourceName, resourceName + ".json"), ContentType.APPLICATION_JSON)); + HttpEntity requestEntity = mpBuilder.build(); + String url = String.format(Urls.IMPORT_RESOURCE_NORMATIVE, config.getCatalogBeHost(), config.getCatalogBePort()); + Map headers = new HashMap(); + headers.put("USER_ID", userRole.getUserId()); + + return HttpRequest.sendHttpPostWithEntity(requestEntity, url, headers); + } + + public static RestResponse importTestResource(ImportTestTypesEnum resource, UserRoleEnum userRole) throws IOException { + Config config = Utils.getConfig(); + CloseableHttpResponse response = null; + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("resourceZip", new FileBody(getTestZipFile(resource.getFolderName()))); + mpBuilder.addPart("resourceMetadata", new StringBody(getTestJsonStringOfFile(resource.getFolderName(), resource.getFolderName() + ".json"), ContentType.APPLICATION_JSON)); + + String url = String.format(Urls.IMPORT_RESOURCE_NORMATIVE, config.getCatalogBeHost(), config.getCatalogBePort()); + + CloseableHttpClient client = HttpClients.createDefault(); + try { + HttpPost httpPost = new HttpPost(url); + RestResponse restResponse = new RestResponse(); + httpPost.addHeader("USER_ID", UserRoleEnum.ADMIN.getUserId()); + httpPost.setEntity(mpBuilder.build()); + response = client.execute(httpPost); + HttpEntity entity = response.getEntity(); + String responseBody = null; + if (entity != null) { + InputStream instream = entity.getContent(); + StringWriter writer = new StringWriter(); + IOUtils.copy(instream, writer); + responseBody = writer.toString(); + try { + + } finally { + instream.close(); + } + } + + restResponse.setErrorCode(response.getStatusLine().getStatusCode()); + // restResponse.setResponse(response.getEntity().toString()); + restResponse.setResponse(responseBody); + return restResponse; + } finally { + closeResponse(response); + closeHttpClient(client); + + } + } + + public static Boolean removeNormativeTypeResource(NormativeTypesEnum current) throws FileNotFoundException, IOException, ClientProtocolException { + User user = new User(UserRoleEnum.ADMIN.getFirstName(), UserRoleEnum.ADMIN.getLastName(), UserRoleEnum.ADMIN.getUserId(), null, null, null); + RestResponse deleteResponse = ResourceRestUtils.deleteResourceByNameAndVersion(user, current.getNormativeName(), "1.0"); + if (deleteResponse.getErrorCode() == 200) { + return true; + } + return false; + } + + public static void validateImportTestTypesResp(ImportTestTypesEnum currResource, RestResponse restResponse) throws IOException, JSONException { + + // assertTrue( status != ResourceUtils.STATUS_CODE_IMPORT_SUCCESS ); + + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(currResource.getActionStatus().name()); + + assertNotNull("check response object is not null after create service", restResponse); + assertNotNull("check error code exists in response after create service", restResponse.getErrorCode()); + assertEquals("Check response code after create service", errorInfo.getCode(), restResponse.getErrorCode()); + + // validate create service response vs actual + List variables = (currResource.getErrorParams() != null ? currResource.getErrorParams() : new ArrayList()); + if (restResponse.getErrorCode() != 200) { + ErrorValidationUtils.checkBodyResponseOnError(currResource.getActionStatus().name(), variables, restResponse.getResponse()); + } + } + + private static String getTestJsonStringOfFile(String folderName, String fileName) throws IOException { + // String sourceDir = "src/test/resources/CI/importResourceTests"; + Config config = Utils.getConfig(); + String sourceDir = config.getImportResourceTestsConfigDir(); + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + folderName, fileName); + byte[] fileContent = Files.readAllBytes(filePath); + String content = new String(fileContent); + return content; + } + + private static File getTestZipFile(String elementName) throws IOException { + Config config = Utils.getConfig(); + String sourceDir = config.getImportResourceTestsConfigDir(); + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + elementName, "normative-types-new-" + elementName + ".zip"); + return filePath.toFile(); + } + + private static void closeHttpClient(CloseableHttpClient client) { + try { + if (client != null) { + client.close(); + } + } catch (IOException e) { + log.debug("failed to close client or response: ", e); + } + } + + private static void closeResponse(CloseableHttpResponse response) { + try { + if (response != null) { + response.close(); + } + } catch (IOException e) { + log.debug("failed to close client or response: {}", e); + } + } + + public static RestResponseAsByteArray getCsar(String csarUid, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_CSAR_USING_SIMULATOR, config.getCatalogBeHost(), config.getCatalogBePort(), csarUid); + + String userId = sdncModifierDetails.getUserId(); + + Map headersMap = prepareHeadersMap(userId); + + // Gson gson = new Gson(); + // String userBodyJson = gson.toJson(resourceDetails); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + + HttpRestClient httpRestClient = new HttpRestClient(); + + for (Map.Entry mapEntry : headersMap.entrySet()) { + + downloadCsarHeaders.put(mapEntry.getKey(), mapEntry.getValue()); + } + RestResponseAsByteArray doGetAsByteArray = httpRestClient.doGetAsByteArray(url, downloadCsarHeaders); + // RestResponse getCsar = http.httpSendGet(url, headersMap); + + return doGetAsByteArray; + + } + + private static File getGroupTypeZipFile(String elementName) throws IOException { + Config config = Utils.getConfig(); + String sourceDir = config.getImportResourceTestsConfigDir(); + sourceDir += File.separator + ".." + File.separator + "importTypesTest" + File.separator; + java.nio.file.Path filePath = FileSystems.getDefault().getPath(sourceDir + File.separator + elementName, elementName + ".zip"); + return filePath.toFile(); + } + + public static RestResponse importNewGroupTypeByName(String groupTypeName, UserRoleEnum userRole) throws IOException { + Config config = Utils.getConfig(); + + MultipartEntityBuilder mpBuilder = MultipartEntityBuilder.create(); + + mpBuilder.addPart("groupTypesZip", new FileBody(getGroupTypeZipFile(groupTypeName))); + HttpEntity requestEntity = mpBuilder.build(); + String url = String.format(Urls.IMPORT_GROUP_TYPE, config.getCatalogBeHost(), config.getCatalogBePort()); + Map headers = new HashMap(); + headers.put("USER_ID", userRole.getUserId()); + + return HttpRequest.sendHttpPostWithEntity(requestEntity, url, headers); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/InputsRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/InputsRestUtils.java new file mode 100644 index 0000000000..de7be077d1 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/InputsRestUtils.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +/** + * RestUtils for inputs + * + * @author il0695 + * + */ +public class InputsRestUtils extends BaseRestUtils { + + @SuppressWarnings("unused") + private static Logger logger = LoggerFactory.getLogger(InputsRestUtils.class.getName()); + + /** + * Add inputs to service + * + * @param component + * @param inputs + * @param userRole + * @return {@link org.openecomp.sdc.ci.tests.datatypes.http.RestResponse} + * @throws Exception + */ + public static RestResponse addInput(Component component, ComponentInstInputsMap inputs, UserRoleEnum userRole) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.ADD_INPUTS, config.getCatalogBeHost(), config.getCatalogBePort(), ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUniqueId()); + String json = new Gson().toJson(inputs); + return sendPost(url, json, userRole.getUserId(), acceptHeaderData); + } + + /** + * Get all Component inputs + * + * @param component + * @return {@link org.openecomp.sdc.ci.tests.datatypes.http.RestResponse} + * @throws Exception + */ + public static RestResponse getComponentInputs(Component component) throws Exception { + Config config = Utils.getConfig(); + //services/{componentId}/inputs + String url = String.format(Urls.GET_COMPONENT_INPUTS, config.getCatalogBeHost(), config.getCatalogBePort(), component.getUniqueId()); + return sendGet(url, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + } + + /** + * Get all inputs of component instance + * + * @param parentComponent + * @param componentInstance + * @return {@link org.openecomp.sdc.ci.tests.datatypes.http.RestResponse} + * @throws Exception + */ + public static RestResponse getComponentInstanceInputs(Component parentComponent, ComponentInstance componentInstance) throws Exception { + Config config = Utils.getConfig(); + //{componentType}/{componentId}/componentInstances/{instanceId}/{originComonentUid}/inputs + String url = String.format(Urls.GET_COMPONENT_INSTANCE_INPUTS, config.getCatalogBeHost(), config.getCatalogBePort(), ComponentTypeEnum.findParamByType(parentComponent.getComponentType()), parentComponent.getUniqueId(), componentInstance.getUniqueId(), componentInstance.getComponentUid()); + return sendGet(url, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + } + + /** + * Delete input from component + * + * @param parentComponent + * @param inputId + * @return {@link org.openecomp.sdc.ci.tests.datatypes.http.RestResponse} + * @throws Exception + */ + public static RestResponse deleteInputFromComponent(Component parentComponent, String inputId) throws Exception { + return deleteInputFromComponent(ComponentTypeEnum.findParamByType(parentComponent.getComponentType()), parentComponent.getUniqueId(), inputId); + } + + /** + * Delete input from component + * + * @param componentType + * @param componentId + * @param inputUniqueId + * @return {@link org.openecomp.sdc.ci.tests.datatypes.http.RestResponse} + * @throws Exception + */ + public static RestResponse deleteInputFromComponent(String componentType, String componentId, String inputUniqueId) throws Exception { + Config config = Utils.getConfig(); + //{componentType}/{componentId}/delete/{inputId}/input + String url = String.format(Urls.DELETE_INPUT_BY_ID, config.getCatalogBeHost(), config.getCatalogBePort(), componentType, componentId, inputUniqueId); + return sendDelete(url, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER).getUserId()); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/LifecycleRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/LifecycleRestUtils.java new file mode 100644 index 0000000000..34651c1b7a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/LifecycleRestUtils.java @@ -0,0 +1,360 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.json.simple.JSONObject; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class LifecycleRestUtils extends BaseRestUtils { + private static Logger logger = LoggerFactory.getLogger(LifecycleRestUtils.class.getName()); + public static final String COMMENT = "comment"; + + public static RestResponse changeResourceState(ResourceReqDetails resourceDetails, User sdncModifierDetails, + String version, LifeCycleStatesEnum LifeCycleStatesEnum) throws IOException { + return changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum, + createLifecycleCommentJson(COMMENT)); + } + + public static RestResponse changeResourceState(ResourceReqDetails resourceDetails, User sdncModifierDetails, + String version, LifeCycleStatesEnum LifeCycleStatesEnum, String LifecycleChangeInfo) throws IOException { + + return changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum, LifecycleChangeInfo); + + } + + public static RestResponse changeResourceState(ResourceReqDetails resourceDetails, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum) throws IOException { + + return changeResourceState(resourceDetails, sdncModifierDetails, LifeCycleStatesEnum, + createLifecycleCommentJson(COMMENT)); + + } + + public static RestResponse changeResourceState(ResourceReqDetails resourceDetails, String modifierUserId, + LifeCycleStatesEnum LifeCycleStatesEnum) throws IOException { + User user = new User(); + user.setUserId(modifierUserId); + return changeResourceState(resourceDetails, user, LifeCycleStatesEnum, createLifecycleCommentJson(COMMENT)); + } + + private static RestResponse changeResourceState(ResourceReqDetails resourceDetails, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum, String LifecycleChangeInfo) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.CHANGE_RESOURCE_LIFECYCLE_STATE, config.getCatalogBeHost(), + config.getCatalogBePort(), resourceDetails.getUniqueId(), LifeCycleStatesEnum); + // System.out.println("url: " + url); + + RestResponse LifeCycleStatesEnumResourceResponse = sendPost(url, LifecycleChangeInfo, + sdncModifierDetails.getUserId(), acceptHeaderData); + if (LifeCycleStatesEnumResourceResponse.getErrorCode() == STATUS_CODE_SUCCESS) { + String stateFromJsonResponse = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumResourceResponse.getResponse(), "lifecycleState"); + resourceDetails.setVersion(ResponseParser.getVersionFromResponse(LifeCycleStatesEnumResourceResponse)); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(LifeCycleStatesEnumResourceResponse)); + if (stateFromJsonResponse != null) { + resourceDetails.setLifecycleState(LifecycleStateEnum.valueOf(stateFromJsonResponse)); + } + } + return LifeCycleStatesEnumResourceResponse; + } + + public static RestResponse changeServiceState(ServiceReqDetails serviceDetails, User sdncModifierDetails, + String version, LifeCycleStatesEnum LifeCycleStatesEnum) throws Exception { + { + return changeServiceState(serviceDetails, sdncModifierDetails, version, LifeCycleStatesEnum, + createLifecycleCommentJson(COMMENT)); + } + } + + public static RestResponse changeServiceState(ServiceReqDetails serviceDetails, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum) throws Exception { + { + return changeServiceState(serviceDetails, sdncModifierDetails, null, LifeCycleStatesEnum, + createLifecycleCommentJson(COMMENT)); + } + } + + public static RestResponse changeServiceState(ServiceReqDetails serviceDetails, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum, String lifecycleChangeInfo) throws Exception { + { + return changeServiceState(serviceDetails, sdncModifierDetails, null, LifeCycleStatesEnum, + lifecycleChangeInfo); + } + } + + public static RestResponse changeServiceState(ServiceReqDetails serviceDetails, User sdncModifierDetails, + String version, LifeCycleStatesEnum LifeCycleStatesEnum, String lifecycleChangeInfo) throws Exception { + + Config config = Utils.getConfig(); + Map headersMap = prepareHeadersMap(sdncModifierDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CHANGE_SERVICE_LIFECYCLE_STATE, config.getCatalogBeHost(), + config.getCatalogBePort(), serviceDetails.getUniqueId(), LifeCycleStatesEnum); + // System.out.println("url: " + url); + RestResponse LifeCycleStatesEnumServiceResponse = http.httpSendPost(url, lifecycleChangeInfo, headersMap); + if (LifeCycleStatesEnumServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS) { + String serviceUniqueId = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "uniqueId"); + serviceDetails.setUniqueId(serviceUniqueId); + String serviceVersion = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "version"); + serviceDetails.setVersion(serviceVersion); + String stateFromJsonResponse = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "lifecycleState"); + serviceDetails.setLifecycleState(LifecycleStateEnum.valueOf(stateFromJsonResponse)); + } + return LifeCycleStatesEnumServiceResponse; + } + + public static RestResponse changeProductState(Product product, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum, String lifecycleChangeInfo) throws Exception { + { + return _changeProductState(product, sdncModifierDetails, LifeCycleStatesEnum, lifecycleChangeInfo); + } + } + + public static RestResponse changeProductState(Product product, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum) throws Exception { + { + return _changeProductState(product, sdncModifierDetails, LifeCycleStatesEnum, COMMENT); + } + } + + public static RestResponse changeProductState(ProductReqDetails productDetails, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CHANGE_PRODUCT_LIFECYCLE_STATE, config.getCatalogBeHost(), + config.getCatalogBePort(), productDetails.getUniqueId(), LifeCycleStatesEnum); + RestResponse LifeCycleStatesEnumServiceResponse = sendPost(url, createLifecycleCommentJson(COMMENT), + sdncModifierDetails.getUserId(), acceptHeaderData); + if (LifeCycleStatesEnumServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS) { + String productUniqueId = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "uniqueId"); + productDetails.setUniqueId(productUniqueId); + String productVersion = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "version"); + productDetails.setVersion(productVersion); + String newLifecycleState = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "lifecycleState"); + productDetails.setLifecycleState(LifecycleStateEnum.valueOf(newLifecycleState)); + } + return LifeCycleStatesEnumServiceResponse; + + } + + public static RestResponse changeComponentState(Component component, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CHANGE_COMPONENT_LIFECYCLE_STATE, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(component.getComponentType()), + component.getUniqueId(), LifeCycleStatesEnum); + RestResponse LifeCycleStatesEnumServiceResponse = sendPost(url, createLifecycleCommentJson(COMMENT), + sdncModifierDetails.getUserId(), acceptHeaderData); + if (LifeCycleStatesEnumServiceResponse.getErrorCode() == STATUS_CODE_SUCCESS) { + String productUniqueId = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "uniqueId"); + component.setUniqueId(productUniqueId); + String productVersion = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "version"); + component.setVersion(productVersion); + String newLifecycleState = ResponseParser + .getValueFromJsonResponse(LifeCycleStatesEnumServiceResponse.getResponse(), "lifecycleState"); + component.setLifecycleState(LifecycleStateEnum.valueOf(newLifecycleState)); + } + return LifeCycleStatesEnumServiceResponse; + + } + + public static RestResponse certifyResource(ResourceReqDetails resourceDetails) throws Exception { + RestResponse restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + // if (restResponseResource.getErrorCode() == 200){ + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + // }else + // return restResponseResource; + User testerDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + if (restResponseResource.getErrorCode() == 200) { + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, testerDetails, + LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponseResource; + if (restResponseResource.getErrorCode() == 200) { + restResponseResource = LifecycleRestUtils.changeResourceState(resourceDetails, testerDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponseResource.getErrorCode() == 200) { + String newVersion = ResponseParser.getVersionFromResponse(restResponseResource); + resourceDetails.setVersion(newVersion); + resourceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + resourceDetails.setLastUpdaterUserId(testerDetails.getUserId()); + resourceDetails.setLastUpdaterFullName(testerDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getUniqueIdFromResponse(restResponseResource); + resourceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponseResource; + } + + public static RestResponse certifyService(ServiceReqDetails serviceDetails) throws Exception { + RestResponse restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CHECKIN); + // if (restResponseService.getErrorCode() == 200){ + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), LifeCycleStatesEnum.CERTIFICATIONREQUEST); + // }else + // return restResponseService; + if (restResponseService.getErrorCode() == 200) { + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.TESTER), LifeCycleStatesEnum.STARTCERTIFICATION); + } else + return restResponseService; + if (restResponseService.getErrorCode() == 200) { + User testerDetails = ElementFactory.getDefaultUser(UserRoleEnum.TESTER); + restResponseService = LifecycleRestUtils.changeServiceState(serviceDetails, testerDetails, + LifeCycleStatesEnum.CERTIFY); + if (restResponseService.getErrorCode() == 200) { + String newVersion = ResponseParser.getVersionFromResponse(restResponseService); + serviceDetails.setVersion(newVersion); + serviceDetails.setLifecycleState(LifecycleStateEnum.CERTIFIED); + serviceDetails.setLastUpdaterUserId(testerDetails.getUserId()); + serviceDetails.setLastUpdaterFullName(testerDetails.getFullName()); + String uniqueIdFromRresponse = ResponseParser.getUniqueIdFromResponse(restResponseService); + serviceDetails.setUniqueId(uniqueIdFromRresponse); + } + } + return restResponseService; + } + + private static RestResponse _changeProductState(Product product, User sdncModifierDetails, + LifeCycleStatesEnum LifeCycleStatesEnum, String lifecycleChangeInfo) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CHANGE_PRODUCT_LIFECYCLE_STATE, config.getCatalogBeHost(), + config.getCatalogBePort(), product.getUniqueId(), LifeCycleStatesEnum); + RestResponse LifeCycleStatesEnumServiceResponse = sendPost(url, createLifecycleCommentJson(lifecycleChangeInfo), + sdncModifierDetails.getUserId(), acceptHeaderData); + + return LifeCycleStatesEnumServiceResponse; + } + + public static String createLifecycleCommentJson(String commentContent) { + String res = null; + if (commentContent != null) { + res = "{\"userRemarks\": \"" + commentContent + "\"}"; + } + return res; + } + + public static void checkLCS_Response(RestResponse response) { + checkStatusCode(response, "change lifecycle request failed", false, STATUS_CODE_SUCCESS); + } + + private static Map prepareHeadersMap(User sdncModifierDetails) { + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + return headersMap; + } + + public static RestResponse changeDistributionStatus(ServiceReqDetails serviceDetails, String version, User user, + String userRemarks, DistributionStatusEnum reqDistributionStatus) throws Exception { + String uniqueId = serviceDetails.getUniqueId(); + if (reqDistributionStatus == DistributionStatusEnum.DISTRIBUTION_APPROVED) { + return sendApproveDistribution(user, uniqueId, userRemarks); + } else if (reqDistributionStatus == DistributionStatusEnum.DISTRIBUTION_REJECTED) { + return rejectDistribution(user, userRemarks, uniqueId); + } else if (reqDistributionStatus == DistributionStatusEnum.DISTRIBUTED) { + Config config = Utils.getConfig(); + // String url = + // String.format("http://%s:%s/sdc2/rest/v1/catalog/services/%s/tempUrlToBeDeleted", + // config.getCatalogBeHost(), config.getCatalogBePort(), uniqueId); + String url = String.format(Urls.ACTIVATE_DISTRIBUTION, config.getCatalogBeHost(), config.getCatalogBePort(), + uniqueId, "PROD"); + return sendDistrState(user, userRemarks, url); + } else + return null; + + } + + public static RestResponse sendApproveDistribution(User sdncModifierDetails, String uniqueId, String userRemarks) + throws FileNotFoundException, IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.APPROVE_DISTRIBUTION, config.getCatalogBeHost(), config.getCatalogBePort(), + uniqueId); + return sendDistrState(sdncModifierDetails, userRemarks, url); + } + + public static RestResponse rejectDistribution(ServiceReqDetails serviceDetails, String version, User user, + String userRemarks) throws Exception { + return rejectDistribution(user, userRemarks, serviceDetails.getUniqueId()); + } + + public static RestResponse rejectDistribution(User user, String userRemarks, String uniqueId) + throws FileNotFoundException, IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.REJECT_DISTRIBUTION, config.getCatalogBeHost(), config.getCatalogBePort(), + uniqueId); + return sendDistrState(user, userRemarks, url); + } + + private static RestResponse sendDistrState(User user, String userRemarks, String url) throws IOException { + Map headersMap = prepareHeadersMap(user); + Map userRemarksMap = new HashMap(); + userRemarksMap.put("userRemarks", userRemarks); + + String serviceBodyJson = new JSONObject().toJSONString(userRemarksMap); + + HttpRequest httpRequest = new HttpRequest(); + logger.debug(url); + logger.debug("Send POST request to create service: {}", url); + logger.debug("Service body: {}", serviceBodyJson); + logger.debug("Service headers: {}", headersMap); + RestResponse rejectDistributionResponse = httpRequest.httpSendPost(url, serviceBodyJson, headersMap); + + return rejectDistributionResponse; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ProductRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ProductRestUtils.java new file mode 100644 index 0000000000..8e617ed75c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ProductRestUtils.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ProductReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +public class ProductRestUtils extends BaseRestUtils { + private static Gson gson = new Gson(); + private static Logger logger = LoggerFactory.getLogger(ProductRestUtils.class.getName()); + + public static RestResponse createProduct(ProductReqDetails product, User user) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_PRODUCT, config.getCatalogBeHost(), config.getCatalogBePort()); + String serviceBodyJson = gson.toJson(product); + + logger.debug("Send POST request to create service: {}", url); + logger.debug("Service body: {}", serviceBodyJson); + + RestResponse res = sendPost(url, serviceBodyJson, user.getUserId(), acceptHeaderData); + if (res.getErrorCode() == STATUS_CODE_CREATED) { + product.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + product.setVersion(ResponseParser.getVersionFromResponse(res)); + product.setUUID(ResponseParser.getUuidFromResponse(res)); + // Creator details never change after component is created - Ella, + // 12/1/2016 + product.setCreatorUserId(user.getUserId()); + product.setCreatorFullName(user.getFullName()); + product.setLastUpdaterFullName(user.getFullName()); + product.setLastUpdaterUserId(user.getUserId()); + product.setLastUpdaterFullName(user.getFullName()); + product.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + product.setVersion("0.1"); + String lastUpdate = ResponseParser.getValueFromJsonResponse(res.getResponse(), "lastUpdateDate"); + product.setLastUpdateDate(Long.parseLong(lastUpdate, 10)); + product.setCreationDate(Long.parseLong(lastUpdate, 10)); + } + return res; + } + + public static RestResponse updateProduct(ProductReqDetails product, User user) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_PRODUCT, config.getCatalogBeHost(), config.getCatalogBePort(), + product.getUniqueId()); + String serviceBodyJson = gson.toJson(product); + + logger.debug("Send POST request to create service: {}", url); + logger.debug("Service body: {}", serviceBodyJson); + + RestResponse res = sendPut(url, serviceBodyJson, user.getUserId(), acceptHeaderData); + if (res.getErrorCode() == STATUS_CODE_CREATED) { + product.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + product.setVersion(ResponseParser.getVersionFromResponse(res)); + product.setUUID(ResponseParser.getUuidFromResponse(res)); + // Creator details never change after component is created - Ella, + // 12/1/2016 + product.setCreatorUserId(user.getUserId()); + product.setCreatorFullName(user.getFullName()); + product.setLastUpdaterFullName(user.getFullName()); + product.setLastUpdaterUserId(user.getUserId()); + product.setLastUpdaterFullName(user.getFullName()); + product.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + String valueFromJsonResponse = ResponseParser.getValueFromJsonResponse(res.getResponse(), "version"); + product.setVersion(valueFromJsonResponse); + String lastUpdate = ResponseParser.getValueFromJsonResponse(res.getResponse(), "lastUpdateDate"); + product.setLastUpdateDate(Long.parseLong(lastUpdate, 10)); + product.setCreationDate(Long.parseLong(lastUpdate, 10)); + } + return res; + } + + public static RestResponse createProduct_Invalid_Json(String userId) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_PRODUCT, config.getCatalogBeHost(), config.getCatalogBePort()); + + RestResponse res = sendPost(url, "kukumuku", userId, acceptHeaderData); + return res; + } + + public static RestResponse deleteProduct(String id, String userId) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_PRODUCT, config.getCatalogBeHost(), config.getCatalogBePort(), id); + return sendDelete(url, userId); + } + + public static RestResponse getProduct(String productId, String userId) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_PRODUCT, config.getCatalogBeHost(), config.getCatalogBePort(), productId); + logger.debug("Send GET request to get product: {}", url); + + return sendGet(url, userId); + } + + public static RestResponse getFollowed(String userId) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_FOLLWED_LIST, config.getCatalogBeHost(), config.getCatalogBePort()); + logger.debug("Send GET request to get user followed page: {}", url); + return sendGet(url, userId); + + } + + public static RestResponse changeProductLifeCycle(Product product, User userModifier, LifeCycleStatesEnum lifeCycle) + throws Exception { + String checkinComment = "my comment"; + RestResponse changeLifeCycleResponse = LifecycleRestUtils.changeProductState(product, userModifier, lifeCycle, + checkinComment); + if (changeLifeCycleResponse.getErrorCode() == STATUS_CODE_SUCCESS) { + product.setLastUpdaterUserId(userModifier.getUserId()); + product.setLastUpdaterFullName(userModifier.getFullName()); + String latestVersion = ResponseParser.getValueFromJsonResponse(changeLifeCycleResponse.getResponse(), + "version"); + product.setVersion(latestVersion); + String lifecycleState = ResponseParser.getValueFromJsonResponse(changeLifeCycleResponse.getResponse(), + "lifecycleState"); + product.setLifecycleState((LifecycleStateEnum.valueOf(lifecycleState))); + String uniqueId = ResponseParser.getValueFromJsonResponse(changeLifeCycleResponse.getResponse(), + "uniqueId"); + product.setUniqueId(uniqueId); + String lastUpdate = ResponseParser.getValueFromJsonResponse(changeLifeCycleResponse.getResponse(), + "lastUpdateDate"); + product.setLastUpdateDate((Long.parseLong(lastUpdate, 10))); + String uuid = ResponseParser.getValueFromJsonResponse(changeLifeCycleResponse.getResponse(), "uuid"); + product.setUUID(uuid); + } + return changeLifeCycleResponse; + } + + public static RestResponse changeServiceInstanceVersion(String componentUniqueId, + String serviceInstanceToReplaceUniqueId, String serviceUniqueId, User sdncModifierDetails, + ComponentTypeEnum componentType) throws IOException { + Config config = Utils.getConfig(); + String resourceUid = ("{\"componentUid\":\"" + serviceUniqueId + "\"}"); + String url = String.format(Urls.CHANGE__RESOURCE_INSTANCE_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), ComponentTypeEnum.findParamByType(componentType), componentUniqueId, + serviceInstanceToReplaceUniqueId); + RestResponse changeResourceInstanceVersion = sendPost(url, resourceUid, sdncModifierDetails.getUserId(), + acceptHeaderData); + return changeResourceInstanceVersion; + + } + + public static RestResponse getProductByNameAndVersion(String productName, String productVersion, String userId) + throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_PRODUCT_BY_NAME_AND_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), productName, productVersion); + logger.debug("Send GET request to get product by name and version: {}", url); + return sendGet(url, userId); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/PropertyRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/PropertyRestUtils.java new file mode 100644 index 0000000000..56ff5ec12b --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/PropertyRestUtils.java @@ -0,0 +1,310 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNull; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PropertyRestUtils extends BaseRestUtils { + private static Logger logger = LoggerFactory.getLogger(PropertyRestUtils.class.getName()); + + public static RestResponse createProperty(String resourceId, String body, User user) throws Exception { + Config config = Config.instance(); + String url = String.format(Urls.CREATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceId); + + return sendPost(url, body, user.getUserId(), acceptHeaderData); + } + + public static RestResponse updateProperty(String resourceId, String propertyId, String body, User user) + throws Exception { + Config config = Config.instance(); + + String url = String.format(Urls.UPDATE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceId, propertyId); + return sendPut(url, body, user.getUserId(), acceptHeaderData); + } + + public static RestResponse getProperty(String resourceId, String propertyId, User user) throws Exception { + Config config = Config.instance(); + String url = String.format(Urls.GET_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId, + propertyId); + return sendGet(url, user.getUserId()); + } + + public static RestResponse deleteProperty(String resourceId, String propertyId, User user) throws Exception { + Config config = Config.instance(); + String url = String.format(Urls.DELETE_PROPERTY, config.getCatalogBeHost(), config.getCatalogBePort(), + resourceId, propertyId); + + return sendDelete(url, user.getUserId()); + } + + public static ComponentInstanceProperty getPropFromListByPropNameAndType(List propList, + String propNameToUpdate, String propTypeToUpdate) { + for (ComponentInstanceProperty componentInstanceProperty : propList) { + if (componentInstanceProperty.getName().equals(propNameToUpdate) + && componentInstanceProperty.getType().equals(propTypeToUpdate)) { + return componentInstanceProperty; + } + } + return null; + } + + public static ComponentInstanceProperty getPropFromListByPropNameTypeAndPath( + List propList, String propNameToUpdate, String propTypeToUpdate, + List path) { + for (ComponentInstanceProperty componentInstanceProperty : propList) { + if (componentInstanceProperty.getPath() == null) { + return getPropFromListByPropNameAndType(propList, propNameToUpdate, propTypeToUpdate); + } + if (componentInstanceProperty.getName().equals(propNameToUpdate) + && componentInstanceProperty.getType().equals(propTypeToUpdate) + && path.containsAll(componentInstanceProperty.getPath())) { + return componentInstanceProperty; + } + } + return null; + } + + public static ComponentInstanceProperty getPropFromListByPropIdAndPath(List propList, + String propId, List path) { + + for (ComponentInstanceProperty componentInstanceProperty : propList) { + if (path != null) { + if (componentInstanceProperty.getUniqueId().equals(propId) + && componentInstanceProperty.getPath().equals(path)) { + return componentInstanceProperty; + } + } else { + if (componentInstanceProperty.getUniqueId().equals(propId)) { + return componentInstanceProperty; + } + } + } + return null; + } + + public static void comparePropertyLists(List expectedList, + List actualList, Boolean isUpdate) { + + assertTrue( + "list size are not equals, expected size is: " + expectedList.size() + " ,actual: " + actualList.size(), + expectedList.size() == actualList.size()); + Boolean flag = false; + for (ComponentInstanceProperty expectedcompInstProp : expectedList) { + for (ComponentInstanceProperty actualcompInstProp : actualList) { + flag = comparePropertyObjects(expectedcompInstProp, actualcompInstProp, isUpdate); + if (flag) { + break; + } + } + } + // System.out.println("expected: " + expectedList + ", actual: " + + // actualList); + logger.debug("expected: {}, actual: {}", expectedList, actualList); + assertTrue("actual lists does not contain all uniqeIds", flag); + } + + public static Boolean comparePropertyObjects(ComponentInstanceProperty expectedCompInstProp, + ComponentInstanceProperty actualCompInstProp, Boolean isUpdate) { + String uniqueId = expectedCompInstProp.getUniqueId(); + String type = expectedCompInstProp.getType(); + String defaulValue = expectedCompInstProp.getDefaultValue(); + if (actualCompInstProp.getUniqueId().equals(uniqueId) + && actualCompInstProp.getPath().equals(expectedCompInstProp.getPath())) { + assertTrue("expected type is: " + type + " ,actual: " + actualCompInstProp.getType(), + actualCompInstProp.getType().equals(type)); + if (defaulValue == null) { + assertTrue( + "expected defaulValue is: " + defaulValue + " ,actual: " + actualCompInstProp.getDefaultValue(), + actualCompInstProp.getDefaultValue() == defaulValue); + } else { + assertTrue( + "expected defaulValue is: " + defaulValue + " ,actual: " + actualCompInstProp.getDefaultValue(), + actualCompInstProp.getDefaultValue().equals(defaulValue)); + } + if (isUpdate) { + assertTrue( + "actual [Value] parameter " + actualCompInstProp.getName() + + "should equal to expected [Value]: " + actualCompInstProp.getValue() + " ,Value: " + + actualCompInstProp.getValue(), + actualCompInstProp.getValue().equals(expectedCompInstProp.getValue())); + assertNotNull("valueId is null", actualCompInstProp.getValueUniqueUid()); + } else { + if (defaulValue == null) { + assertTrue( + "actual [Value] parameter " + actualCompInstProp.getName() + + "should equal to expected [defaultValue]: " + actualCompInstProp.getValue() + + " ,defaultValue: " + actualCompInstProp.getDefaultValue(), + actualCompInstProp.getValue() == expectedCompInstProp.getDefaultValue()); + } else { + assertTrue( + "actual [Value] parameter " + actualCompInstProp.getName() + + "should equal to expected [defaultValue]: " + actualCompInstProp.getValue() + + " ,defaultValue: " + actualCompInstProp.getDefaultValue(), + actualCompInstProp.getValue().equals(expectedCompInstProp.getDefaultValue())); + } + assertNull("valueId is not null", actualCompInstProp.getValueUniqueUid()); + } + return true; + } + return false; + } + + public static List addResourcePropertiesToList(Resource resource, + List listToFill) { + for (PropertyDefinition prop : resource.getProperties()) { + listToFill.add(new ComponentInstanceProperty(prop, null, null)); + } + return listToFill; + } + + public static List addComponentInstPropertiesToList(Component component, + List listToFill, String componentId) { + + if (componentId != null) { + List list = component.getComponentInstancesProperties().get(componentId); + for (ComponentInstanceProperty prop : list) { + ComponentInstanceProperty componentInstanceProperty = new ComponentInstanceProperty(prop, null, null); + componentInstanceProperty.setPath(prop.getPath()); + componentInstanceProperty.setValueUniqueUid(prop.getValueUniqueUid()); + componentInstanceProperty.setValue(prop.getValue()); + listToFill.add(componentInstanceProperty); + } + } else { + Map> componentInstancesProperties = component + .getComponentInstancesProperties(); + for (Map.Entry> componentInstanceProperties : componentInstancesProperties + .entrySet()) { + for (ComponentInstanceProperty prop : componentInstanceProperties.getValue()) { + ComponentInstanceProperty componentInstanceProperty = new ComponentInstanceProperty(prop, null, + null); + componentInstanceProperty.setPath(prop.getPath()); + componentInstanceProperty.setValueUniqueUid(prop.getValueUniqueUid()); + componentInstanceProperty.setValue(prop.getValue()); + listToFill.add(componentInstanceProperty); + } + } + } + + if (component.getComponentType().getValue().equals("Resource")) { + for (PropertyDefinition prop : ((Resource) component).getProperties()) { + listToFill.add(new ComponentInstanceProperty(prop, null, null)); + } + } + return listToFill; + } + + public static ComponentInstanceProperty getCompPropInstListByInstIdAndPropName(Component component, + ComponentInstance componentInstanceDetails, String name, String type) { + List propList = component.getComponentInstancesProperties() + .get(componentInstanceDetails.getUniqueId()); + if (propList != null) { + return getPropFromListByPropNameAndType(propList, name, type); + } + return null; + } + + private static void updatePropertyListWithPathParameter(Resource resource, List path, + List expectedPropertyList) { + List propertyList = resource.getProperties(); + for (PropertyDefinition propertyDefinition : propertyList) { + ComponentInstanceProperty propDetailsToRemove = PropertyRestUtils.getPropFromListByPropNameAndType( + expectedPropertyList, propertyDefinition.getName(), propertyDefinition.getType()); + ComponentInstanceProperty propDetailsToAdd = propDetailsToRemove; + propDetailsToAdd.setPath(path); + expectedPropertyList.remove(propDetailsToRemove); + expectedPropertyList.add(propDetailsToAdd); + } + } + + private static void updatePropertyListWithPathParameterOnCompInst(Service service, List path, + List expectedPropertyList) { + List servicePropertyList = new ArrayList<>(); + servicePropertyList = PropertyRestUtils.addComponentInstPropertiesToList(service, servicePropertyList, + path.get(0)); + + for (ComponentInstanceProperty serviceCompInstProperty : servicePropertyList) { + ComponentInstanceProperty propDetailsToRemove = PropertyRestUtils.getPropFromListByPropNameTypeAndPath( + expectedPropertyList, serviceCompInstProperty.getName(), serviceCompInstProperty.getType(), + serviceCompInstProperty.getPath()); + ComponentInstanceProperty propDetailsToAdd = propDetailsToRemove; + List tempPathList = new ArrayList(); + for (String tempPath : path) { + tempPathList.add(tempPath); + } + // path parameter can not contain the same service unique ID twice + if (propDetailsToAdd.getPath() != null + && !propDetailsToAdd.getPath().get(0).contains(service.getUniqueId())) { + if (!propDetailsToAdd.getPath().containsAll(tempPathList)) { + tempPathList.addAll(propDetailsToAdd.getPath()); + } + } + propDetailsToAdd.setPath(tempPathList); + expectedPropertyList.remove(propDetailsToRemove); + expectedPropertyList.add(propDetailsToAdd); + } + } + + public static void updatePropertyListWithPathOnResource(ComponentInstance componentInstDetails, Resource resource, + List list, Component container) { + List path = new ArrayList<>(); + if (container != null) { + List componentInstances = container.getComponentInstances(); + for (ComponentInstance componentInstance : componentInstances) { + if (componentInstance.getNormalizedName().equals(componentInstDetails.getNormalizedName())) { + path.add(componentInstance.getUniqueId()); + break; + } + } + + } else { + path.add(componentInstDetails.getUniqueId()); + } + updatePropertyListWithPathParameter(resource, path, list); + } + + public static void updatePropertyListWithPathOnComponentInstance(ComponentInstance componentInstDetails, + Service service, List list) { + List path = new ArrayList<>(); + path.add(componentInstDetails.getUniqueId()); + updatePropertyListWithPathParameterOnCompInst(service, path, list); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResourceRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResourceRestUtils.java new file mode 100644 index 0000000000..16ffd2f9e2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResourceRestUtils.java @@ -0,0 +1,575 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.http.client.ClientProtocolException; +import org.json.JSONException; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.RelationshipInstData; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ComponentInstanceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ImportReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +public class ResourceRestUtils extends BaseRestUtils { + private static Logger logger = LoggerFactory.getLogger(ResourceRestUtils.class.getName()); + + // ****** CREATE ******* + + public static RestResponse createResource(ResourceReqDetails resourceDetails, User sdncModifierDetails) throws Exception { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + + String userId = sdncModifierDetails.getUserId(); + + Map headersMap = prepareHeadersMap(userId); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + String calculateMD5 = GeneralUtility.calculateMD5ByString(userBodyJson); + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), calculateMD5); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(userBodyJson); + RestResponse createResourceResponse = http.httpSendPost(url, userBodyJson, headersMap); + if (createResourceResponse.getErrorCode() == STATUS_CODE_CREATED) { + resourceDetails.setUUID(ResponseParser.getUuidFromResponse(createResourceResponse)); + resourceDetails.setVersion(ResponseParser.getVersionFromResponse(createResourceResponse)); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(createResourceResponse)); + String lastUpdaterUserId = ResponseParser.getValueFromJsonResponse(createResourceResponse.getResponse(), "lastUpdaterUserId"); + resourceDetails.setLastUpdaterUserId(lastUpdaterUserId); + String lastUpdaterFullName = ResponseParser.getValueFromJsonResponse(createResourceResponse.getResponse(), "lastUpdaterFullName"); + resourceDetails.setLastUpdaterFullName(lastUpdaterFullName); + // Creator details never change after component is created - Ella, + // 12/1/2016 + resourceDetails.setCreatorUserId(userId); + resourceDetails.setCreatorFullName(sdncModifierDetails.getFullName()); + } + return createResourceResponse; + + } + + public static RestResponse createImportResource(ImportReqDetails importReqDetails, User sdncModifierDetails, Map additionalHeaders) throws JSONException, IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort()); + String userId = sdncModifierDetails.getUserId(); + + Gson gson = new Gson(); + String resourceImportBodyJson = gson.toJson(importReqDetails); + HttpRequest http = new HttpRequest(); + // System.out.println(url); + // System.out.println(resourceImportBodyJson); + + Map headersMap = prepareHeadersMap(userId); + if (additionalHeaders != null) { + headersMap.putAll(additionalHeaders); + } else { + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), ArtifactRestUtils.calculateMD5(resourceImportBodyJson)); + } + + RestResponse createResourceResponse = http.httpSendPost(url, resourceImportBodyJson, headersMap); + if (createResourceResponse.getErrorCode() == STATUS_CODE_CREATED) { + importReqDetails.setVersion(ResponseParser.getVersionFromResponse(createResourceResponse)); + importReqDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(createResourceResponse)); + // Creator details never change after component is created - Ella, + // 12/1/2016 + importReqDetails.setCreatorUserId(userId); + importReqDetails.setCreatorFullName(sdncModifierDetails.getFullName()); + importReqDetails.setToscaResourceName(ResponseParser.getToscaResourceNameFromResponse(createResourceResponse)); + importReqDetails.setDerivedList(ResponseParser.getDerivedListFromJson(createResourceResponse)); + } + return createResourceResponse; + + } + + // ***** DELETE **** + public static RestResponse deleteResource(ResourceReqDetails resourceDetails, User sdncModifierDetails, String version) throws IOException { + + if (resourceDetails.getUniqueId() != null) { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_RESOURCE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), config.getCatalogBePort(), resourceDetails.getName(), version); + return sendDelete(url, sdncModifierDetails.getUserId()); + } else { + return null; + } + + } + + public static RestResponse markResourceToDelete(String resourceId, String userId) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + RestResponse sendDelete = sendDelete(url, userId); + + return sendDelete; + + } + + public static RestResponse deleteResource(String resourceId, String userId) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + RestResponse sendDelete = sendDelete(url, userId); + + deleteMarkedResources(userId); + + return sendDelete; + + } + + public static void deleteMarkedResources(String userId) throws IOException { + String url; + Config config = Utils.getConfig(); + url = String.format(Urls.DELETE_MARKED_RESOURCES, config.getCatalogBeHost(), config.getCatalogBePort()); + sendDelete(url, userId); + } + + public static RestResponse deleteResourceByNameAndVersion(User sdncModifierDetails, String resourceName, String resourceVersion) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_RESOURCE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), config.getCatalogBePort(), resourceName, resourceVersion); + RestResponse sendDelete = sendDelete(url, sdncModifierDetails.getUserId()); + + deleteMarkedResources(sdncModifierDetails.getUserId()); + + return sendDelete; + } + + public static Boolean deleteResourceByNameAndVersion(String resourceName, String resourceVersion) throws IOException { + RestResponse deleteResponse = ResourceRestUtils.deleteResourceByNameAndVersion(ElementFactory.getDefaultUser(UserRoleEnum.ADMIN), resourceName, resourceVersion); + return checkErrorCode(deleteResponse); + } + + public static Boolean removeResource(String resourceId) throws FileNotFoundException, IOException, ClientProtocolException { + RestResponse response = deleteResource(resourceId, ElementFactory.getDefaultUser(UserRoleEnum.ADMIN).getUserId()); + return checkErrorCode(response); + } + + // ************** GET ************* + public static RestResponse getResource(User sdncModifierDetails, String uniqueId) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), uniqueId); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse getModule(User sdncModifierDetails, String componentId, String moduleId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_MODULE_BY_ID, config.getCatalogBeHost(), config.getCatalogBePort(), componentId, moduleId); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse getLatestResourceFromCsarUuid(User sdncModifierDetails, String csarUuid) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_RESOURCE_BY_CSAR_UUID, config.getCatalogBeHost(), config.getCatalogBePort(), csarUuid); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse getResource(ResourceReqDetails resourceDetails, User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceDetails.getUniqueId()); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static RestResponse getResourceByNameAndVersion(String userId, String resourceName, String resourceVersion) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_RESOURCE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), config.getCatalogBePort(), resourceName, resourceVersion); + + return sendGet(url, userId); + } + + public static RestResponse getResourceList(User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_FOLLWED_LIST, config.getCatalogBeHost(), config.getCatalogBePort()); + + return sendGet(url, sdncModifierDetails.getUserId()); + + } + + public static RestResponse getResource(String resourceId) throws ClientProtocolException, IOException { + return getResource(ElementFactory.getDefaultUser(UserRoleEnum.ADMIN), resourceId); + } + + public static RestResponse getLatestResourceFromCsarUuid(String csarUuid) throws ClientProtocolException, IOException { + return getLatestResourceFromCsarUuid(ElementFactory.getDefaultUser(UserRoleEnum.ADMIN), csarUuid); + } + + public static RestResponse getResourceLatestVersionList(User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_RESOURCE_lATEST_VERSION, config.getCatalogBeHost(), config.getCatalogBePort()); + + return sendGet(url, sdncModifierDetails.getUserId()); + + } + + public static RestResponse putAllCategoriesTowardsCatalogFeWithUuidNotAllowed(String uuid) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES_FE, config.getCatalogFeHost(), config.getCatalogFePort(), BaseRestUtils.RESOURCE_COMPONENT_TYPE); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + headersMap.put(HttpHeaderEnum.X_ECOMP_REQUEST_ID_HEADER.getValue(), uuid); + HttpRequest http = new HttpRequest(); + + logger.debug("Send PUT request to get all categories (should be 405): {}", url); + return http.httpSendByMethod(url, "PUT", null, headersMap); + } + + public static RestResponse getAllTagsTowardsCatalogBe() throws IOException { + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ALL_TAGS, config.getCatalogBeHost(), config.getCatalogBePort()); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + + // logger.debug("Send GET request to get all tags: {}", url); + return http.httpSendGet(url, headersMap); + + } + + public static RestResponse getAllPropertyScopesTowardsCatalogBe() throws IOException { + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_PROPERTY_SCOPES_LIST, config.getCatalogBeHost(), config.getCatalogBePort()); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), "cs0008"); + + // logger.debug("Send GET request to get all property scopes: {}", url); + return http.httpSendGet(url, headersMap); + + } + + public static RestResponse getAllArtifactTypesTowardsCatalogBe() throws IOException { + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ALL_ARTIFACTS, config.getCatalogBeHost(), config.getCatalogBePort()); + + Map headersMap = new HashMap(); + + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), "cs0008"); + + // logger.debug("Send GET request to get all property scopes: {}", url); + return http.httpSendGet(url, headersMap); + + } + + public static RestResponse getConfigurationTowardsCatalogBe() throws IOException { + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_CONFIGURATION, config.getCatalogBeHost(), config.getCatalogBePort()); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), "cs0008"); + + // logger.debug("Send GET request to get all property scopes: {}", url); + return http.httpSendGet(url, headersMap); + + } + + public static RestResponse sendOptionsTowardsCatalogFeWithUuid() throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_ALL_CATEGORIES_FE, config.getCatalogFeHost(), config.getCatalogFePort(), BaseRestUtils.RESOURCE_COMPONENT_TYPE); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderData); + HttpRequest http = new HttpRequest(); + + logger.debug("Send OPTIONS request for categories: {}", url); + return http.httpSendByMethod(url, "OPTIONS", null, headersMap); + } + + // ********** UPDATE ************* + public static RestResponse updateResourceMetadata(ResourceReqDetails updatedResourceDetails, User sdncModifierDetails, String uniqueId, String encoding) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), uniqueId); + + String ContentTypeString = String.format("%s;%s", contentTypeHeaderData, encoding); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(updatedResourceDetails); + String userId = sdncModifierDetails.getUserId(); + + RestResponse updateResourceResponse = sendPut(url, userBodyJson, userId, ContentTypeString); + + updatedResourceDetails.setVersion(ResponseParser.getVersionFromResponse(updateResourceResponse)); + updatedResourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(updateResourceResponse)); + + return updateResourceResponse; + } + + public static RestResponse updateResourceTEST(Resource resource, User sdncModifierDetails, String uniqueId, String encoding) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), uniqueId); + + String ContentTypeString = String.format("%s;%s", contentTypeHeaderData, encoding); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resource); + String userId = sdncModifierDetails.getUserId(); + + RestResponse updateResourceResponse = sendPut(url, userBodyJson, userId, ContentTypeString); + return updateResourceResponse; + } + + public static RestResponse updateResourceMetadata(ResourceReqDetails updatedResourceDetails, User sdncModifierDetails, String uniqueId) throws Exception { + return updateResourceMetadata(updatedResourceDetails, sdncModifierDetails, uniqueId, ""); + } + + public static RestResponse updateResourceMetadata(String json, User sdncModifierDetails, String resourceId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + String userId = sdncModifierDetails.getUserId(); + RestResponse updateResourceResponse = sendPut(url, json, userId, contentTypeHeaderData); + return updateResourceResponse; + } + + public static RestResponse updateResource(ResourceReqDetails resourceDetails, User sdncModifierDetails, String resourceId) throws IOException { + String userId = sdncModifierDetails.getUserId(); + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_RESOURCE, config.getCatalogBeHost(), config.getCatalogBePort(), resourceId); + + Map headersMap = prepareHeadersMap(userId); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(resourceDetails); + String calculateMD5 = GeneralUtility.calculateMD5ByString(userBodyJson); + headersMap.put(HttpHeaderEnum.Content_MD5.getValue(), calculateMD5); + HttpRequest http = new HttpRequest(); + RestResponse updateResourceResponse = http.httpSendPut(url, userBodyJson, headersMap); + if (updateResourceResponse.getErrorCode() == STATUS_CODE_UPDATE_SUCCESS) { + resourceDetails.setUUID(ResponseParser.getUuidFromResponse(updateResourceResponse)); + resourceDetails.setVersion(ResponseParser.getVersionFromResponse(updateResourceResponse)); + resourceDetails.setUniqueId(ResponseParser.getUniqueIdFromResponse(updateResourceResponse)); + String lastUpdaterUserId = ResponseParser.getValueFromJsonResponse(updateResourceResponse.getResponse(), "lastUpdaterUserId"); + resourceDetails.setLastUpdaterUserId(lastUpdaterUserId); + String lastUpdaterFullName = ResponseParser.getValueFromJsonResponse(updateResourceResponse.getResponse(), "lastUpdaterFullName"); + resourceDetails.setLastUpdaterFullName(lastUpdaterFullName); + resourceDetails.setCreatorUserId(userId); + resourceDetails.setCreatorFullName(sdncModifierDetails.getFullName()); + } + return updateResourceResponse; + } + + public static RestResponse createResourceInstance(ResourceReqDetails resourceDetails, User modifier, String vfResourceUniqueId) throws Exception { + ComponentInstanceReqDetails resourceInstanceReqDetails = ElementFactory.getComponentResourceInstance(resourceDetails); + RestResponse createResourceInstanceResponse = ComponentInstanceRestUtils.createComponentInstance(resourceInstanceReqDetails, modifier, vfResourceUniqueId, ComponentTypeEnum.RESOURCE); + ResourceRestUtils.checkCreateResponse(createResourceInstanceResponse); + return createResourceInstanceResponse; + } + + public static RestResponse associateResourceInstances(JSONObject body, User sdncModifierDetails, Component component) throws IOException { + + Config config = Utils.getConfig(); + Gson gson = new Gson(); + String bodyJson = gson.toJson(body); + component.getComponentType(); + String componentType = ComponentTypeEnum.findParamByType(component.getComponentType()); + String url = String.format(Urls.ASSOCIATE__RESOURCE_INSTANCE, config.getCatalogBeHost(), config.getCatalogBePort(), componentType, component.getUniqueId()); + return sendPost(url, bodyJson, sdncModifierDetails.getUserId(), null); + + } + + public static RestResponse getFollowedList(User sdncModifierDetails) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_FOLLWED_LIST, config.getCatalogBeHost(), config.getCatalogBePort()); + return sendGet(url, sdncModifierDetails.getUserId()); + } + + public static List restResponseToResourceObjectList(String restResponse) { + JsonElement jelement = new JsonParser().parse(restResponse); + JsonArray jsonArray = jelement.getAsJsonArray(); + List restResponseArray = new ArrayList<>(); + Resource resource = null; + for (int i = 0; i < jsonArray.size(); i++) { + String resourceString = (String) jsonArray.get(i).toString(); + resource = ResponseParser.convertResourceResponseToJavaObject(resourceString); + restResponseArray.add(resource); + } + + return restResponseArray; + + } + + public static Resource getResourceObjectFromResourceListByUid(List resourceList, String uid) { + if (resourceList != null && resourceList.size() > 0) { + for (Resource resource : resourceList) { + if (resource.getUniqueId().equals(uid)) + return resource; + } + } else + return null; + return null; + } + + // =======================================resource + // associate================================================== + public static RestResponse associate2ResourceInstances(Component container, ComponentInstance fromNode, ComponentInstance toNode, String assocType, User sdncUserDetails) throws IOException { + return associate2ResourceInstances(container, fromNode.getUniqueId(), toNode.getUniqueId(), assocType, sdncUserDetails); + } + + public static RestResponse associate2ResourceInstances(Component component, String fromNode, String toNode, String assocType, User sdncUserDetails) throws IOException { + + RelationshipInstData relationshipInstData = new RelationshipInstData(); + Map> capabilitiesMap = component.getCapabilities(); + Map> requirementMap = component.getRequirements(); + List capabilitiesList = capabilitiesMap.get(assocType); + List requirementList = requirementMap.get(assocType); + + RequirementDefinition requirementDefinitionFrom = getRequirementDefinitionByOwnerId(requirementList, fromNode); + CapabilityDefinition capabilityDefinitionTo = getCapabilityDefinitionByOwnerId(capabilitiesList, toNode); + relationshipInstData.setCapabilityOwnerId(capabilityDefinitionTo.getOwnerId()); + relationshipInstData.setCapabiltyId(capabilityDefinitionTo.getUniqueId()); + relationshipInstData.setRequirementOwnerId(requirementDefinitionFrom.getOwnerId()); + relationshipInstData.setRequirementId(requirementDefinitionFrom.getUniqueId()); + + JSONObject assocBody = assocBuilder(relationshipInstData, capabilityDefinitionTo, requirementDefinitionFrom, toNode, fromNode); + return ResourceRestUtils.associateResourceInstances(assocBody, sdncUserDetails, component); + + } + + private static JSONObject assocBuilder(RelationshipInstData relationshipInstData, CapabilityDefinition capabilityDefinitionTo, RequirementDefinition requirementDefinitionFrom, String toNode, String fromNode) { + + String type = capabilityDefinitionTo.getType(); + String requirement = requirementDefinitionFrom.getName(); + String capability = requirementDefinitionFrom.getName(); + + JSONObject wrapper = new JSONObject(); + JSONArray relationshipsArray = new JSONArray(); + JSONObject relationship = new JSONObject(); + JSONObject simpleObject = new JSONObject(); + + relationship.put("type", type); + simpleObject.put("relationship", relationship); + simpleObject.put("requirement", requirement); + simpleObject.put("capability", capability); + simpleObject.put("capabilityUid", relationshipInstData.getCapabiltyId()); + simpleObject.put("capabilityOwnerId", relationshipInstData.getCapabilityOwnerId()); + simpleObject.put("requirementOwnerId", relationshipInstData.getRequirementOwnerId()); + simpleObject.put("requirementUid", relationshipInstData.getRequirementId()); + relationshipsArray.add(simpleObject); + + ArrayList relationships = new ArrayList(relationshipsArray); + wrapper.put("fromNode", fromNode); + wrapper.put("toNode", toNode); + wrapper.put("relationships", relationships); + return wrapper; + + } + + private static CapabilityDefinition getCapabilityDefinitionByOwnerId(List capabilityDefinitionList, String ownerId) { + + for (CapabilityDefinition capabilityDefinition : capabilityDefinitionList) { + if (capabilityDefinition.getOwnerId().equals(ownerId)) { + return capabilityDefinition; + } + } + return null; + } + + private static RequirementDefinition getRequirementDefinitionByOwnerId(List requirementDefinitionList, String ownerId) { + + for (RequirementDefinition requirementDefinition : requirementDefinitionList) { + if (requirementDefinition.getOwnerId().equals(ownerId)) { + return requirementDefinition; + } + } + return null; + } + + public static String getRiUniqueIdByRiName(Component component, String resourceInstanceName) { + + List componentInstances = component.getComponentInstances(); + String name = null; + for (ComponentInstance componentInstance : componentInstances) { + if (componentInstance.getName().equals(resourceInstanceName)) { + name = componentInstance.getUniqueId(); + break; + } + } + return name; + } + + public static Resource convertResourceGetResponseToJavaObject(ResourceReqDetails resourceDetails) throws IOException { + RestResponse response = ResourceRestUtils.getResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + assertEquals("Check response code after get resource", 200, response.getErrorCode().intValue()); + return ResponseParser.convertResourceResponseToJavaObject(response.getResponse()); + } + + public static RestResponse changeResourceInstanceVersion(String containerUniqueId, String instanceToReplaceUniqueId, String newResourceUniqueId, User sdncModifierDetails, ComponentTypeEnum componentType) throws IOException { + return ProductRestUtils.changeServiceInstanceVersion(containerUniqueId, instanceToReplaceUniqueId, newResourceUniqueId, sdncModifierDetails, componentType); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResponseParser.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResponseParser.java new file mode 100644 index 0000000000..dfcb9c2736 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ResponseParser.java @@ -0,0 +1,541 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; +import org.apache.log4j.Logger; +import org.codehaus.jackson.Version; +import org.codehaus.jackson.map.JsonDeserializer; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.module.SimpleModule; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintJacksonDeserialiser; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class ResponseParser { + + private static final String INVARIANT_UUID = "invariantUUID"; + public static final String UNIQUE_ID = "uniqueId"; + public static final String VERSION = "version"; + public static final String UUID = "uuid"; + public static final String NAME = "name"; + public static final String ORIGIN_TYPE = "originType"; + public static final String TOSCA_RESOURCE_NAME = "toscaResourceName"; + + static Logger logger = Logger.getLogger(ResponseParser.class.getName()); + + public static String getValueFromJsonResponse(String response, String fieldName) { + try { + JSONObject jsonResp = (JSONObject) JSONValue.parse(response); + Object fieldValue = jsonResp.get(fieldName); + return fieldValue.toString(); + + } catch (Exception e) { + return null; + } + + } + + public static String getUniqueIdFromResponse(RestResponse response) { + return getValueFromJsonResponse(response.getResponse(), UNIQUE_ID); + } + + public static String getInvariantUuid(RestResponse response) { + return getValueFromJsonResponse(response.getResponse(), INVARIANT_UUID); + } + + public static String getUuidFromResponse(RestResponse response) { + return getValueFromJsonResponse(response.getResponse(), UUID); + } + + public static String getNameFromResponse(RestResponse response) { + return getValueFromJsonResponse(response.getResponse(), NAME); + } + + public static String getVersionFromResponse(RestResponse response) { + return ResponseParser.getValueFromJsonResponse(response.getResponse(), VERSION); + } + + public static String getComponentTypeFromResponse(RestResponse response) { + return ResponseParser.getValueFromJsonResponse(response.getResponse(), ORIGIN_TYPE); + } + + public static String getToscaResourceNameFromResponse(RestResponse response) { + return getValueFromJsonResponse(response.getResponse(), TOSCA_RESOURCE_NAME); + } + + @SuppressWarnings("unchecked") + public static ResourceRespJavaObject parseJsonListReturnResourceDetailsObj(RestResponse restResponse, + String resourceType, String searchPattern, String expectedResult) throws Exception { + + // Gson gson = new Gson; + + JsonElement jElement = new JsonParser().parse(restResponse.getResponse()); + JsonObject jObject = jElement.getAsJsonObject(); + JsonArray arrayOfObjects = (JsonArray) jObject.get(resourceType); + Gson gson = new Gson(); + Map map = new HashMap(); + ResourceRespJavaObject jsonToJavaObject = new ResourceRespJavaObject(); + + for (int counter = 0; counter < arrayOfObjects.size(); counter++) { + JsonObject jHitObject = (JsonObject) arrayOfObjects.get(counter); + + map = (Map) gson.fromJson(jHitObject.toString(), map.getClass()); + if (map.get(searchPattern).toString().contains(expectedResult)) { + + jsonToJavaObject = gson.fromJson(jObject, ResourceRespJavaObject.class); + break; + } + } + return jsonToJavaObject; + + } + + public static Resource convertResourceResponseToJavaObject(String response) { + + ObjectMapper mapper = new ObjectMapper(); + final SimpleModule module = new SimpleModule("customerSerializationModule", + new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + + mapper.registerModule(module); + Resource resource = null; + try { + resource = mapper.readValue(response, Resource.class); + logger.debug(resource.toString()); + } catch (IOException e) { + try { + List resources = Arrays.asList(mapper.readValue(response.toString(), Resource[].class)); + resource = resources.get(0); + } catch (Exception e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + } + + return resource; + } + + public static ComponentInstanceProperty convertPropertyResponseToJavaObject(String response) { + + ObjectMapper mapper = new ObjectMapper(); + final SimpleModule module = new SimpleModule("customerSerializationModule", + new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + + mapper.registerModule(module); + ComponentInstanceProperty propertyDefinition = null; + try { + propertyDefinition = mapper.readValue(response, ComponentInstanceProperty.class); + logger.debug(propertyDefinition.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return propertyDefinition; + } + + // public static ResourceInstanceReqDetails + // convertResourceInstanceResponseToJavaObject(String response) { + // + // ObjectMapper mapper = new ObjectMapper(); + // final SimpleModule module = new + // SimpleModule("customerSerializationModule", new Version(1, 0, 0, "static + // version")); + // JsonDeserializer desrializer = new + // PropertyConstraintJacksonDeserialiser(); + // addDeserializer(module, PropertyConstraint.class, desrializer); + // + // mapper.registerModule(module); + // ResourceInstanceReqDetails resourceInstanceReqDetails = null; + // try { + // resourceInstanceReqDetails = mapper.readValue(response, + // ResourceInstanceReqDetails.class); + // logger.debug(resourceInstanceReqDetails.toString()); + // } catch (IOException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // + // return resourceInstanceReqDetails; + // } + public static String toJson(Object object) { + Gson gson = new Gson(); + return gson.toJson(object); + } + + public static ArtifactDefinition convertArtifactDefinitionResponseToJavaObject(String response) { + ObjectMapper mapper = new ObjectMapper(); + ArtifactDefinition artifactDefinition = null; + try { + + artifactDefinition = mapper.readValue(response, ArtifactDefinition.class); + logger.debug(artifactDefinition.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return artifactDefinition; + + } + + public static ArtifactReqDetails convertArtifactReqDetailsToJavaObject(String response) { + + ArtifactReqDetails artifactReqDetails = null; + // try { + // + // artifactDefinition = mapper.readValue(response, + // ArtifactReqDetails.class); + // logger.debug(artifactDefinition.toString()); + // } catch (IOException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // + // return artifactDefinition; + Gson gson = new Gson(); + artifactReqDetails = gson.fromJson(response, ArtifactReqDetails.class); + return artifactReqDetails; + } + + public static T parseToObject(String json, Class clazz) { + Gson gson = new Gson(); + T object; + try { + object = gson.fromJson(json, clazz); + } catch (Exception e) { + object = parseToObjectUsingMapper(json, clazz); + } + return object; + } + + public static T parseToObjectUsingMapper(String json, Class clazz) { + // Generic convert + ObjectMapper mapper = new ObjectMapper(); + T object = null; + final SimpleModule module = new SimpleModule("customerSerializationModule", + new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + mapper.registerModule(module); + try { + object = mapper.readValue(json, clazz); + // System.out.println("Class: "+clazz.getSimpleName()+", json: + // "+json); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return object; + } + + public static ArtifactReqDetails convertArtifactDefinitionToArtifactReqDetailsObject( + ArtifactDefinition artifactDefinition) { + + ArtifactReqDetails artifactReqDetails = null; + // try { + // + // artifactDefinition = mapper.readValue(response, + // ArtifactReqDetails.class); + // logger.debug(artifactDefinition.toString()); + // } catch (IOException e) { + // // TODO Auto-generated catch block + // e.printStackTrace(); + // } + // + // return artifactDefinition; + Gson gson = new Gson(); + String artDef = gson.toJson(artifactDefinition); + artifactReqDetails = gson.fromJson(artDef, ArtifactReqDetails.class); + return artifactReqDetails; + } + + public static void addDeserializer(SimpleModule module, Class clazz, + final JsonDeserializer deserializer) { + module.addDeserializer(clazz, deserializer); + } + + public static Service convertServiceResponseToJavaObject(String response) { + + ObjectMapper mapper = new ObjectMapper(); + final SimpleModule module = new SimpleModule("customerSerializationModule", + new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + + mapper.registerModule(module); + Service service = null; + try { + service = mapper.readValue(response, Service.class); + logger.debug(service.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return service; + } + + public static Product convertProductResponseToJavaObject(String response) { + + ObjectMapper mapper = new ObjectMapper(); + Product product = null; + try { + product = mapper.readValue(response, Product.class); + logger.debug(product.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return product; + } + + public static ComponentInstance convertComponentInstanceResponseToJavaObject(String response) { + + ObjectMapper mapper = new ObjectMapper(); + final SimpleModule module = new SimpleModule("customerSerializationModule", + new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + + mapper.registerModule(module); + ComponentInstance componentInstance = null; + try { + componentInstance = mapper.readValue(response, ComponentInstance.class); + logger.debug(componentInstance.toString()); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return componentInstance; + } + + public static List getValuesFromJsonArray(RestResponse message) throws Exception { + List artifactTypesArrayFromApi = new ArrayList(); + + org.json.JSONObject responseObject = new org.json.JSONObject(message.getResponse()); + JSONArray jArr = responseObject.getJSONArray("artifactTypes"); + + for (int i = 0; i < jArr.length(); i++) { + org.json.JSONObject jObj = jArr.getJSONObject(i); + String value = jObj.get("name").toString(); + + artifactTypesArrayFromApi.add(value); + } + return artifactTypesArrayFromApi; + } + + public static String calculateMD5Header(ArtifactReqDetails artifactDetails) { + Gson gson = new Gson(); + String jsonBody = gson.toJson(artifactDetails); + // calculate MD5 for json body + return calculateMD5(jsonBody); + + } + + public static String calculateMD5(String data) { + String calculatedMd5 = org.apache.commons.codec.digest.DigestUtils.md5Hex(data); + // encode base-64 result + byte[] encodeBase64 = Base64.encodeBase64(calculatedMd5.getBytes()); + String encodeBase64Str = new String(encodeBase64); + return encodeBase64Str; + + } + + public static List> getAuditFromMessage(Map auditingMessage) { + List> auditList = new ArrayList>(); + // JsonElement jElement = new JsonParser().parse(auditingMessage); + // JsonObject jObject = jElement.getAsJsonObject(); + // JsonObject hitsObject = (JsonObject) jObject.get("hits"); + // JsonArray hitsArray = (JsonArray) hitsObject.get("hits"); + // + // Iterator hitsIterator = hitsArray.iterator(); + // while(hitsIterator.hasNext()) + // { + // JsonElement nextHit = hitsIterator.next(); + // JsonObject jHitObject = nextHit.getAsJsonObject(); + // JsonObject jSourceObject = (JsonObject) jHitObject.get("_source"); + // + // Gson gson=new Gson(); + // String auditUnparsed = jSourceObject.toString(); + // + // Map map = new HashMap(); + // map = (Map) gson.fromJson(auditUnparsed, + // map.getClass()); + + auditList.add(auditingMessage); + // } + return auditList; + } + + public static List parseCategories(RestResponse getAllCategoriesRest) { + + List categories = new ArrayList<>(); + try { + JsonElement jElement = new JsonParser().parse(getAllCategoriesRest.getResponse()); + JsonArray cagegories = jElement.getAsJsonArray(); + Iterator iter = cagegories.iterator(); + while (iter.hasNext()) { + JsonElement next = iter.next(); + CategoryDefinition category = ResponseParser.parseToObject(next.toString(), CategoryDefinition.class); + categories.add(category); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return categories; + } + + public static JSONArray getListFromJson(RestResponse res, String field) throws JSONException { + String valueFromJsonResponse = getValueFromJsonResponse(res.getResponse(), field); + JSONArray jArr = new JSONArray(valueFromJsonResponse); + + return jArr; + } + + public static List getDerivedListFromJson(RestResponse res) throws JSONException { + JSONArray listFromJson = getListFromJson(res, "derivedList"); + List lst = new ArrayList(); + for (int i = 0; i < listFromJson.length(); i++) { + lst.add(listFromJson.getString(i)); + } + + return lst; + } + + public static Map convertStringToMap(String obj) { + Map object = (Map) JSONValue.parse(obj); + return object; + } + + public static List> getListOfMapsFromJson(RestResponse res, String field) throws Exception { + List> list = new ArrayList>(); + JSONArray listFromJson = getListFromJson(res, field); + for (int i = 0; i < listFromJson.length(); i++) { + Map convertStringToMap = convertStringToMap(listFromJson.getString(i)); + list.add(convertStringToMap); + } + return list; + + } + + public static Map getJsonValueAsMap(RestResponse response, String key) { + String valueField = getValueFromJsonResponse(response.getResponse(), key); + Map convertToMap = convertStringToMap(valueField); + return convertToMap; + } + + public static String getJsonObjectValueByKey(String metadata, String key) { + JsonElement jelement = new JsonParser().parse(metadata); + + JsonObject jobject = jelement.getAsJsonObject(); + Object obj = jobject.get(key); + if (obj == null) { + return null; + } else { + return obj.toString(); + } + } + + public static Map> convertCatalogResponseToJavaObject(String response) { + + Map> map = new HashMap>(); + + JsonElement jElement = new JsonParser().parse(response); + JsonObject jObject = jElement.getAsJsonObject(); + JsonArray jArrReousrces = jObject.getAsJsonArray("resources"); + JsonArray jArrServices = jObject.getAsJsonArray("services"); + JsonArray jArrProducts = jObject.getAsJsonArray("products"); + + //////// RESOURCE///////////////////////////// + ArrayList restResponseArray = new ArrayList<>(); + Component component = null; + for (int i = 0; i < jArrReousrces.size(); i++) { + String resourceString = (String) jArrReousrces.get(i).toString(); + component = ResponseParser.convertResourceResponseToJavaObject(resourceString); + restResponseArray.add(component); + } + + map.put("resources", restResponseArray); + + ///////// SERVICE///////////////////////////// + + restResponseArray = new ArrayList<>(); + component = null; + for (int i = 0; i < jArrServices.size(); i++) { + String resourceString = (String) jArrServices.get(i).toString(); + component = ResponseParser.convertServiceResponseToJavaObject(resourceString); + restResponseArray.add(component); + } + + map.put("services", restResponseArray); + + ///////// PRODUCT///////////////////////////// + restResponseArray = new ArrayList<>(); + component = null; + for (int i = 0; i < jArrProducts.size(); i++) { + String resourceString = (String) jArrProducts.get(i).toString(); + component = ResponseParser.convertProductResponseToJavaObject(resourceString); + restResponseArray.add(component); + } + + map.put("products", restResponseArray); + + return map; + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceRestUtils.java new file mode 100644 index 0000000000..d62c74c3d2 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/ServiceRestUtils.java @@ -0,0 +1,262 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +public class ServiceRestUtils extends BaseRestUtils { + private static Logger logger = LoggerFactory.getLogger(ServiceRestUtils.class.getName()); + private final static String cacheControl = "no-cache"; + private final static String contentTypeHeaderData = "application/json"; + private final static String acceptHeaderDate = "application/json"; + // ****** CREATE ******* + + private static Gson gson = new Gson(); + + public static RestResponse deleteService(String serviceName, String version, User sdncModifierDetails) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_SERVICE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), config.getCatalogBePort(), serviceName, version); + String userId = sdncModifierDetails.getUserId(); + RestResponse sendDelete = sendDelete(url, userId); + deleteMarkedServices(userId); + return sendDelete; + } + + public static RestResponse deleteServiceById(String serviceId, String userId) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.DELETE_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId); + RestResponse sendDelete = sendDelete(url, userId); + deleteMarkedServices(userId); + return sendDelete; + } + + public static void deleteMarkedServices(String userId) throws IOException { + String url; + Config config = Utils.getConfig(); + url = String.format(Urls.DELETE_MARKED_SERVICES, config.getCatalogBeHost(), config.getCatalogBePort()); + sendDelete(url, userId); + } + + public static RestResponse createService(ServiceReqDetails service, User user) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.CREATE_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort()); + String serviceBodyJson = gson.toJson(service); + + logger.debug("Send POST request to create service: {]", url); + logger.debug("Service body: {}", serviceBodyJson); + + RestResponse res = sendPost(url, serviceBodyJson, user.getUserId(), acceptHeaderData); + if (res.getErrorCode() == STATUS_CODE_CREATED) { + service.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + service.setVersion(ResponseParser.getVersionFromResponse(res)); + service.setUUID(ResponseParser.getUuidFromResponse(res)); + // Creator details never change after component is created - Ella, + // 12/1/2016 + service.setCreatorUserId(user.getUserId()); + service.setCreatorFullName(user.getFullName()); + } + + return res; + } + + public static RestResponse updateService(ServiceReqDetails service, User user) throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.UPDATE_SERVICE_METADATA, config.getCatalogBeHost(), config.getCatalogBePort(), + service.getUniqueId()); + String serviceBodyJson = gson.toJson(service); + + logger.debug("Send PUT request to create service: {}", url); + logger.debug("Service body: {}", serviceBodyJson); + + RestResponse res = sendPut(url, serviceBodyJson, user.getUserId(), acceptHeaderData); + if (res.getErrorCode() == STATUS_CODE_CREATED) { + service.setUniqueId(ResponseParser.getUniqueIdFromResponse(res)); + service.setVersion(ResponseParser.getVersionFromResponse(res)); + } + + return res; + } + + public static RestResponse getService(ServiceReqDetails serviceReqDetails, User sdncModifierDetails) + throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), + serviceReqDetails.getUniqueId()); + return getServiceFromUrl(url, sdncModifierDetails, false); + } + + public static RestResponse getService(String serviceId, User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SERVICE, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId); + return getServiceFromUrl(url, sdncModifierDetails, false); + } + + public static RestResponse getServiceByNameAndVersion(User sdncModifierDetails, String serviceName, + String serviceVersion) throws IOException { + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SERVICE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), serviceName, serviceVersion); + return getServiceFromUrl(url, sdncModifierDetails, false); + } + + public static RestResponse getServiceFromUrl(String url, User sdncModifierDetails, boolean isCached) + throws IOException { + Map headersMap = prepareHeadersMap(sdncModifierDetails, isCached); + HttpRequest http = new HttpRequest(); + logger.debug("Send GET request to create service: {}", url); + logger.debug("Service headers: {}", headersMap); + RestResponse sendGetServerRequest = http.httpSendGet(url, headersMap); + + return sendGetServerRequest; + } + + public static Map prepareHeadersMap(User sdncModifierDetails, boolean isCached) { + Map headersMap = new HashMap(); + if (isCached) + headersMap.put(HttpHeaderEnum.CACHE_CONTROL.getValue(), cacheControl); + + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + return headersMap; + } + + public static RestResponse approveServiceDistribution(String serviceId, String userId) throws Exception { + return changeServiceDistributionState(serviceId, userId, Urls.APPROVE_DISTRIBUTION); + } + + public static RestResponse rejectServiceDistribution(String serviceId, String userId) throws Exception { + return changeServiceDistributionState(serviceId, userId, Urls.REJECT_DISTRIBUTION); + } + + // Benny + public static RestResponse rejectServiceDistribution(String serviceId, String userId, String comment) + throws Exception { + Config config = Utils.getConfig(); + String url = String.format(Urls.REJECT_DISTRIBUTION, config.getCatalogBeHost(), config.getCatalogBePort(), + serviceId); + String userBodyJson = gson.toJson(comment); + return sendPost(url, userBodyJson, userId, acceptHeaderData); + + } + + private static RestResponse changeServiceDistributionState(String serviceId, String userId, String distributionUrl) + throws Exception { + Config config = Utils.getConfig(); + String url = String.format(distributionUrl, config.getCatalogBeHost(), config.getCatalogBePort(), serviceId); + String defComment = "{ userRemarks : \"this is an test\" }"; + String userBodyJson = gson.toJson(defComment); + return sendPost(url, userBodyJson, userId, acceptHeaderData); + + } + + public static RestResponse getServiceLatestVersionList(User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + String url = String.format(Urls.GET_SERVICE_lATEST_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort()); + + return sendGet(url, sdncModifierDetails.getUserId()); + + } + + public static RestResponse createServiceByHttpMethod(ServiceReqDetails serviceDetails, User sdncModifierDetails, + String method, String urls) throws IOException { + Map headersMap = prepareHeadersMap(sdncModifierDetails, true); + + Config config = Utils.getConfig(); + String serviceBodyJson = gson.toJson(serviceDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(urls, config.getCatalogBeHost(), config.getCatalogBePort()); + // TODO: ADD AUTHENTICATION IN REQUEST + logger.debug(url); + logger.debug("Send {} request to create user: {}", method, url); + logger.debug("User body: {}", serviceBodyJson); + logger.debug("User headers: {}", headersMap); + RestResponse sendCreateUserRequest = http.httpSendByMethod(url, method, serviceBodyJson, headersMap); + + return sendCreateUserRequest; + + } + + public static RestResponse deleteServiceByNameAndVersion(User sdncModifierDetails, String serviceName, + String serviceVersion) throws IOException { + Config config = Utils.getConfig(); + + Map headersMap = prepareHeadersMap(sdncModifierDetails, true); + + HttpRequest http = new HttpRequest(); + + String url = String.format(Urls.DELETE_SERVICE_BY_NAME_AND_VERSION, config.getCatalogBeHost(), + config.getCatalogBePort(), serviceName, serviceVersion); + RestResponse deleteResponse = http.httpSendDelete(url, headersMap); + + return deleteResponse; + } + + public static RestResponse getFollowed(User user) throws Exception { + Config config = Utils.getConfig(); + + HttpRequest httpRequest = new HttpRequest(); + + String url = String.format(Urls.GET_FOLLWED_LIST, config.getCatalogBeHost(), config.getCatalogBePort()); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), user.getUserId()); + + RestResponse getResourceNotAbstarctResponse = httpRequest.httpSendGet(url, headersMap); + + return getResourceNotAbstarctResponse; + } + + public static JSONArray getListArrayFromRestResponse(RestResponse restResponse) { + String json = restResponse.getResponse(); + JSONObject jsonResp = (JSONObject) JSONValue.parse(json); + JSONArray servicesArray = (JSONArray) jsonResp.get("services"); + + logger.debug("services = {}", servicesArray); + + return servicesArray; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/UserRestUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/UserRestUtils.java new file mode 100644 index 0000000000..a8f39b9ad8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/rest/UserRestUtils.java @@ -0,0 +1,282 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.rest; + +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.run.StartTest; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; + +public class UserRestUtils extends BaseRestUtils { + + static Gson gson = new Gson(); + + static Logger logger = LoggerFactory.getLogger(UserRestUtils.class.getName()); + static String contentTypeHeaderData = "application/json"; + static String acceptHeaderDate = "application/json"; + + public UserRestUtils() { + super(); + + StartTest.enableLogger(); + } + + public static RestResponse createUser(User sdncUserDetails, User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + String userBodyJson = gson.toJson(sdncUserDetails); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.CREATE_USER, config.getCatalogBeHost(), config.getCatalogBePort()); + + logger.debug("Send POST request to create user: {}", url); + logger.debug("User body: {}", userBodyJson); + logger.debug("User headers: {}", headersMap); + RestResponse sendCreateUserRequest = http.httpSendPost(url, userBodyJson, headersMap); + + return sendCreateUserRequest; + + } + + public static RestResponse deactivateUser(User sdncUserDetails, User sdncModifierDetails) throws IOException { + return deleteUser(sdncUserDetails, sdncModifierDetails, true); + } + + public static RestResponse deActivateUser(User sdncUserDetails, User sdncModifierDetails) throws IOException { + return deleteUser(sdncUserDetails, sdncModifierDetails, false); + } + + public static RestResponse deleteUser(User sdncUserDetails, User sdncModifierDetails, boolean isForceDelete) + throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + if (isForceDelete) { + headersMap.put(User.FORCE_DELETE_HEADER_FLAG, User.FORCE_DELETE_HEADER_FLAG); + } + + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.DELETE_USER, config.getCatalogBeHost(), config.getCatalogBePort(), + sdncUserDetails.getUserId()); + RestResponse sendDeleteUserRequest = http.httpSendDelete(url, headersMap); + return sendDeleteUserRequest; + + } + + public static RestResponse updateUser(User sdncUserDetails, User sdncModifierDetails) + throws IOException, CloneNotSupportedException { + + Config config = Utils.getConfig(); + User user = new User(sdncModifierDetails); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + user.setUserId(StringUtils.EMPTY); + user.setRole(StringUtils.EMPTY); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(user); + logger.debug("userBodyJson: {}", userBodyJson); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_USER, config.getCatalogBeHost(), config.getCatalogBePort(), + sdncModifierDetails.getUserId()); + RestResponse sendUpdateUserRequest = http.httpSendPost(url, userBodyJson, headersMap); + + return sendUpdateUserRequest; + } + + /// Benny + public static RestResponse updateUserRole(User sdncUserDetails, User sdncModifierDetails, String userIdToUpdate) + throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + Gson gson = new Gson(); + String userBodyJson = gson.toJson(sdncUserDetails); + logger.debug("userBodyJson: {}", userBodyJson); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.UPDATE_USER_ROLE, config.getCatalogBeHost(), config.getCatalogBePort(), + userIdToUpdate); + RestResponse sendUpdateUserRequest = http.httpSendPost(url, userBodyJson, headersMap); + + return sendUpdateUserRequest; + + } + + public static RestResponse getUser(User sdncUserDetails, User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_USER, config.getCatalogBeHost(), config.getCatalogBePort(), + sdncUserDetails.getUserId()); + RestResponse sendGetUserRequest = http.httpSendGet(url, headersMap); + return sendGetUserRequest; + + } + + public static RestResponse getAllAdminUsers(User sdncModifierDetails) throws IOException { + + Config config = Utils.getConfig(); + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + // Gson gson = new Gson(); + // String userBodyJson = gson.toJson(sdncModifierDetails); + // System.out.println(userBodyJson); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_ALL_ADMIN_USERS, config.getCatalogBeHost(), config.getCatalogBePort()); + logger.debug("Send following url: {} and headers: {}", url, headersMap.toString()); + RestResponse sendGetUserRequest = http.httpSendGet(url, headersMap); + + return sendGetUserRequest; + + } + + // US571255 + public static RestResponse getUsersByRoles(User sdncModifierDetails, String roles) throws IOException { + + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + + HttpRequest http = new HttpRequest(); + String url; + if (roles == "/") { + url = String.format(Urls.GET_ALL_USERS, config.getCatalogBeHost(), config.getCatalogBePort()); + } else { + url = String.format(Urls.GET_USERS_BY_ROLES, config.getCatalogBeHost(), config.getCatalogBePort(), roles); + + } + logger.debug("Send following url: {} and headers: {}", url, headersMap.toString()); + RestResponse sendGetUserRequest = http.httpSendGet(url, headersMap); + return sendGetUserRequest; + } + + public static RestResponse getUsersByRolesHttpCspAtuUidIsMissing(User sdncModifierDetails, String roles) + throws Exception { + + Config config = Utils.getConfig(); + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), contentTypeHeaderData); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), acceptHeaderDate); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncModifierDetails.getUserId()); + headersMap.remove("USER_ID"); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.GET_USERS_BY_ROLES, config.getCatalogBeHost(), config.getCatalogBePort(), + roles); + logger.debug( + "Send following url without USER_ID header : " + url + " headers: " + headersMap.toString()); + + RestResponse sendGetUserRequest = http.httpSendGet(url, headersMap); + return sendGetUserRequest; + } + + public static RestResponse authorizedUserTowardsCatalogBe(User sdncUserDetails) throws IOException { + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + if (sdncUserDetails.getFirstName() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_FIRSTNAME.getValue(), sdncUserDetails.getFirstName()); + } + if (sdncUserDetails.getLastName() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_LASTNAME.getValue(), sdncUserDetails.getLastName()); + } + if (sdncUserDetails.getEmail() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_EMAIL.getValue(), sdncUserDetails.getEmail()); + } + + logger.debug("headersMap: {}", headersMap.toString()); + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.AUTHORIZE_USER, config.getCatalogBeHost(), config.getCatalogBePort()); + logger.debug("Send GET request to login as seal user : {}", url); + return http.httpSendGet(url, headersMap); + } + + public static RestResponse authorizedUserTowardsCatalogBeQA(User sdncUserDetails) throws IOException { + + Map headersMap = new HashMap(); + headersMap.put(HttpHeaderEnum.CONTENT_TYPE.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.ACCEPT.getValue(), "application/json"); + headersMap.put(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + if (sdncUserDetails.getFirstName() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_FIRSTNAME.getValue(), sdncUserDetails.getFirstName()); + } + if (sdncUserDetails.getLastName() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_LASTNAME.getValue(), sdncUserDetails.getLastName()); + } + if (sdncUserDetails.getEmail() != null) { + headersMap.put(HttpHeaderEnum.HTTP_CSP_EMAIL.getValue(), sdncUserDetails.getEmail()); + } + + logger.debug("headersMap: {}", headersMap.toString()); + + Config config = Utils.getConfig(); + HttpRequest http = new HttpRequest(); + String url = String.format(Urls.AUTHORIZE_USER, config.getCatalogBeHost(), config.getCatalogBePort()); + logger.debug("Send GET request to login as seal user : {}", url); + return http.httpSendGet(url, headersMap); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ArtifactValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ArtifactValidationUtils.java new file mode 100644 index 0000000000..21b520c97a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ArtifactValidationUtils.java @@ -0,0 +1,228 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import org.codehaus.jackson.JsonParseException; +import org.codehaus.jackson.JsonProcessingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Decoder; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.FileUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; + +public class ArtifactValidationUtils { + + private static String desc = "description"; + private static String artifactType = "artifactType"; + private static String artifactName = "artifactName"; + private static String artifactChecksum = "artifactChecksum"; + private static String uniqueId = "uniqueId"; + protected Utils utils; + + public static void validateInformationalArtifact(ArtifactReqDetails expectedArtifact, + Map actualArtifact) { + assertTrue("description is not as expected", + expectedArtifact.getDescription().equals(actualArtifact.get(desc).toString())); + assertTrue("artifactType is not as expected", + expectedArtifact.getArtifactType().toUpperCase().equals(actualArtifact.get(artifactType).toString())); + assertTrue("artifactName is not as expected", + expectedArtifact.getArtifactName().equals(actualArtifact.get(artifactName).toString())); + assertTrue("uniqueId is not as expected", + expectedArtifact.getUniqueId().equals(actualArtifact.get(uniqueId).toString())); + assertTrue("description is not as expected", expectedArtifact.getArtifactLabel().toLowerCase() + .equals(actualArtifact.get("artifactLabel").toString())); + } + + public static void validateArtifactsNumberInComponent(Component component, ArtifactGroupTypeEnum artifactGroupType, + ArtifactTypeEnum artifactType, int expectedNumber) { + Map deploymentArtifacts; + int counter = 0; + if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) { + deploymentArtifacts = component.getDeploymentArtifacts(); + } else { + deploymentArtifacts = component.getArtifacts(); + } + if (deploymentArtifacts != null) { + for (ArtifactDefinition artifactDefinition : deploymentArtifacts.values()) { + if (artifactDefinition.getArtifactType().equals(artifactType.getType())) { + counter++; + } + } + } + assertEquals("Unexpected number of " + artifactGroupType.getType() + " artifacts in component", expectedNumber, + counter); + } + + // Benny + public static void validateArtifactsNumberInComponentInstance(ComponentInstance componentInstance, + ArtifactGroupTypeEnum artifactGroupType, ArtifactTypeEnum artifactType, int expectedNumber) { + Map deploymentArtifacts = null; + int counter = 0; + if (artifactGroupType == ArtifactGroupTypeEnum.DEPLOYMENT) { + deploymentArtifacts = componentInstance.getDeploymentArtifacts(); + } + if (deploymentArtifacts != null) { + for (ArtifactDefinition artifactDefinition : deploymentArtifacts.values()) { + if (artifactDefinition.getArtifactType().equals(artifactType.getType())) { + counter++; + } + } + } + assertEquals("Unexpected number of " + artifactGroupType.getType() + " artifacts in component", expectedNumber, + counter); + } + + public static ESArtifactData parseArtifactRespFromES(RestResponse resResponse) + throws JsonParseException, JsonProcessingException, Exception { + String bodyToParse = resResponse.getResponse(); + JsonElement jElement = new JsonParser().parse(bodyToParse); + JsonElement jsourceElement = jElement.getAsJsonObject().get("_source"); + + ObjectMapper mapper = new ObjectMapper(); + ESArtifactData esArtifactObject = mapper.readValue(jsourceElement.toString(), ESArtifactData.class); + + // logger.debug("got artifact details from ElasticSearch as json"); + + return esArtifactObject; + + } + + public static void validateArtifactReqVsResp(ArtifactReqDetails expectedArtifactDetails, + ArtifactDefinition actualArtifactJavaObject) { + String expected; + + expected = expectedArtifactDetails.getArtifactName(); + if (expected == null) + expected = ""; + assertEquals("artifact name is not correct ", expected, actualArtifactJavaObject.getArtifactName()); + + expected = expectedArtifactDetails.getArtifactType(); + if (expected == null) + expected = ""; + assertEquals("artifact type is not correct ", expected, actualArtifactJavaObject.getArtifactType()); + + expected = expectedArtifactDetails.getDescription(); + if (expected == null) + expected = ""; + assertEquals("artifact description is not correct ", expected, actualArtifactJavaObject.getDescription()); + + expected = expectedArtifactDetails.getArtifactLabel(); + if (expected == null || expected == "") { + expected = expectedArtifactDetails.getArtifactName().toLowerCase().substring(0, + expectedArtifactDetails.getArtifactName().lastIndexOf(".")); + // expected = tmp.substring(0, + // artifactInfo.getArtifactName().lastIndexOf(".")); + } + assertEquals("artifact label is not correct ", expected, actualArtifactJavaObject.getArtifactLabel()); + + expected = expectedArtifactDetails.getUrl(); + if (expected != "") { + assertEquals(expected, actualArtifactJavaObject.getApiUrl()); + assertEquals(expectedArtifactDetails.getArtifactDisplayName(), + actualArtifactJavaObject.getArtifactDisplayName()); + } + + // assertEquals(validChecksum, + // actualArtifactJavaObject.getArtifactChecksum()); + + // expected = expectedArtifactDetails.getArtifactDisplayName(); + // if (expected != "") + // { + // assertEquals(expected, + // actualArtifactJavaObject.getArtifactDisplayName()); + // } + + boolean actual = actualArtifactJavaObject.getMandatory(); + assertEquals(expectedArtifactDetails.isMandatory(), actual); + + if (actualArtifactJavaObject.getServiceApi()) { + + boolean actual2 = actualArtifactJavaObject.getServiceApi(); + assertEquals(expectedArtifactDetails.isServiceApi(), actual2); + } + + } + + public static void validateEsArtifactReqVsResp(ArtifactReqDetails expectedArtifactInfo, + ESArtifactData esArtifactData) throws Exception { + String expectedArtifactUid = expectedArtifactInfo.getUniqueId(); + if (expectedArtifactUid == null) + expectedArtifactUid = ""; + assertEquals("artifact name is not correct ", expectedArtifactUid, esArtifactData.getId()); + + String actualPayload = Decoder.encode(esArtifactData.getData().array()); + assertEquals("artifact payloadData is not correct ", expectedArtifactInfo.getPayload(), actualPayload); + } + + public static List getListOfArtifactFromFolder(String folderName) throws IOException, Exception { + Config config = Utils.getConfig(); + String sourceDir = config.getResourceConfigDir(); + String testResourcesPath = sourceDir + File.separator + folderName; + List listofFiles = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + return listofFiles; + } + + public static ArtifactReqDetails replaceDefaultArtWithArtFromList_(ArtifactReqDetails heatArtifactDetails, + String heatExtension, String folderName, int positionInlist) throws IOException, Exception { + + Config config = Utils.getConfig(); + String ext = heatExtension; + String sourceDir = config.getResourceConfigDir(); + String testResourcesPath = sourceDir + File.separator + folderName; + List listFileName = FileUtils.getFileListFromBaseDirectoryByTestName(testResourcesPath); + // logger.debug("listFileName: {}", listFileName.get(positionInlist)); + String payload = FileUtils.loadPayloadFile(listFileName, ext, true); + heatArtifactDetails.setPayload(payload); + heatArtifactDetails.setArtifactName(listFileName.get(positionInlist) + "." + ext); + return heatArtifactDetails; + } + + public static ArtifactReqDetails replaceDefaultArtWithArtFromList(ArtifactReqDetails heatArtifactDetails, + String heatExtension, String folderName, int positionInlist) throws IOException, Exception { + List listOfArtifactFromFolder = getListOfArtifactFromFolder(folderName); + // logger.debug("listFileName: {}", listOfArtifactFromFolder.get(positionInlist)); + String payload = FileUtils.loadPayloadFileFromListUsingPosition(listOfArtifactFromFolder, heatExtension, true, + positionInlist); + heatArtifactDetails.setPayload(payload); + heatArtifactDetails.setArtifactName(heatArtifactDetails.getArtifactType() + + listOfArtifactFromFolder.get(positionInlist) + "." + heatExtension); + return heatArtifactDetails; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/AuditValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/AuditValidationUtils.java new file mode 100644 index 0000000000..882498a63c --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/AuditValidationUtils.java @@ -0,0 +1,1328 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.io.FileNotFoundException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.log4j.Logger; +import org.codehaus.jettison.json.JSONArray; +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.javatuples.Pair; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.AuditEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.AuditJsonKeysEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ComponentType; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedAuthenticationAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedCategoryAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedDistDownloadAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedEcomConsumerAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedGetUserListAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedProductAudit; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedUserCRUDAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpRequest; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.run.StartTest; +import org.openecomp.sdc.ci.tests.utils.ArtifactUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.cassandra.CassandraUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils.CategoryAuditJsonKeysEnum; +import org.openecomp.sdc.ci.tests.utils.rest.ConsumerRestUtils.EcompConsumerAuditJsonKeysEnum; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; + +import com.datastax.driver.core.ColumnDefinitions; +import com.datastax.driver.core.Row; + +public class AuditValidationUtils { + protected static Logger logger = Logger.getLogger(AuditValidationUtils.class.getName()); + private static final String auditKeySpaceName = "sdcaudit"; + + public AuditValidationUtils() { + super(); + + StartTest.enableLogger(); + logger = Logger.getLogger(AuditValidationUtils.class.getName()); + + } + + public static String buildAuditDescription(ErrorInfo errorInfo, List variables) { + + String auditDesc = errorInfo.getMessageId() + ": " + errorInfo.getMessage(); + for (int i = 0; i < variables.size(); i++) { + if (auditDesc.contains("%" + (i + 1))) { + auditDesc = auditDesc.replace("%" + (i + 1), variables.get(i)); + } + } + + // logger.debug("audit description - {}", auditDesc); + return auditDesc; + } + + public static String getModifierString(String userName, String uid) { + + if (userName.isEmpty() && uid.isEmpty()) + return "(UNKNOWN)"; + + StringBuilder sb = new StringBuilder(); + sb.append(userName).append("(").append(uid).append(")"); + return sb.toString(); + + } + + public static void validateAuditDownloadExternalAPI(ExpectedResourceAuditJavaObject resourceAuditJavaObject, + String action, String body, boolean checkAllFields) throws Exception { + Map actualAuditRecords = new HashMap(); + // Andrey's comment + // actualAuditRecords = parseAuditResourceByAction(action, body); + actualAuditRecords = parseAuditResourceByAction(action, null); + + // List> actualAuditRecords = new + // ArrayList>(); + // actualAuditRecords = parseAuditResourceByActionToList(action, body); + + validateField(actualAuditRecords, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(actualAuditRecords, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(actualAuditRecords, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + + validateField(actualAuditRecords, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getStatus()); + validateField(actualAuditRecords, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + resourceAuditJavaObject.getDesc()); + + // validateField(actualAuditRecords, + // AuditJsonKeysEnum.CONSUMER_ID.getAuditJsonKeyName(), + // resourceAuditJavaObject.getCONSUMER_ID()); + // validateField(actualAuditRecords, + // AuditJsonKeysEnum.RESOURCE_URL.getAuditJsonKeyName(), + // resourceAuditJavaObject.getRESOURCE_URL()); + + } + + public static void validateAudit(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action, + String body, boolean checkAllFields) throws Exception { + Map actualAuditRecords = new HashMap(); + // Andrey's comment + // actualAuditRecords = parseAuditResourceByAction(action, body); + actualAuditRecords = parseAuditResourceByAction(action, null); + + if ((resourceAuditJavaObject.getModifierName() != null) && (resourceAuditJavaObject.getModifierUid() != null)) { + resourceAuditJavaObject.setModifierUid(getModifierString(resourceAuditJavaObject.getModifierName(), + resourceAuditJavaObject.getModifierUid())); + } + + validateField(actualAuditRecords, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(actualAuditRecords, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(actualAuditRecords, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(actualAuditRecords, AuditJsonKeysEnum.PREV_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getPrevVersion()); + validateField(actualAuditRecords, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + + validateField(actualAuditRecords, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + resourceAuditJavaObject.getModifierUid()); + validateField(actualAuditRecords, AuditJsonKeysEnum.PREV_STATE.getAuditJsonKeyName(), + resourceAuditJavaObject.getPrevState()); + validateField(actualAuditRecords, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrState()); + validateField(actualAuditRecords, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getStatus()); + // validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + // Double.parseDouble(resourceAuditJavaObject.getStatus())); + validateField(actualAuditRecords, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + resourceAuditJavaObject.getDesc()); + validateField(actualAuditRecords, AuditJsonKeysEnum.COMMENT.getAuditJsonKeyName(), + resourceAuditJavaObject.getComment()); + // validateField(map2, + // AuditJsonKeysEnum.ARTIFACT_DATA.getAuditJsonKeyName(), + // resourceAuditJavaObject.getArtifactData()); + validateField(actualAuditRecords, AuditJsonKeysEnum.TOSCA_NODE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getToscaNodeType()); + validateField(actualAuditRecords, AuditJsonKeysEnum.CURR_ARTIFACT_UUID.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrArtifactUuid()); + validateField(actualAuditRecords, AuditJsonKeysEnum.PREV_ARTIFACT_UUID.getAuditJsonKeyName(), + resourceAuditJavaObject.getPrevArtifactUuid()); + + validateAtifactDataField(actualAuditRecords, AuditJsonKeysEnum.ARTIFACT_DATA.getAuditJsonKeyName(), + resourceAuditJavaObject.getArtifactData(), checkAllFields); + } + + public static void validateExternalAudit(ExpectedExternalAudit externalAuditObject, String action, + Map body) throws Exception { + + Map actualAuditRecord = new HashMap(); + actualAuditRecord = parseAuditResourceByAction(action, body); + + validateField(actualAuditRecord, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(actualAuditRecord, AuditJsonKeysEnum.CONSUMER_ID.getAuditJsonKeyName(), + externalAuditObject.getCONSUMER_ID()); + validateField(actualAuditRecord, AuditJsonKeysEnum.RESOURCE_URL.getAuditJsonKeyName(), + externalAuditObject.getRESOURCE_URL()); + validateField(actualAuditRecord, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + externalAuditObject.getRESOURCE_NAME()); + validateField(actualAuditRecord, AuditJsonKeysEnum.SERVICE_INSTANCE_ID.getAuditJsonKeyName(), + externalAuditObject.getSERVICE_INSTANCE_ID()); + validateField(actualAuditRecord, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + externalAuditObject.getRESOURCE_TYPE()); + validateField(actualAuditRecord, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + externalAuditObject.getSTATUS()); + validateField(actualAuditRecord, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + externalAuditObject.getDESC()); + validateField(actualAuditRecord, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + externalAuditObject.getMODIFIER()); + validateField(actualAuditRecord, AuditJsonKeysEnum.PREV_ARTIFACT_UUID.getAuditJsonKeyName(), + externalAuditObject.getPREV_ARTIFACT_UUID()); + validateField(actualAuditRecord, AuditJsonKeysEnum.CURR_ARTIFACT_UUID.getAuditJsonKeyName(), + externalAuditObject.getCURR_ARTIFACT_UUID()); + validateField(actualAuditRecord, AuditJsonKeysEnum.ARTIFACT_DATA.getAuditJsonKeyName(), + externalAuditObject.getARTIFACT_DATA()); + + } + + public enum ArtifactDataFieldEnum { + attGroup, artLable, artType, artName, artTimeout, artPayloadUUID, artVersion, artUUID + } + + private static void validateAtifactDataField(Map map, String auditJsonKeyName, + String expectedArtifactData, boolean checkAllFields) { + Map expectedArtifactDataFileds = new HashMap(); + Map actualAtifactDataFileds = new HashMap(); + if (expectedArtifactData != null) { + String[] expected = expectedArtifactData.split(","); + + assertTrue("Audit field " + auditJsonKeyName + " not found", map.containsKey(auditJsonKeyName)); + String actualValue = (String) map.get(auditJsonKeyName); + String[] actual = actualValue.split(","); + + if (expected.length == 1 && actual.length == 1) { + assertEquals(expectedArtifactData, actualValue); + return; + } + + assertEquals(ArtifactDataFieldEnum.values().length, expected.length); + assertEquals(ArtifactDataFieldEnum.values().length, actual.length); + + for (ArtifactDataFieldEnum field : ArtifactDataFieldEnum.values()) { + + expectedArtifactDataFileds.put(field, expected[field.ordinal()]); + actualAtifactDataFileds.put(field, actual[field.ordinal()]); + } + for (Map.Entry entry : expectedArtifactDataFileds.entrySet()) { + ArtifactDataFieldEnum field = entry.getKey(); + if (checkAllFields || (!field.equals(ArtifactDataFieldEnum.artVersion) + && !field.equals(ArtifactDataFieldEnum.artUUID))) { + assertTrue("Audit field ArtifactData dosn't containt " + field, + actualAtifactDataFileds.containsKey(field)); + assertEquals("Audit field ArtifactData dosn't equal " + field, + expectedArtifactDataFileds.get(field), actualAtifactDataFileds.get(field)); + } + + } + } + } + + // //Benny + public static void validateEcompConsumerAudit(ExpectedEcomConsumerAudit ecompConsumerAuditJavaObject, String action) + throws Exception { + + String fixedAction = BaseRestUtils.encodeUrlForDownload(action); + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(fixedAction, null); + + validateField(map2, EcompConsumerAuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + ecompConsumerAuditJavaObject.getModifier()); + validateField(map2, EcompConsumerAuditJsonKeysEnum.ECOMP_USER.getAuditJsonKeyName(), + ecompConsumerAuditJavaObject.getEcomUser()); + validateField(map2, EcompConsumerAuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + ecompConsumerAuditJavaObject.getStatus()); + validateField(map2, EcompConsumerAuditJsonKeysEnum.DESC.getAuditJsonKeyName(), + ecompConsumerAuditJavaObject.getDesc()); + validateField(map2, EcompConsumerAuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + } + + public static void ecompConsumerAuditSuccess(String action, ConsumerDataDefinition consumerDataDefinition, + User user, int status) throws Exception { + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(action); + expectedEcomConsumerAuditJavaObject.setEcomUser( + consumerDataDefinition.getConsumerName() + "," + consumerDataDefinition.getConsumerSalt().toLowerCase() + + "," + consumerDataDefinition.getConsumerPassword().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(String.valueOf(status)); + expectedEcomConsumerAuditJavaObject.setDesc("OK"); + expectedEcomConsumerAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, action); + } + + public static void createEcompConsumerAuditFailure(String action, ConsumerDataDefinition consumerDataDefinition, + User user, ActionStatus errorMessage, Object... variables) throws Exception { + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorMessage.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + expectedEcomConsumerAuditJavaObject.setAction(action); + expectedEcomConsumerAuditJavaObject.setEcomUser( + consumerDataDefinition.getConsumerName() + "," + consumerDataDefinition.getConsumerSalt().toLowerCase() + + "," + consumerDataDefinition.getConsumerPassword().toLowerCase()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + expectedEcomConsumerAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, action); + } + + public static void deleteEcompConsumerAuditFailure(String action, ConsumerDataDefinition consumerDataDefinition, + User user, ActionStatus errorMessage, Object... variables) throws Exception { + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorMessage.name()); + ExpectedEcomConsumerAudit expectedEcomConsumerAuditJavaObject = new ExpectedEcomConsumerAudit(); + // String auditAction = ADD_ECOMP_USER_CREDENTIALS_AUDIT_ACTION; + expectedEcomConsumerAuditJavaObject.setAction(action); + expectedEcomConsumerAuditJavaObject.setEcomUser(consumerDataDefinition.getConsumerName()); + expectedEcomConsumerAuditJavaObject.setStatus(errorInfo.getCode().toString()); + expectedEcomConsumerAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + expectedEcomConsumerAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + AuditValidationUtils.validateEcompConsumerAudit(expectedEcomConsumerAuditJavaObject, action); + } + + ////////////////////// US571255 + public static void GetListOfUsersByRolesAuditFailure(String action, String roles, int status, User userModifier, + ActionStatus errorMessage, Object... variables) throws Exception { + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorMessage.name()); + ExpectedGetUserListAudit expectedGetListOfUsersAuditJavaObject = new ExpectedGetUserListAudit(); // String + // auditAction + // = + // ADD_ECOMP_USER_CREDENTIALS_AUDIT_ACTION; + expectedGetListOfUsersAuditJavaObject.setAction(action); + expectedGetListOfUsersAuditJavaObject.setStatus(String.valueOf(status)); + expectedGetListOfUsersAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + + expectedGetListOfUsersAuditJavaObject.setDetails(roles); + if (errorMessage == ActionStatus.USER_INACTIVE || errorMessage == ActionStatus.MISSING_INFORMATION) { + expectedGetListOfUsersAuditJavaObject.setModifier("(UNKNOWN)"); + } else { + expectedGetListOfUsersAuditJavaObject + .setModifier(userModifier.getFullName() + "(" + userModifier.getUserId() + ")"); + } + AuditValidationUtils.validateAuditGetListOfUsersByRoles(expectedGetListOfUsersAuditJavaObject, action); + } + + public static void GetListOfUsersByRolesAuditSuccess(String action, String roles, User user, int status) + throws Exception { + ExpectedGetUserListAudit expectedGetListOfUsersAuditJavaObject = new ExpectedGetUserListAudit(); + expectedGetListOfUsersAuditJavaObject.setAction(action); + expectedGetListOfUsersAuditJavaObject.setStatus(String.valueOf(status)); + expectedGetListOfUsersAuditJavaObject.setDesc("OK"); + expectedGetListOfUsersAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + expectedGetListOfUsersAuditJavaObject.setDetails(roles); + validateAuditGetListOfUsersByRoles(expectedGetListOfUsersAuditJavaObject, action); + } + + public static void validateAuditGetListOfUsersByRoles(ExpectedGetUserListAudit GetListOfUsersAuditJavaObject, + String action) throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), GetListOfUsersAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + GetListOfUsersAuditJavaObject.getModifier()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + GetListOfUsersAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.DETAILS.getAuditJsonKeyName(), + GetListOfUsersAuditJavaObject.getDetails()); + } + + public static void validateAuditImport(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action) + throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + resourceAuditJavaObject.setModifierUid( + getModifierString(resourceAuditJavaObject.getModifierName(), resourceAuditJavaObject.getModifierUid())); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.PREV_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getPrevVersion()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), resourceAuditJavaObject.getModifierUid()); + validateField(map2, AuditJsonKeysEnum.PREV_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getPrevState()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getCurrState()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + + } + + public static void validateAuditDistribution(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action) + throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + resourceAuditJavaObject.setModifierUid( + getModifierString(resourceAuditJavaObject.getModifierName(), resourceAuditJavaObject.getModifierUid())); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), resourceAuditJavaObject.getModifierUid()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getCurrState()); + validateField(map2, AuditJsonKeysEnum.DPREV_STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getDprevStatus()); + validateField(map2, AuditJsonKeysEnum.DCURR_STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getDcurrStatus()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.COMMENT.getAuditJsonKeyName(), resourceAuditJavaObject.getComment()); + validateField(map2, AuditJsonKeysEnum.DID.getAuditJsonKeyName(), resourceAuditJavaObject.getDistributionId()); + + } + + // Benny + public static void validateAudit_Distribution(ExpectedResourceAuditJavaObject resourceAuditJavaObject, + String action) throws Exception { + + List> actionToList = getAuditListByAction(resourceAuditJavaObject.getAction(), 1); + Map map2 = actionToList.get(0); + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), resourceAuditJavaObject.getMODIFIER()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getCurrState()); + validateField(map2, AuditJsonKeysEnum.DPREV_STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getDprevStatus()); + validateField(map2, AuditJsonKeysEnum.DCURR_STATUS.getAuditJsonKeyName(), + resourceAuditJavaObject.getDcurrStatus()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.COMMENT.getAuditJsonKeyName(), resourceAuditJavaObject.getComment()); + + } + + public void validateAuditNotification(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action) + throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + resourceAuditJavaObject.setModifierUid( + getModifierString(resourceAuditJavaObject.getModifierName(), resourceAuditJavaObject.getModifierUid())); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getCurrState()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.DID.getAuditJsonKeyName(), resourceAuditJavaObject.getDistributionId()); + validateField(map2, AuditJsonKeysEnum.TOPIC_NAME.getAuditJsonKeyName(), resourceAuditJavaObject.getTopicName()); + + } + + public static void validateAudit(ExpectedDistDownloadAudit expectedDistDownloadAudit, String action) + throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), expectedDistDownloadAudit.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), expectedDistDownloadAudit.getDesc()); + validateField(map2, AuditJsonKeysEnum.CONSUMER_ID.getAuditJsonKeyName(), + expectedDistDownloadAudit.getConsumerId()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_URL.getAuditJsonKeyName(), + expectedDistDownloadAudit.getResourceUrl()); + } + + public void validateAuditDeploy(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action) + throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + resourceAuditJavaObject.setModifierUid( + getModifierString(resourceAuditJavaObject.getModifierName(), resourceAuditJavaObject.getModifierUid())); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), resourceAuditJavaObject.getModifierUid()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.DID.getAuditJsonKeyName(), resourceAuditJavaObject.getDistributionId()); + + } + + public static void validateAuditProduct(ExpectedProductAudit productExpectedAudit, String action, + AuditJsonKeysEnum... additionalFields) throws Exception { + + Map map2 = new HashMap(); + map2 = parseAuditResourceByAction(action, null); + + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + productExpectedAudit.getRESOURCE_NAME()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + productExpectedAudit.getRESOURCE_TYPE()); + validateField(map2, AuditJsonKeysEnum.PREV_VERSION.getAuditJsonKeyName(), + productExpectedAudit.getPREV_VERSION()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + productExpectedAudit.getCURR_VERSION()); + validateField(map2, AuditJsonKeysEnum.PREV_STATE.getAuditJsonKeyName(), productExpectedAudit.getPREV_STATE()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), productExpectedAudit.getCURR_STATE()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), productExpectedAudit.getMODIFIER()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), productExpectedAudit.getSTATUS()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), productExpectedAudit.getDESC()); + validateField(map2, AuditJsonKeysEnum.SERVICE_INSTANCE_ID.getAuditJsonKeyName(), + productExpectedAudit.getSERVICE_INSTANCE_ID()); + if (additionalFields != null) { + List fieldsList = Arrays.asList(additionalFields); + if (fieldsList.contains(AuditJsonKeysEnum.COMMENT)) { + validateField(map2, AuditJsonKeysEnum.COMMENT.getAuditJsonKeyName(), productExpectedAudit.getCOMMENT()); + } + } + } + + private static List> getAuditListByAction(String action, int expectedNumOfAudit) + throws Exception { + List> actionToList = parseAuditResourceByActionToList(action, null); + assertEquals("recieved different audits number than expected", expectedNumOfAudit, actionToList.size()); + return actionToList; + } + + public static void validateAuthenticationAudit(ExpectedAuthenticationAudit expectedAudit) throws Exception { + List> actionToList = getAuditListByAction(expectedAudit.getAction(), 1); + assertEquals("expected number of ES action is 1", 1, actionToList.size()); + + Map map = actionToList.get(0); + validateField(map, AuditEnum.ACTION.getValue(), expectedAudit.getAction()); + validateField(map, AuditEnum.URL.getValue(), expectedAudit.getUrl()); + validateField(map, AuditEnum.USER.getValue(), expectedAudit.getUser()); + validateField(map, AuditEnum.AUTH_STATUS.getValue(), expectedAudit.getAuthStatus()); + validateField(map, AuditEnum.REALM.getValue(), expectedAudit.getRealm()); + + } + + private static void validateField(Map actualAuditRecord, String jsonField, Object expectedValue) { + if (expectedValue == null) { + // || changed to && + if (actualAuditRecord.containsKey(jsonField)) { + assertTrue("Audit field " + jsonField + ": expected null, actual " + actualAuditRecord.get(jsonField), + actualAuditRecord.get(jsonField).toString().equals("null") + || actualAuditRecord.get(jsonField).toString().equals(Constants.EMPTY_STRING)); + } + + } else { + assertTrue("Audit field " + jsonField + " not found in actual", actualAuditRecord.containsKey(jsonField)); + Object foundValue = actualAuditRecord.get(jsonField); + compareElements(expectedValue, foundValue); + } + } + + private static void compareElements(Object expectedValue, Object foundValue) { + if (expectedValue instanceof String) { + assertTrue("Actual value " + foundValue + " is not string", foundValue instanceof String); + assertTrue("Expected " + expectedValue + " not equal to actual " + foundValue, + foundValue.equals(expectedValue)); + } + /* + * else if( expectedValue instanceof Number){ assertTrue(foundValue + * instanceof Number); assertTrue(foundValue == expectedValue); } + */ + else if (expectedValue instanceof Boolean) { + assertTrue(foundValue instanceof Boolean); + assertTrue(foundValue == expectedValue); + } else if (expectedValue instanceof Map) { + assertTrue(foundValue instanceof Map); + Map foundMap = (Map) foundValue; + Map excpectedMap = (Map) expectedValue; + assertTrue(foundMap.size() == excpectedMap.size()); + Iterator foundkeyItr = foundMap.keySet().iterator(); + while (foundkeyItr.hasNext()) { + String foundKey = foundkeyItr.next(); + assertTrue(excpectedMap.containsKey(foundKey)); + compareElements(excpectedMap.get(foundKey), foundMap.get(foundKey)); + } + + } else if (expectedValue instanceof List) { + assertTrue(foundValue instanceof List); + List foundList = (List) foundValue; + List excpectedList = (List) expectedValue; + assertTrue(foundList.size() == excpectedList.size()); + for (int i = 0; i < foundList.size(); i++) { + compareElements(excpectedList.get(i), foundList.get(i)); + } + + } else { + assertTrue(foundValue.equals(expectedValue)); + } + } + + // public static Map parseAuditResourceByAction(String + // action, String body) throws Exception { + // + // Map auditingMessage = null; + // auditingMessage = retrieveAuditMessagesByPattern(action, null); + // + // return auditingMessage; + // + // } + + public static Map parseAuditResourceByAction(String action, + Map body) throws Exception { + + Map auditingMessage = null; + auditingMessage = retrieveAuditMessagesByPattern(action, body); + + return auditingMessage; + + } + + // public static List> + // parseAuditResourceByActionToList(String action, String body) throws + // Exception { + // + // List> auditList = new ArrayList>(); + // + //// String auditingMessage = null; + // + // Map auditingMessage = null; + // auditingMessage = retrieveAuditMessagesByPattern(action); + // + // if (body == null) { + //// String pattern = "/_search?q=ACTION:\"" + action + "\""; + //// auditingMessage = retrieveAuditMessagesByPattern(action); + //// auditingMessage = retrieveAuditMessagesByPattern(pattern); + // } else { + //// auditingMessage = retrieveAuditMessagesUsingBody(body); + // } + // + // return ResponseParser.getAuditFromMessage(auditingMessage); + // + // } + + public static List> parseAuditResourceByActionToList(String action, + Map body) throws Exception { + + List> auditList = new ArrayList>(); + + // String auditingMessage = null; + + Map auditingMessage = null; + + if (body == null || body.isEmpty()) { + auditingMessage = retrieveAuditMessagesByPattern(action, null); + // String pattern = "/_search?q=ACTION:\"" + action + "\""; + // auditingMessage = retrieveAuditMessagesByPattern(action); + // auditingMessage = retrieveAuditMessagesByPattern(pattern); + } else { + auditingMessage = retrieveAuditMessagesByPattern(action, body); + // auditingMessage = retrieveAuditMessagesUsingBody(body); + } + + return ResponseParser.getAuditFromMessage(auditingMessage); + + } + + public JSONObject buildElasticQueryStringObject(String defaultField, String queryValue) throws JSONException { + + JSONObject query_string = new JSONObject(); + JSONObject jSONObject = new JSONObject(); + jSONObject.put("default_field", defaultField); + jSONObject.put("query", queryValue); + + query_string.put("query_string", jSONObject); + + return query_string; + } + + public static JSONObject buildElasticQueryBody(List listObjects) throws JSONException { + + JSONObject query = new JSONObject(); + JSONObject bool = new JSONObject(); + JSONObject must = new JSONObject(); + JSONArray mustA = new JSONArray(); + + for (int i = 0; i < listObjects.size(); i++) { + JSONObject match = new JSONObject(); + match.put("match", listObjects.get(i)); + mustA.put(match); + + } + + must.put("must", mustA); + bool.put("bool", must); + query.put("query", bool); + + return query; + } + + public static String retrieveAuditMessagesUsingBody(String query_string) throws IOException { + + Config config = Utils.getConfig(); + HttpRequest getAuditingMessage = new HttpRequest(); + Map headersMap = new HashMap(); + String body = query_string; + + String url = String.format(Urls.GET_SEARCH_DATA_FROM_ES, config.getEsHost(), config.getEsPort(), "_search"); + RestResponse restResponse = getAuditingMessage.httpSendPost(url, body, headersMap); + + return restResponse.getResponse(); + } + + public static Map retrieveAuditMessagesByPattern(String action, Map body) + throws IOException { + + // get cassandra table name by action + String esType = AuditingActionEnum.getActionByName(action).getAuditingEsType(); + + List> myFields = new ArrayList>(); + Pair myPair = new Pair( + AuditingFieldsKeysEnum.AUDIT_ACTION, action); + myFields.add(0, myPair); + if (body != null && !body.isEmpty()) { + for (Map.Entry mapElement : body.entrySet()) { + myFields.add(new Pair(mapElement.getKey(), mapElement.getValue())); + } + } + + List fetchFromTable = CassandraUtils.fetchFromTable(auditKeySpaceName, esType, myFields); + assertTrue("expected on fetching from data base one record only, actual: " + fetchFromTable.size(), + fetchFromTable.size() == 1); + Row row = fetchFromTable.get(0); + + ColumnDefinitions columnDefinitions = row.getColumnDefinitions(); + + Map resultsMap = new HashMap(); + + for (int i = 0; i < columnDefinitions.size(); i++) { + resultsMap.put(columnDefinitions.getName(i), row.getObject(columnDefinitions.getName(i)) == null ? "null" + : row.getObject(columnDefinitions.getName(i)).toString()); + } + + return resultsMap; + } + + // public static Map retrieveAuditMessagesByPattern(String pattern) throws + // IOException { + // + //// Config config = Utils.getConfig(); + //// HttpRequest getAuditingMessage = new HttpRequest(); + //// String url = String.format(Urls.GET_SEARCH_DATA_FROM_ES, + // config.getEsHost(), config.getEsPort(), pattern); + //// RestResponse restResponse = getAuditingMessage.httpSendGet(url, null); + // + //// get cassandra table name by action + // String esType = + // AuditingActionEnum.getActionByName(pattern).getAuditingEsType(); + //// AuditingActionEnum actionByName = + // AuditingActionEnum.getActionByName(pattern); + // + //// Map myFields= new + // HashMap(); + //// myFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION , pattern); + // + // List> myFields = new + // ArrayList>(); + // Pair myPair = new + // Pair(AuditingFieldsKeysEnum.AUDIT_ACTION + // , pattern); + // myFields.add(0, myPair); + // + // + // List fetchFromTable = CassandraUtils.fetchFromTable("sdcaudit", + // esType, myFields); + // Row row = fetchFromTable.get(0); + // + // + // ColumnDefinitions columnDefinitions = row.getColumnDefinitions(); + //// String string = row.getString(columnDefinitions.getName(1)); + // + //// String metaData = row.getColumnDefinitions().toString(); + //// metaData =metaData.replaceAll("\\((.*?)\\)|\\[|\\]|Columns", ""); + //// List metaDataList = new + // ArrayList(Arrays.asList(metaData.split(", "))); + // + // + // + // Map resultsMap = new HashMap(); + // + // + // for (int i=0 ; i < columnDefinitions.size() ; i++){ + // resultsMap.put(columnDefinitions.getName(i) , + // row.getObject(columnDefinitions.getName(i)) == null ? "null" : + // row.getObject(columnDefinitions.getName(i)).toString()); + // } + //// for (String string : metaDataList) { + //// resultsMap.put(string , row.getString(string)); + //// } + //// + // + //// String dataString = fetchFromTable.toString(); + //// dataString = dataString.replaceAll("\\[|\\]|Row", ""); + //// List dataArray = new + // ArrayList(Arrays.asList(dataString.split(", "))); + //// + //// + //// Map resultsMap = new HashMap(); + //// for (int i=0 ; i> actionToList = getAuditListByAction(expectedAddUserAuditJavaObject.getAction(), 1); + Map map = actionToList.get(0); + validateField(map, UserAuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map, UserAuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + expectedAddUserAuditJavaObject.getModifier()); + validateField(map, UserAuditJsonKeysEnum.USER_AFTER.getAuditJsonKeyName(), + expectedAddUserAuditJavaObject.getUserAfter()); + validateField(map, UserAuditJsonKeysEnum.USER_BEFORE.getAuditJsonKeyName(), + expectedAddUserAuditJavaObject.getUserBefore()); + validateField(map, UserAuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + expectedAddUserAuditJavaObject.getStatus()); + validateField(map, UserAuditJsonKeysEnum.DESC.getAuditJsonKeyName(), expectedAddUserAuditJavaObject.getDesc()); + + } + + private static void categoryAuditFailureInternal(String action, CategoryDefinition categoryDataDefinition, + SubCategoryDefinition subCategoryDefinition, GroupingDefinition groupingDefinition, User user, + ActionStatus errorMessage, int status, String resourceType, Object... variables) throws Exception { + // validate audit + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorMessage.name()); + ExpectedCategoryAudit expectedCatrgoryAuditJavaObject = new ExpectedCategoryAudit(); + expectedCatrgoryAuditJavaObject.setAction(action); + expectedCatrgoryAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + expectedCatrgoryAuditJavaObject.setCategoryName(categoryDataDefinition.getName()); + String subCategoryName = (subCategoryDefinition != null ? subCategoryDefinition.getName() + : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setSubCategoryName(subCategoryName); + String groupingName = (groupingDefinition != null ? groupingDefinition.getName() : Constants.EMPTY_STRING); + expectedCatrgoryAuditJavaObject.setGroupingName(groupingName); + expectedCatrgoryAuditJavaObject.setResourceType(resourceType); + expectedCatrgoryAuditJavaObject.setStatus(String.valueOf(status)); + expectedCatrgoryAuditJavaObject.setDesc(errorInfo.getAuditDesc(variables)); + AuditValidationUtils.validateCategoryAudit(expectedCatrgoryAuditJavaObject, action); + } + + public static void validateGetCategoryHirarchy(ExpectedCategoryAudit expectedCatrgoryAuditJavaObject, String action) + throws Exception { + + List> actionToList = getAuditListByAction(expectedCatrgoryAuditJavaObject.getAction(), 1); + Map map = actionToList.get(0); + + expectedCatrgoryAuditJavaObject.setModifier(getModifierString(expectedCatrgoryAuditJavaObject.getModifierName(), + expectedCatrgoryAuditJavaObject.getModifierUid())); + validateField(map, CategoryAuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map, CategoryAuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getModifier()); + validateField(map, CategoryAuditJsonKeysEnum.DETAILS.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getDetails()); + validateField(map, CategoryAuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getStatus()); + validateField(map, CategoryAuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getDesc()); + + } + + public static void validateCategoryAudit(ExpectedCategoryAudit expectedCatrgoryAuditJavaObject, String action) + throws Exception { + + List> actionToList = getAuditListByAction(expectedCatrgoryAuditJavaObject.getAction(), 1); + Map map = actionToList.get(0); + validateField(map, CategoryAuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map, CategoryAuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getModifier()); + validateField(map, CategoryAuditJsonKeysEnum.CATEGORY_NAME.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getCategoryName()); + validateField(map, CategoryAuditJsonKeysEnum.SUB_CATEGORY_NAME.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getSubCategoryName()); + validateField(map, CategoryAuditJsonKeysEnum.GROUPING_NAME.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getGroupingName()); + validateField(map, CategoryAuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getResourceType()); + validateField(map, CategoryAuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getStatus()); + validateField(map, CategoryAuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), + expectedCatrgoryAuditJavaObject.getDesc()); + } + + public static void GetCategoryHierarchyAuditSuccess(String action, String componentType, User user, int status) + throws Exception { + ExpectedGetUserListAudit expectedGetListOfUsersAuditJavaObject = new ExpectedGetUserListAudit(); + expectedGetListOfUsersAuditJavaObject.setAction(action); + expectedGetListOfUsersAuditJavaObject.setStatus(String.valueOf(status)); + expectedGetListOfUsersAuditJavaObject.setDesc("OK"); + expectedGetListOfUsersAuditJavaObject.setModifier(user.getFullName() + "(" + user.getUserId() + ")"); + expectedGetListOfUsersAuditJavaObject.setDetails(componentType.toLowerCase()); + validateAuditGetListOfUsersByRoles(expectedGetListOfUsersAuditJavaObject, action); + } + + public static String buildArtifactDataAudit(ArtifactDefinition artifactDefinition) { + StringBuilder sb = new StringBuilder(); + if (artifactDefinition.getTimeout() == null) { + artifactDefinition.setTimeout(0); + } + if (artifactDefinition != null) { + sb.append(artifactDefinition.getArtifactGroupType() == null ? null + : artifactDefinition.getArtifactGroupType().getType()).append(",").append("'") + .append(artifactDefinition.getArtifactLabel()).append("'").append(",") + .append(artifactDefinition.getArtifactType()).append(",") + .append(artifactDefinition.getArtifactName()).append(",").append(artifactDefinition.getTimeout()) + .append(",").append(artifactDefinition.getEsId()); + sb.append(","); + if (artifactDefinition.getArtifactVersion() != null) { + sb.append(artifactDefinition.getArtifactVersion()); + } else { + sb.append(" "); + } + sb.append(","); + if (artifactDefinition.getArtifactUUID() != null) { + sb.append(artifactDefinition.getArtifactUUID()); + } else { + sb.append(" "); + } + } + + return sb.toString(); + } + + public static ExpectedResourceAuditJavaObject expectedMissingInformationAuditObject(String Action, + String resourceUid, ComponentType resourceType) throws FileNotFoundException { + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceUid); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(""); + expectedAudit.setModifierName(""); + expectedAudit.setModifierUid(""); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(""); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(""); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("403"); + expectedAudit.setDesc(buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.MISSING_INFORMATION.name()), + new ArrayList())); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedComponentNotFoundAuditObject(String Action, + String resourceUid, ComponentType resourceType, String artifactUid, User user, + ArrayList notFoundComponent) throws FileNotFoundException { + String desc = null; + + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceUid); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(""); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(""); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(artifactUid); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("404"); + + if (resourceType.getValue() == ComponentType.SERVICE.getValue()) { + desc = buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.SERVICE_NOT_FOUND.name()), + notFoundComponent); + } else if (resourceType.getValue() == ComponentType.RESOURCE.getValue()) + desc = buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.RESOURCE_NOT_FOUND.name()), + notFoundComponent); + + expectedAudit.setDesc(desc); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedArtifactNotFoundAuditObject(String Action, String resourceUid, + ComponentType resourceType, String artifactUid, User user, String currState, String currVersion) + throws FileNotFoundException { + String desc = null; + + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceUid); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(currVersion); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(currState); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(artifactUid); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("404"); + + desc = buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()), + Arrays.asList("")); + + expectedAudit.setDesc(desc); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedArtifactNotFoundAuditObject(String Action, + String resourceName, ComponentType resourceType, String artifactUid, LifecycleStateEnum lifecycle, + User user, String currVersion) throws FileNotFoundException { + String desc = null; + + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceName); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(currVersion); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(lifecycle.name()); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(artifactUid); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("404"); + + desc = buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.ARTIFACT_NOT_FOUND.name()), + new ArrayList()); + + expectedAudit.setDesc(desc); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedRestrictedOperationAuditObject(String Action, + String resourceNameOrUid, ComponentType resourceType, String artifactUid, User user, String currVersion, + String currState) throws FileNotFoundException { + String desc = null; + + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceNameOrUid); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(currVersion); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(currState); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(artifactUid); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("409"); + + desc = buildAuditDescription( + new ErrorValidationUtils().parseErrorConfigYaml(ActionStatus.RESTRICTED_OPERATION.name()), + new ArrayList()); + + expectedAudit.setDesc(desc); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedInvalidContentAuditObject(String Action, String resourceName, + ComponentType resourceType, String artifactUid, User user, String currVersion, String currState, + ArrayList invalidContentList) throws FileNotFoundException { + return expectedInvalidContentAuditObject(ActionStatus.INVALID_CONTENT, Action, resourceName, resourceType, + artifactUid, user, currVersion, currState, invalidContentList); + } + + public static ExpectedResourceAuditJavaObject expectedInvalidContentAuditObject(ActionStatus actionStatus, + String Action, String resourceName, ComponentType resourceType, String artifactUid, User user, + String currVersion, String currState, ArrayList invalidContentList) throws FileNotFoundException { + String desc = null; + + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceName); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(currVersion); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(currState); + expectedAudit.setPrevArtifactUuid(""); + expectedAudit.setCurrArtifactUuid(artifactUid); + expectedAudit.setArtifactData(""); + expectedAudit.setStatus("400"); + + desc = buildAuditDescription(new ErrorValidationUtils().parseErrorConfigYaml(actionStatus.name()), + invalidContentList); + + expectedAudit.setDesc(desc); + return expectedAudit; + } + + public static ExpectedResourceAuditJavaObject expectedSuccessAuditObject(String Action, String resourceName, + ComponentType resourceType, ArtifactReqDetails artifactReq, User user, String currVersion, String currState, + String prevArtifactUuid) throws FileNotFoundException { + ExpectedResourceAuditJavaObject expectedAudit = new ExpectedResourceAuditJavaObject(); + expectedAudit.setAction(Action); + expectedAudit.setResourceName(resourceName); + expectedAudit.setResourceType(resourceType.getValue()); + expectedAudit.setPrevVersion(""); + expectedAudit.setCurrVersion(currVersion); + expectedAudit.setModifierName(user.getFirstName() + " " + user.getLastName()); + expectedAudit.setModifierUid(user.getUserId()); + expectedAudit.setPrevState(""); + expectedAudit.setCurrState(currState); + expectedAudit.setPrevArtifactUuid(prevArtifactUuid); + expectedAudit.setCurrArtifactUuid(artifactReq.getUniqueId()); + expectedAudit + .setArtifactData(buildArtifactDataAudit(ArtifactUtils.convertArtifactReqToDefinition(artifactReq))); + expectedAudit.setStatus("200"); + expectedAudit.setDesc("OK"); + return expectedAudit; + } + + public static JSONObject filterAuditByUuid(String action, String uuid) throws Exception { + Map actionMap = new HashMap(); + actionMap.put("ACTION", action); + JSONObject actionJsonObject = new JSONObject(actionMap); + Map uuidMap = new HashMap(); + uuidMap.put("SERVICE_INSTANCE_ID", uuid); + JSONObject uuidJsonObject = new JSONObject(uuidMap); + + List filters = new ArrayList(Arrays.asList(actionJsonObject, uuidJsonObject)); + JSONObject body = buildElasticQueryBody(filters); + return body; + } + + public static void validateAudit(ExpectedResourceAuditJavaObject resourceAuditJavaObject, String action) + throws Exception { + List> actionToList = getAuditListByAction(resourceAuditJavaObject.getAction(), 1); + Map map2 = actionToList.get(0); + validateField(map2, AuditJsonKeysEnum.ACTION.getAuditJsonKeyName(), action); + validateField(map2, AuditJsonKeysEnum.RESOURCE_NAME.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceName()); + validateField(map2, AuditJsonKeysEnum.RESOURCE_TYPE.getAuditJsonKeyName(), + resourceAuditJavaObject.getResourceType()); + validateField(map2, AuditJsonKeysEnum.PREV_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getPrevVersion()); + validateField(map2, AuditJsonKeysEnum.CURR_VERSION.getAuditJsonKeyName(), + resourceAuditJavaObject.getCurrVersion()); + validateField(map2, AuditJsonKeysEnum.MODIFIER.getAuditJsonKeyName(), resourceAuditJavaObject.getMODIFIER()); + validateField(map2, AuditJsonKeysEnum.PREV_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getPrevState()); + validateField(map2, AuditJsonKeysEnum.CURR_STATE.getAuditJsonKeyName(), resourceAuditJavaObject.getCurrState()); + validateField(map2, AuditJsonKeysEnum.STATUS.getAuditJsonKeyName(), resourceAuditJavaObject.getStatus()); + validateField(map2, AuditJsonKeysEnum.DESCRIPTION.getAuditJsonKeyName(), resourceAuditJavaObject.getDesc()); + validateField(map2, AuditJsonKeysEnum.COMMENT.getAuditJsonKeyName(), resourceAuditJavaObject.getComment()); + } + + ////// service audit validation///////////////////// + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ServiceReqDetails serviceReqDetails, + String serviceVersion, User sdncUserDetails) { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + + expectedResourceAuditJavaObject.setAction("Create"); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + String userFirstLastName = sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName(); + expectedResourceAuditJavaObject.setModifierName(userFirstLastName); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setResourceName(serviceReqDetails.getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + expectedResourceAuditJavaObject.setPrevVersion(String.valueOf(Float.parseFloat(serviceVersion) - 0.1f)); + expectedResourceAuditJavaObject.setCurrVersion(serviceVersion); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setComment(null); + + return expectedResourceAuditJavaObject; + + } + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ServiceReqDetails serviceReqDetails, + String serviceVersion, User sdncUserDetails, ActionStatus errorStatus, List variables) + throws FileNotFoundException { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = constructFieldsForAuditValidation( + serviceReqDetails, serviceVersion, sdncUserDetails); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(errorStatus.name()); + + expectedResourceAuditJavaObject.setStatus(errorInfo.getCode().toString()); + String auditDesc = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + expectedResourceAuditJavaObject.setDesc(auditDesc); + + return expectedResourceAuditJavaObject; + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/BaseValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/BaseValidationUtils.java new file mode 100644 index 0000000000..eb3ee331ed --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/BaseValidationUtils.java @@ -0,0 +1,116 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.FileNotFoundException; +import java.util.Arrays; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.exception.ResponseFormat; +import org.testng.Assert; + +public class BaseValidationUtils { + + public static final int STATUS_CODE_SUCCESS = 200; + public static final int STATUS_CODE_CREATED = 201; + public static final int STATUS_CODE_DELETE = 204; + public static final int STATUS_CODE_NOT_FOUND = 404; + public static final int STATUS_CODE_SUCCESS_NO_CONTENT = 204; + public static final int STATUS_CODE_SUCCESS_DELETE = 204; + public static final int STATUS_CODE_INVALID_CONTENT = 400; + public static final int STATUS_CODE_MISSING_DATA = 400; + public static final int STATUS_CODE_MISSING_INFORMATION = 403; + public static final int STATUS_CODE_RESTRICTED_ACCESS = 403; + public static final int STATUS_CODE_RESTRICTED_OPERATION = 409; + public static final int STATUS_CODE_ALREADY_EXISTS = 409; + + // ------ + protected static Boolean checkErrorCode(RestResponse deleteResponse) { + if (deleteResponse.getErrorCode() == STATUS_CODE_SUCCESS + || deleteResponse.getErrorCode() == STATUS_CODE_DELETE) { + return true; + } + return false; + } + + // *** STATUS CODE VALIDATION UTIITIES **** + public static void checkStatusCode(RestResponse response, String assertMessage, boolean AND, int... statuses) { + int statusCode = response.getErrorCode(); + for (int status : statuses) { + if (AND && statusCode != status) { + Assert.fail(assertMessage + " status: " + statusCode); + } else if (statusCode == status) { + return; + } + } + if (!AND) { + Assert.fail(assertMessage + " status: " + statusCode); + } + } + + public static void checkDeleteResponse(RestResponse response) { + checkStatusCode(response, "delete request failed", false, STATUS_CODE_DELETE, STATUS_CODE_NOT_FOUND, + STATUS_CODE_SUCCESS); // STATUS_CODE_SUCCESS for deActivate user + } + + public static void checkCreateResponse(RestResponse response) { + checkStatusCode(response, "create request failed", false, STATUS_CODE_CREATED); + } + + public static void checkSuccess(RestResponse response) { + checkStatusCode(response, "request failed", false, STATUS_CODE_SUCCESS); + } + + public static void checkErrorResponse(RestResponse errorResponse, ActionStatus actionStatus, + String... expectedVariables) throws FileNotFoundException { + // Expected error + ErrorInfo expectedError = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + String expectedMessage = expectedError.getMessage(); + + // Actual error + ResponseFormat responseFormat = ResponseParser.parseToObjectUsingMapper(errorResponse.getResponse(), + ResponseFormat.class); + String actualMessage = responseFormat.getText(); + String[] actualVariables = responseFormat.getVariables(); + + assertEquals("Unexpected error message", expectedMessage, actualMessage); + assertEquals("Unexpected error variables", Arrays.asList(expectedVariables), Arrays.asList(actualVariables)); + } + + public static void checkErrorMessageResponse(RestResponse errorResponse, ActionStatus actionStatus) + throws FileNotFoundException { + // Expected error + ErrorInfo expectedError = ErrorValidationUtils.parseErrorConfigYaml(actionStatus.name()); + String expectedMessage = expectedError.getMessage(); + + // Actual error + ResponseFormat responseFormat = ResponseParser.parseToObjectUsingMapper(errorResponse.getResponse(), + ResponseFormat.class); + String actualMessage = responseFormat.getText(); + + assertEquals("Unexpected error message", expectedMessage, actualMessage); + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CategoryValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CategoryValidationUtils.java new file mode 100644 index 0000000000..cd2297fd19 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CategoryValidationUtils.java @@ -0,0 +1,126 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertTrue; + +import org.json.JSONObject; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.CategoryRestUtils; + +public class CategoryValidationUtils { + + public static void verifyCategoryExistInGetResponse(RestResponse getAllCategoryRest, + CategoryDefinition categoryDefinition) { + + int categoriesNum = CategoryRestUtils.getMatchingCategoriesNum(getAllCategoryRest, categoryDefinition); + assertEquals("category " + categoryDefinition.getName() + " not found during get or found more than once", 1, + categoriesNum); + } + + public static void verifyCategoryNotExistsInGetResponse(RestResponse getAllCategoryRest, + CategoryDefinition categoryDefinition) { + + int categoriesNum = CategoryRestUtils.getMatchingCategoriesNum(getAllCategoryRest, categoryDefinition); + assertEquals("category " + categoryDefinition.getName() + " should't be found during get", 0, categoriesNum); + } + + public static void verifySubCategoryExistInGetResponse(RestResponse getAllCategoryRest, String parentCategoryId, + SubCategoryDefinition expectedSubCategoryDefinition) { + + int subCategoriesNum = CategoryRestUtils.getMatchingSubCategoriesNum(getAllCategoryRest, parentCategoryId, + expectedSubCategoryDefinition); + assertEquals( + "sub-category " + expectedSubCategoryDefinition.getName() + + " not found during get or found more than once for parentId " + parentCategoryId, + 1, subCategoriesNum); + } + + public static void verifyGroupingExistInGetResponse(RestResponse getAllCategoryRest, String parentCategoryId, + String subCategoryId, GroupingDefinition expectedGroupingDefinition) { + + int groupingNum = CategoryRestUtils.getMatchingGroupingNum(getAllCategoryRest, parentCategoryId, subCategoryId, + expectedGroupingDefinition); + assertEquals( + "sub-category " + expectedGroupingDefinition.getName() + + " not found during get or found more than once for parentId " + parentCategoryId, + 1, groupingNum); + } + + public static void verifyGroupingNotExistInGetResponse(RestResponse getAllCategoryRest, String parentCategoryId, + String subCategoryId, GroupingDefinition expectedGroupingDefinition) { + + int groupingNum = CategoryRestUtils.getMatchingGroupingNum(getAllCategoryRest, parentCategoryId, subCategoryId, + expectedGroupingDefinition); + assertEquals( + "sub-category " + expectedGroupingDefinition.getName() + + " not found during get or found more than once for parentId " + parentCategoryId, + 0, groupingNum); + } + + public static void verifySubCategoryNotExistsInGetResponse(RestResponse getAllCategoryRest, String parentCategoryId, + SubCategoryDefinition expectedSubCategoryDefinition) { + + int subCategoriesNum = CategoryRestUtils.getMatchingSubCategoriesNum(getAllCategoryRest, parentCategoryId, + expectedSubCategoryDefinition); + assertEquals("sub-category " + expectedSubCategoryDefinition.getName() + + " should't be found during get for parentId " + parentCategoryId, 0, subCategoriesNum); + } + + /// NEE Benny + public static void validateCreateGroupResponse(RestResponse createSubCategoryRest, + GroupingDefinition expectedGroupDefinition) throws Exception { + + String response = createSubCategoryRest.getResponse(); + JSONObject jobject = new JSONObject(response); + assertTrue(jobject.get("name").equals(expectedGroupDefinition.getName())); + assertTrue(jobject.get("normalizedName").equals(expectedGroupDefinition.getNormalizedName())); + // assertNotNull(jobject.get("normalizedName")); + assertNotNull(jobject.get("uniqueId")); + expectedGroupDefinition.setUniqueId(jobject.get("uniqueId").toString()); + + } + + public static void validateCreateSubCategoryResponse(RestResponse createSubCategoryRest, + SubCategoryDefinition expectedSubCategoryDefinition) throws Exception { + + String response = createSubCategoryRest.getResponse(); + JSONObject jobject = new JSONObject(response); + assertTrue(jobject.get("name").equals(expectedSubCategoryDefinition.getName())); + assertNotNull(jobject.get("normalizedName")); + assertNotNull(jobject.get("uniqueId")); + } + + public static void validateCreateCategoryResponse(RestResponse createCategoryRest, + CategoryDefinition expectedCategoryDefinition) throws Exception { + String response = createCategoryRest.getResponse(); + JSONObject jobject = new JSONObject(response); + assertTrue(jobject.get("name").equals(expectedCategoryDefinition.getName())); + assertTrue(jobject.get("normalizedName").equals(expectedCategoryDefinition.getNormalizedName())); + assertNotNull(jobject.get("uniqueId")); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CsarValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CsarValidationUtils.java new file mode 100644 index 0000000000..29f9e84dd8 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/CsarValidationUtils.java @@ -0,0 +1,274 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertTrue; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.ci.tests.datatypes.GroupHeatMetaDefinition; +import org.openecomp.sdc.ci.tests.datatypes.PropertyHeatMetaDefinition; +import org.openecomp.sdc.ci.tests.datatypes.TypeHeatMetaDefinition; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaNodeTemplatesTopologyTemplateDefinition; +import org.openecomp.sdc.ci.tests.tosca.datatypes.ToscaRequirementsNodeTemplatesDefinition; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ImportRestUtils; +import org.openecomp.sdc.common.rest.api.RestResponseAsByteArray; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CsarValidationUtils { + private static Logger log = LoggerFactory.getLogger(CsarValidationUtils.class.getName()); + + public static String getCsarPayload(String csarName, String fileLocation) throws Exception { + + RestResponseAsByteArray csar = ImportRestUtils.getCsar(csarName, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + assertTrue("Return response code different from 200", csar.getHttpStatusCode() == BaseRestUtils.STATUS_CODE_SUCCESS); + Map readZip = null; + byte[] data = csar.getResponse(); + if (data != null && data.length > 0) { + readZip = ZipUtil.readZip(data); + + } + + byte[] artifactsBs = readZip.get(fileLocation); + String str = new String(artifactsBs, StandardCharsets.UTF_8); + + return str; + + } + + public static List getListTypeHeatMetaDefinition(String csarUUID) throws Exception { + + String artifactHeatMetaLocation = "Artifacts/HEAT.meta"; + JSONParser parser = new JSONParser(); + String csarPayload = getCsarPayload(csarUUID, artifactHeatMetaLocation); + if (csarPayload != null) { + Object parse = parser.parse(csarPayload); + JSONObject jsonObject = (JSONObject) parse; + JSONObject jsonObjectImportStructure = (JSONObject) jsonObject.get("importStructure"); + List listHeatMetaDefenition = new ArrayList(); + listHeatMetaDefenition = getArtifactsByGroup(jsonObjectImportStructure, listHeatMetaDefenition); + return listHeatMetaDefenition; + } + return null; + + } + + protected static List getArtifactsByGroup(JSONObject jsonObjectImportStructure, List listHeatMetaDefenition) { + + @SuppressWarnings("unchecked") + Set typeSet = jsonObjectImportStructure.keySet(); + for (Object type : typeSet) { + TypeHeatMetaDefinition heatMetaDefenition = new TypeHeatMetaDefinition(); + log.debug(type.toString()); + log.debug("{}", jsonObjectImportStructure.get(type)); + JSONArray array = (JSONArray) jsonObjectImportStructure.get(type); + heatMetaDefenition.setTypeName((String) type); + List groupHeatMetaDefinitions = new ArrayList(); + heatMetaDefenition.setGroupHeatMetaDefinition(fetchArtifactByGroup(array, groupHeatMetaDefinitions, true)); + listHeatMetaDefenition.add(heatMetaDefenition); + } + return listHeatMetaDefenition; + } + + protected static List fetchArtifactByGroup(JSONArray array, List listGroupHeatMetaDefinition, Boolean openNewGroup) { + + GroupHeatMetaDefinition groupHeatMetaDefinition; + + if (array != null) { + for (int i = 0; i < array.size(); i++) { + if (openNewGroup) { + groupHeatMetaDefinition = new GroupHeatMetaDefinition(); + int groupNumber = listGroupHeatMetaDefinition.size() + 1; + log.debug("groupName={}", groupNumber); + groupHeatMetaDefinition.setGroup(groupNumber); + listGroupHeatMetaDefinition.add(groupHeatMetaDefinition); + PropertyHeatMetaDefinition propertyHeatMetaDefinition = new PropertyHeatMetaDefinition(); + propertyHeatMetaDefinition.setName("isBase"); + propertyHeatMetaDefinition.setValue(false); + groupHeatMetaDefinition.setPropertyHeatMetaDefinition(propertyHeatMetaDefinition); + } + groupHeatMetaDefinition = listGroupHeatMetaDefinition.get(listGroupHeatMetaDefinition.size() - 1); + JSONObject jsonObject = (JSONObject) array.get(i); + @SuppressWarnings("unchecked") + Set groupsKey = jsonObject.keySet(); + for (Object groupKey : groupsKey) { + String groupKeyStr = (String) groupKey; + if (groupKeyStr.equals("isBase")) { + PropertyHeatMetaDefinition propertyHeatMetaDefinition = new PropertyHeatMetaDefinition(); + propertyHeatMetaDefinition.setName(groupKeyStr); + propertyHeatMetaDefinition.setValue((boolean) jsonObject.get(groupKeyStr)); + if (!groupHeatMetaDefinition.getPropertyHeatMetaDefinition().equals(propertyHeatMetaDefinition)) { + groupHeatMetaDefinition.getPropertyHeatMetaDefinition().setValue((boolean) jsonObject.get(groupKeyStr)); + } + } + if (groupKeyStr.equals("fileName") || groupKeyStr.equals("env")) { + String artifactName = (String) jsonObject.get(groupKeyStr); + List listArtifactNames = groupHeatMetaDefinition.getArtifactList(); + listArtifactNames.add(artifactName); + groupHeatMetaDefinition.setArtifactList(listArtifactNames); + } else { + if (!groupKeyStr.equals("isBase")) { + fetchArtifactByGroup((JSONArray) jsonObject.get(groupKeyStr), listGroupHeatMetaDefinition, false); + } + } + } + } + } + return listGroupHeatMetaDefinition; + } + + private static Integer getArtifactCount(List listHeatMetaDefenition, Boolean isEnvIncluded) { + int count = 0; + List uniqeArtifactList = new ArrayList<>(); + + for (TypeHeatMetaDefinition typeHeatMetaDefinition : listHeatMetaDefenition) { + for (GroupHeatMetaDefinition groupHeatMetaDefinition : typeHeatMetaDefinition.getGroupHeatMetaDefinition()) { + if (isEnvIncluded) { + count = count + groupHeatMetaDefinition.getArtifactList().size(); + } else { + for (String fileName : groupHeatMetaDefinition.getArtifactList()) { + if (!fileName.contains(".env") && !uniqeArtifactList.contains(fileName)) { + uniqeArtifactList.add(fileName); + count = count + 1; + } + } + } + } + } + return count; + } + + private static Integer getGroupCount(List listHeatMetaDefenition) { + int count = 0; + for (TypeHeatMetaDefinition typeHeatMetaDefinition : listHeatMetaDefenition) { + count = count + typeHeatMetaDefinition.getGroupHeatMetaDefinition().size(); + } + return count; + } + + private static String groupNameBuilder(Resource resource) { + String separator = "::"; + String module = "module-"; + String groupName = resource.getSystemName() + separator + module; + return groupName; + } + + public static void validateCsarVfArtifact(String csarUUID, Resource resource) throws Exception { + + List listTypeHeatMetaDefinition = getListTypeHeatMetaDefinition(csarUUID); + assertTrue("check group count, expected: " + getGroupCount(listTypeHeatMetaDefinition) + ", actual: " + resource.getGroups().size(), getGroupCount(listTypeHeatMetaDefinition) == resource.getGroups().size()); + assertTrue("check artifact count, expected: " + getArtifactCount(listTypeHeatMetaDefinition, false) + ", actual: " + resource.getDeploymentArtifacts().size(), + getArtifactCount(listTypeHeatMetaDefinition, false) == resource.getDeploymentArtifacts().size()); + + } + + public static void validateToscaDefinitonObjectVsResource(ToscaDefinition toscaDefinition, Resource resource) throws Exception { + + assertTrue("check resource instance count, expected: " + getResourceInstanceCount(toscaDefinition) + ", actual: " + resource.getComponentInstances().size(), + getResourceInstanceCount(toscaDefinition) == resource.getComponentInstances().size()); + assertTrue("check resource instance relation count, expected: " + getResourceInstanceRelationCount(toscaDefinition) + ", actual: " + resource.getComponentInstancesRelations().size(), + getResourceInstanceRelationCount(toscaDefinition) == resource.getComponentInstancesRelations().size()); + + } + + public static Integer getResourceInstanceCount(ToscaDefinition toscaDefinition) { + + return toscaDefinition.getToscaTopologyTemplate().getToscaNodeTemplatesTopologyTemplateDefinition().size(); + } + + public static Integer getResourceInstanceRelationCount(ToscaDefinition toscaDefinition) { + int count = 0; + List toscaNodeTemplatesTopologyTemplateDefinition = toscaDefinition.getToscaTopologyTemplate().getToscaNodeTemplatesTopologyTemplateDefinition(); + for (int i = 0; i < toscaNodeTemplatesTopologyTemplateDefinition.size(); i++) { + List requirements = toscaNodeTemplatesTopologyTemplateDefinition.get(i).getRequirements(); + if (requirements != null) { + for (ToscaRequirementsNodeTemplatesDefinition requirement : requirements) { + if (requirement.getNode() != null) { + count = count + 1; + } + } + } + } + return count; + } + + // not finished yet + private static void validateCsarVfgroup(String csarUUID, Resource resource) { + + List groups = resource.getGroups(); + for (GroupDefinition groupDefinition : groups) { + List artifacts = groupDefinition.getArtifacts(); + assertTrue("group description is null", groupDefinition.getDescription() != null); + assertTrue("InvariantUUID is null", groupDefinition.getInvariantUUID() != null); + // groupDefinition.getMembers(); + assertTrue("name format mismatch, expected: " + groupNameBuilder(resource) + "[0-9], actual: " + groupDefinition.getName(), groupDefinition.getName().contains(groupNameBuilder(resource))); + // groupDefinition.getProperties(); + // groupDefinition.getPropertyValueCounter(); + assertTrue(groupDefinition.getType().equals(getGroupType())); + } + + String expectedCsarUUID = csarUUID; + // String expectedToscaResourceName = "org.openecomp.resource.vf." + + // WordUtils.capitalize(resourceDetails.getName().toLowerCase()); + // + // assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, + // resource.getCsarUUID()), + // expectedCsarUUID.equals(resource.getCsarUUID())); + // assertTrue("toscaResourceName : " + + // buildAssertMessage(expectedToscaResourceName, + // resource.getToscaResourceName()), + // expectedToscaResourceName.equals(resource.getToscaResourceName())); + // + // RestResponse getResourceResponse = + // ResourceRestUtils.getResource(resource.getUniqueId()); + // Resource getResource = + // ResponseParser.parseToObjectUsingMapper(getResourceResponse.getResponse(), + // Resource.class); + // assertTrue("csarUUID : " + buildAssertMessage(expectedCsarUUID, + // getResource.getCsarUUID()), + // expectedCsarUUID.equals(getResource.getCsarUUID())); + // assertTrue("toscaResourceName : " + + // buildAssertMessage(expectedToscaResourceName, + // getResource.getToscaResourceName()), + // expectedToscaResourceName.equals(getResource.getToscaResourceName())); + + } + + private static String getGroupType() { + return "org.openecomp.groups.VfModule"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ErrorValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ErrorValidationUtils.java new file mode 100644 index 0000000000..ac5a05d7ca --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ErrorValidationUtils.java @@ -0,0 +1,112 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +import org.codehaus.jettison.json.JSONException; +import org.codehaus.jettison.json.JSONObject; +import org.openecomp.sdc.ci.tests.config.Config; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.ExceptionEnumType; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.yaml.snakeyaml.Yaml; + +public class ErrorValidationUtils { + + static Logger logger = LoggerFactory.getLogger(Utils.class.getName()); + + public static void checkBodyResponseOnError(String errorType, List variables, String actualResponse) + throws FileNotFoundException, JSONException { + + ErrorInfo errorInfo = parseErrorConfigYaml(errorType); + JSONObject expectedResponseBody = null; + if (errorInfo.getMessageId() != null) { + if (errorInfo.getMessageId().contains("SVC")) { + expectedResponseBody = restExceptionFormatBuilder(errorInfo.getMessageId(), errorInfo.getMessage(), + variables, ExceptionEnumType.SERVICE_EXCEPTION.getValue()); + } else { + expectedResponseBody = restExceptionFormatBuilder(errorInfo.getMessageId(), errorInfo.getMessage(), + variables, ExceptionEnumType.POLICY_EXCPTION.getValue()); + } + } + actualResponse = actualResponse.replaceAll("\\n", ""); + logger.debug("actualResponse - {}", actualResponse); + logger.debug("expectedResponseBody - {}", expectedResponseBody); + assertEquals(expectedResponseBody, new JSONObject(actualResponse)); + } + + public static JSONObject restExceptionFormatBuilder(String messageId, String text, List variables, + String type) { + + JSONObject simpleElements = new JSONObject(); + JSONObject exceptionType = new JSONObject(); + JSONObject requestError = new JSONObject(); + + try { + simpleElements.put("messageId", messageId); + simpleElements.put("text", text); + simpleElements.put("variables", variables); + exceptionType.put(type, simpleElements); + requestError.put("requestError", exceptionType); + + } catch (JSONException e) { + e.printStackTrace(); + } + + return requestError; + + } + + public static ErrorInfo parseErrorConfigYaml(String error) throws FileNotFoundException { + Yaml yaml = new Yaml(); + ErrorInfo errInfo = null; + Config config = Utils.getConfig(); + String errorConfigurationFile = config.getErrorConfigurationFile(); + File file = new File(errorConfigurationFile); + // File file = new + // File("../catalog-be/src/main/resources/config/error-configuration.yaml"); + InputStream inputStream = new FileInputStream(file); + Map map = (Map) yaml.load(inputStream); + // System.out.println(map.get("errors")); + @SuppressWarnings("unchecked") + Map errorMap = (Map) map.get("errors"); + @SuppressWarnings("unchecked") + Map errorInfo = (Map) errorMap.get(error); + + String message = (String) errorInfo.get("message"); + String messageId = (String) errorInfo.get("messageId"); + int code = (Integer) errorInfo.get("code"); + errInfo = new ErrorInfo(code, message, messageId); + + return errInfo; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ProductValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ProductValidationUtils.java new file mode 100644 index 0000000000..ba5114c1bc --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ProductValidationUtils.java @@ -0,0 +1,239 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.log4j.Logger; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; +import org.json.simple.JSONValue; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest.ComponentOperationEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ProductRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; + +public class ProductValidationUtils { + + static Logger logger = Logger.getLogger(ProductValidationUtils.class.getName()); + + public static void compareExpectedAndActualProducts(Product expectedProduct, Product actualProduct) { + compareExpectedAndActualProducts(expectedProduct, actualProduct, null); + } + + public static void compareExpectedAndActualProducts(Product expectedProduct, Product actualProduct, + ComponentOperationEnum operation) { + + assertEquals(expectedProduct.getName(), actualProduct.getName()); + assertEquals(expectedProduct.getFullName(), actualProduct.getFullName()); + assertEquals(expectedProduct.getDescription(), actualProduct.getDescription()); + + List expectedContacts = expectedProduct.getContacts(); + List actualContacts = actualProduct.getContacts(); + assertTrue( + "Expected contacts:" + Arrays.toString(expectedContacts.toArray()) + ", actual contacts:" + + Arrays.toString(actualContacts.toArray()), + expectedContacts.size() == actualContacts.size() && expectedContacts.containsAll(actualContacts) + && actualContacts.containsAll(expectedContacts)); + + List expectedTags = expectedProduct.getTags(); + List actualTags = actualProduct.getTags(); + assertTrue( + "Expected tags:" + Arrays.toString(expectedTags.toArray()) + ", actual tags:" + + Arrays.toString(actualTags.toArray()), + expectedTags.size() == actualTags.size() && expectedTags.containsAll(actualTags) + && actualTags.containsAll(expectedTags)); + + assertEquals(expectedProduct.getLifecycleState(), actualProduct.getLifecycleState()); + assertEquals(expectedProduct.getVersion(), actualProduct.getVersion()); + assertEquals(expectedProduct.isHighestVersion(), actualProduct.isHighestVersion()); + assertEquals(expectedProduct.getNormalizedName(), actualProduct.getNormalizedName()); + + compareCategories(expectedProduct, actualProduct); + assertEquals(expectedProduct.getLastUpdaterUserId(), actualProduct.getLastUpdaterUserId()); + if (operation != null) { + assertEquals(expectedProduct.getCreatorUserId(), actualProduct.getCreatorUserId()); + } + + Long lastUpdateDate = actualProduct.getLastUpdateDate(); + Long creationDate = actualProduct.getCreationDate(); + Map allVersions = actualProduct.getAllVersions(); + + if (operation != null) { + if (operation == ComponentOperationEnum.UPDATE_COMPONENT + || operation == ComponentOperationEnum.CHANGE_STATE_CHECKOUT + || operation == ComponentOperationEnum.CHANGE_STATE_CHECKIN + || operation == ComponentOperationEnum.CHANGE_STATE_UNDO_CHECKOUT) { + assertTrue("Last update date:" + lastUpdateDate + ", creation date: " + creationDate, + lastUpdateDate > 0 && creationDate > 0 && lastUpdateDate > creationDate); + } else { + assertTrue("Last update date:" + lastUpdateDate + ", creation date: " + creationDate, + lastUpdateDate > 0 && lastUpdateDate.equals(creationDate)); + } + } + + // Check UUIDs + // If just created, no way to test the UUIDs themselves + // If updated, we expect the UUIDs of actual to match the expected + String uniqueId = actualProduct.getUniqueId(); + if (operation == ComponentOperationEnum.CREATE_COMPONENT) { + UUID.fromString(uniqueId); + UUID.fromString(actualProduct.getUUID()); + UUID.fromString(actualProduct.getInvariantUUID()); + assertTrue(allVersions.size() == 1); + assertTrue(allVersions.get("0.1").equals(uniqueId)); + } else { + if (operation == ComponentOperationEnum.CHANGE_STATE_CHECKOUT) { + assertFalse(expectedProduct.getUniqueId().equals(uniqueId)); + // Assigning the updated uniqueId to expected so that it can be + // passed to further logic + expectedProduct.setUniqueId(uniqueId); + } else if (operation != null) { + assertTrue(expectedProduct.getUniqueId().equals(uniqueId)); + } + assertEquals(expectedProduct.getUUID(), actualProduct.getUUID()); + assertEquals(expectedProduct.getInvariantUUID(), actualProduct.getInvariantUUID()); + } + } + + private static void compareCategories(Product expectedProduct, Product actualProduct) { + List expectedCategories = expectedProduct.getCategories(); + List actualCategories = actualProduct.getCategories(); + if (expectedCategories != null && actualCategories != null) { + int expSize = expectedCategories.size(); + int actSize = actualCategories.size(); + + assertTrue("Expected size:" + expSize + ", actual size:" + actSize, expSize == actSize); + + for (CategoryDefinition actualDefinition : actualCategories) { + int lastIndexOfCat = expectedCategories.lastIndexOf(actualDefinition); + assertTrue("Actual category " + actualDefinition + " not found in expected.", lastIndexOfCat != -1); + CategoryDefinition expectedDefinition = expectedCategories.get(lastIndexOfCat); + List actualSubcategories = actualDefinition.getSubcategories(); + List expectedSubcategories = expectedDefinition.getSubcategories(); + for (SubCategoryDefinition actualSub : actualSubcategories) { + lastIndexOfCat = expectedSubcategories.lastIndexOf(actualSub); + assertTrue("Actual subcategory " + actualSub + " not found in expected.", lastIndexOfCat != -1); + SubCategoryDefinition expectedSub = expectedSubcategories.get(lastIndexOfCat); + List actualGroupings = actualSub.getGroupings(); + List expectedGroupings = expectedSub.getGroupings(); + for (GroupingDefinition actualGrouping : actualGroupings) { + lastIndexOfCat = expectedGroupings.lastIndexOf(actualGrouping); + assertTrue("Actual grouping " + actualSub + " not found in expected.", lastIndexOfCat != -1); + } + } + } + + for (CategoryDefinition expectedDefinition : expectedCategories) { + int lastIndexOfCat = actualCategories.lastIndexOf(expectedDefinition); + assertTrue("Expected category " + expectedDefinition + " not found in actual.", lastIndexOfCat != -1); + CategoryDefinition actualDefinition = actualCategories.get(lastIndexOfCat); + List actualSubcategories = actualDefinition.getSubcategories(); + List expectedSubcategories = expectedDefinition.getSubcategories(); + for (SubCategoryDefinition expectedSub : expectedSubcategories) { + lastIndexOfCat = actualSubcategories.lastIndexOf(expectedSub); + assertTrue("Expected subcategory " + expectedSub + " not found in actual.", lastIndexOfCat != -1); + SubCategoryDefinition actualSub = actualSubcategories.get(lastIndexOfCat); + List actualGroupings = actualSub.getGroupings(); + List expectedGroupings = expectedSub.getGroupings(); + for (GroupingDefinition expectedGrouping : expectedGroupings) { + lastIndexOfCat = actualGroupings.lastIndexOf(expectedGrouping); + assertTrue("Expected grouping " + expectedGrouping + " not found in actual.", + lastIndexOfCat != -1); + } + } + } + } + } + + public static void verifyProductsNotExistInUserFollowedPage(User user, Product... nonExpectedProducts) + throws Exception { + String component = "products"; + Boolean isExist; + Product nonExpectedProduct; + RestResponse getFollowedPage = ProductRestUtils.getFollowed(user.getUserId()); + JSONArray followedProductes = getListArrayFromRestResponse(getFollowedPage, component); + if (followedProductes != null) { // if any product exist in followed + // page + for (int i = 0; i < nonExpectedProducts.length; i++) { + nonExpectedProduct = nonExpectedProducts[i]; + isExist = false; + for (int k = 0; k < followedProductes.size(); k++) { + JSONObject jobject = (JSONObject) followedProductes.get(k); + if (jobject.get("uuid").toString().equals(nonExpectedProduct.getUUID())) { + isExist = true; + k = followedProductes.size(); + } + } + assertFalse(isExist); + } + } + + } + + public static void checkUserFollowedPage(User user, Product... expectedProducts) throws Exception { + String component = "products"; + Boolean isExist; + Product expectedProduct; + RestResponse getFollowedPage = ProductRestUtils.getFollowed(user.getUserId()); + JSONArray followedProductes = getListArrayFromRestResponse(getFollowedPage, component); + assertTrue("check if any followedProductes received ", followedProductes != null); + assertTrue("check if any expectedProducts and followedProductes are the same size", + expectedProducts.length == followedProductes.size()); + for (int i = 0; i < expectedProducts.length; i++) { + expectedProduct = expectedProducts[i]; + isExist = false; + for (int k = 0; k < followedProductes.size(); k++) { + JSONObject jobject = (JSONObject) followedProductes.get(k); + // if(jobject.get("uuid").toString().equals(expectedProduct.getUUID())) + if (jobject.get("uniqueId").toString().equals(expectedProduct.getUniqueId())) { + + String productString = jobject.toJSONString(); + Product actualProduct = ResponseParser.parseToObjectUsingMapper(productString, Product.class); + ProductValidationUtils.compareExpectedAndActualProducts(expectedProduct, actualProduct, null); + isExist = true; + k = followedProductes.size(); + } + } + assertTrue(isExist); + } + } + + private static JSONArray getListArrayFromRestResponse(RestResponse restResponse, String lst) { + String json = restResponse.getResponse(); + JSONObject jsonResp = (JSONObject) JSONValue.parse(json); + JSONArray resources = (JSONArray) jsonResp.get(lst); + return resources; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ResourceValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ResourceValidationUtils.java new file mode 100644 index 0000000000..a3440df8ad --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ResourceValidationUtils.java @@ -0,0 +1,354 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceRespJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.enums.RespJsonKeysEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; + +import com.google.gson.Gson; + +public class ResourceValidationUtils { + + public static void validateResourceReqVsResp(ResourceReqDetails resourceDetails, + ResourceRespJavaObject resourceRespJavaObject) { + + String expected; + + expected = resourceDetails.getDescription(); + assertEquals("resource description - ", expected, resourceRespJavaObject.getDescription()); + + expected = resourceDetails.getVendorName(); + assertEquals("resource vendorName - ", expected, resourceRespJavaObject.getVendorName()); + + expected = resourceDetails.getVendorRelease(); + assertEquals("resource vendorReleaseName - ", expected, resourceRespJavaObject.getVendorRelease()); + + expected = resourceDetails.getContactId(); + assertEquals("resource contactId - ", expected, resourceRespJavaObject.getContactId()); + + } + + public static void validateResourceReqVsResp(ResourceReqDetails resourceDetails, Resource resourceRespJavaObject) { + + String expected; + + expected = resourceDetails.getDescription(); + assertEquals("resource description - ", expected, resourceRespJavaObject.getDescription()); + + expected = resourceDetails.getVendorName(); + assertEquals("resource vendorName - ", expected, resourceRespJavaObject.getVendorName()); + + expected = resourceDetails.getVendorRelease(); + assertEquals("resource vendorReleaseName - ", expected, resourceRespJavaObject.getVendorRelease()); + + expected = resourceDetails.getContactId(); + assertEquals("resource contactId - ", expected, resourceRespJavaObject.getContactId()); + + // Validating deduplication of tags + List expectedTags = resourceDetails.getTags(); + if (expectedTags != null) { + Set hs = new LinkedHashSet<>(expectedTags); + expectedTags.clear(); + expectedTags.addAll(hs); + List receivedTags = resourceRespJavaObject.getTags(); + assertEquals("resource tags - ", expectedTags, receivedTags); + } + + } + + public static void validateModelObjects(Resource expected, Resource actual) throws Exception { + + compareElements(expected.getUniqueId(), actual.getUniqueId()); + compareElements(expected.getName(), actual.getName()); + compareElements(expected.getVersion(), actual.getVersion()); + compareElements(expected.getCreatorUserId(), actual.getCreatorUserId()); + compareElements(expected.getCreatorFullName(), actual.getCreatorFullName()); + compareElements(expected.getLastUpdaterUserId(), actual.getLastUpdaterUserId()); + compareElements(expected.getLastUpdaterFullName(), actual.getLastUpdaterFullName()); + compareElements(expected.getCreatorFullName(), actual.getCreatorFullName()); + compareElements(expected.getCreationDate(), actual.getCreationDate()); + compareElements(expected.getLastUpdateDate(), actual.getLastUpdateDate()); + compareElements(expected.getDescription(), actual.getDescription()); + compareElements(expected.getIcon(), actual.getIcon()); + compareElements(expected.getLastUpdateDate(), actual.getLastUpdateDate()); + // TODO compare tags + compareElements(expected.getCategories(), actual.getCategories()); + compareElements(expected.getLifecycleState(), actual.getLifecycleState()); + compareElements(expected.getVendorName(), actual.getVendorName()); + compareElements(expected.getVendorRelease(), actual.getVendorRelease()); + compareElements(expected.getContactId(), actual.getContactId()); + compareElements(expected.getUUID(), actual.getUUID()); + compareElements(expected.getVersion(), actual.getVersion()); + + } + + public static void validateResp(RestResponse restResponse, ResourceRespJavaObject resourceRespJavaObject) + throws Exception { + + Gson gson = new Gson(); + String response = restResponse.getResponse(); + + validateResp(response, resourceRespJavaObject, gson); + + } + + public static void validateResp(String response, ResourceRespJavaObject resourceRespJavaObject, Gson gson) { + + Map map = new HashMap(); + map = (Map) gson.fromJson(response, map.getClass()); + + // De-duplicating the tags list for comparison + List tags = resourceRespJavaObject.getTags(); + if (tags != null) { + Set hs = new LinkedHashSet<>(tags); + tags = new ArrayList(hs); + resourceRespJavaObject.setTags(tags); + tags = new ArrayList(hs); + resourceRespJavaObject.setTags(tags); + } + + validateField(map, RespJsonKeysEnum.RESOURCE_NAME.getRespJsonKeyName(), resourceRespJavaObject.getName()); + validateField(map, RespJsonKeysEnum.RESOURCE_DESC.getRespJsonKeyName(), + resourceRespJavaObject.getDescription()); + // validateField(map, RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName(), + // resourceRespJavaObject.getCategories()); + validateField(map, RespJsonKeysEnum.VENDOR_NAME.getRespJsonKeyName(), resourceRespJavaObject.getVendorName()); + validateField(map, RespJsonKeysEnum.VENDOR_RELEASE.getRespJsonKeyName(), + resourceRespJavaObject.getVendorRelease()); + validateField(map, RespJsonKeysEnum.CONTACT_ID.getRespJsonKeyName(), resourceRespJavaObject.getContactId()); + validateField(map, RespJsonKeysEnum.ICON.getRespJsonKeyName(), resourceRespJavaObject.getIcon()); + validateField(map, RespJsonKeysEnum.IS_ABSTRACT.getRespJsonKeyName(), + Boolean.valueOf(resourceRespJavaObject.getAbstractt())); + validateField(map, RespJsonKeysEnum.HIGHEST_VERSION.getRespJsonKeyName(), + Boolean.valueOf(resourceRespJavaObject.getIsHighestVersion())); + validateField(map, RespJsonKeysEnum.UNIQUE_ID.getRespJsonKeyName(), resourceRespJavaObject.getUniqueId()); + validateField(map, RespJsonKeysEnum.RESOURCE_VERSION.getRespJsonKeyName(), resourceRespJavaObject.getVersion()); + validateField(map, RespJsonKeysEnum.LIFE_CYCLE_STATE.getRespJsonKeyName(), + resourceRespJavaObject.getLifecycleState()); + validateField(map, RespJsonKeysEnum.TAGS.getRespJsonKeyName(), tags); + validateField(map, RespJsonKeysEnum.CREATOR_USER_ID.getRespJsonKeyName(), + resourceRespJavaObject.getCreatorUserId()); + validateField(map, RespJsonKeysEnum.CREATOR_FULL_NAME.getRespJsonKeyName(), + resourceRespJavaObject.getCreatorFullName()); + validateField(map, RespJsonKeysEnum.LAST_UPDATER_ATT_UID.getRespJsonKeyName(), + resourceRespJavaObject.getLastUpdaterUserId()); + validateField(map, RespJsonKeysEnum.LAST_UPDATER_FULL_NAME.getRespJsonKeyName(), + resourceRespJavaObject.getLastUpdaterFullName()); + validateField(map, RespJsonKeysEnum.COST.getRespJsonKeyName(), resourceRespJavaObject.getCost()); + validateField(map, RespJsonKeysEnum.LICENSE_TYPE.getRespJsonKeyName(), resourceRespJavaObject.getLicenseType()); + validateField(map, RespJsonKeysEnum.RESOURCE_TYPE.getRespJsonKeyName(), + resourceRespJavaObject.getResourceType().toString()); + if (resourceRespJavaObject.getResourceType().equals("VF")) { + validateField(map, RespJsonKeysEnum.DERIVED_FROM.getRespJsonKeyName(), null); + } else { + validateField(map, RespJsonKeysEnum.DERIVED_FROM.getRespJsonKeyName(), + resourceRespJavaObject.getDerivedFrom()); + } + + validateCategories(resourceRespJavaObject, map); + + String uuid = ResponseParser.getValueFromJsonResponse(response, RespJsonKeysEnum.UUID.getRespJsonKeyName()); + assertTrue("UUID is empty", uuid != null && !uuid.isEmpty()); + } + + private static void validateCategories(ResourceRespJavaObject resourceRespJavaObject, Map map) { + assertTrue(RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName() + " is missing", + map.containsKey(RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName())); + Object foundValue = map.get(RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName()); + List> foundList = (List>) foundValue; + List excpectedList = resourceRespJavaObject.getCategories(); + + assertTrue(foundList.size() == excpectedList.size()); + for (int i = 0; i < foundList.size(); i++) { + CategoryDefinition expCat = excpectedList.get(i); + Map foun = foundList.get(i); + assertTrue("expected " + expCat.getName() + " not equal to actual " + foundValue, + foun.get("name").equals(expCat.getName())); + } + } + + public static void validateField(Map map, String jsonField, Object expectedValue) { + if (expectedValue == null) { + assertTrue(jsonField + " is expected to be null", !map.containsKey(jsonField)); + } else { + assertTrue(jsonField + " is missing", map.containsKey(jsonField)); + Object foundValue = map.get(jsonField); + compareElements(expectedValue, foundValue); + } + } + + public static void compareElements(Object expectedValue, Object foundValue) { + if (expectedValue instanceof String) { + assertTrue(foundValue instanceof String); + assertTrue("expected " + expectedValue + " not equal to actual " + foundValue, + foundValue.equals(expectedValue)); + } + else if (expectedValue instanceof Boolean) { + assertTrue(foundValue instanceof Boolean); + assertTrue(foundValue == expectedValue); + } else if (expectedValue instanceof Map) { + assertTrue(foundValue instanceof Map); + Map foundMap = (Map) foundValue; + Map excpectedMap = (Map) expectedValue; + assertTrue(foundMap.size() == excpectedMap.size()); + Iterator foundkeyItr = foundMap.keySet().iterator(); + while (foundkeyItr.hasNext()) { + String foundKey = foundkeyItr.next(); + assertTrue(excpectedMap.containsKey(foundKey)); + compareElements(excpectedMap.get(foundKey), foundMap.get(foundKey)); + } + + } else if (expectedValue instanceof List) { + assertTrue(foundValue instanceof List); + List foundList = (List) foundValue; + List excpectedList = (List) expectedValue; + assertTrue(foundList.size() == excpectedList.size()); + for (int i = 0; i < foundList.size(); i++) { + compareElements(excpectedList.get(i), foundList.get(i)); + } + + } else { + assertTrue(foundValue.equals(expectedValue)); + } + } + + public static boolean validateUuidAfterChangingStatus(String oldUuid, String newUuid) { + return oldUuid.equals(newUuid); + + } + + public static void validateRespArt(RestResponse restResponse, ResourceRespJavaObject resourceRespJavaObject, + String interfaze) throws Exception { + + Gson gson = new Gson(); + String response = restResponse.getResponse(); + + Map map = new HashMap(); + map = (Map) gson.fromJson(response, map.getClass()); + + Resource resource = gson.fromJson(response, Resource.class); + + Map artifacts = resource.getArtifacts(); + Map interfaces = null; + + if (interfaze != null) { + interfaces = resource.getInterfaces(); + Map operation = interfaces.get(interfaze).getOperations(); + // operation.get("configure").getUniqueId(); + } + + validateField(map, RespJsonKeysEnum.RESOURCE_NAME.getRespJsonKeyName(), resourceRespJavaObject.getName()); + validateField(map, RespJsonKeysEnum.RESOURCE_DESC.getRespJsonKeyName(), + resourceRespJavaObject.getDescription()); + // validateField(map, RespJsonKeysEnum.CATEGORIES.getRespJsonKeyName(), + // resourceRespJavaObject.getCategories()); + validateField(map, RespJsonKeysEnum.DERIVED_FROM.getRespJsonKeyName(), resourceRespJavaObject.getDerivedFrom()); + validateField(map, RespJsonKeysEnum.VENDOR_NAME.getRespJsonKeyName(), resourceRespJavaObject.getVendorName()); + validateField(map, RespJsonKeysEnum.VENDOR_RELEASE.getRespJsonKeyName(), + resourceRespJavaObject.getVendorRelease()); + validateField(map, RespJsonKeysEnum.CONTACT_ID.getRespJsonKeyName(), resourceRespJavaObject.getContactId()); + validateField(map, RespJsonKeysEnum.ICON.getRespJsonKeyName(), resourceRespJavaObject.getIcon()); + validateField(map, RespJsonKeysEnum.IS_ABSTRACT.getRespJsonKeyName(), + Boolean.valueOf(resourceRespJavaObject.getAbstractt())); + validateField(map, RespJsonKeysEnum.HIGHEST_VERSION.getRespJsonKeyName(), + Boolean.valueOf(resourceRespJavaObject.getIsHighestVersion())); + validateField(map, RespJsonKeysEnum.UNIQUE_ID.getRespJsonKeyName(), resourceRespJavaObject.getUniqueId()); + validateField(map, RespJsonKeysEnum.RESOURCE_VERSION.getRespJsonKeyName(), resourceRespJavaObject.getVersion()); + validateField(map, RespJsonKeysEnum.LIFE_CYCLE_STATE.getRespJsonKeyName(), + resourceRespJavaObject.getLifecycleState()); + validateField(map, RespJsonKeysEnum.TAGS.getRespJsonKeyName(), resourceRespJavaObject.getTags()); + validateField(map, RespJsonKeysEnum.CREATOR_USER_ID.getRespJsonKeyName(), + resourceRespJavaObject.getCreatorUserId()); + validateField(map, RespJsonKeysEnum.CREATOR_FULL_NAME.getRespJsonKeyName(), + resourceRespJavaObject.getCreatorFullName()); + validateField(map, RespJsonKeysEnum.LAST_UPDATER_ATT_UID.getRespJsonKeyName(), + resourceRespJavaObject.getLastUpdaterUserId()); + validateField(map, RespJsonKeysEnum.LAST_UPDATER_FULL_NAME.getRespJsonKeyName(), + resourceRespJavaObject.getLastUpdaterFullName()); + + // validate number of artifacts + if (resourceRespJavaObject.getArtifacts() != null) { + + // assertEquals("check number of artifacts", + // resourceRespJavaObject.getArtifacts().size(), artifacts.size()); + int iterNum = -1; + ArrayList myArtifacats = new ArrayList(); + Iterator it = artifacts.entrySet().iterator(); + while (it.hasNext()) { + iterNum++; + Map.Entry pair = (Map.Entry) it.next(); + // System.out.println(pair.getKey() + " = " + pair.getValue()); + ArtifactDefinition myArtifact = artifacts.get(pair.getKey()); + myArtifacats.add(myArtifact.getEsId()); + it.remove(); // avoids a ConcurrentModificationException + } + // assertTrue("check service contains + // artifacts",myArtifacats.containsAll(resourceRespJavaObject.getArtifacts())); + } + + // validate number of interfaces: + + if (interfaze != null) { + assertEquals("check number of interfaces", resourceRespJavaObject.getInterfaces().size(), + interfaces.size()); + } + + } + + public static boolean validateResourceIsAbstartct(List resourceList, Boolean bool) { + if (resourceList != null && resourceList.size() > 0) { + for (Resource resource : resourceList) { + if (resource.isAbstract().equals(bool)) + continue; + else + return false; + } + } else + return false; + return true; + } + + public static void validateResourceVersion(Resource resource, String expectedVersion) { + if (resource != null && !resource.equals("")) { + assertTrue("expected resource version is: " + expectedVersion + ", but actual is: " + resource.getVersion(), + resource.getVersion().equals(expectedVersion)); + } + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ServiceValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ServiceValidationUtils.java new file mode 100644 index 0000000000..19bd7b9488 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/ServiceValidationUtils.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertFalse; + +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedResourceAuditJavaObject; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; + +public class ServiceValidationUtils { + + public static void validateServiceResponseMetaData(ServiceReqDetails serviceDetails, Service service, User user, + LifecycleStateEnum lifecycleState) { + validateServiceResponseMetaData(serviceDetails, service, user, user, lifecycleState); + } + + public static void validateServiceResponseMetaData(ServiceReqDetails expectedService, Service service, + User creatorUser, User updaterUser, LifecycleStateEnum lifeCycleState) { + List expectedTags = expectedService.getTags(); + expectedTags.add(expectedService.getName()); + List receivedTags = service.getTags(); + if (expectedTags != null) { + Set hs = new LinkedHashSet<>(expectedTags); + expectedTags.clear(); + expectedTags.addAll(hs); + } + + assertEquals("Check service name on response after create service", expectedService.getName(), + service.getName()); + // check size of list + assertEquals("Check only 1 category returned on response after create service", 1, + expectedService.getCategories().size()); + assertEquals("Check service name on response after create service", expectedService.getName(), + service.getName()); + assertEquals("Check categories on response after create service", + expectedService.getCategories().get(0).getName(), service.getCategories().get(0).getName()); + assertEquals("Check tag list on response after create service", expectedTags, receivedTags); + assertEquals("Check description on response after create service", expectedService.getDescription(), + service.getDescription()); + // assertEquals("Check vendor name on response after create service", + // expectedService.getVendorName(), service.getVendorName()); + // assertEquals("Check vendor release on response after create service", + // expectedService.getVendorRelease(), service.getVendorRelease()); + assertEquals("Check attContant name on response after create service", + expectedService.getContactId().toLowerCase(), service.getContactId()); + assertEquals("Check icon name on response after create service", expectedService.getIcon(), service.getIcon()); + assertEquals("Check LastUpdaterUserId after create service", updaterUser.getUserId(), service.getLastUpdaterUserId()); + assertEquals("Check LastUpdaterName after create service", + updaterUser.getFirstName() + " " + updaterUser.getLastName(), service.getLastUpdaterFullName()); + assertEquals("Check CreatorUserId after create service", creatorUser.getUserId(), service.getCreatorUserId()); + assertEquals("Check CreatorName after create service", + creatorUser.getFirstName() + " " + creatorUser.getLastName(), service.getCreatorFullName()); + assertEquals("Check version after create service", expectedService.getVersion(), service.getVersion()); + // assertEquals("Check UniqueId after create service", SERVICE_PREFIX + + // serviceDetails.getServiceName().toLowerCase()+"." + + // serviceBaseVersion, service.getUniqueId()); + assertFalse("Check uuid after create service", service.getUUID().isEmpty()); + + // assertTrue("check creation date after create service", + // service.getCreationDate() != null); + // assertTrue("check update date after create service", + // service.getLastUpdateDate() != null); + + if (lifeCycleState != null) + assertEquals("Check LifecycleState after create service", lifeCycleState, service.getLifecycleState()); + else + assertEquals("Check LifecycleState after create service", LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT, + service.getLifecycleState()); + } + + public static ExpectedResourceAuditJavaObject constructFieldsForAuditValidation(ServiceReqDetails serviceReqDetails, + String serviceVersion, User sdncUserDetails) { + + ExpectedResourceAuditJavaObject expectedResourceAuditJavaObject = new ExpectedResourceAuditJavaObject(); + + expectedResourceAuditJavaObject.setAction("Create"); + expectedResourceAuditJavaObject.setModifierUid(sdncUserDetails.getUserId()); + String userFirstLastName = sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName(); + expectedResourceAuditJavaObject.setModifierName(userFirstLastName); + expectedResourceAuditJavaObject.setStatus("200"); + expectedResourceAuditJavaObject.setDesc("OK"); + expectedResourceAuditJavaObject.setResourceName(serviceReqDetails.getName()); + expectedResourceAuditJavaObject.setResourceType("Service"); + expectedResourceAuditJavaObject.setPrevVersion(String.valueOf(Float.parseFloat(serviceVersion) - 0.1f)); + expectedResourceAuditJavaObject.setCurrVersion(serviceVersion); + expectedResourceAuditJavaObject.setPrevState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setCurrState((LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT).toString()); + expectedResourceAuditJavaObject.setComment(null); + + return expectedResourceAuditJavaObject; + + } + + public static void validateDistrubtionStatusValue(RestResponse response, + DistributionStatusEnum expectedDistributionValue) throws Exception { + String actualDistributionValue = ResponseParser.getValueFromJsonResponse(response.getResponse(), + "distributionStatus"); + assertEquals(expectedDistributionValue.name(), actualDistributionValue); + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/UserValidationUtils.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/UserValidationUtils.java new file mode 100644 index 0000000000..a75434edcf --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/utils/validation/UserValidationUtils.java @@ -0,0 +1,279 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.utils.validation; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertTrue; + +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.users.AddUserAuditMessageInfo; +import org.openecomp.sdc.ci.tests.users.UserAuditJavaObject; +import org.openecomp.sdc.ci.tests.utils.DbUtils; +import org.openecomp.sdc.ci.tests.utils.Utils; + +import com.google.gson.Gson; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +public class UserValidationUtils { + public static void compareExpectedAndActualUsers(User expected, User actual) { + + String actualFirstName = actual.getFirstName(); + String expectedFirstName = expected.getFirstName(); + assertEquals("check user first name - ", expectedFirstName, actualFirstName); + + String actualLastName = actual.getLastName(); + String expectedLastName = expected.getLastName(); + assertEquals("check user last name - ", expectedLastName, actualLastName); + + String actualUserId = actual.getUserId(); + String expectedUserId = expected.getUserId(); + assertEquals("check user userId - ", expectedUserId, actualUserId); + + String actualEmail = actual.getEmail(); + String expectedEmail = expected.getEmail(); + assertEquals("check user email - ", expectedEmail, actualEmail); + + Long actualLastLoginTime = actual.getLastLoginTime(); + Long expectedLastLoginTime = expected.getLastLoginTime(); + assertEquals("check user last login time - ", expectedLastLoginTime, actualLastLoginTime); + + String actualRole = actual.getRole(); + if (expected.getRole() == null) { + String expectedRole = UserRoleEnum.DESIGNER.name(); + assertEquals("check user role - ", expectedRole, actualRole); + } else { + String expectedRole = expected.getRole(); + assertEquals("check user role - ", expectedRole, actualRole); + } + + UserStatusEnum actualStatus = expected.getStatus(); + UserStatusEnum expectedStatus = expected.getStatus(); + assertEquals("check user status - ", expectedStatus, actualStatus); + } + + public static void validateDeleteUserAuditMessage(User sdncUserDetails, User sdncModifierDetails, + String responseCode, String responseMessage, AddUserAuditMessageInfo addUserAuditMessageInfo) { + String action = "DeleteUser"; + validateUserAuditMessage(sdncUserDetails, sdncModifierDetails, responseCode, responseMessage, + addUserAuditMessageInfo, action); + + } + + private static void validateUserAuditMessage(User sdncUserDetails, User sdncModifierDetails, String responseCode, + String responseMessage, AddUserAuditMessageInfo addUserAuditMessageInfo, String expectedAction) { + + assertEquals("check audit action - ", expectedAction, addUserAuditMessageInfo.getACTION()); + + // String expectedModifierFirstLastName = + // sdncModifierDetails.getFirstName() + " " + + // sdncModifierDetails.getLastName(); + // assertEquals("check audit modifier name - ", + // expectedModifierFirstLastName, + // addUserAuditMessageInfo.getMODIFIER_NAME()); + String fullName = sdncModifierDetails.getFullName(); + if (sdncModifierDetails.getFullName().equals(" ")) { + fullName = ""; + } + String expectedModifierId = fullName + "(" + sdncModifierDetails.getUserId() + ")"; + assertEquals("check audit modifier uid - ", expectedModifierId, addUserAuditMessageInfo.getMODIFIER()); + + String expectedUserFirstLastName = sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName(); + if (expectedUserFirstLastName.equals("null null")) { + expectedUserFirstLastName = ""; + } + + String email = (sdncUserDetails.getEmail() == null) ? "" : sdncUserDetails.getEmail(); + String role = (sdncUserDetails.getRole() == null) ? "DESIGNER" : sdncUserDetails.getRole(); + + String formatedUser = String.format("%s,%s,%s,%s", sdncUserDetails.getUserId(), expectedUserFirstLastName, + email, role); + + // + // String expectedUserFirstLastName = sdncUserDetails.getFirstName() + " + // " + sdncUserDetails.getLastName(); + // if (expectedUserFirstLastName.equals("null null")) { + // expectedUserFirstLastName = ""; + // } + // + // String expectedUserFirstLastName = ""; + // expectedUserFirstLastName += sdncUserDetails.getFirstName() == null ? + // "" : sdncUserDetails.getFirstName(); + // String lastName = sdncUserDetails.getLastName() == null ? "" : + // sdncUserDetails.getLastName(); + // if (expectedUserFirstLastName.isEmpty()) { + // expectedUserFirstLastName = lastName; + // } else { + // expectedUserFirstLastName += " " + lastName; + // } + + assertEquals("check audit user name - ", formatedUser, addUserAuditMessageInfo.getUSER()); + + // String expectedUserUid = sdncUserDetails.getUserId(); + // assertEquals("check audit user uid - ", expectedUserUid, + // addUserAuditMessageInfo.getUSER_UID()); + // + // String expectedUserEmail = sdncUserDetails.getEmail() == null ? "" : + // sdncUserDetails.getEmail(); + // //TODO: esofer check with Andrey. Audit return "" but in user we have + // null + // assertEquals("check audit user email - ", expectedUserEmail, + // addUserAuditMessageInfo.getUSER_EMAIL()); + // + // String expectedUserRole = sdncUserDetails.getRole(); + // if (expectedUserRole ==null){ + // expectedUserRole = "DESIGNER"; + // assertEquals("check audit user role - ", expectedUserRole, + // addUserAuditMessageInfo.getUSER_ROLE()); + // }else{ + // assertEquals("check audit user role - ", expectedUserRole, + // addUserAuditMessageInfo.getUSER_ROLE()); + // } + + String expectedUserResponseCode = responseCode; + assertEquals("check audit user response code - ", expectedUserResponseCode, + addUserAuditMessageInfo.getSTATUS()); + + String expectedUserResponseMessage = responseMessage; + assertEquals("check audit user response message - ", expectedUserResponseMessage, + addUserAuditMessageInfo.getDESC()); + + } + + public static void validateDataAgainstAuditDB_access(User sdncUserDetails, UserAuditJavaObject auditJavaObject, + RestResponse restResponse, ErrorInfo errorInfo, List variables) { + + validateAuditDataAgainstAuditDbInAccess(sdncUserDetails, auditJavaObject, restResponse, errorInfo, variables); + + } + + public static void validateAuditDataAgainstAuditDbInAccess(User sdncUserDetails, + UserAuditJavaObject auditJavaObject, RestResponse restResponse, ErrorInfo errorInfo, + List variables) { + + String expected; + + expected = "Access"; + assertEquals("ACTION- ", expected, auditJavaObject.getACTION()); + + if (sdncUserDetails.getFirstName() != StringUtils.EMPTY && sdncUserDetails.getLastName() != StringUtils.EMPTY) { + expected = sdncUserDetails.getFirstName() + " " + sdncUserDetails.getLastName(); + } else { + expected = StringUtils.EMPTY; + } + String formatedUser = String.format("%s(%s)", expected, sdncUserDetails.getUserId()); + assertTrue( + "check audit user: expected start with - " + formatedUser + " ,actual - " + auditJavaObject.getUSER(), + auditJavaObject.getUSER().startsWith(formatedUser)); + + expected = restResponse.getErrorCode().toString(); + assertEquals("check audit user status code - ", expected, auditJavaObject.getSTATUS()); + + if (restResponse.getErrorCode() == 200 || restResponse.getErrorCode() == 201) { + expected = errorInfo.getMessage(); + } else { + expected = AuditValidationUtils.buildAuditDescription(errorInfo, variables); + } + + assertEquals("check audit user desc - ", expected, auditJavaObject.getDESC()); + + // expected = sdncUserDetails.getUserId(); + // assertEquals(expected, auditJavaObject.getUSER()); + + } + + public static void validateUserDetailsOnResponse(User sdncUserDetails, String userDetailsOnResponse) { + + String actualFirstName = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "firstName"); + String expectedFirstName = sdncUserDetails.getFirstName(); + assertEquals("check user first name - ", expectedFirstName, actualFirstName); + + String actualLastName = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "lastName"); + String expectedLastName = sdncUserDetails.getLastName(); + assertEquals("check user last name - ", expectedLastName, actualLastName); + + String actualUserId = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "userId"); + String expectedUserId = sdncUserDetails.getUserId(); + assertEquals("check user userId - ", expectedUserId, actualUserId); + + String actualEmail = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "email"); + String expectedEmail = sdncUserDetails.getEmail(); + assertEquals("check user email - ", expectedEmail, actualEmail); + + String actualRole = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "role"); + if (sdncUserDetails.getRole() == null) { + String expectedRole = UserRoleEnum.DESIGNER.name(); + assertEquals("check user role - ", expectedRole, actualRole); + } else { + String expectedRole = sdncUserDetails.getRole(); + assertEquals("check user role - ", expectedRole, actualRole); + } + + String actualStatus = Utils.getJsonObjectValueByKey(userDetailsOnResponse, "status"); + String expectedStatus = sdncUserDetails.getStatus().name(); + assertEquals("check user status - ", expectedStatus, actualStatus); + + } + + public static AddUserAuditMessageInfo getAddUserAuditMessage(String action) throws Exception { + + Gson gson = new Gson(); + String index = "auditingevents*"; + String type = "useradminevent"; + String pattern = "/_search?q=ACTION:\"" + action + "\""; + String auditingMessage = DbUtils.retrieveAuditMessagesByPattern(pattern); + // String auditingMessage = retrieveAuditMessageByIndexType(index, type, + // pattern); + JsonElement jElement = new JsonParser().parse(auditingMessage); + JsonObject jObject = jElement.getAsJsonObject(); + JsonObject hitsObject = (JsonObject) jObject.get("hits"); + JsonArray hitsArray = (JsonArray) hitsObject.get("hits"); + // for (int i = 0; i < hitsArray.size();){ + if (hitsArray != null) { + JsonObject jHitObject = (JsonObject) hitsArray.get(0); + JsonObject jSourceObject = (JsonObject) jHitObject.get("_source"); + AddUserAuditMessageInfo addUserAuditMessageInfo = new AddUserAuditMessageInfo(); + addUserAuditMessageInfo = gson.fromJson(jSourceObject, AddUserAuditMessageInfo.class); + return addUserAuditMessageInfo; + } + return null; + + } + + public static void validateAddUserAuditMessage(User sdncUserDetails, User sdncModifierDetails, String responseCode, + String responseMessage, AddUserAuditMessageInfo addUserAuditMessageInfo) { + + String action = "AddUser"; + validateUserAuditMessage(sdncUserDetails, sdncModifierDetails, responseCode, responseMessage, + addUserAuditMessageInfo, action); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/webSealAccess/NeoJavaObject.java b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/webSealAccess/NeoJavaObject.java new file mode 100644 index 0000000000..0c19627bda --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/ci/tests/webSealAccess/NeoJavaObject.java @@ -0,0 +1,111 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.ci.tests.webSealAccess; + +public class NeoJavaObject { + + String userId; + String firstName; + String lastName; + String email; + String role; + String label; + String elementType; + + public NeoJavaObject(String userId, String firstName, String lastName, String email, String role, String label, + String elementType) { + super(); + this.userId = userId; + this.firstName = firstName; + this.lastName = lastName; + this.email = email; + this.role = role; + this.label = label; + this.elementType = elementType; + } + + public NeoJavaObject() { + super(); + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getFirstName() { + return firstName; + } + + public void setFirstName(String firstName) { + this.firstName = firstName; + } + + public String getLastName() { + return lastName; + } + + public void setLastName(String lastName) { + this.lastName = lastName; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getRole() { + return role; + } + + public void setRole(String role) { + this.role = role; + } + + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + public String getElementType() { + return elementType; + } + + public void setElementType(String elementType) { + this.elementType = elementType; + } + + @Override + public String toString() { + return "QueryUserNeo4jInfo [userId=" + userId + ", firstName=" + firstName + ", lastName=" + lastName + + ", email=" + email + ", role=" + role + ", label=" + label + ", elementType=" + elementType + "]"; + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetAssetServlet.java b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetAssetServlet.java new file mode 100644 index 0000000000..8ea8524489 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetAssetServlet.java @@ -0,0 +1,351 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.externalApis; + +import static org.testng.AssertJUnit.assertEquals; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.codehaus.jackson.map.ObjectMapper; +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.datatypes.elements.ConsumerDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.api.Urls; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.HttpHeaderEnum; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.AssetRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import com.google.gson.Gson; + +public class GetAssetServlet extends ComponentBaseTest { + + protected User sdncUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER); + protected User sdncAdminUserDetails = ElementFactory.getDefaultUser(UserRoleEnum.ADMIN); + protected ConsumerDataDefinition consumerDataDefinition; + + @Rule + public static TestName name = new TestName(); + + public GetAssetServlet() { + super(name, GetAssetServlet.class.getName()); + } + + Gson gson = new Gson(); + + @BeforeMethod + public void setup() throws Exception { + + AtomicOperationUtils.createDefaultConsumer(true); + // consumerDataDefinition = + // ConsumerRestUtils.getDefaultConsumerDetails(); + // RestResponse deleteResponse = + // ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + // sdncAdminUserDetails); + // BaseRestUtils.checkStatusCode(deleteResponse, "delete operation + // filed", false, 404,200);; + // + // RestResponse createResponse = + // ConsumerRestUtils.createConsumer(consumerDataDefinition, + // sdncAdminUserDetails); + // BaseRestUtils.checkCreateResponse(createResponse); + + } + + // @AfterMethod + // public void tearDown() throws Exception{ + // RestResponse deleteResponse = + // ConsumerRestUtils.deleteConsumer(consumerDataDefinition, + // sdncAdminUserDetails); + // BaseRestUtils.checkStatusCode(deleteResponse, "delete operation filed", + // false, 404,200); + // + // } + + @Test // (enabled = false) + public void getResourceAssetSuccess() throws Exception { + + List expectedAssetNamesList = new ArrayList<>(); + + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("Resource1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource2"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource3"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource4"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource5"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource6"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.STARTCERTIFICATION, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails.setName("Resource7"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + expectedAssetNamesList.add(resource.getName()); + + System.out.println("7 VF resources were created"); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getResourceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getResourceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + AssetRestUtils.checkResourceTypeInObjectList(resourceAssetList, ResourceTypeEnum.VF); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_ASSET_LIST); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_ASSET_LIST.getName(), null); + + } + + @Test // (enabled = false) + public void getServiceAssetSuccess() throws Exception { + + List expectedAssetNamesList = new ArrayList<>(); + ArtifactReqDetails artifactDetails = ElementFactory.getArtifactByType(ArtifactTypeEnum.OTHER, ArtifactTypeEnum.OTHER, true); + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setName("Service1"); + RestResponse createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + Service service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service2"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service3"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service4"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service5"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service6"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.STARTCERTIFICATION, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service7"); + createService = ServiceRestUtils.createService(serviceDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils.changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true).getLeft(); + expectedAssetNamesList.add(service.getName()); + expectedAssetNamesList.add(service.getName()); + + System.out.println("7 Services were created"); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES); + BaseRestUtils.checkSuccess(assetResponse); + + List serviceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(serviceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_ASSET_LIST); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_ASSET_LIST.getName(), null); + + } + + @Test + public void getToscaModelSuccess() throws Exception { + + CloseableHttpClient httpclient = HttpClients.createDefault(); + ResourceReqDetails resourceDetails = ElementFactory.getDefaultResource(); + resourceDetails.setName("Resource1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, sdncUserDetails); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + HttpResponse assetResponse = AssetRestUtils.getComponentToscaModel(AssetTypeEnum.RESOURCES, resource.getUUID()); + resource = (Resource) AtomicOperationUtils.changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + String artId = resource.getToscaArtifacts().get("assettoscacsar").getEsId(); + String url = String.format(Urls.UI_DOWNLOAD_RESOURCE_ARTIFACT, config.getCatalogBeHost(), config.getCatalogBePort(), resource.getUniqueId(), artId); + HttpGet httpGet = createGetRequest(url); + HttpResponse response = httpclient.execute(httpGet); + InputStream inputStream = response.getEntity().getContent(); + ArtifactUiDownloadData artifactUiDownloadData = getArtifactUiDownloadData(IOUtils.toString(inputStream)); + assetResponse = AssetRestUtils.getComponentToscaModel(AssetTypeEnum.RESOURCES, resource.getUUID()); + inputStream = assetResponse.getEntity().getContent(); + int len = (int) assetResponse.getEntity().getContentLength(); + byte[] res = new byte[len]; + inputStream.read(res, 0, len); + byte[] fromUiDownload = artifactUiDownloadData.getBase64Contents().getBytes(); + assertEquals(Base64.encodeBase64(res), fromUiDownload); + String fileName = assetResponse.getFirstHeader(Constants.CONTENT_DISPOSITION_HEADER).getValue(); + assertEquals(fileName, new StringBuilder().append("attachment; filename=\"").append(artifactUiDownloadData.getArtifactName()).append("\"").toString()); + } + + private HttpGet createGetRequest(String url) { + HttpGet httpGet = new HttpGet(url); + httpGet.addHeader(HttpHeaderEnum.USER_ID.getValue(), sdncUserDetails.getUserId()); + return httpGet; + } + + private ArtifactUiDownloadData getArtifactUiDownloadData(String artifactUiDownloadDataStr) throws Exception { + + ObjectMapper mapper = new ObjectMapper(); + try { + ArtifactUiDownloadData artifactUiDownloadData = mapper.readValue(artifactUiDownloadDataStr, ArtifactUiDownloadData.class); + return artifactUiDownloadData; + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetFilteredAssetServlet.java b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetFilteredAssetServlet.java new file mode 100644 index 0000000000..3886c5aa3e --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetFilteredAssetServlet.java @@ -0,0 +1,438 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.externalApis; + +import static org.testng.AssertJUnit.assertEquals; +import static org.testng.AssertJUnit.assertNotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ErrorInfo; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.NormativeTypesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ServiceCategoriesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.AssetRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GetFilteredAssetServlet extends ComponentBaseTest { + + protected final static String categoryFilterKey = "category"; + protected final static String subCategoryFilterKey = "subCategory"; + protected final static String distributionStatusFilterKey = "distributionStatus"; + protected final static String serviceKey = "service"; + protected final static String resourceKey = "resource"; + + @Rule + public static TestName name = new TestName(); + + public GetFilteredAssetServlet() { + super(name, GetFilteredAssetServlet.class.getName()); + } + + @BeforeMethod + public void setup() throws Exception { + AtomicOperationUtils.createDefaultConsumer(true); + } + + // RESOURCE + // Success + + @Test // (enabled = false) + public void getResourceAssetBySpecifiedCategory() throws Exception { + String[] filter = { categoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_ABSTRACT.getCategory() }; + List expectedAssetNamesList = new ArrayList<>(); + + Resource resource1 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(resource1.getName()); + Resource resource2 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.DATABASE, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(resource2.getName()); + Resource resource3 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.NETWORK_CONNECTIVITY_CON_POINT, UserRoleEnum.DESIGNER, true).left().value(); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getResourceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getResourceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + // 2 resources has the same category and different subcategory + @Test // (enabled = false) + public void getResourceAssetBySpecifiedCategoryAndSubCategory() throws Exception { + String[] filter = { categoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_ABSTRACT.getCategory(), subCategoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_ABSTRACT.getSubCategory() }; + // String[] filter2 = {categoryFilterKey + "=" + + // ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS.getCategory(), + // subCategoryFilterKey + "=" + + // ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS.getSubCategory()}; + List expectedAssetNamesList = new ArrayList<>(); + + Resource resource1 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(resource1.getName()); + Resource resource2 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.DATABASE, ResourceCategoryEnum.GENERIC_NETWORK_ELEMENTS, UserRoleEnum.DESIGNER, true).left().value(); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetBySpecifiedSubCategoryAndCategory() throws Exception { + String[] filter = { subCategoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_DATABASE.getSubCategory(), categoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_DATABASE.getCategory(), }; + List expectedAssetNamesList = new ArrayList<>(); + + Resource resource1 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.COMPUTE, ResourceCategoryEnum.GENERIC_ABSTRACT, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils.createResourcesByTypeNormTypeAndCatregory(ResourceTypeEnum.VF, NormativeTypesEnum.DATABASE, ResourceCategoryEnum.GENERIC_DATABASE, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(resource2.getName()); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + // Failure + @Test // (enabled = false) + public void getResourceAssetCategoryNotExists() throws Exception { + String[] filter = { categoryFilterKey + "=" + "NotExistingCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(resourceKey, categoryFilterKey, "NotExistingCategory"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetSubCategoryNotExists() throws Exception { + String[] filter = { categoryFilterKey + "=" + ResourceCategoryEnum.GENERIC_ABSTRACT.getCategory(), subCategoryFilterKey + "=" + "NotExistingSubCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_SUB_CATEGORY_NOT_FOUND_FOR_CATEGORY.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList("Resource", "NotExistingSubCategory", ResourceCategoryEnum.GENERIC_ABSTRACT.getCategory()); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_SUB_CATEGORY_NOT_FOUND_FOR_CATEGORY.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetCategoryNotExistsSubCategoryExists() throws Exception { + String[] filter = { subCategoryFilterKey + "=" + ResourceCategoryEnum.NETWORK_L2_3_GETEWAY.getSubCategory(), categoryFilterKey + "=" + "NotExistingCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(resourceKey, categoryFilterKey, "NotExistingCategory"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetInvalidFilterKey() throws Exception { + String[] filter = { subCategoryFilterKey + "1=" + ResourceCategoryEnum.NETWORK_L2_3_GETEWAY.getSubCategory(), categoryFilterKey + "=" + "NotExistingCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.RESOURCES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_FILTER_KEY.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(subCategoryFilterKey + "1", "[" + subCategoryFilterKey + ", " + categoryFilterKey + "]"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FILTER_KEY.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.RESOURCES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + // --------------------------------------------------------------------------------------------------------- + // SERVICE + // Success + @Test // (enabled = false) + public void getServiceAssetBySpecifiedCategory() throws Exception { + String[] filter = { categoryFilterKey + "=" + ServiceCategoriesEnum.MOBILITY.getValue() }; + List expectedAssetNamesList = new ArrayList<>(); + + Service service1 = AtomicOperationUtils.createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(service1.getName()); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List serviceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(serviceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + + } + + @Test // (enabled = false) + public void getServiceAssetBySpecifiedCategoryAndDistributionStatus() throws Exception { + String[] filter = { categoryFilterKey + "=" + ServiceCategoriesEnum.MOBILITY.getValue(), distributionStatusFilterKey + "=" + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED }; + List expectedAssetNamesList = new ArrayList<>(); + ArtifactReqDetails artifactDetails = ElementFactory.getArtifactByType(ArtifactTypeEnum.OTHER, ArtifactTypeEnum.OTHER, true); + + Service service1 = AtomicOperationUtils.createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(service1.getName()); + Service service2 = AtomicOperationUtils.createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service2.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service2 = (Service) AtomicOperationUtils.changeComponentState(service2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + expectedAssetNamesList.add(service2.getName()); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List serviceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(serviceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetByDistributionStatus() throws Exception { + String[] filter = { distributionStatusFilterKey + "=" + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED }; + List expectedAssetNamesList = new ArrayList<>(); + ArtifactReqDetails artifactDetails = ElementFactory.getArtifactByType(ArtifactTypeEnum.OTHER, ArtifactTypeEnum.OTHER, true); + + Service service1 = AtomicOperationUtils.createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + expectedAssetNamesList.add(service1.getName()); + Service service2 = AtomicOperationUtils.createServiceByCategory(ServiceCategoriesEnum.MOBILITY, UserRoleEnum.DESIGNER, true).left().value(); + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service2.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service2 = (Service) AtomicOperationUtils.changeComponentState(service2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + ServiceRestUtils.approveServiceDistribution(service2.getUniqueId(), UserRoleEnum.GOVERNOR.getUserId()); + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + BaseRestUtils.checkSuccess(assetResponse); + + List serviceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(serviceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + // Failure + @Test // (enabled = false) + public void getServiceAssetCategoryNotExists() throws Exception { + String[] filter = { categoryFilterKey + "=" + "NotExistingCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(serviceKey, categoryFilterKey, "NotExistingCategory"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetInvalidDistributionStatus() throws Exception { + String[] filter = { distributionStatusFilterKey + "=" + "NotExistingDistributionStatus" }; + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(serviceKey, distributionStatusFilterKey, "NotExistingDistributionStatus"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetCategoryExitsDistributionStatusInvalid() throws Exception { + String[] filter = { categoryFilterKey + "=" + ServiceCategoriesEnum.MOBILITY.getValue(), distributionStatusFilterKey + "=" + "NotExistingDistributionStatus" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(serviceKey, distributionStatusFilterKey, "NotExistingDistributionStatus"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetCategoryNotExistsDistributionStatus() throws Exception { + String[] filter = { distributionStatusFilterKey + "=" + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, categoryFilterKey + "=" + "NotExistingCategory" }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(serviceKey, categoryFilterKey, "NotExistingCategory"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.COMPONENT_CATEGORY_NOT_FOUND.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetInvalidFilterKey() throws Exception { + String[] filter = { distributionStatusFilterKey + "1=" + DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED, categoryFilterKey + "=" + ServiceCategoriesEnum.MOBILITY.getValue() }; + + RestResponse assetResponse = AssetRestUtils.getComponentListByAssetType(true, AssetTypeEnum.SERVICES, filter); + ErrorInfo errorInfo = ErrorValidationUtils.parseErrorConfigYaml(ActionStatus.INVALID_FILTER_KEY.name()); + + assertNotNull("check response object is not null after create resouce", assetResponse); + assertNotNull("check error code exists in response after create resource", assetResponse.getErrorCode()); + assertEquals("Check response code after create resource", errorInfo.getCode(), assetResponse.getErrorCode()); + + List variables = Arrays.asList(distributionStatusFilterKey + "1", "[" + categoryFilterKey + ", " + distributionStatusFilterKey + "]"); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.INVALID_FILTER_KEY.name(), variables, assetResponse.getResponse()); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory.getDefaultAssetListAudit(AssetTypeEnum.SERVICES, AuditingActionEnum.GET_FILTERED_ASSET_LIST); + expectedAssetListAudit.setRESOURCE_URL(AssetRestUtils.buildUrlWithFilter(expectedAssetListAudit.getRESOURCE_URL(), filter)); + expectedAssetListAudit.setSTATUS(errorInfo.getCode().toString()); + expectedAssetListAudit.setDESC(AuditValidationUtils.buildAuditDescription(errorInfo, variables)); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + + } +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetSpecificAssetMetadataServlet.java b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetSpecificAssetMetadataServlet.java new file mode 100644 index 0000000000..05d305ad9a --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/externalApis/GetSpecificAssetMetadataServlet.java @@ -0,0 +1,773 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.externalApis; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Rule; +import org.junit.rules.TestName; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.ci.tests.api.ComponentBaseTest; +import org.openecomp.sdc.ci.tests.datatypes.ArtifactReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ResourceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceDetailedAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ResourceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.ServiceAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceDetailedAssetStructure; +import org.openecomp.sdc.ci.tests.datatypes.ServiceReqDetails; +import org.openecomp.sdc.ci.tests.datatypes.enums.ArtifactTypeEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.LifeCycleStatesEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.ResourceCategoryEnum; +import org.openecomp.sdc.ci.tests.datatypes.enums.UserRoleEnum; +import org.openecomp.sdc.ci.tests.datatypes.expected.ExpectedExternalAudit; +import org.openecomp.sdc.ci.tests.datatypes.http.RestResponse; +import org.openecomp.sdc.ci.tests.utils.Utils; +import org.openecomp.sdc.ci.tests.utils.general.AtomicOperationUtils; +import org.openecomp.sdc.ci.tests.utils.general.ElementFactory; +import org.openecomp.sdc.ci.tests.utils.rest.ArtifactRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.AssetRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.BaseRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.LifecycleRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResourceRestUtils; +import org.openecomp.sdc.ci.tests.utils.rest.ResponseParser; +import org.openecomp.sdc.ci.tests.utils.rest.ServiceRestUtils; +import org.openecomp.sdc.ci.tests.utils.validation.AuditValidationUtils; +import org.openecomp.sdc.ci.tests.utils.validation.ErrorValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +public class GetSpecificAssetMetadataServlet extends ComponentBaseTest { + private static Logger log = LoggerFactory.getLogger(GetAssetServlet.class.getName()); + + @Rule + public static TestName name = new TestName(); + + public GetSpecificAssetMetadataServlet() { + super(name, GetSpecificAssetMetadataServlet.class.getName()); + } + + @BeforeMethod + public void setup() throws Exception { + AtomicOperationUtils.createDefaultConsumer(true); + } + + // get specific asset metadata + + // Resource + @Test // (enabled = false) + public void getResourceAssetMetadataSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithResourceInstancesSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resourceVF = ResponseParser.parseToObjectUsingMapper( + ResourceRestUtils.getResource(resourceVF.getUniqueId()).getResponse(), Resource.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithNonCertifiedResourceInstancesSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + + // certify resource2 and add to VF(VF with resource2 0.1, 1.0 and 1.1 + // versions) + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resourceVF = ResponseParser.parseToObjectUsingMapper( + ResourceRestUtils.getResource(resourceVF.getUniqueId()).getResponse(), Resource.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithResourceInstancesVfInSubmitForTestingSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + + // certify resource2 and add to VF(VF with resource2 1.0, 2.0 and 3.0 + // versions) + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithResourceInstancesVfInStartCertificationSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + + // certify resource2 and add to VF(VF with resource2 1.0, 2.0 and 3.0 + // versions) + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.STARTCERTIFICATION, true) + .getLeft(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithResourceInstancesCertifiedVFSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + + // certify resource2 and add to VF(VF with resource2 1.0, 2.0 and 3.0 + // versions) + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getResourceAssetMetadataWithNonCertifiedResourceInstancesAndArtifactsSuccess() throws Exception { + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + Resource resource2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource2 = (Resource) AtomicOperationUtils + .changeComponentState(resource2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + Resource resource3 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VFC, UserRoleEnum.DESIGNER, true).left().value(); + resource3 = (Resource) AtomicOperationUtils + .changeComponentState(resource3, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFICATIONREQUEST, true) + .getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource2, resourceVF, UserRoleEnum.DESIGNER, + true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resource3, resourceVF, UserRoleEnum.DESIGNER, + true); + + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, + true, true); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.APPC_CONFIG, resourceVF, UserRoleEnum.DESIGNER, true, + true); + resourceVF = ResponseParser.parseToObjectUsingMapper( + ResourceRestUtils.getResource(resourceVF.getUniqueId()).getResponse(), Resource.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.RESOURCES, + resourceVF.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ResourceDetailedAssetStructure resourceAssetMetadata = AssetRestUtils.getResourceAssetMetadata(assetResponse); + AssetRestUtils.resourceMetadataValidatior(resourceAssetMetadata, resourceVF, AssetTypeEnum.RESOURCES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.RESOURCES, resourceVF); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + // Import CSAR + + // Service + @Test // (enabled = false) + public void getServiceAssetMetadataSuccess() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + service.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ServiceDetailedAssetStructure serviceAssetMetadata = AssetRestUtils.getServiceAssetMetadata(assetResponse); + AssetRestUtils.serviceMetadataValidatior(serviceAssetMetadata, service, AssetTypeEnum.SERVICES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.SERVICES, service); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetMetadataWithResourceInstancesSuccess() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + service = ResponseParser.parseToObjectUsingMapper(ServiceRestUtils + .getService(service.getUniqueId(), ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)).getResponse(), + Service.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + service.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ServiceDetailedAssetStructure serviceAssetMetadata = AssetRestUtils.getServiceAssetMetadata(assetResponse); + AssetRestUtils.serviceMetadataValidatior(serviceAssetMetadata, service, AssetTypeEnum.SERVICES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.SERVICES, service); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + + } + + @Test // (enabled = false) + public void getServiceAssetMetadataWithNonCertifiedResourceInstancesWithArtifactsSuccess() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, + true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + Resource resourceVF2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.APPC_CONFIG, resourceVF2, UserRoleEnum.DESIGNER, + true, true); + resourceVF2 = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF2, service, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + + // service with 0.1, 0.1 and 1.0 RIs versions + service = ResponseParser.parseToObjectUsingMapper(ServiceRestUtils + .getService(service.getUniqueId(), ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)).getResponse(), + Service.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + service.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ServiceDetailedAssetStructure serviceAssetMetadata = AssetRestUtils.getServiceAssetMetadata(assetResponse); + AssetRestUtils.serviceMetadataValidatior(serviceAssetMetadata, service, AssetTypeEnum.SERVICES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.SERVICES, service); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + + } + + @Test // (enabled = false) + public void getServiceAssetMetadataWithCertifiedResourceInstancesAndArtifactsOnRIsAndServiceSuccess() + throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, + true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + Resource resourceVF2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.APPC_CONFIG, resourceVF2, UserRoleEnum.DESIGNER, + true, true); + resourceVF2 = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF2, service, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, resourceVF, + UserRoleEnum.DESIGNER, true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + + // service with resourceVF 1.0(1 art), 2.0(2 art) versions and + // resourceVF2 1.0(1 art), service 1 artifact version + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, service, + UserRoleEnum.DESIGNER, true, true); + service = ResponseParser.parseToObjectUsingMapper(ServiceRestUtils + .getService(service.getUniqueId(), ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)).getResponse(), + Service.class); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + service.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ServiceDetailedAssetStructure serviceAssetMetadata = AssetRestUtils.getServiceAssetMetadata(assetResponse); + AssetRestUtils.serviceMetadataValidatior(serviceAssetMetadata, service, AssetTypeEnum.SERVICES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.SERVICES, service); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + + } + + @Test // (enabled = false) + public void getServiceAssetMetadataWithResourceInstancesServiceInSubmitForTestingSuccess() throws Exception { + + Service service = AtomicOperationUtils.createDefaultService(UserRoleEnum.DESIGNER, true).left().value(); + + Resource resourceVF = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.VENDOR_LICENSE, resourceVF, UserRoleEnum.DESIGNER, + true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + Resource resourceVF2 = AtomicOperationUtils + .createResourceByType(ResourceTypeEnum.VF, UserRoleEnum.DESIGNER, true).left().value(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.APPC_CONFIG, resourceVF2, UserRoleEnum.DESIGNER, + true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF2, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF2, service, UserRoleEnum.DESIGNER, + true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, resourceVF, + UserRoleEnum.DESIGNER, true, true); + resourceVF = (Resource) AtomicOperationUtils + .changeComponentState(resourceVF, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + AtomicOperationUtils.addComponentInstanceToComponentContainer(resourceVF, service, UserRoleEnum.DESIGNER, true); + + // service with resourceVF 1.0(1 art), 2.0(2 art) versions and + // resourceVF2 1.0(1 art), service 1 artifact version + AtomicOperationUtils.uploadArtifactByType(ArtifactTypeEnum.MODEL_INVENTORY_PROFILE, service, + UserRoleEnum.DESIGNER, true, true); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + service.getUUID()); + BaseRestUtils.checkSuccess(assetResponse); + + ServiceDetailedAssetStructure serviceAssetMetadata = AssetRestUtils.getServiceAssetMetadata(assetResponse); + AssetRestUtils.serviceMetadataValidatior(serviceAssetMetadata, service, AssetTypeEnum.SERVICES); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultAssetMetadataAudit(AssetTypeEnum.SERVICES, service); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_ASSET_METADATA.getName(), null); + } + + @Test // (enabled = false) + public void getServiceAssetMetadataServiceNotFound() throws Exception { + + String serviceUuid = "notExistingServiceUuid"; + RestResponse assetResponse = AssetRestUtils.getAssetMetadataByAssetTypeAndUuid(true, AssetTypeEnum.SERVICES, + serviceUuid); + + // Validate audit message + ArrayList variables = new ArrayList<>(); + variables.add(serviceUuid); + ErrorValidationUtils.checkBodyResponseOnError(ActionStatus.RESOURCE_NOT_FOUND.name(), variables, + assetResponse.getResponse()); + } + + // Add to service VF instance imported from CSAR + + @Test + public void getFilteredResourceAssetSuccess() throws Exception { + + List expectedAssetNamesList = new ArrayList<>(); + + ResourceReqDetails resourceDetails = ElementFactory + .getDefaultResource(ResourceCategoryEnum.APPLICATION_L4_APP_SERVER); + resourceDetails.setName("Resource1"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + RestResponse createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + Resource resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + expectedAssetNamesList.add(resource.getName()); + + resourceDetails = ElementFactory.getDefaultResource(ResourceCategoryEnum.APPLICATION_L4_BORDER); + resourceDetails.setName("Resource2"); + resourceDetails.setResourceType(ResourceTypeEnum.VFC.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + + resourceDetails = ElementFactory.getDefaultResource(ResourceCategoryEnum.GENERIC_INFRASTRUCTURE); + resourceDetails.setName("Resource3"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + resourceDetails = ElementFactory.getDefaultResource(ResourceCategoryEnum.APPLICATION_L4_FIREWALL); + resourceDetails.setName("Resource4"); + resourceDetails.setResourceType(ResourceTypeEnum.VF.name()); + createResource = ResourceRestUtils.createResource(resourceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createResource); + resource = ResponseParser.parseToObjectUsingMapper(createResource.getResponse(), Resource.class); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + resource = (Resource) AtomicOperationUtils + .changeComponentState(resource, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + expectedAssetNamesList.add(resource.getName()); + + log.debug("4 resources created"); + String query = "category=Application%20L4%2B"; + RestResponse assetResponse = AssetRestUtils.getFilteredComponentList(AssetTypeEnum.RESOURCES, query); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getResourceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getResourceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + AssetRestUtils.checkResourceTypeInObjectList(resourceAssetList, ResourceTypeEnum.VF); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultFilteredAssetListAudit(AssetTypeEnum.RESOURCES, "?" + query); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + + } + + @Test + public void getFilteredResourceAssetCategoryNotFound() throws Exception { + + String query = "category=Application%20L3%2B"; + RestResponse assetResponse = AssetRestUtils.getFilteredComponentList(AssetTypeEnum.RESOURCES, query); + BaseRestUtils.checkErrorResponse(assetResponse, ActionStatus.COMPONENT_CATEGORY_NOT_FOUND, "resource", + "category", "Application L3+"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getFilteredAssetListAuditCategoryNotFound(AssetTypeEnum.RESOURCES, "?" + query, "Application L3+"); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + + } + + @Test + public void getFilteredServiceAssetSuccess() throws Exception { + + List expectedAssetNamesList = new ArrayList<>(); + ArtifactReqDetails artifactDetails = ElementFactory.getArtifactByType(ArtifactTypeEnum.OTHER, + ArtifactTypeEnum.OTHER, true); + + ServiceReqDetails serviceDetails = ElementFactory.getDefaultService(); + serviceDetails.setName("Service1"); + RestResponse createService = ServiceRestUtils.createService(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + Service service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + + serviceDetails.setName("Service2"); + createService = ServiceRestUtils.createService(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + RestResponse addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService( + artifactDetails, ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + + ServiceReqDetails certifyService = new ServiceReqDetails(service); + LifecycleRestUtils.changeDistributionStatus(certifyService, certifyService.getVersion(), + ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR), null, + DistributionStatusEnum.DISTRIBUTION_APPROVED); + AtomicOperationUtils.distributeService(service, false); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service3"); + createService = ServiceRestUtils.createService(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + addInformationalArtifactToService = ArtifactRestUtils.addInformationalArtifactToService(artifactDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER), service.getUniqueId()); + BaseRestUtils.checkSuccess(addInformationalArtifactToService); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CERTIFY, true).getLeft(); + certifyService = new ServiceReqDetails(service); + LifecycleRestUtils.changeDistributionStatus(certifyService, certifyService.getVersion(), + ElementFactory.getDefaultUser(UserRoleEnum.GOVERNOR), null, + DistributionStatusEnum.DISTRIBUTION_APPROVED); + AtomicOperationUtils.distributeService(service, false); + expectedAssetNamesList.add(service.getName()); + + serviceDetails.setName("Service4"); + createService = ServiceRestUtils.createService(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + + serviceDetails.setName("Service5"); + createService = ServiceRestUtils.createService(serviceDetails, + ElementFactory.getDefaultUser(UserRoleEnum.DESIGNER)); + BaseRestUtils.checkCreateResponse(createService); + service = ResponseParser.parseToObjectUsingMapper(createService.getResponse(), Service.class); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKIN, true).getLeft(); + service = (Service) AtomicOperationUtils + .changeComponentState(service, UserRoleEnum.DESIGNER, LifeCycleStatesEnum.CHECKOUT, true).getLeft(); + + String query = "distributionStatus=Distributed"; + RestResponse assetResponse = AssetRestUtils.getFilteredComponentList(AssetTypeEnum.SERVICES, query); + BaseRestUtils.checkSuccess(assetResponse); + + List resourceAssetList = AssetRestUtils.getServiceAssetList(assetResponse); + List getActualAssetNamesList = AssetRestUtils.getServiceNamesList(resourceAssetList); + Utils.compareArrayLists(getActualAssetNamesList, expectedAssetNamesList, "Element"); + + // Validate audit message + ExpectedExternalAudit expectedAssetListAudit = ElementFactory + .getDefaultFilteredAssetListAudit(AssetTypeEnum.SERVICES, "?" + query); + AuditValidationUtils.validateExternalAudit(expectedAssetListAudit, + AuditingActionEnum.GET_FILTERED_ASSET_LIST.getName(), null); + + } + +} diff --git a/asdc-tests/src/main/java/org/openecomp/sdc/post/Install.java b/asdc-tests/src/main/java/org/openecomp/sdc/post/Install.java new file mode 100644 index 0000000000..f0494fe177 --- /dev/null +++ b/asdc-tests/src/main/java/org/openecomp/sdc/post/Install.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.post; + +import java.io.File; + +import org.openecomp.sdc.be.dao.titan.TitanGraphClient; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; + +public class Install { + public static void main(String[] args) { + + if (args == null || args.length == 0) { + System.out.println("Usage: org.openecomp.sdc.post.Install path_to_titan.properties"); + System.exit(1); + } + String titanPropsFile = args[0]; + + if (!isFileExists(titanPropsFile)) { + System.exit(2); + } + + if (!createTitanSchema(titanPropsFile)) { + System.exit(3); + } + + System.exit(0); + } + + private static boolean createTitanSchema(String titanPropsFile) { + TitanGraphClient titanGraphClient = new TitanGraphClient(); + TitanOperationStatus status = titanGraphClient.createGraph(titanPropsFile, true); + if (TitanOperationStatus.OK == status) { + System.out.println("Titan schema ,indexes and default values created successfully."); + return true; + } else { + System.out.println( + "Problem while creating titan schema ,indexes and default values. (" + status.name() + ")"); + return false; + } + } + + private static boolean isFileExists(String titanPropsFile) { + File f = new File(titanPropsFile); + if (!f.exists()) { + System.out.println(titanPropsFile + " not found"); + return false; + } + return true; + } +} diff --git a/asdc-tests/src/main/resources/ci/conf/log4j.properties b/asdc-tests/src/main/resources/ci/conf/log4j.properties new file mode 100644 index 0000000000..d313e92b55 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/conf/log4j.properties @@ -0,0 +1,34 @@ +# Define the root logger with appender file +log4j.rootLogger = INFO, FILE, stdout + +# Define the file appender +log4j.appender.FILE=org.apache.log4j.RollingFileAppender +log4j.appender.FILE.File=${targetlog}logs/ci-log.out + +# Define the layout for file appender +log4j.appender.FILE.layout=org.apache.log4j.PatternLayout +log4j.appender.FILE.layout.conversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p [%10c] : %m%n + +# Set the maximum file size before rollover +log4j.appender.FILE.maxFileSize=5MB + +# Set the the backup index +log4j.appender.FILE.maxBackupIndex=10 + + +############################################################# + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +#log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %5p %10c:%L - %m%n + +log4j.logger.org.apache.cassandra.service.StorageProxy=INFO +log4j.logger.com.thinkaurelius.titan.diskstorage.cassandra.CassandraTransaction=INFO, FILE, stdout + +log4j.logger.org.openecomp.sdc.ci.tests.utils=INFO, FILE, stdout +log4j.additivity.org.openecomp.sdc.ci.tests.utils=false + + diff --git a/asdc-tests/src/main/resources/ci/conf/sdc-packages.yaml b/asdc-tests/src/main/resources/ci/conf/sdc-packages.yaml new file mode 100644 index 0000000000..5d1a3e1537 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/conf/sdc-packages.yaml @@ -0,0 +1,12 @@ +packages: + - org.openecomp.sdc.ci.tests.execute.general + - org.openecomp.sdc.ci.tests.execute.user + - org.openecomp.sdc.ci.tests.execute.property + - org.openecomp.sdc.ci.tests.execute.lifecycle + - org.openecomp.sdc.ci.tests.execute.resource + - org.openecomp.sdc.ci.tests.execute.service + - org.openecomp.sdc.ci.tests.execute.artifacts + - org.openecomp.sdc.ci.tests.execute.imports + - org.openecomp.sdc.ci.tests.execute.category + - org.openecomp.sdc.ci.tests.execute.distribution + - org.openecomp.sdc.ci.tests.execute.product \ No newline at end of file diff --git a/asdc-tests/src/main/resources/ci/conf/sdc.yaml b/asdc-tests/src/main/resources/ci/conf/sdc.yaml new file mode 100644 index 0000000000..c9730811b3 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/conf/sdc.yaml @@ -0,0 +1,88 @@ +outputFolder: target +reportName: index.html +catalogBeHost: behost +catalogFeHost: fehost +esHost: eshost +disributionClientHost: disClient +catalogFePort: 8181 +catalogBePort: 8080 +disributionClientPort: 8181 +esPort: 9200 +neoHost: neoHost +neoPort: 7474 +neoDBusername: neo4j +neoDBpassword: 123456 + +resourceConfigDir: src/test/resources/CI/tests +componentsConfigDir: src/test/resources/CI/components +importResourceConfigDir: ../catalog-be/src/main/resources/import/tosca/capability-types +importResourceTestsConfigDir: src/test/resources/CI/importResourceTests +errorConfigurationFile: ../catalog-be/src/main/resources/config/error-configuration.yaml +configurationFile: ../catalog-be/src/main/resources/config/configuration.yaml +importTypesConfigDir: src/test/resources/CI/importTypesTest + + +titanPropertiesFile: src/main/resources/ci/conf/titan.properties +cassandraHost: 127.0.0.1 +cassandraAuthenticate: false +cassandraUsername: koko +cassandraPassword: bobo +cassandraSsl: false +cassandraTruststorePath : /path/path +cassandraTruststorePassword : 123123 +cassandraAuditKeySpace: sdcAudit +cassandraArtifactKeySpace: sdcArtifact + + +stopOnClassFailure: false + +#List of non-abstract resources to keep during titan cleanup between tests +#Only 1.0 version will be kept +resourcesNotToDelete: + - Compute + - Database + - ObjectStorage + - BlockStorage + - LoadBalancer + - Port + - Network + - Root + - ContainerApplication + - ContainerRuntime + - DBMS + - SoftwareComponent + - WebApplication + - WebServer + - CinderVolume + - ContrailVirtualNetwork + - NeutronNet + - NeutronPort + - NovaServer + - AbstractSubstitute + - ContrailAbstractSubstitute + - ContrailCompute + - ContrailNetworkRules + - ContrailPort + - ContrailV2NetworkRules + - ContrailV2VirtualMachineInterface + - ContrailV2VirtualNetwork + - ContrailVirtualNetwork + - VL ELINE + - SecurityRules + - VL + +#Resource categories to keep (including all their subcategories) +resourceCategoriesNotToDelete: + - Generic + - Network L2-3 + - Network L4+ + - Application L4+ + - Network Connectivity + - DcaeComponent + +#Service categories to keep +serviceCategoriesNotToDelete: + - Mobility + - Network L1-3 + - Network L4+ + - VoIP Call Control \ No newline at end of file diff --git a/asdc-tests/src/main/resources/ci/conf/testngLifeCycle.xml b/asdc-tests/src/main/resources/ci/conf/testngLifeCycle.xml new file mode 100644 index 0000000000..aa390dc213 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/conf/testngLifeCycle.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/conf/titan.properties b/asdc-tests/src/main/resources/ci/conf/titan.properties new file mode 100644 index 0000000000..42e1998f89 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/conf/titan.properties @@ -0,0 +1,8 @@ +storage.backend=cassandra +#storage.hostname=cassandrahost +storage.hostname=localhost +storage.port=9160 + +cache.db-cache = false + + diff --git a/asdc-tests/src/main/resources/ci/conf/truststore b/asdc-tests/src/main/resources/ci/conf/truststore new file mode 100644 index 0000000000..bdec93d862 Binary files /dev/null and b/asdc-tests/src/main/resources/ci/conf/truststore differ diff --git a/asdc-tests/src/main/resources/ci/scripts/startTest.sh b/asdc-tests/src/main/resources/ci/scripts/startTest.sh new file mode 100644 index 0000000000..ca3add59c5 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/scripts/startTest.sh @@ -0,0 +1,88 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function exitOnError() { + if [ $1 -ne 0 ] + then + echo "Failed running task $2" + exit 2 + fi +} + +if [ $# -lt 1 ] +then + usage + exit 2 +fi + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +LOGS_PROP_FILE=file:${FULL_PATH}/conf/log4j.properties +############################################# +TARGET_DIR=${FULL_PATH}/target +CONF_FILE=${FULL_PATH}/conf/sdc.yaml +DEBUG=true +MainClass=org.openecomp.sdc.ci.tests.run.StartTest + +JAR_FILE=$1 +SUITE_FILE=$2 + +#TARGET_DIR=`echo ${TARGET_DIR} | sed 's/\//\//g'` +#echo $TARGET_DIR + +TESTS_DIR=/opt/app/sdc/ci/resources/tests +COMPONENTS_DIR=/opt/app/sdc/ci/resources/components + +#sed -i 's#\(outputFolder:\).*#\1 '${TARGET_DIR}'#g' $CONF_FILE +#sed -i 's#\(resourceConfigDir:\).*#\1 '${TESTS_DIR}'#g' $CONF_FILE +#sed -i 's#\(componentsConfigDir:\).*#\1 '${COMPONENTS_DIR}'#g' $CONF_FILE +TARGET_LOG_DIR="${TARGET_DIR}/" + +# mkdir -p ${TARGET_DIR} +#if [ -d ${TARGET_DIR} ] +#then +# rm -rf ${TARGET_DIR}/* +#exitOnError $? "Failed_to_delete_target_dir" +#fi + +debug_port=8800 +#JAVA_OPTION="-javaagent:/var/tmp/jacoco/lib/jacocoagent.jar=destfile=jacoco-it.exec" +JAVA_OPTION="" +case "$2" in + -debug) echo "Debug mode, Listen on port $debug_port"; JAVA_OPTION="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=${debug_port}" ;; + "") echo "Standard mode";; + *) echo "USAGE: startTest.sh [-debug]";; +esac + +cmd="java $JAVA_OPTION -DdisplayException=true -Dtargetlog=${TARGET_LOG_DIR} -Dconfig.resource=${CONF_FILE} -Ddebug=${DEBUG} -Dlog4j.configuration=${LOGS_PROP_FILE} -cp $JAR_FILE ${MainClass} $SUITE_FILE" + +#echo $cmd +#console=`$cmd` + +if [ $DEBUG == "true" ] +then + $cmd +else + $cmd >> /dev/null +fi +status=`echo $?` + + + +echo "##################################################" +echo "################# status is ${status} #################" +echo "##################################################" + +exit $status + diff --git a/asdc-tests/src/main/resources/ci/testSuites/artifacts.xml b/asdc-tests/src/main/resources/ci/testSuites/artifacts.xml new file mode 100644 index 0000000000..24229b8586 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/artifacts.xml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/category.xml b/asdc-tests/src/main/resources/ci/testSuites/category.xml new file mode 100644 index 0000000000..f2a0b3790c --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/category.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/ciFull.xml b/asdc-tests/src/main/resources/ci/testSuites/ciFull.xml new file mode 100644 index 0000000000..9877670a90 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/ciFull.xml @@ -0,0 +1,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/asdc-tests/src/main/resources/ci/testSuites/externalApis.xml b/asdc-tests/src/main/resources/ci/testSuites/externalApis.xml new file mode 100644 index 0000000000..5db368ecf4 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/externalApis.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/asdc-tests/src/main/resources/ci/testSuites/general.xml b/asdc-tests/src/main/resources/ci/testSuites/general.xml new file mode 100644 index 0000000000..bd7e6b6650 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/general.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/imports.xml b/asdc-tests/src/main/resources/ci/testSuites/imports.xml new file mode 100644 index 0000000000..ae4a5bc1f8 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/imports.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/product.xml b/asdc-tests/src/main/resources/ci/testSuites/product.xml new file mode 100644 index 0000000000..4ea495d0d7 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/product.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/property.xml b/asdc-tests/src/main/resources/ci/testSuites/property.xml new file mode 100644 index 0000000000..f94f89737a --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/property.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/resource.xml b/asdc-tests/src/main/resources/ci/testSuites/resource.xml new file mode 100644 index 0000000000..5f23325790 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/resource.xml @@ -0,0 +1,336 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/sanity.xml b/asdc-tests/src/main/resources/ci/testSuites/sanity.xml new file mode 100644 index 0000000000..11b4b79fc4 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/sanity.xml @@ -0,0 +1,389 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/asdc-tests/src/main/resources/ci/testSuites/service.xml b/asdc-tests/src/main/resources/ci/testSuites/service.xml new file mode 100644 index 0000000000..18d5630c4e --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/service.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/testngLifeCycle.xml b/asdc-tests/src/main/resources/ci/testSuites/testngLifeCycle.xml new file mode 100644 index 0000000000..54f1868470 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/testngLifeCycle.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asdc-tests/src/main/resources/ci/testSuites/user.xml b/asdc-tests/src/main/resources/ci/testSuites/user.xml new file mode 100644 index 0000000000..948993c144 --- /dev/null +++ b/asdc-tests/src/main/resources/ci/testSuites/user.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/asdc-tests/src/test/resources/CI/components/apache/apache-type.yml b/asdc-tests/src/test/resources/CI/components/apache/apache-type.yml new file mode 100644 index 0000000000..360b1a2d60 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/apache/apache-type.yml @@ -0,0 +1,50 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: TOSCA simple profile with Apache. +template_name: apache-type +template_version: 2.0.0-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-webServer:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Apache: + derived_from: tosca.nodes.WebServer + description: > + The TOSCA Apache Node Type represents an apache component + that can be managed and run by a TOSCA Compute Node Type. + capabilities: + host: + type: alien.capabilities.ApacheContainer + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + tags: + icon: /images/apache.png + properties: + version: + type: version + default: 2.4 + constraints: + - equal: 2.4 + port: + type: integer + description: Port for the Apache server + default: 80 + constraints: + - greater_or_equal: 1 + document_root: + type: string + default: "/var/www" + interfaces: + Standard: + create: + inputs: + PORT: { get_property: [SELF, port] } + DOC_ROOT: { get_property: [SELF, document_root] } + implementation: scripts/install_apache.sh + start: scripts/start_apache.sh + +capability_types: + alien.capabilities.ApacheContainer: + derived_from: tosca.capabilities.Container diff --git a/asdc-tests/src/test/resources/CI/components/apache/images/apache.png b/asdc-tests/src/test/resources/CI/components/apache/images/apache.png new file mode 100644 index 0000000000..8e9f402d90 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/apache/images/apache.png differ diff --git a/asdc-tests/src/test/resources/CI/components/apache/scripts/install_apache.sh b/asdc-tests/src/test/resources/CI/components/apache/scripts/install_apache.sh new file mode 100644 index 0000000000..a77f9a13f8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/apache/scripts/install_apache.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +echo "Using apt-get. Installing apache2 on one of the following : Debian, Ubuntu, Mint" +LOCK="/tmp/lockaptget" +DEFAULT_PORT=80 + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "Apache take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done + +sudo rm -f /var/lib/dpkg/lock +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo apt-get install -y -q apache2 || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/apache2 stop +if [ ! -d $DOC_ROOT ]; then + eval "sudo mkdir -p $DOC_ROOT" +fi +eval "sudo chown -R www-data:www-data $DOC_ROOT" + +if [[ ("$PORT" == "$DEFAULT_PORT") ]]; then + echo "Use default port for Apache : $DEFAULT_PORT" +else + echo "Replacing port $DEFAULT_PORT with $PORT..." + sudo sed -i -e "s/$DEFAULT_PORT/$PORT/g" /etc/apache2/ports.conf || exit ${1} +fi + +echo "Change config of apache2" +if sudo test -f "/etc/apache2/sites-available/default"; then + echo "Change the DocumentRoot of apache2 on Ubuntu < 14.04" + sudo sed -i -e "s#DocumentRoot /var/www#DocumentRoot $DOC_ROOT#g" /etc/apache2/sites-available/default +fi +if sudo test -f "/etc/apache2/sites-available/000-default.conf"; then + echo "Change the DocumentRoot of Apache2 on Ubuntu >= 14.04" + sudo sed -i -e "s#DocumentRoot /var/www/html#DocumentRoot $DOC_ROOT#g" /etc/apache2/sites-available/000-default.conf +fi + +sudo bash -c "echo ServerName localhost >> /etc/apache2/apache2.conf" + +echo "Start apache2 whith new conf" +sudo /etc/init.d/apache2 start +echo "End of $0" diff --git a/asdc-tests/src/test/resources/CI/components/apache/scripts/start_apache.sh b/asdc-tests/src/test/resources/CI/components/apache/scripts/start_apache.sh new file mode 100644 index 0000000000..478c56edf5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/apache/scripts/start_apache.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +service="apache2" + +if (( $(ps -ef | grep -v grep | grep $service | wc -l) > 0 )) +then + sudo /etc/init.d/$service restart +else + sudo /etc/init.d/$service start +fi diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/images/relational_db.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/images/relational_db.png new file mode 100644 index 0000000000..a7a632effd Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/images/relational_db.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/normative-types-DBMS.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/normative-types-DBMS.yml new file mode 100644 index 0000000000..4a924672fc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/DBMS/normative-types-DBMS.yml @@ -0,0 +1,36 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-DBMS +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-softwareComponent:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.DBMS: + abstract: true + derived_from: tosca.nodes.SoftwareComponent + description: > + The TOSCA DBMS node represents a typical relational, SQL Database Management System software component or service. + tags: + icon: /images/relational_db.png + properties: + dbms_root_password: + type: string + required: false + description: the root password for the DBMS service. + dbms_port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests + capabilities: + host: + type: tosca.capabilities.Container + properties: + valid_node_types: [tosca.nodes.Database] + endpoint: + type: tosca.capabilities.DatabaseEndpoint + diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/images/volume.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/images/volume.png new file mode 100644 index 0000000000..16fa17bd70 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/images/volume.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/normative-types-blockStorage.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/normative-types-blockStorage.yml new file mode 100644 index 0000000000..df942b9f4f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/blockStorage/normative-types-blockStorage.yml @@ -0,0 +1,40 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-blockStorage +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.BlockStorage: + derived_from: tosca.nodes.Root + description: > + The TOSCA BlockStorage node currently represents a server-local block storage device (i.e., not shared) + offering evenly sized blocks of data from which raw storage volumes can be created. + tags: + icon: /images/volume.png + properties: + size: + type: integer + required: false + constraints: + - greater_than: 0 + description: The requested storage size in MegaBytes (MB). + volume_id: + type: string + required: false + description: ID of an existing volume (that is in the accessible scope of the requesting application). + snapshot_id: + type: string + required: false + description: Some identifier that represents an existing snapshot that should be used when creating the block storage (volume). + attributes: + volume_id: + type: string + description: ID provided by the orchestrator for newly created volumes. + requirements: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/images/compute.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/images/compute.png new file mode 100644 index 0000000000..7d5297eed3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/images/compute.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/normative-types-compute.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/normative-types-compute.yml new file mode 100644 index 0000000000..3a972a81e0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/compute/normative-types-compute.yml @@ -0,0 +1,77 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-compute +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + +node_types: + # Infrastructure components + tosca.nodes.Compute: + derived_from: tosca.nodes.Root + description: > + Represents a real or virtual machine or ‘server’. Informations specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing informations are specified the cloud’s provider default + machine will be used. It is strongly recommended to specify the required cpus and memory + at least. + tags: + icon: /images/compute.png + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_than: 0 + description: Number of (actual or virtual) CPUs associated with the Compute node. + mem_size: + type: integer + required: false + constraints: + - greater_than: 0 + description: Size of memory, in Megabytes (MB), available to applications running on the Compute node. + disk_size: + type: integer + required: false + constraints: + - greater_than: 0 + description: Size of the local disk, in Gigabytes (GB), available to applications running on the Compute node. + os_arch: + type: string + constraints: + - valid_values: ["x86_32", "x86_64"] + description: The host Operating System (OS) architecture. + os_type: + type: string + constraints: + - valid_values: ["linux", "aix", "mac os", "windows"] + description: The host Operating System (OS) type. + os_distribution: + type: string + required: false + description: The host Operating System (OS) distribution. + os_version: + type: string + required: false + description: The host Operating System version. + attributes: + ip_address: + type: string + description: > + The primary IP address assigned by the cloud provider that applications may use to access the Compute node. + Note: This is used by the platform provider to convey the primary address used to access the compute node. Future working drafts will address implementations that support floating or multiple IP addresses. + requirements: + network: + type: tosca.capabilities.Connectivity + lower_bound: 0 + upper_bound: unbounded + capabilities: + host: + type: tosca.capabilities.Container + properties: + valid_node_types: [tosca.nodes.SoftwareComponent] + attach: tosca.capabilities.Attachment + scalable: tosca.capabilities.Scalable diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/database/images/relational_db.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/database/images/relational_db.png new file mode 100644 index 0000000000..a7a632effd Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/database/images/relational_db.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/database/normative-types-database.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/database/normative-types-database.yml new file mode 100644 index 0000000000..38bf5d11db --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/database/normative-types-database.yml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-database +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.Database: + derived_from: tosca.nodes.Root + description: > + Base type for the schema and content associated with a DBMS. + The TOSCA Database node represents a logical database that can be managed and hosted by a TOSCA DBMS node. + tags: + icon: /images/relational_db.png + properties: + db_user: + type: string + required: false + description: The special user account used for database administration. + db_password: + type: string + required: false + description: The password associated with the user account provided in the ‘db_user’ property. + db_port: + type: integer + required: false + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: false + description: The logical name of the database. + requirements: + - host: tosca.nodes.DBMS + relationship_type: tosca.relationships.HostedOn + capabilities: + database_endpoint: tosca.capabilities.DatabaseEndpoint diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/network/images/network.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/network/images/network.png new file mode 100644 index 0000000000..c8bf18f31a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/network/images/network.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/network/normative-types-network.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/network/normative-types-network.yml new file mode 100644 index 0000000000..bb860f82be --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/network/normative-types-network.yml @@ -0,0 +1,39 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-network +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.Network: + derived_from: tosca.nodes.Root + description: > + The TOSCA Network node represents a simple, logical network service. + properties: + ip_version: + type: integer + required: false + default: 4 + constraints: + - valid_values: [ 4, 6 ] + cidr: + type: string + required: false + gateway_ip: + type: string + required: false + network_name: + type: string + required: false + network_id: + type: string + required: false + capabilities: + connection: + type: tosca.capabilities.Connectivity + tags: + icon: /images/network.png diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/images/objectstore.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/images/objectstore.png new file mode 100644 index 0000000000..2b2063c4f7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/images/objectstore.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/normative-types-objectStorage.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/normative-types-objectStorage.yml new file mode 100644 index 0000000000..a56fad5363 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/objectStorage/normative-types-objectStorage.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-objectStorage +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.ObjectStorage: + abstract: true + derived_from: tosca.nodes.Root + description: > + The TOSCA ObjectStorage node represents storage that provides the ability to store data as objects (or BLOBs of data) + without consideration for the underlying filesystem or devices. + tags: + icon: /images/objectstore.png + properties: + store_name: + type: string + description: The logical name of the object store (or container). + store_size: + type: integer + required: false + constraints: + - greater_or_equal: 0 + description: The requested initial storage size in Gigabytes. + store_maxsize: + type: integer + required: false + constraints: + - greater_than: 0 + description: The requested maximum storage size in Gigabytes. diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/root/images/root.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/root/images/root.png new file mode 100644 index 0000000000..170f1c3c27 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/root/images/root.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/root/normative-types-root.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/root/normative-types-root.yml new file mode 100644 index 0000000000..7f4c16c260 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/root/normative-types-root.yml @@ -0,0 +1,168 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-root +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. + +node_types: + tosca.nodes.Root: + abstract: true + description: > + This is the default (root) TOSCA Node Type that all other TOSCA nodes should extends. + This allows all TOSCA nodes to have a consistent set of features for modeling and management + (e.g, consistent definitions for requirements, capabilities, and lifecycle interfaces). + tags: + icon: /images/root.png + attributes: + tosca_id: + type: string + tosca_name: + type: string + requirements: + dependency: + type: tosca.capabilities.Root + lower_bound: 0 + upper_bound: unbounded + capabilities: + root: + type: tosca.capabilities.Root + interfaces: + tosca.interfaces.node.lifecycle.Standard: + description: > + This lifecycle interface defines the essential, normative operations that TOSCA nodes may support. + create: + description: Standard lifecycle create operation. + configure: + description: Standard lifecycle configure operation (pre-start). + start: + description: Standard lifecycle start operation. + post_start: + description: Standard lifecycle post-configure operation (post-start) + stop: + description: Standard lifecycle stop operation. + delete: + description: Standard lifecycle delete operation. + + +capability_types: + tosca.capabilities.Root: + description: This is the default (root) TOSCA Capability Type definition that all other TOSCA Capability Types derive from. + tosca.capabilities.Container: + derived_from: tosca.capabilities.Root + properties: + valid_node_types: + type: string + required: true + description: > + A list of one or more names of Node Types that are supported as containees that declare the Container type as a Capability. + tosca.capabilities.Endpoint: + derived_from: tosca.capabilities.Root + properties: + protocol: + type: string + default: tcp + port: + type: integer + required: false + constraints: + - greater_or_equal: 1 + - less_or_equal: 65535 + secure: + type: boolean + default: false + url_path: + type: string + required: false + tosca.capabilities.DatabaseEndpoint: + derived_from: tosca.capabilities.Endpoint + description: This is the default TOSCA type that should be used or extended to define a specialized database endpoint capability. + tosca.capabilities.Attachment: + derived_from: tosca.capabilities.Root + description: This is the default TOSCA type that should be used or extended to define a network endpoint capability. + tosca.capabilities.Scalable: + derived_from: tosca.capabilities.Root + properties: + min_intances: + type: integer + default: 1 + max_intances: + type: integer + default: 1 + default_instances: + type: integer + default: 1 + tosca.capabilities.Connectivity: + derived_from: tosca.capabilities.Root + +relationship_types: + tosca.relationships.Root: + abstract: true + description: This is the default (root) TOSCA Relationship Type definition that all other TOSCA Relationship Types derive from. + valid_targets: [ tosca.capabilities.Root ] + attributes: + tosca_id: + type: string + tosca_name: + type: string + interfaces: + tosca.interfaces.relationship.Configure: + description: > + The lifecycle interfaces define the essential, normative operations that each TOSCA Relationship Types may support. + pre_configure_source: + description: Operation to pre-configure the source endpoint. + pre_configure_target: + description: Operation to pre-configure the target endpoint. + post_configure_source: + description: Operation to post-configure the source endpoint. + post_configure_target: + description: Operation to post-configure the target endpoint. + add_target: + description: Operation to notify the source node of a target node being added via a relationship. + add_source: + description: Operation to notify the target node of a source node which is now available via a relationship. + remove_target: + description: Operation to notify the source node of a target node being removed from a relationship. + remove_source: + description: Operation to notify the target node of a source node being removed from a relationship. + target_changed: + description: Operation to notify source some property or attribute of the target. + source_changed: + description: Operation to notify target some property or attribute of the source. + tosca.relationships.DependsOn: + derived_from: tosca.relationships.Root + description: > + A generic depends on relationship. + tosca.relationships.HostedOn: + derived_from: tosca.relationships.DependsOn + description: Relationship to use to describe that the source is hosted (installed/ deployed) on the target node. + valid_targets: [ tosca.capabilities.Container ] + tosca.relationships.ConnectsTo: + derived_from: tosca.relationships.DependsOn + valid_targets: [ tosca.capabilities.Endpoint ] + tosca.relationships.AttachTo: + derived_from: tosca.relationships.Root + valid_targets: [ tosca.capabilities.Attachment ] + properties: + location: + type: string + constraints: + - min_length: 1 + device: + type: string + required: false + tosca.relationships.Network: + derived_from: tosca.relationships.Root + valid_sources: [ tosca.capabilities.Connectivity ] + valid_targets: [ tosca.capabilities.Connectivity ] + +artifact_types: + tosca.artifacts.Root: + description: The TOSCA Artifact Type all other TOSCA Artifact Types derive from. + tosca.artifacts.File: + derived_from: tosca.artifacts.Root + description: This artifact type is used when an artifact definition needs to have its associated file simply treated as a file and no special handling/handlers are invoked. + tosca.artifacts.ShellScript: + description: A shell script (.sh file) + file_ext: [ sh ] diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/images/software.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/images/software.png new file mode 100644 index 0000000000..dc9c53245d Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/images/software.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/normative-types-softwareComponent.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/normative-types-softwareComponent.yml new file mode 100644 index 0000000000..04e04af640 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/softwareComponent/normative-types-softwareComponent.yml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-softwareComponent +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + +node_types: + + tosca.nodes.SoftwareComponent: + abstract: true + derived_from: tosca.nodes.Root + description: > + The TOSCA SoftwareComponent Node Type represents a generic software component + that can be managed and run by a TOSCA Compute Node Type. + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/software.png + diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/images/network.png b/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/images/network.png new file mode 100644 index 0000000000..c8bf18f31a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/images/network.png differ diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/normative-types-webApplication.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/normative-types-webApplication.yml new file mode 100644 index 0000000000..ded008ebdf --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/webApplication/normative-types-webApplication.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-webApplication +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-webServer:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.WebApplication: + derived_from: tosca.nodes.Root + description: > + The TOSCA WebApplication node represents a software application that can be managed and run by a TOSCA WebServer node. Specific types of web applications such as Java, etc. could be derived from this type. + tags: + icon: /images/network.png + requirements: + - host: tosca.nodes.WebServer + type: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/components/normativeTypes/webServer/normative-types-webServer.yml b/asdc-tests/src/test/resources/CI/components/normativeTypes/webServer/normative-types-webServer.yml new file mode 100644 index 0000000000..1c2e4b2ea5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/components/normativeTypes/webServer/normative-types-webServer.yml @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 + +template_name: tosca-normative-types-webServer +template_author: TOSCA TC +template_version: 1.0.0.wd03-SNAPSHOT + +description: Contains the normative types definition. +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-softwareComponent:1.0.0.wd03-SNAPSHOT" + +node_types: + tosca.nodes.WebServer: + abstract: true + derived_from: tosca.nodes.SoftwareComponent + description: > + The TOSCA WebServer Node Type represents an abstract software component or service that is capable of hosting and providing management operations for one or more WebApplication nodes + capabilities: + app_endpoint: tosca.capabilities.Endpoint + secure_endpoint: tosca.capabilities.Endpoint + host: + type: tosca.capabilities.Container + properties: + valid_node_types: [ tosca.nodes.WebApplication ] diff --git a/asdc-tests/src/test/resources/CI/configuration.yaml b/asdc-tests/src/test/resources/CI/configuration.yaml new file mode 100644 index 0000000000..cb91316a21 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/configuration.yaml @@ -0,0 +1,382 @@ +identificationHeaderFields: + - HTTP_IV_USER + - HTTP_CSP_FIRSTNAME + - HTTP_CSP_LASTNAME + - HTTP_IV_REMOTE_ADDRESS + - HTTP_CSP_WSTYPE + + + +# catalog backend hostname +beFqdn: sdccatalog.att.com + +# catalog backend http port +beHttpPort: 8080 + +# catalog backend http context +beContext: /sdc/rest/config/get + +# catalog backend protocol +beProtocol: http + +# catalog backend ssl port +beSslPort: 8443 + +version: 1.0 +released: 2012-11-30 + +titanCfgFile: /home/vagrant/catalog-be/config/catalog-be/titan.properties +titanInMemoryGraph: false +titanLockTimeout: 30 +titanReconnectIntervalInSeconds: 3 +titanHealthCheckReadTimeout: 1 +esReconnectIntervalInSeconds: 3 +uebHealthCheckReconnectIntervalInSeconds: 15 +uebHealthCheckReadTimeout: 4 + +# Protocols +protocols: + - http + - https + +# Users +users: + tom: passwd + bob: passwd + +neo4j: + host: neo4jhost + port: 7474 + user: neo4j + password: "12345" + + +#Application-specific settings of ES +elasticSearch: + # Mapping of index prefix to time-based frame. For example, if below is configured: + # + # - indexPrefix: auditingevents + # creationPeriod: minute + # + # then ES object of type which is mapped to "auditingevents-*" template, and created on 2015-12-23 13:24:54, will enter "auditingevents-2015-12-23-13-24" index. + # Another object created on 2015-12-23 13:25:54, will enter "auditingevents-2015-12-23-13-25" index. + # If creationPeriod: month, both of the above will enter "auditingevents-2015-12" index. + # + # PLEASE NOTE: the timestamps are created in UTC/GMT timezone! This is needed so that timestamps will be correctly presented in Kibana. + # + # Legal values for creationPeriod - year, month, day, hour, minute, none (meaning no time-based behaviour). + # + # If no creationPeriod is configured for indexPrefix, default behavour is creationPeriod: month. + + indicesTimeFrequency: + - indexPrefix: auditingevents + creationPeriod: month + - indexPrefix: monitoring_events + creationPeriod: month + +artifactTypes: + - CHEF + - PUPPET + - SHELL + - YANG + - YANG_XML + - HEAT + - BPEL + - DG_XML + - MURANO_PKG + - WORKFLOW + - NETWORK_CALL_FLOW + - OTHER + +licenseTypes: + - User + - Installation + - CPU + +#Deployment artifacts placeHolder +resourceTypes: &allResourceTypes + - VFC + - CP + - VL + - VF + +# validForResourceTypes usage +# validForResourceTypes: +# - VF +# - VL +deploymentResourceArtifacts: + heat: + displayName: "Base HEAT Template" + type: HEAT + validForResourceTypes: *allResourceTypes + heatVol: + displayName: "Volume HEAT Template" + type: HEAT_VOL + validForResourceTypes: *allResourceTypes + heatNet: + displayName: "Network HEAT Template" + type: HEAT_NET + validForResourceTypes: *allResourceTypes + +deploymentResourceInstanceArtifacts: + heatEnv: + displayName: "HEAT ENV" + type: HEAT_ENV + description: "Auto-generated HEAT Environment deployment artifact" + fileExtension: "env" + +#Informational artifacts placeHolder +excludeResourceCategory: + - Generic +informationalResourceArtifacts: + features: + displayName: Features + type: OTHER + capacity: + displayName: Capacity + type: OTHER + vendorTestResult: + displayName: Vendor Test Result + type: OTHER + testScripts: + displayName: Test Scripts + type: OTHER + cloudQuestionnaire: + displayName: Cloud Questionnaire (completed) + type: OTHER + HEATTemplateFromVendor: + displayName: HEAT Template from Vendor + type: HEAT + resourceSecurityTemplate: + displayName: Resource Security Template + type: OTHER + +excludeServiceCategory: + +informationalServiceArtifacts: + serviceArtifactPlan: + displayName: Service Artifact Plan + type: OTHER + summaryOfImpactsToECOMPElements: + displayName: Summary of impacts to ECOMP elements,OSSs, BSSs + type: OTHER + controlLoopFunctions: + displayName: Control Loop Functions + type: OTHER + dimensioningInfo: + displayName: Dimensioning Info + type: OTHER + affinityRules: + displayName: Affinity Rules + type: OTHER + operationalPolicies: + displayName: Operational Policies + type: OTHER + serviceSpecificPolicies: + displayName: Service-specific Policies + type: OTHER + engineeringRules: + displayName: Engineering Rules (ERD) + type: OTHER + distributionInstructions: + displayName: Distribution Instructions + type: OTHER + certificationTestResults: + displayName: TD Certification Test Results + type: OTHER + deploymentVotingRecord: + displayName: Deployment Voting Record + type: OTHER + serviceQuestionnaire: + displayName: Service Questionnaire + type: OTHER + serviceSecurityTemplate: + displayName: Service Security Template + type: OTHER + +serviceApiArtifacts: + configuration: + displayName: Configuration + type: OTHER + instantiation: + displayName: Instantiation + type: OTHER + monitoring: + displayName: Monitoring + type: OTHER + reporting: + displayName: Reporting + type: OTHER + logging: + displayName: Logging + type: OTHER + testing: + displayName: Testing + type: OTHER + + +additionalInformationMaxNumberOfKeys: 50 + +systemMonitoring: + enabled: false + isProxy: false + probeIntervalInSeconds: 15 + +defaultHeatArtifactTimeoutMinutes: 60 + +serviceDeploymentArtifacts: + YANG_XML: + acceptedTypes: + - xml + VNF_CATALOG: + acceptedTypes: + - xml + MODEL_INVENTORY_PROFILE: + acceptedTypes: + - xml + MODEL_QUERY_SPEC: + acceptedTypes: + - xml + OTHER: + acceptedTypes: + +resourceDeploymentArtifacts: + HEAT: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + HEAT_VOL: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + HEAT_NET: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + YANG_XML: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VNF_CATALOG: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VF_LICENSE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VENDOR_LICENSE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + MODEL_INVENTORY_PROFILE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + MODEL_QUERY_SPEC: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + APPC_CONFIG: + acceptedTypes: + - xml + - json + validForResourceTypes: + - VF + OTHER: + acceptedTypes: + validForResourceTypes: *allResourceTypes + +resourceInstanceDeploymentArtifacts: + HEAT_ENV: + acceptedTypes: + - env + +resourceInformationalDeployedArtifacts: + + +requirementsToFulfillBeforeCert: + CP: + - tosca.capabilities.network.Bindable + +capabilitiesToConsumeBeforeCert: + +unLoggedUrls: + - /sdc2/rest/healthCheck + +cleanComponentsConfiguration: + cleanIntervalInMinutes: 1440 + componentsToClean: + - Resource + - Service + +artifactsIndex: resources + +cassandraConfig: + cassandraHosts: ['localhost'] + localDataCenter: + reconnectTimeout : 30000 + authenticate: false + username: koko + password: bobo + ssl: false + truststorePath : /path/path + truststorePassword : 123123 + keySpaces: + - { name: sdcaudit, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + - { name: sdcartifact, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + +heatEnvArtifactHeader: + "" +heatEnvArtifactFooter: + "" + +onboarding: + protocol: http + host: localhost + port: 8181 + downloadCsarUri: "/onboardingci/onbrest/onboarding-api/v1.0/vendor-software-products/packages" + +switchoverDetector: + gBeFqdn: + gFeFqdn: + beVip: 1.2.3.4 + feVip: 1.2.3.4 + beResolveAttempts: 3 + feResolveAttempts: 3 + enabled: false + interval: 60 + changePriorityUser: ecompasdc + changePriorityPassword: ecompasdc123 + publishNetworkUrl: "http://localhost/crt/CipDomain.ECOMP-ASDC-DEVST/config/update_network?user=root" + publishNetworkBody: '{"note":"publish network"}' + groups: + beSet: { changePriorityUrl: "http://localhost/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-BE.ecomp.idns.cip?user=root", + changePriorityBody: '{"name":"AIO-BE.ecomp.idns.cip","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-BE.ecomp.idns.cip","no_ad_redirection":false,"v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_be","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_be"],"failover_policy":["FAILALL"]},"comment":"AIO BE G-fqdn","intended_app_proto":"DNS"}'} + feSet: { changePriorityUrl: "http://cora.web/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-FE.ecomp.idns.cip?user=root", + changePriorityBody: '{"comment":"AIO G-fqdn","name":"AIO-FE.ecomp.idns.cip","v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_fe","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_fe"],"failover_policy":["FAILALL"]},"no_ad_redirection":false,"intended_app_proto":"DNS","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-FE.ecomp.idns.cip.att.com"}'} + + +applicationL1Cache: + datatypes: + enabled: true + firstRunDelay: 10 + pollIntervalInSec: 60 + +applicationL2Cache: + enabled: false + catalogL1Cache: + enabled: true + resourcesSizeInCache: 300 + servicesSizeInCache: 200 + productsSizeInCache: 100 + queue: + syncIntervalInSecondes: 60 + waitOnShutDownInMinutes: 30 + numberOfCacheWorkers: 4 + +toscaValidators: + stringMaxLength: 1024 \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/csars/FCGI_with_inputs.csar b/asdc-tests/src/test/resources/CI/csars/FCGI_with_inputs.csar new file mode 100644 index 0000000000..a702c78d25 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/FCGI_with_inputs.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/LDSA1_with_inputs.csar b/asdc-tests/src/test/resources/CI/csars/LDSA1_with_inputs.csar new file mode 100644 index 0000000000..a551ce3263 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/LDSA1_with_inputs.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar new file mode 100644 index 0000000000..a6678a47d1 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_a.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_a.csar new file mode 100644 index 0000000000..ca0ab91e39 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_a.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_b.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_b.csar new file mode 100644 index 0000000000..890ae20cb3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_b.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming.csar new file mode 100644 index 0000000000..04464af741 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_a.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_a.csar new file mode 100644 index 0000000000..68819afc4b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_a.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_add_update.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_add_update.csar new file mode 100644 index 0000000000..528599e0c5 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_add_update.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_delete_update.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_delete_update.csar new file mode 100644 index 0000000000..6a708d335f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_group_naming_delete_update.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_update.csar b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_update.csar new file mode 100644 index 0000000000..035497a52e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/VF_RI2_G4_withArtifacts_update.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/jsonPropertyTypeTest.csar b/asdc-tests/src/test/resources/CI/csars/jsonPropertyTypeTest.csar new file mode 100644 index 0000000000..2aa2ef4582 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/jsonPropertyTypeTest.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/mycompute.yml b/asdc-tests/src/test/resources/CI/csars/mycompute.yml new file mode 100644 index 0000000000..c8a0c03384 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/csars/mycompute.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.mycompute: + derived_from: tosca.nodes.Compute + capabilities: + scalable: + type: tosca.capabilities.Scalable + properties: + propertyForTest: + type: string + description: test + required: true + default: success + # min_instances property should override property from tosca.capabilities.Scalable + min_instances: + type: integer + default: 3 + diff --git a/asdc-tests/src/test/resources/CI/csars/mycompute2.yml b/asdc-tests/src/test/resources/CI/csars/mycompute2.yml new file mode 100644 index 0000000000..9d479a1a55 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/csars/mycompute2.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.mycompute2: + derived_from: tosca.nodes.Compute + capabilities: + scalable: + type: tosca.capabilities.Scalable + properties: + propertyForTest: + type: string + description: test + required: true + default: success + # min_instances property should override property from tosca.capabilities.Scalable + min_instances: + type: integer + default: 3 + diff --git a/asdc-tests/src/test/resources/CI/csars/mycompute_failed.yml b/asdc-tests/src/test/resources/CI/csars/mycompute_failed.yml new file mode 100644 index 0000000000..a4d8e448f1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/csars/mycompute_failed.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.mycompute: + derived_from: tosca.nodes.Compute + capabilities: + scalable: + type: tosca.capabilities.Scalable + properties: + propertyForTest: + type: string + description: test + required: true + default: success + # min_instances property should override property from tosca.capabilities.Scalable + min_instances: + type: string + default: 3 + diff --git a/asdc-tests/src/test/resources/CI/csars/orig2G.csar b/asdc-tests/src/test/resources/CI/csars/orig2G.csar new file mode 100644 index 0000000000..609cd0a8b4 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2G.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2GV001.csar b/asdc-tests/src/test/resources/CI/csars/orig2GV001.csar new file mode 100644 index 0000000000..a7e04cbf10 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2GV001.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2GV001_a.csar b/asdc-tests/src/test/resources/CI/csars/orig2GV001_a.csar new file mode 100644 index 0000000000..07371acaf2 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2GV001_a.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2GV006-remove-all-nested-artifacts.csar b/asdc-tests/src/test/resources/CI/csars/orig2GV006-remove-all-nested-artifacts.csar new file mode 100644 index 0000000000..ebd95548f8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2GV006-remove-all-nested-artifacts.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2GV008-change-nested-oam-fileContent.csar b/asdc-tests/src/test/resources/CI/csars/orig2GV008-change-nested-oam-fileContent.csar new file mode 100644 index 0000000000..dc75ae1549 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2GV008-change-nested-oam-fileContent.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2G_a.csar b/asdc-tests/src/test/resources/CI/csars/orig2G_a.csar new file mode 100644 index 0000000000..2f6ad121a6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2G_a.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/orig2G_updated.csar b/asdc-tests/src/test/resources/CI/csars/orig2G_updated.csar new file mode 100644 index 0000000000..1968eabf4b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/orig2G_updated.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf.csar new file mode 100644 index 0000000000..01bf159071 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf_a.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf_a.csar new file mode 100644 index 0000000000..01bf159071 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf_a.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf_b.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf_b.csar new file mode 100644 index 0000000000..3c0b683321 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf_b.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf_c.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf_c.csar new file mode 100644 index 0000000000..57e3551682 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf_c.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf_d.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf_d.csar new file mode 100644 index 0000000000..d66dfb60d9 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf_d.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/valid_vf_f.csar b/asdc-tests/src/test/resources/CI/csars/valid_vf_f.csar new file mode 100644 index 0000000000..a9a4bc75ab Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/valid_vf_f.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vf_relate_by_cap_name.csar b/asdc-tests/src/test/resources/CI/csars/vf_relate_by_cap_name.csar new file mode 100644 index 0000000000..f2a7efb69e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vf_relate_by_cap_name.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop.csar b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop.csar new file mode 100644 index 0000000000..df98e259d6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1.csar b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1.csar new file mode 100644 index 0000000000..d4561a0640 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1_failed.csar b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1_failed.csar new file mode 100644 index 0000000000..f145ebd5d2 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop1_failed.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop_failed.csar b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop_failed.csar new file mode 100644 index 0000000000..6e23829e8a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vf_with_cap_prop_override_cap_type_prop_failed.csar differ diff --git a/asdc-tests/src/test/resources/CI/csars/vmmc_relate_by_cap_name.csar b/asdc-tests/src/test/resources/CI/csars/vmmc_relate_by_cap_name.csar new file mode 100644 index 0000000000..ada1451cea Binary files /dev/null and b/asdc-tests/src/test/resources/CI/csars/vmmc_relate_by_cap_name.csar differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.json new file mode 100644 index 0000000000..1bf593852b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "LAN_Connector.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.Connector.LAN_Connector", + "description": "Represents a LAN_Connector Node Type.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "org.openecomp.asdc.nodes.Connector.LAN_Connector" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.yml new file mode 100644 index 0000000000..4fff368cdc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.yml @@ -0,0 +1,23 @@ +org.openecomp.asdc.nodes.Connector.LAN_Connector: + #The LAN_Connector node connects Router and VNF_Container + derived_from: org.openecomp.asdc.nodes.Connector + properties: + network_id: + #or called: vlan_id + type: string + required: true + network_type: + #The technology types used by LAN connector + type: string + attributes: + network_ip_address: + #ip address is generated only after the node is instantiated at run-time + type: string + requirements: + - connectToRouter : + capability: tosca.capabilities.Root + node: org.openecomp.asdc.nodes.Router + - connectToVNF : + capability: tosca.capabilities.Root + node: org.openecomp.asdc.nodes.VNF_Container + #These two explicit requirements specify the LAN_Connector has two "connectTo" to connect to the node of Router type and VNF_Container type respectively diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.zip new file mode 100644 index 0000000000..1b02f06386 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/LAN_Connector/LAN_Connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.json new file mode 100644 index 0000000000..35b426c831 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "VNF.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.VNF", + "description": "Represents a VNF Node Type.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "org.openecomp.asdc.nodes.VNF" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.yml new file mode 100644 index 0000000000..22be623303 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.yml @@ -0,0 +1,16 @@ +org.openecomp.asdc.nodes.VNF: + #The VNF node is required to be hosted by a VNF_Container + derived_from: org.openecomp.asdc.nodes.Root + properties: + service_name: + type: string + attributes: + #attribute means the value is fulfilled at run-time. + service_id: + #In this case, we consider the VNF node only has the service_id value when the node is instantiated + type: string + requirements: + #the "host" requirement can establish the relationship with a VNF_Container node + - host : + capability: org.openecomp.asdc.capabilities.Container + node: org.openecomp.asdc.nodes.VNF_Container \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.zip new file mode 100644 index 0000000000..c01081f0ab Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF/VNF.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.json new file mode 100644 index 0000000000..c1347780e3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.json @@ -0,0 +1,11 @@ +{ + "payloadName": "VNF_Container.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.VNF_Container", + "description": "Represents a VNF_Container Node Type.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "org.openecomp.asdc.nodes.VNF_Container" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.yml new file mode 100644 index 0000000000..b8dd8355fa --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.yml @@ -0,0 +1,10 @@ +org.openecomp.asdc.nodes.VNF_Container: + #The VNF_Container node provides the capability to host VNFs. + derived_from: org.openecomp.asdc.nodes.Root + capabilities: + host: + #The "host" capability allows other TOSCA nodes (VNF) that requires such a capability to connect to this node + type: org.openecomp.asdc.capabilities.Container + connectTo: + #The "connectTo" capability allows other TOSCA nodes (connectors) that requires such a capability to connect to this node. + type: org.openecomp.asdc.capabilities.Endpoint \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.zip new file mode 100644 index 0000000000..a8e006e728 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/VNF_Container/VNF_Container.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.json new file mode 100644 index 0000000000..4cb0880297 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "WAN_Connector.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.Connector.WAN_Connector", + "description": "Represents a WAN_Connector Node Type.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "org.openecomp.asdc.nodes.Connector.WAN_Connector" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.yml new file mode 100644 index 0000000000..741d585488 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.yml @@ -0,0 +1,25 @@ +org.openecomp.asdc.nodes.Connector.WAN_Connector: + #The WAN_Connector node only connects to Router + derived_from: org.openecomp.asdc.nodes.Connector + properties: + customer_id: + type: string + required: true + vpn_id: + type: string + required: true + vpn_name: + type: string + required: true + network_type: + #The technology types used by WAN connector + type: string + attributes: + network_ip_address: + #ip address is generated only after the node is instantiated at run-time + type: string + requirements: + - connectTo : + capability: org.openecomp.asdc.capabilities.Endpoint + node: org.openecomp.asdc.nodes.Router + #This explicit requirement specifies WAN_Connector has only one "connectTo" to connect to the node of Router type \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.zip new file mode 100644 index 0000000000..e193820659 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/WAN_Connector/WAN_Connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.yml new file mode 100644 index 0000000000..32989237d2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.yml @@ -0,0 +1,4 @@ +org.openecomp.asdc.capabilities.Endpoint: + derived_from: tosca.capabilities.Endpoint +org.openecomp.asdc.capabilities.Container: + derived_from: tosca.capabilities.Container \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.zip new file mode 100644 index 0000000000..869be32b53 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/capabilityTypesWanLan.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.json new file mode 100644 index 0000000000..99be86c707 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "connector.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.Connector", + "description": "Represents a connector Node Type.", + "resourceIconPath": "defaulticon", + "category": "Abstract", + "tags": [ + "org.openecomp.asdc.nodes.Connector" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.yml new file mode 100644 index 0000000000..d9c9361daa --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.yml @@ -0,0 +1,10 @@ +org.openecomp.asdc.nodes.Connector: + #Connector is the parent node of both WAN and LAN connectors. + derived_from: org.openecomp.asdc.nodes.Root + requirements: + - connectTo: + capability: org.openecomp.asdc.capabilities.Endpoint + #the requirement can establish the relationship with a node providing such capability + relationship: org.openecomp.asdc.relationships.ConnectsTo + #occurrences means how many times this requirement can appear in one node. + occurrences: [1, UNBOUNDED] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.zip new file mode 100644 index 0000000000..3c37303a3a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/connector/connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/deleteResourcesLanWanDemo.sh b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/deleteResourcesLanWanDemo.sh new file mode 100644 index 0000000000..9f992d56dd --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/deleteResourcesLanWanDemo.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function deleteResource() { + + ELEMENT_NAME=$1 + echo "###################### Removing Element ${ELEMENT_NAME} Start ######################" + curl -X "DELETE" -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/resources/res_${ELEMENT_NAME}".1.0" + echo "" + echo "###################### Removing Element ${ELEMENT_NAME} End ########################" + echo "" + echo "" + echo "" +} +if [ $# -lt 2 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + + +deleteResource "org.openecomp.asdc.nodes.Connector.LAN_Connector" +deleteResource "org.openecomp.asdc.nodes.Connector.WAN_Connector" +deleteResource "org.openecomp.asdc.nodes.Connector" +deleteResource "org.openecomp.asdc.nodes.VNF" +deleteResource "org.openecomp.asdc.nodes.VNF_Container" +deleteResource "org.openecomp.asdc.nodes.Router" +deleteResource "org.openecomp.asdc.nodes.Root" + + diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/importResourcesLanWanDemo.sh b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/importResourcesLanWanDemo.sh new file mode 100644 index 0000000000..90a06d53b5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/importResourcesLanWanDemo.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function addResource() { + + ELEMENT_NAME=$1 + echo -e "###################### Adding Element ${ELEMENT_NAME} Start ######################" + CURRENT_ZIP_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.zip + CURRENT_JSON_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.json + JSON_CONTENT=`paste -s ${CURRENT_JSON_FILE}` + curl -v -F resourceMetadata="${JSON_CONTENT}" -F resourceZip=@${CURRENT_ZIP_FILE} -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/upload/multipart + echo "" + echo -e "###################### Adding Element ${ELEMENT_NAME} End ########################" + +} +if [ $# -lt 2 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + +#Add The CapabilityTypes +http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F capabilityTypeZip=@capabilityTypesWanLan.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/capability) +if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The CapabilityTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 +else + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 +fi + +addResource "root" +addResource "router" +addResource "VNF_Container" +addResource "VNF" +addResource "connector" +addResource "WAN_Connector" +addResource "LAN_Connector" + + + diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.json new file mode 100644 index 0000000000..54cbb798a2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.json @@ -0,0 +1,11 @@ +{ + "payloadName": "root.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.Root", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "category": "Abstract", + "tags": [ + "org.openecomp.asdc.nodes.Root" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.yml new file mode 100644 index 0000000000..34e7d0fb62 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.yml @@ -0,0 +1,3 @@ +org.openecomp.asdc.nodes.Root: + #Define the root node for ASDC modeling + derived_from: tosca.nodes.Root \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.zip new file mode 100644 index 0000000000..ff604d55a7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/root/root.zip differ diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.json b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.json new file mode 100644 index 0000000000..19e4669a38 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.json @@ -0,0 +1,11 @@ +{ + "payloadName": "router.yml", + "contactId": "jh0003", + "resourceName": "org.openecomp.asdc.nodes.Router", + "description": "Represents a Router Node Type.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "org.openecomp.asdc.nodes.Router" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.yml b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.yml new file mode 100644 index 0000000000..0598663c64 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.yml @@ -0,0 +1,13 @@ +org.openecomp.asdc.nodes.Router: + #The Router node has a property "routing_table" which is a list. The entry of the routing_table is the customized data type "RoutingTableEntry" + derived_from: org.openecomp.asdc.nodes.Root + properties: + routing_table: + type: list + entry_schema: + #"entry_schema" is the TOSCA spec to describe the type of the list item + type: RoutingTableEntry + capabilities: + connectTo: + #The "connectTo" capability allows other TOSCA nodes (connectors) that requires such a capability to connect to this node. + type: org.openecomp.asdc.capabilities.Endpoint \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.zip b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.zip new file mode 100644 index 0000000000..57ff8e0e2a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/demoResourcesWanLan/router/router.zip differ diff --git a/asdc-tests/src/test/resources/CI/error-configuration.yaml b/asdc-tests/src/test/resources/CI/error-configuration.yaml new file mode 100644 index 0000000000..6d4e2373fa --- /dev/null +++ b/asdc-tests/src/test/resources/CI/error-configuration.yaml @@ -0,0 +1,1576 @@ +# Errors +errors: + OK: { + code: 200, + message: "OK" + } + CREATED: { + code: 201, + message: "OK" + } + NO_CONTENT: { + code: 204, + message: "No Content" + } +#--------POL4050----------------------------- + NOT_ALLOWED: { + code: 405, + message: "Error: Method not allowed.", + messageId: "POL4050" + } +#--------POL5000----------------------------- + GENERAL_ERROR: { + code: 500, + message: "Error: Internal Server Error. Please try again later.", + messageId: "POL5000" + } +#---------POL5001------------------------------ + MISSING_X_ECOMP_INSTANCE_ID: { + code: 400 , + message: "Error: Missing 'X-ECOMP-InstanceID' HTTP header.", + messageId: "POL5001" + } +#---------POL5002------------------------------ + AUTH_REQUIRED: { + code: 401 , + message: "Error: Authentication is required to use the API.", + messageId: "POL5002" + } +#---------POL5003------------------------------ + AUTH_FAILED: { + code: 403 , + message: "Error: Not authorized to use the API.", + messageId: "POL5003" + } +#---------SVC4000----------------------------- + INVALID_CONTENT: { + code: 400, + message: "Error: Invalid content.", + messageId: "SVC4000" + } +#---------SVC4002----------------------------- + MISSING_INFORMATION: { + code: 403, + message: "Error: Missing information.", + messageId: "SVC4002" + } +#---------SVC4003------------------------------ +# %1 - Users's USER_ID + USER_NOT_FOUND: { + code: 404, + message: "Error: User '%1' was not found.", + messageId: "SVC4003" + } +#---------SVC4004----------------------------- +# %1 - Users's email address + INVALID_EMAIL_ADDRESS: { + code: 400, + message: "Error: Invalid email address '%1'.", + messageId: "SVC4004" + } +#---------SVC4005------------------------------ +# %1 - role + INVALID_ROLE: { + code: 400, + message: "Error: Invalid role '%1'.", + messageId: "SVC4005" + } +#---------SVC4006------------------------------ +# %1 - Users's USER_ID + USER_ALREADY_EXIST: { + code: 409, + message: "Error: User with '%1' ID already exists.", + messageId: "SVC4006" + } +#---------SVC4007------------------------------ + DELETE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator can only be deleted by another administrator.", + messageId: "SVC4007" + } +#---------SVC4008----------------------------- +# %1 - Users's userId + INVALID_USER_ID: { + code: 400, + message: "Error: Invalid userId '%1'.", + messageId: "SVC4008" + } +#---------SVC4049------------------------------ +# %1 - service/resource + COMPONENT_MISSING_CONTACT: { + code: 400, + message: "Error: Invalid Content. Missing %1 contact id.", + messageId: "SVC4049" + } +#---------SVC4050----------------------------- +# %1 - Service/Resource/Additional parameter +# %2 - service/resource/label name + COMPONENT_NAME_ALREADY_EXIST: { + code: 409, + message: "Error: %1 with name '%2' already exists.", + messageId: "SVC4050" + } +#---------SVC4051------------------------------ +# %1 - resource/service + COMPONENT_MISSING_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Missing %1 category.", + messageId: "SVC4051" + } + +#---------SVC4052------------------------------ + COMPONENT_MISSING_TAGS: { + code: 400, + message: "Error: Invalid Content. At least one tag has to be specified.", + messageId: "SVC4052" + } + +#---------SVC4053------------------------------ +# %1 - service/resource + COMPONENT_MISSING_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. Missing %1 description.", + messageId: "SVC4053" + } +#---------SVC4054------------------------------ +# %1 - resource/service + COMPONENT_INVALID_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Invalid %1 category.", + messageId: "SVC4054" + } +#---------SVC4055------------------------------ + MISSING_VENDOR_NAME: { + code: 400, + message: "Error: Invalid Content. Missing vendor name.", + messageId: "SVC4055" + } +#---------SVC4056------------------------------ + MISSING_VENDOR_RELEASE: { + code: 400, + message: "Error: Invalid Content. Missing vendor release.", + messageId: "SVC4056" + } + +#---------SVC4057------------------------------ + MISSING_DERIVED_FROM_TEMPLATE: { + code: 400, + message: "Error: Invalid Content. Missing derived from template specification.", + messageId: "SVC4057" + } + +#---------SVC4058------------------------------ +# %1 - service/resource + COMPONENT_MISSING_ICON: { + code: 400, + message: "Error: Invalid Content. Missing %1 icon.", + messageId: "SVC4058" + } +#---------SVC4059------------------------------ +# %1 - service/resource + COMPONENT_INVALID_ICON: { + code: 400, + message: "Error: Invalid Content. Invalid %1 icon.", + messageId: "SVC4059" + } +#---------SVC4060------------------------------ + PARENT_RESOURCE_NOT_FOUND: { + code: 400, + message: "Error: Invalid Content. Derived from resource template was not found.", + messageId: "SVC4060" + } +#---------SVC4061------------------------------ + MULTIPLE_PARENT_RESOURCE_FOUND: { + code: 400, + message: "Error: Invalid Content. Multiple derived from resource template is not allowed.", + messageId: "SVC4061" + } + +#---------SVC4062------------------------------ +# %1 - service/resource + MISSING_COMPONENT_NAME: { + code: 400, + message: "Error: Invalid Content. Missing %1 name.", + messageId: "SVC4062" + } +#---------SVC4063------------------------------ + #%1  -  resource/service name + RESOURCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource was not found.", + messageId: "SVC4063" + } + +#---------SVC4064------------------------------ +# %1 - Service/Resource + COMPONENT_INVALID_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. %1 description contains non-english characters.", + messageId: "SVC4064" + } +#---------SVC4065------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name length + COMPONENT_DESCRIPTION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 description exceeds limit of %2 characters.", + messageId: "SVC4065" + } +#---------SVC4066------------------------------ +# %1 - max length + COMPONENT_TAGS_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Tags overall length exceeds limit of %1 characters.", + messageId: "SVC4066" + } +#---------SVC4067------------------------------ +# %1 - max length + VENDOR_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor name exceeds limit of %1 characters.", + messageId: "SVC4067" + } +#---------SVC4068------------------------------ +# %1 - max length + VENDOR_RELEASE_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor release exceeds limit of %1 characters.", + messageId: "SVC4068" + } + +#---------SVC4069------------------------------ +# %1 - Service/Resource/Product + COMPONENT_INVALID_CONTACT_ID: { + code: 400, + message: "Error: Invalid Content. %1 contact id should be in format 'mnnnnnn' or 'aannna' or 'aannnn', where m=m ,a=a-zA-Z and n=0-9", + messageId: "SVC4069" + } +#---------SVC4070------------------------------ +# %1 - Service/Resource + INVALID_COMPONENT_NAME: { + code: 400, + message: 'Error: Invalid Content. %1 name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4070" + } + +#---------SVC4071------------------------------ + INVALID_VENDOR_NAME: { + code: 400, + message: 'Error: Invalid Content. Vendor name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4071" + } +#---------SVC4072------------------------------ + INVALID_VENDOR_RELEASE: { + code: 400, + message: 'Error: Invalid Content. Vendor release is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4072" + } +#---------SVC4073------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name + COMPONENT_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 name exceeds limit of %2 characters.", + messageId: "SVC4073" + } +#---------SVC4080------------------------------ +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CHECKOUT_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for modification by %3 %4(%5).", + messageId: "SVC4080" + } +#---------SVC4081----------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CERT_IN_PROGRESS_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for certification by %3 %4(%5).", + messageId: "SVC4081" + } + +#-----------SVC4082--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_SENT_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is sent for certification by %3 %4(%5).", + messageId: "SVC4082" + } +#-----------SVC4083--------------------------- + COMPONENT_VERSION_ALREADY_EXIST: { + code: 409, + message: "Error: Version of this %1 was already promoted.", + messageId: "SVC4083" + } +#-----------SVC4084--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CHECKED_IN: { + code: 409, + message: "Error: The current version of '%1' %2 was already checked-in by %3 %4(%5).", + messageId: "SVC4084" + } +#-----------SVC4085--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_CHECKOUT_BY_ANOTHER_USER: { + code: 403, + message: "Error: %1 %2 has already been checked out by %3 %4(%5).", + messageId: "SVC4085" + } +#-----------SVC4086--------------------------- +# %1  - resource/service name +# %2  - resource/service + COMPONENT_IN_USE: { + code: 403, + message: "Error: Requested '%1' %2 is in use by another user.", + messageId: "SVC4086" + } +#-----------SVC4087--------------------------- +# %1 - component name +# %2 - resource/service/product + COMPONENT_HAS_NEWER_VERSION: { + code: 409, + message: "Error: Checking out of the requested version of the '%1' %2 is not allowed as a newer version exists.", + messageId: "SVC4087" + } +#-----------SVC4088--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CERTIFIED: { + code: 403, + message: "Error: Requested %1 %2 has already been certified by %3 %4(%5).", + messageId: "SVC4088" + } +#-----------SVC4089--------------------------- +# %1 - resource/service name +# %2 - resource/service + COMPONENT_NOT_READY_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification.", + messageId: "SVC4089" + } +#-----------SVC4100--------------------------- +#%1 - property name + PROPERTY_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' property was not found.", + messageId: "SVC4100" + } +#-----------SVC4101--------------------------- +#%1 - property name + PROPERTY_ALREADY_EXIST: { + code: 409, + message: "Error: Property with '%1' name already exists.", + messageId: "SVC4101" + } + +#-----------SVC4102--------------------------- +# %1 - capability type name + CAPABILITY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Capability Type with name '%1' already exists.", + messageId: "SVC4102" + } +#-----------SVC4114--------------------------- + AUTH_FAILED_INVALIDE_HEADER: { + code: 400, + message: "Error: Invalid Authorization header.", + messageId: "SVC4114" + } +#-----------SVC4115--------------------------- +# %1 - capability type name + MISSING_CAPABILITY_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Capability Type '%1'.", + messageId: "SVC4115" + } + RESOURCE_INSTANCE_BAD_REQUEST: { + code: 400, + message: "Error: Invalid Content.", + messageId: "SVC4116" + } +#-----------SVC4117--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_MATCH_NOT_FOUND: { + code: 404, + message: "Error: Match not found between resource instance '%1' and resource instance '%2' for requirement '%3'.", + messageId: "SVC4117" + } +#-----------SVC4118--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_ALREADY_EXIST: { + code: 409, + message: "Error: Resource instances '%1' and '%2' are already associated with requirement '%3'.", + messageId: "SVC4118" + } +#-----------SVC4119--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_RELATION_NOT_FOUND: { + code: 404, + message: "Error: No relation found between resource instances '%1' and '%2' for requirement '%3'.", + messageId: "SVC4119" + } +#-----------SVC4120--------------------------- +# %1 - User's USER_ID + USER_INACTIVE: { + code: 404, + message: "Error: User %1 was not found.", + messageId: "SVC4120" + } +#-----------SVC4121--------------------------- +# %1 - User's USER_ID + USER_HAS_ACTIVE_ELEMENTS: { + code: 403, + message: "Error: User with %1 ID can not be deleted since it has active elements(resources/services/artifacts).", + messageId: "SVC4121" + } +#-----------SVC4122--------------------------- +# %1 - artifact type + ARTIFACT_TYPE_NOT_SUPPORTED: { + code: 400, + message: "Error: Invalid artifact type '%1'.", + messageId: "SVC4122" + } +#-----------SVC4123--------------------------- + ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Artifact logical name cannot be changed.", + messageId: "SVC4123" + } +#-----------SVC4124--------------------------- + MISSING_ARTIFACT_TYPE: { + code: 400, + message: "Error: Missing artifact type.", + messageId: "SVC4124" + } +#-----------SVC4125--------------------------- +# %1-artifact name + ARTIFACT_EXIST: { + code: 400, + message: "Error: Artifact '%1' already exists.", + messageId: "SVC4125" + } +#---------SVC4126------------------------------ +# %1 - resource/service/product/... +# %2 - field (tag, vendor name...) + INVALID_FIELD_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 format.", + messageId: "SVC4126" + } +#-----------SVC4127--------------------------- + ARTIFACT_INVALID_MD5: { + code: 400, + message: "Error: Invalid artifact checksum.", + messageId: "SVC4127" + } +#-----------SVC4128--------------------------- + MISSING_ARTIFACT_NAME: { + code: 400, + message: "Error: Invalid content. Missing artifact name.", + messageId: "SVC4128" + } +#-----------SVC4129--------------------------- + MISSING_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. Missing PROJECT_CODE number.", + messageId: "SVC4129" + } +#-----------SVC4130--------------------------- + INVALID_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. PROJECT_CODE number must be numeric from 5 up to 10 digits.", + messageId: "SVC4130" + } +#-----------SVC4131--------------------------- +# %1-resource/service +# %2-srtifact/artifacts +# %3-semicolomn separated list of artifact + COMPONENT_MISSING_MANDATORY_ARTIFACTS: { + code: 403, + message: "Error: Missing mandatory informational %1 %2: [%3].", + messageId: "SVC4131" + } +#-----------SVC4132--------------------------- +# %1 - lifecycle type name + LIFECYCLE_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Lifecycle Type with name '%1' already exists.", + messageId: "SVC4132" + } +#-----------SVC4133--------------------------- +# %1 - service version +# %2 - service name + SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION: { + code: 403, + message: "Error: Version %1 of '%2' service is not available for distribution.", + messageId: "SVC4133" + } +#-----------SVC4134--------------------------- + MISSING_LIFECYCLE_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing interface life-cycle type.", + messageId: "SVC4134" + } +#---------SVC4135------------------------------ + SERVICE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service category cannot be changed once the service is certified.", + messageId: "SVC4135" + } +#---------SVC4136------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE: { + code: 500, + message: "Error: Requested distribution environment '%1' is not available.", + messageId: "SVC4136" + } +#---------SVC4137------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_FOUND: { + code: 400, + message: "Error: Requested distribution environment '%1' was not found.", + messageId: "SVC4137" + } +#---------SVC4138------------------------------ + DISTRIBUTION_ENVIRONMENT_INVALID: { + code: 400, + message: "Error: Invalid distribution environment.", + messageId: "SVC4138" + } +#---------SVC4139------------------------------ +# %1 - service name + DISTRIBUTION_ARTIFACT_NOT_FOUND: { + code: 409, + message: "Error: Service '%1' cannot be distributed due to missing deployment artifacts.", + messageId: "SVC4139" + } +#---------SVC4200------------------------------ +# %1 - Service/Resource +# %2 - max icon name length + COMPONENT_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 icon name exceeds limit of %2 characters.", + messageId: "SVC4200" + } +#---------SVC4300------------------------------ + RESTRICTED_ACCESS: { + code: 403, + message: "Error: Restricted access.", + messageId: "SVC4300" + } +#---------SVC4301------------------------------ + RESTRICTED_OPERATION: { + code: 409, + message: "Error: Restricted operation.", + messageId: "SVC4301" + } +#---------SVC4500------------------------------ + MISSING_BODY: { + code: 400 , + message: "Error: Missing request body.", + messageId: "SVC4500" + } +#---------SVC4501------------------------------ + MISSING_PUBLIC_KEY: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'apiPublicKey'." , + messageId: "SVC4501" + } +#---------SVC4502------------------------------ + DISTRIBUTION_ENV_DOES_NOT_EXIST: { + code: 400 , + message: "Error: Invalid Body : Missing mandatory parameter 'distrEnvName'." , + messageId: "SVC4502" + } +#-----------SVC4503--------------------------- +# %1 - service name + SERVICE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' service was not found.", + messageId: "SVC4503" + } + +#---------SVC4504------------------------------ +# %1 - Service/Resource +# %2 - service/resource version + COMPONENT_VERSION_NOT_FOUND: { + code: 404, + message: "Error: %1 version %2 was not found.", + messageId: "SVC4504" + } +#-----------SVC4505--------------------------- + #%1-artifact name + + ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Artifact '%1' was not found.", + messageId: "SVC4505" + } +#---------SVC4506------------------------------ + MISSING_ENV_NAME: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'distrEnvName'.", + messageId: "SVC4506" + } +#---------SVC4507------------------------------ + COMPONENT_INVALID_TAGS_NO_COMP_NAME: { + code: 400, + message: "Error: Invalid Content. One of the tags should be the component name.", + messageId: "SVC4507" + } + +#---------SVC4508------------------------------ + SERVICE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service name cannot be changed once the service is certified.", + messageId: "SVC4508" + } + +#---------SVC4509------------------------------ + SERVICE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the service is certified.", + messageId: "SVC4509" + } +#---------SVC4510------------------------------ +# %1 - icon name max length + SERVICE_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Icon name exceeds limit of %1 characters.", + messageId: "SVC4510" + } +#---------SVC4511------------------------------ + DISTRIBUTION_REQUESTED_NOT_FOUND: { + code: 404, + message: "Error: Requested distribution was not found.", + messageId: "SVC4511" + } +#---------SVC4512------------------------------ +# %1 - Distribution ID + DISTRIBUTION_REQUESTED_FAILED: { + code: 403, + message: "Error: Requested distribution '%1' failed.", + messageId: "SVC4512" + } +#---------SVC4513------------------------------ + RESOURCE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource category cannot be changed once the resource is certified.", + messageId: "SVC4513" + } +#---------SVC4514------------------------------ + RESOURCE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource name cannot be changed once the resource is certified.", + messageId: "SVC4514" + } +#---------SVC4515------------------------------ + RESOURCE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the resource is certified.", + messageId: "SVC4515" + } +#---------SVC4516------------------------------ + RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Vendor name cannot be changed once the resource is certified.", + messageId: "SVC4516" + } +#---------SVC4517------------------------------ + RESOURCE_DERIVED_FROM_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Derived from resource template cannot be changed once the resource is certified.", + messageId: "SVC4517" + } +#---------SVC4518------------------------------ +# %1 - max length + COMPONENT_SINGLE_TAG_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Single tag exceeds limit of %1 characters.", + messageId: "SVC4518" + } +#---------SVC4519------------------------------ + INVALID_DEFAULT_VALUE: { + code: 400, + message: "Error: mismatch in data-type occurred for property %1. data type is %2 and default value found is %3.", + messageId: "SVC4519" + } +#---------SVC4520------------------------------ +# %1 - service or resource + ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED: { + code: 409, + message: "Error: Maximal number of additional %1 parameters was reached.", + messageId: "SVC4520" + } +#---------SVC4521------------------------------ + ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED: { + code: 400, + message: "Error: Invalid Content. The Additional information label and value cannot be empty.", + messageId: "SVC4521" + } +#---------SVC4522------------------------------ +# %1 - label/value +# %2 - Maximal length of %1 + ADDITIONAL_INFORMATION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Additional information %1 exceeds limit of %2 characters.", + messageId: "SVC4522" + } +#---------SVC4523------------------------------ + ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information label is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4523" + } +#---------SVC4524------------------------------ + ADDITIONAL_INFORMATION_NOT_FOUND: { + code: 409, + message: "Error: Requested additional information was not found.", + messageId: "SVC4524" + } +#---------SVC4525------------------------------ + ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information contains non-english characters.', + messageId: "SVC4525" + } +#---------SVC4526------------------------------ + RESOURCE_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource instance was not found.", + messageId: "SVC4526" + } +#---------SVC4527------------------------------ + ASDC_VERSION_NOT_FOUND: { + code: 500, + message: 'Error: ASDC version cannot be displayed.', + messageId: "SVC4527" + } +#---------SVC4528------------------------------ +# %1-artifact url/artifact label/artifact description/VNF Service Indicator + MISSING_DATA: { + code: 400, + message: "Error: Invalid content. Missing %1.", + messageId: "SVC4528" + } +#---------SVC4529------------------------------ +# %1-artifact url/artifact label/artifact description/artifact name +# %2 - Maximal length of %1 + EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 exceeds limit of %2 characters.", + messageId: "SVC4529" + } +#---------SVC4530------------------------------ + ARTIFACT_INVALID_TIMEOUT: { + code: 400, + message: "Error: Invalid Content. Artifact Timeout should be set to valid positive non-zero number of minutes.", + messageId: "SVC4530" + } +#---------SVC4531------------------------------ + SERVICE_IS_VNF_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: VNF Indicator cannot be updated for certified service.", + messageId: "SVC4531" + } + #---------SVC4532------------------------------ + RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE: { + code: 404, + message: "Error: Requested '%1' resource instance was not found on the service '%2.", + messageId: "SVC4532" + } + #---------SVC4533------------------------------ + # %1 - "HEAT"/"HEAT_ENV"/"MURANO_PKG"/"YANG_XML" + WRONG_ARTIFACT_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for %1 artifact type.", + messageId: "SVC4533" + } + +#---------SVC4534------------------------------ +# %1 - "HEAT"/"HEAT_ENV" + INVALID_YAML: { + code: 400, + message: "Error: Uploaded YAML file for %1 artifact is invalid.", + messageId: "SVC4534" + } + +#---------SVC4535------------------------------ +# %1 - "HEAT" + INVALID_DEPLOYMENT_ARTIFACT_HEAT: { + code: 400, + message: "Error: Invalid %1 artifact.", + messageId: "SVC4535" + } +#---------SVC4536------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "HEAT"/"HEAT_ENV"/"MURANO_PKG" +# %4 - "HEAT"/"HEAT_ENV"/"MURANO_PKG + DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact of %3 type .Please delete or update an existing %4 artifact.", + messageId: "SVC4536" + } + +#---------SVC4537------------------------------ + MISSING_HEAT: { + code: 400, + message: "Error: Missing HEAT artifact. HEAT_ENV artifact cannot be uploaded without corresponding HEAT template.", + messageId: "SVC4537" + } +#---------SVC4538------------------------------ + MISMATCH_HEAT_VS_HEAT_ENV: { + code: 400, + message: "Error: Invalid artifact content. Parameter's set in HEAT_ENV '%1' artifact doesn't match the parameters in HEAT '%2' artifact.", + messageId: "SVC4538" + } +#---------SVC4539------------------------------ + INVALID_RESOURCE_PAYLOAD: { + code: 400, + message: "Error: Invalid resource payload.", + messageId: "SVC4539" + } +#---------SVC4540------------------------------ + INVALID_TOSCA_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for TOSCA template.", + messageId: "SVC4540" + } +#---------SVC4541------------------------------ + INVALID_YAML_FILE: { + code: 400, + message: "Error: Invalid YAML file.", + messageId: "SVC4541" + } +#---------SVC4542------------------------------ + INVALID_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Invalid TOSCA template.", + messageId: "SVC4542" + } +#---------SVC4543------------------------------ + NOT_RESOURCE_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Imported Service TOSCA template.", + messageId: "SVC4543" + } +#---------SVC4544------------------------------ + NOT_SINGLE_RESOURCE: { + code: 400, + message: "Error: Imported TOSCA template should contain one resource definition.", + messageId: "SVC4544" + } +#---------SVC4545------------------------------ + INVALID_RESOURCE_NAMESPACE: { + code: 400, + message: "Error: Invalid resource namespace.", + messageId: "SVC4545" + } +#---------SVC4546------------------------------ + RESOURCE_ALREADY_EXISTS: { + code: 400, + message: "Error: Imported resource already exists in ASDC Catalog.", + messageId: "SVC4546" + } +#---------SVC4549------------------------------ + INVALID_RESOURCE_CHECKSUM: { + code: 400, + message: "Error: Invalid resource checksum.", + messageId: "SVC4549" + } +#---------SVC4550------------------------------ + #%1  -  Consumer salt + INVALID_LENGTH: { + code: 400, + message: "Error: Invalid %1 length.", + messageId: "SVC4550" + } + #---------SVC4551------------------------------ + #%1  -  ECOMP User name + ECOMP_USER_NOT_FOUND: { + code: 404, + message: "Error: ECOMP User '%1' was not found.", + messageId: "SVC4551" + } +#---------SVC4552------------------------------ + CONSUMER_ALREADY_EXISTS: { + code: 409, + message: "Error: ECOMP User already exists.", + messageId: "SVC4552" + } +#---------SVC4553----------------------------- + #%1  -  Consumer name / Consumer password/ Consumer salt + INVALID_CONTENT_PARAM: { + code: 400, + message: "Error: %1 is invalid.", + messageId: "SVC4553" + } + #---------SVC4554------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Requested artifact doesn't belong to specified %1.", + messageId: "SVC4554" + } +#---------SVC4554------------------------------ +# %1 - "Service name" + SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND: { + code: 403, + message: "Error: Requested '%1' service is not ready for certification. Service has to have at least one deployment artifact.", + messageId: "SVC4554" + } +#---------SVC4555------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_LENGTH: { + code: 400, + message: "Error: Invalid %1 %2 name length.", + messageId: "SVC4555" + } +#---------SVC4556------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 name format.", + messageId: "SVC4556" + } +#---------SVC4557------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category name" + COMPONENT_CATEGORY_ALREADY_EXISTS: { + code: 409, + message: "Error: %1 category name '%2' already exists.", + messageId: "SVC4557" + } +#---------SVC4558------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + VALIDATED_RESOURCE_NOT_FOUND: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource.", + messageId: "SVC4558" + } +#---------SVC4559------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_ALREADY_VALIDATED_RESOURCE: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use already available validated resource version.", + messageId: "SVC4559" + } +#---------SVC4560------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_LIST_VALIDATED_RESOURCES: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use one of available validated resource versions.", + messageId: "SVC4560" + } +#---------SVC4561------------------------------ +# %1 - "resource"/"product" +# %2 - "category" +# %2 - "category name" + COMPONENT_CATEGORY_NOT_FOUND: { + code: 404, + message: "Error: Requested %1 %2 '%3' was not found.", + messageId: "SVC4561" + } +#---------SVC4562------------------------------ +# %1 - "Resource"/"Product" +# %2 - "sub-category name" +# %2 - "category name" + COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY: { + code: 409, + message: "Error: %1 sub-category '%2' already exists under '%3' category.", + messageId: "SVC4562" + } +#---------SVC4563------------------------------ +# %1 - "Product" +# %2 - "grouping name" +# %2 - "sub-category name" + COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY: { + code: 409, + message: "Error: %1 grouping '%2' already exists under '%3' sub-category.", + messageId: "SVC4563" + } +#---------SVC4564------------------------------ +# %1 - product name + PRODUCT_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' product was not found.", + messageId: "SVC4564" + } +#---------SVC4565------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") +# %3 - parameter name + INVALID_HEAT_PARAMETER_VALUE: { + code: 400, + message: "Error: Invalid %1 artifact. Invalid %2 value set for '%3' parameter.", + messageId: "SVC4565" + } +#---------SVC4566------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") + INVALID_HEAT_PARAMETER_TYPE: { + code: 400, + message: "Error: Invalid %1 artifact. Unsupported '%2' parameter type.", + messageId: "SVC4566" + } +#---------SVC4567------------------------------ +# %1 - "YANG_XML" + INVALID_XML: { + code: 400, + message: "Error: Uploaded XML file for %1 artifact is invalid.", + messageId: "SVC4567" + } +#---------SVC4567------------------------------ +# %1 - "User Name and UserId" +# %2 -"checked-out"/"in-certification" + CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: User cannot be deleted. User '%1' has %2 projects.", + messageId: "SVC4567" + } +#---------SVC4568------------------------------ +# %1 - "User Name and UserId" +# %2 -"checked-out"/"in-certification" + CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: Role cannot be changed. User '%1' has %2 projects.", + messageId: "SVC4568" + } +#---------SVC4570------------------------------ + UPDATE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator is not allowed to change his/her role.", + messageId: "SVC4570" + } +#---------SVC4571------------------------------ + SERVICE_CANNOT_CONTAIN_SUBCATEGORY: { + code: 400, + message: "Error: Sub category cannot be defined for service", + messageId: "SVC4571" + } +#---------SVC4572------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_TOO_MUCH_CATEGORIES: { + code: 400, + message: "Error: %1 must have only 1 category", + messageId: "SVC4572" + } +#---------SVC4574------------------------------ + RESOURCE_TOO_MUCH_SUBCATEGORIES: { + code: 400, + message: "Error: Resource must have only 1 sub category", + messageId: "SVC4574" + } +#---------SVC4575------------------------------ + COMPONENT_MISSING_SUBCATEGORY: { + code: 400, + message: "Error: Missing sub category", + messageId: "SVC4575" + } + #---------SVC4576------------------------------ +# %1 - "component type" + UNSUPPORTED_ERROR: { + code: 400, + message: "Error : Requested component type %1 is unsupported.", + messageId: "SVC4576" + } + #---------SVC4577------------------------------ +# %1 - "resource type" + RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES: { + code: 409, + message: "Error : Resource of type %1 cannot contain resource instances.", + messageId: "SVC4577" + } +#---------SVC4578------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "artifact name" + DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact named '%3'.", + messageId: "SVC4578" + } +#---------SVC4579------------------------------ +# %1 - "Category"/"Sub-Category"/"Group" +# %2 - category/sub-category/grouping name. + INVALID_GROUP_ASSOCIATION: { + code: 400, + message: "Error: Invalid group association. %1 '%2' was not found.", + messageId: "SVC4579" + } +#---------SVC4580------------------------------ + EMPTY_PRODUCT_CONTACTS_LIST: { + code: 400, + message: "Error: Invalid content. At least one Product Contact has to be specified.", + messageId: "SVC4580" + } +#---------SVC4581------------------------------ +# %1 - userId + INVALID_PRODUCT_CONTACT: { + code: 400, + message: "Error: Invalid content. User '%1' cannot be set as Product Contact.", + messageId: "SVC4581" + } +#---------SVC4582------------------------------ +# %1 - Product +# %2 - "abbreviated"/"full" + MISSING_ONE_OF_COMPONENT_NAMES: { + code: 400, + message: "Error: Invalid content. Missing %1 %2 name.", + messageId: "SVC4582" + } +#---------SVC4583------------------------------ +# %1 - "Icon" +# %2 - "resource"/"service"/"product" + COMPONENT_PARAMETER_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: %1 cannot be changed once the %2 is certified.", + messageId: "SVC4583" + } +#---------SVC4584------------------------------ +# %1 - service/VF name +# %2 - "service" /"VF" +# %3 - resource instance origin type +# %4 - resource instance name +# %5 - requirement/capability +# %6 - requirement/capability name +# %7 - "fulfilled" (for req)/"consumed (for cap)" + REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification. %3 '%4' has to have %5 '%6' %7.", + messageId: "SVC4584" + } +#---------SVC4585------------------------------ + INVALID_OCCURRENCES: { + code: 400, + message: "Error: Invalid occurrences format.", + messageId: "SVC4585" + } +#---------SVC4586------------------------------ +#---------SVC4586------------------------------ + INVALID_SERVICE_API_URL: { + code: 400, + message: 'Error: Invalid Service API URL. Please check whether your URL has a valid domain extension and does not contain the following characters - #?&@%+;,=$<>~^`\[]{}|"*!', + messageId: "SVC4586" + } +#---------SVC4587------------------------------ +# %1 - Data type name + DATA_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Data type %1 already exists.', + messageId: "SVC4587" + } +#---------SVC4588------------------------------ +# %1 - Data type name + DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM: { + code: 400, + message: 'Error: Invalid Data type %1. Data type must have either a valid derived from declaration or at least one valid property', + messageId: "SVC4588" + } +#---------SVC4589------------------------------ +# %1 - Data type name + DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY: { + code: 400, + message: "Error: Invalid Data type %1. 'properties' parameter cannot be empty if provided.", + messageId: "SVC4589" + } +#---------SVC4590------------------------------ +# %1 - Property type name +# %2 - Property name + INVALID_PROPERTY_TYPE: { + code: 400, + message: "Error: Invalid Property type %1 in property %2.", + messageId: "SVC4590" + } +#---------SVC4591------------------------------ +# %1 - Property inner type +# %2 - Property name + INVALID_PROPERTY_INNER_TYPE: { + code: 400, + message: "Error: Invalid property inner type %1, in property %2", + messageId: "SVC4591" + } +#---------SVC4592------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" + COMPONENT_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' %2 was not found.", + messageId: "SVC4592" + } +#---------SVC4593------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" +# %3 - "resource/"service"/"product" +# %4 - container name + COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER: { + code: 404, + message: "Error: Requested '%1' %2 was not found on the %3 '%4'.", + messageId: "SVC4593" + } +#---------SVC4594------------------------------ +#%1 - requirement / capability +#%2 - requirement name + IMPORT_DUPLICATE_REQ_CAP_NAME: { + code: 400, + message: "Error: Imported TOSCA template contains more than one %1 named '%2'.", + messageId: "SVC4594" + } +#---------SVC4595------------------------------ +#%1 - requirement / capability +#%2 - requirement name +#%3 - parent containing the requirement + IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED: { + code: 400, + message: "Error: Imported TOSCA template contains %1 '%2' that is already defined by derived template %3.", + messageId: "SVC4595" + } +#---------SVC4596------------------------------ +# %1 - Data type name + DATA_TYPE_DERIVED_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The ancestor data type %1 cannot be found in the system.", + messageId: "SVC4596" + } +#---------SVC4597------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties named %2 which are already defined in one of its ancestors.", + messageId: "SVC4597" + } +#---------SVC4598------------------------------ +# %1 - Data type name + DATA_TYPE_DUPLICATE_PROPERTY: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains duplicate property.", + messageId: "SVC4598" + } +#---------SVC4599------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties %2 which their type is this data type.", + messageId: "SVC4599" + } +#---------SVC4600------------------------------ +# %1 - Data type name + DATA_TYPE_CANNOT_HAVE_PROPERTIES: { + code: 400, + message: "Error: Invalid Content. The data type %1 cannot have properties since it is of type scalar", + messageId: "SVC4600" + } +#---------SVC4601------------------------------ + NOT_TOPOLOGY_TOSCA_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file %1 cannot be modeled to VF as it does not contain 'topology_template.", + messageId: "SVC4601" + } +#---------SVC4602-------------------------------- +# %1 - yaml file name +# %2 - node_template label +# %3 - node_template type + INVALID_NODE_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file '%1' contains node_template '%2' of type '%3' that does not represent existing VFC/CP/VL", + messageId: "SVC4602" + } +#---------SVC4603------------------------------ +# %1 - component type +# %2 - component name +# %3 - state + ILLEGAL_COMPONENT_STATE: { + code: 403, + message: "Error: Component instance of %1 can not be created because the component '%2' is in an illegal state %3.", + messageId: "SVC4603" + } +#---------SVC4604------------------------------ +# %1 - csar file name + CSAR_INVALID: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. 'TOSCA-Metadata/Tosca.meta' file must be provided.", + messageId: "SVC4604" + } +#---------SVC4605------------------------------ +# %1 - csar file name + CSAR_INVALID_FORMAT: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. Invalid 'TOSCA-Metadata/Tosca.meta' file format.", + messageId: "SVC4605" + } +#---------SVC4606------------------------------ +# %1 - property name +# %2 - property type +# %3 - property innerType +# %4 - default value is + INVALID_COMPLEX_DEFAULT_VALUE: { + code: 400, + message: "Error: Invalid default value of property %1. Data type is %2 with inner type %3 and default value found is %4.", + messageId: "SVC4606" + } +#---------SVC4607------------------------------ +# %1 - csar file name + CSAR_NOT_FOUND: { + code: 400, + message: "Error: TOSCA CSAR '%1' is not found.", + messageId: "SVC4607" + } +#---------SVC4608------------------------------ +# %1 - artifact name +# %2 - component type +# %3 - actual component type + MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE: { + code: 400, + message: "Error: Artifact %1 is only compatible with component of type %2, but component type is %3.", + messageId: "SVC4608" + } + +#---------SVC4609------------------------------ +# %1 - "INVALID_JSON" + INVALID_JSON: { + code: 400, + message: "Error: Uploaded JSON file for %1 artifact is invalid.", + messageId: "SVC4609" + } +#---------SVC4610------------------------------ +# %1 - csar file name +# %2 - missing file name + YAML_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error - TOSCA CSAR %1 is invalid. TOSCA-Metadata/Tosca.meta refers to file %2 that is not provided.", + messageId: "SVC4610" + } +#---------SVC4611------------------------------ +# %1 - group name + GROUP_MEMBER_EMPTY: { + code: 400, + message: "Error: Invalid Content. Group %1 member list was provided but does not have values", + messageId: "SVC4611" + } +#---------SVC4612------------------------------ +# %1 - group name + GROUP_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Group type %1 already exists.', + messageId: "SVC4612" + } +#---------SVC4613------------------------------ +# %1 - group name +# %2 - VF name(component name) +# %3 - actual component type [VF] + GROUP_ALREADY_EXIST: { + code: 409, + message: "Error: Group with name '%1' already exists in %2 %3.", + messageId: "SVC4613" + } +#---------SVC4614------------------------------ +# %1 - group type + GROUP_TYPE_IS_INVALID: { + code: 400, + message: "Error: Invalid content. Group type %1 does not exist", + messageId: "SVC4614" + } +#---------SVC4615------------------------------ +# %1 - group name + GROUP_MISSING_GROUP_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Group Type for group '%1'", + messageId: "SVC4615" + } +#---------SVC4616------------------------------ +# %1 - member name +# %2 - group name +# %3 - VF name +# %4 - component type [VF ] + GROUP_INVALID_COMPONENT_INSTANCE: { + code: 400, + message: "Error: member %1 listed in group %2 is not part of %3 %4.", + messageId: "SVC4616" + } +#---------SVC4617------------------------------ +# %1 - member name +# %2 - group name +# %3 - group type + GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE: { + code: 400, + message: "Error: member %1 listed in group %2 is not part of allowed members of group type %3.", + messageId: "SVC4617" + } +#---------SVC4618------------------------------ +# %1 - missing file name +# %2 - csar file name + ARTIFACT_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", + messageId: "SVC4618" + } +#---------SVC4619------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - existing artifact type + ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { + code: 400, + message: "Error: artifact %1 in type %2 already exists in type %3.", + messageId: "SVC4619" + } +#---------SVC4620------------------------------ + FAILED_RETRIVE_ARTIFACTS_TYPES: { + code: 400, + message: "Error: Failed to retrieve list of suported artifact types.", + messageId: "SVC4620" + } +#---------SVC4621------------------------------ +# %1 - artifact name +# %2 - master + ARTIFACT_ALRADY_EXIST_IN_MASTER_IN_CSAR: { + code: 400, + message: "Error: artifact %1 already exists in master %2 .", + messageId: "SVC4621" + } +#---------SVC4622------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - master name +# %4 - master type + ARTIFACT_NOT_VALID_IN_MASTER: { + code: 400, + message: "Error: artifact %1 in type %2 can not be exists under master %3 in type %4.", + messageId: "SVC4622" + } +#---------SVC4623------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - env name +# %4 - existing env + ARTIFACT_NOT_VALID_ENV: { + code: 400, + message: "Error: Artifact %1 in type %2 with env %3 already exists with another env %4", + messageId: "SVC4623" + } +#---------SVC4624------------------------------ +# %1 - groups names +# %2 - VF name +# %3 - component type [VF ] + GROUP_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The groups '%1' cannot be found under %2 %3.", + messageId: "SVC4624" + } +#---------SVC4625------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_ASSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already associated to group '%1'.", + messageId: "SVC4625" + } +#---------SVC4626------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_DISSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already dissociated from group '%1'.", + messageId: "SVC4626" + } +#---------SVC4627------------------------------ +# %1 - property name +# %2 - group name +# %3 - group type name + GROUP_PROPERTY_NOT_FOUND: { + code: 400, + message: "Error: property %1 listed in group %2 is not exist in group type %3.", + messageId: "SVC4627" + } +#---------SVC4628------------------------------ +# %1 - csarUUID +# %2 - VF name + VSP_ALREADY_EXISTS: { + code: 400, + message: "Error: The VSP with UUID %1 was already imported for VF %2. Please select another or update the existing VF.", + messageId: "SVC4628" + } +#---------SVC4629------------------------------ +# %1 - VF name + MISSING_CSAR_UUID: { + code: 400, + message: "Error: The Csar UUID or payload name is missing for VF %1.", + messageId: "SVC4629" + } +#---------SVC4630------------------------------ +# %1 - VF name +# %2 - new csarUUID +# %3 - old csarUUID + RESOURCE_LINKED_TO_DIFFERENT_VSP: { + code: 400, + message: "Error: Resource %1 cannot be updated using CsarUUID %2 since the resource is linked to a different VSP with csarUUID %3.", + messageId: "SVC4630" + } +#---------SVC4631------------------------------ +# %1 - policy name + POLICY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Policy type %1 already exists.", + messageId: "SVC4631" + } +#---------SVC4632------------------------------ +# %1 - target name +# %2 - policy type name + TARGETS_NON_VALID: { + code: 400, + message: "Error: target %1 listed in policy type %2 is not a group or resource.", + messageId: "SVC4632" + } +#---------SVC4633------------------------------ +# %1 - policy name + TARGETS_EMPTY: { + code: 400, + message: "Error: Invalid Content. Policy %1 target list was provided but does not have values", + messageId: "SVC4633" + } +#---------SVC4634------------------------------ + DATA_TYPE_CANNOT_BE_EMPTY: { + code: 500, + message: "Error: Data types are empty. Please import the data types.", + messageId: "SVC4634" + } +#---------SVC4635------------------------------ +# %1 - csar uuid + RESOURCE_FROM_CSAR_NOT_FOUND: { + code: 400, + message: "Error: resource from csar uuid %1 not found", + messageId: "SVC4635" + } \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.json b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.json new file mode 100644 index 0000000000..2560a8acfa --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.json @@ -0,0 +1,11 @@ +{ + "payloadName": "HSS.yml", + "contactId": "jh0003", + "resourceName": "att.nodes.ims.HSS", + "description": "The home subscriber server (HSS), or user profile server function (UPSF), is a master user database that supports the IMS network entities that actually handle calls. It contains the subscription-related information (subscriber profiles), performs authentication and authorization of the user, and can provide information about the subscriber's location and IP information.", + "resourceIconPath": "defaulticon", + "category": "IMS", + "tags": [ + "att.nodes.ims.HSS", "IMS_TAG" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml new file mode 100644 index 0000000000..060059508a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml @@ -0,0 +1,18 @@ +att.nodes.ims.HSS: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + icscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more I-CSCF functions + scscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more S-CSCF functions + requirements: + database_endpoint: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml.old b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml.old new file mode 100644 index 0000000000..c58191e85b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.yml.old @@ -0,0 +1,28 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +description: > + The home subscriber server (HSS), or user profile server function (UPSF), + is a master user database that supports the IMS network entities that actually handle calls. + It contains the subscription-related information (subscriber profiles), + performs authentication and authorization of the user, and can provide information about the + subscriber's location and IP information. + +node_types: + att.nodes.ims.HSS: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + icscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more I-CSCF functions + scscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more S-CSCF functions + requirements: + database_endpoint: + capability: tosca.capabilities.Endpoint.Database + node: tosca.nodes.Database + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.zip b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.zip new file mode 100644 index 0000000000..ed8949f445 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/HSS/HSS.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.json b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.json new file mode 100644 index 0000000000..89bf58a2fb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "ICSCF.yml", + "contactId": "jh0003", + "resourceName": "att.nodes.ims.ICSCF", + "description": "Interrogating-CSCF (I-CSCF) is a SIP function located at the edge of an administrative domain. Its IP address is published in the Domain Name System (DNS) of the domain(using NAPTR and SRV type of DNS records), so that remote servers can find it, and use it as a forwarding point (e.g., registering) for SIP packets to this domain.It queries the HSS to retrieve the address of the S-CSCF and assign it to a user performing SIP registration. It also forwards SIP request or response to the S-CSCF.", + "resourceIconPath": "defaulticon", + "category": "IMS", + "tags": [ + "att.nodes.ims.ICSCF", "IMS_TAG" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml new file mode 100644 index 0000000000..a00685bc03 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml @@ -0,0 +1,13 @@ +att.nodes.ims.ICSCF: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + pcscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more P-CSCF functions + requirements: + hss_endpoint: + capability: tosca.capabilities.Endpoint + node: att.nodes.ims.HSS + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml.old b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml.old new file mode 100644 index 0000000000..183f8db3f4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.yml.old @@ -0,0 +1,24 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +description: > + Interrogating-CSCF (I-CSCF) is a SIP function located at the edge of an administrative domain. + Its IP address is published in the Domain Name System (DNS) of the domain + (using NAPTR and SRV type of DNS records), so that remote servers can find it, + and use it as a forwarding point (e.g., registering) for SIP packets to this domain. + It queries the HSS to retrieve the address of the S-CSCF and assign it to a user performing SIP + registration. It also forwards SIP request or response to the S-CSCF. + +node_types: + att.nodes.ims.ICSCF: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + pcscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more P-CSCF functions + requirements: + hss_endpoint: + capability: tosca.capabilities.Endpoint + node: att.nodes.ims.HSS + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.zip b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.zip new file mode 100644 index 0000000000..228372e2f3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/ICSCF/ICSCF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.json b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.json new file mode 100644 index 0000000000..bf8ee08d30 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "PCSCF.yml", + "contactId": "jh0003", + "resourceName": "att.nodes.ims.PCSCF", + "description": "A Proxy-CSCF (P-CSCF) is a SIP proxy that is the first point of contact for the IMS terminal. It can be located either in the visited network (in full IMS networks) or in the home network (when the visited network is not IMS compliant yet). The P-CSCF is at its core a specialized SBC for the User network interface which not onlyprotects the network, but also the IMS terminal. The use of an additional SBC between the IMS terminal and the P-CSCF is unnecessary and infeasible due to the signaling being encrypted on this leg. The terminal discovers its P-CSCF with either DHCP, or it may be configured (e.g. during initial provisioning or via a 3GPP IMS Management Object (MO)) or in the ISIM or assigned in the PDP Context (in General Packet Radio Service (GPRS)).", + "resourceIconPath": "defaulticon", + "category": "IMS", + "tags": [ + "att.nodes.ims.PCSCF", "IMS_TAG" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.yml b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.yml new file mode 100644 index 0000000000..3d0e38eefc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.yml @@ -0,0 +1,13 @@ +att.nodes.ims.PCSCF: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + pcscf_endpoint: + type: tosca.capabilities.Endpoint.Public + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more UAs + requirements: + icscf_endpoint: + capability: tosca.capabilities.Endpoint + node: att.nodes.ims.ICSCF + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.zip b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.zip new file mode 100644 index 0000000000..37a6bac251 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/PCSCF/PCSCF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.json b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.json new file mode 100644 index 0000000000..0f893ddb9b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "SCSCF.yml", + "resourceName": "att.nodes.ims.SCSCF", + "description": "A Serving-CSCF (S-CSCF) is the central node of the signaling plane. It is a SIP server, but performs session control too. It is always located in the home network. It uses Diameter Cx and Dx interfaces to the HSS to download user profiles and upload user-to-S-CSCF associations (the user profile is only cached locally for processing reasons only and is not changed). All necessary subscriber profile information is loaded from the HSS.", + "resourceIconPath": "defaulticon", + "category": "IMS", + "contactId": jh0003, + "tags": [ + "att.nodes.ims.SCSCF", "IMS_TAG" + ] +} diff --git a/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml new file mode 100644 index 0000000000..a2672ddb13 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml @@ -0,0 +1,13 @@ +att.nodes.ims.SCSCF: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + icscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more I-CSCF functions + requirements: + hss_endpoint: + capability: tosca.capabilities.Endpoint + node: att.nodes.ims.HSS + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml.old b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml.old new file mode 100644 index 0000000000..d8fb1b0d33 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.yml.old @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +description: > + A Serving-CSCF (S-CSCF) is the central node of the signalling plane. + It is a SIP server, but performs session control too. It is always located in the home network. + It uses Diameter Cx and Dx interfaces to the HSS to download user profiles and upload + user-to-S-CSCF associations (the user profile is only cached locally for processing reasons only + and is not changed). All necessary subscriber profile information is loaded from the HSS. + +node_types: + att.nodes.ims.SCSCF: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + icscf_endpoint: + type: tosca.capabilities.Endpoint + relationship: tosca.relationships.ConnectTo + occurrences: [0, UNBOUNDED] + description: Connection with one ore more I-CSCF functions + requirements: + hss_endpoint: + capability: tosca.capabilities.Endpoint + node: att.nodes.ims.HSS + relationship: tosca.relationships.ConnectsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.zip b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.zip new file mode 100644 index 0000000000..7a579dc5c1 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/SCSCF/SCSCF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.json b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.json new file mode 100644 index 0000000000..7425778dd1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.json @@ -0,0 +1,15 @@ +{ + "payloadName": "compute.yml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.Compute", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "tosca.nodes.Compute" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.yml b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.yml new file mode 100644 index 0000000000..b110157df3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Compute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.zip b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.zip new file mode 100644 index 0000000000..95a1325d92 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/compute/compute.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/deleteResourcesDemo.sh b/asdc-tests/src/test/resources/CI/importAttResources/deleteResourcesDemo.sh new file mode 100644 index 0000000000..549a4ca78d --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/deleteResourcesDemo.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function deleteResource() { + + ELEMENT_NAME=$1 + echo "###################### Removing Element ${ELEMENT_NAME} Start ######################" + curl -X "DELETE" -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/resources/res_${ELEMENT_NAME}".1.0" + echo "" + echo "###################### Removing Element ${ELEMENT_NAME} End ########################" + echo "" + echo "" + echo "" +} +if [ $# -lt 2 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + +deleteResource "tosca.nodes.root" +deleteResource "tosca.nodes.compute" +deleteResource "tosca.nodes.softwarecomponent" +deleteResource "tosca.nodes.loadbalancer" +deleteResource "att.nodes.ims.hss" +deleteResource "att.nodes.ims.icscf" +deleteResource "att.nodes.ims.pcscf" +deleteResource "att.nodes.ims.scscf" + + diff --git a/asdc-tests/src/test/resources/CI/importAttResources/importResourcesDemo.sh b/asdc-tests/src/test/resources/CI/importAttResources/importResourcesDemo.sh new file mode 100644 index 0000000000..92beb9625a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/importResourcesDemo.sh @@ -0,0 +1,39 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function addResource() { + + ELEMENT_NAME=$1 + echo "###################### Adding Element ${ELEMENT_NAME} Start ######################" + CURRENT_ZIP_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.zip + CURRENT_JSON_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.json + JSON_CONTENT=`paste -s ${CURRENT_JSON_FILE}` + curl -v -F resourceMetadata="${JSON_CONTENT}" -F resourceZip=@${CURRENT_ZIP_FILE} -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/upload/multipart + echo "" + echo "###################### Adding Element ${ELEMENT_NAME} End ########################" + echo "" + echo "" + echo "" +} +if [ $# -lt 2 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + +addResource "root" +addResource "compute" +addResource "softwareComponent" +addResource "loadBalancer" +addResource "HSS" +addResource "ICSCF" +addResource "PCSCF" +addResource "SCSCF" + + diff --git a/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.json b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.json new file mode 100644 index 0000000000..d74dc3a3d5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.json @@ -0,0 +1,11 @@ +{ + "payloadName": "loadBalancer.yml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.LoadBalancer", + "description": "Represents logical function that be used in conjunction with a Floating Address to distribute an application’s traffic (load) across a number of instances of the application (e.g., for a clustered or scaled application).", + "resourceIconPath": "defaulticon", + "category": "Infrastructure", + "tags": [ + "tosca.nodes.LoadBalancer" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.yml b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.yml new file mode 100644 index 0000000000..53c053f0a6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.yml @@ -0,0 +1,16 @@ +tosca.nodes.LoadBalancer: + derived_from: tosca.nodes.Root + properties: + # TBD + algorithm : + type: string + required: false + status: experimental + capabilities : + client: + type: tosca.capabilities.Endpoint.Public + description: the Floating (IP) client’s on the public network can connect to + requirements: + - application: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.RoutesTo diff --git a/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.zip b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.zip new file mode 100644 index 0000000000..45edc204b5 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/loadBalancer/loadBalancer.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/root/root.json b/asdc-tests/src/test/resources/CI/importAttResources/root/root.json new file mode 100644 index 0000000000..6f96cf8b02 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/root/root.json @@ -0,0 +1,11 @@ +{ + "payloadName": "root.yml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.Root", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "category": "Abstract", + "tags": [ + "tosca.nodes.Root" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/root/root.yml b/asdc-tests/src/test/resources/CI/importAttResources/root/root.yml new file mode 100644 index 0000000000..81aacd56ab --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/root/root.yml @@ -0,0 +1,21 @@ +tosca.nodes.Root: + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature: + type: tosca.capabilities.Node + requirements: + - dependency : + capability: tosca.capabilities.Node + node: tosca.nodes.Root + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + interfaces: + Standard: + type: tosca.interfaces.node.lifecycle.Standard diff --git a/asdc-tests/src/test/resources/CI/importAttResources/root/root.zip b/asdc-tests/src/test/resources/CI/importAttResources/root/root.zip new file mode 100644 index 0000000000..bdafdfbeb6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/root/root.zip differ diff --git a/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.json b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.json new file mode 100644 index 0000000000..22379bf695 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.json @@ -0,0 +1,11 @@ +{ + "payloadName": "softwareComponent.yml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "category": "Abstract", + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.yml b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.yml new file mode 100644 index 0000000000..287a376fc3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.yml @@ -0,0 +1,15 @@ +tosca.nodes.SoftwareComponent: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.zip b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.zip new file mode 100644 index 0000000000..8e39b87808 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importAttResources/softwareComponent/softwareComponent.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.capabilities.yaml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.capabilities.yaml new file mode 100644 index 0000000000..073eba5ee7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.capabilities.yaml @@ -0,0 +1,13 @@ +asdc.capabilities.NetworkInterface: + derived_from: tosca.capabilities.Root + +asdc.capabilities.Container: + derived_from: tosca.capabilities.Container + +# binding a VDU to a CP +asdc.capabilities.nfv.VirtualBindable: + derived_from: tosca.capabilities.Root + +# linking a VL to a CP +asdc.capabilities.nfv.VirtualLinkable: + derived_from: tosca.capabilities.Root diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.json new file mode 100644 index 0000000000..e1727aca5c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.json @@ -0,0 +1,11 @@ +{ + "payloadName": "asdc.nodes.Module.yml", + "contactId": "jh0003", + "name": "asdc.nodes.Module", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "asdc.nodes.Module", "module" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.yml new file mode 100644 index 0000000000..b95156b5e1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.yml @@ -0,0 +1,2 @@ +asdc.nodes.Module: + derived_from: tosca.nodes.Root diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.zip new file mode 100644 index 0000000000..08003f1af8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Module/asdc.nodes.Module.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.json new file mode 100644 index 0000000000..c52bbeebc2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.json @@ -0,0 +1,11 @@ +{ + "payloadName": "asdc.nodes.Network.yml", + "contactId": "jh0003", + "name": "asdc.nodes.Network", + "description": "This is the default AT&T TOSCA Network Node Type that all other AT&T Network TOSCA nodes should extends.", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "asdc.nodes.Network", "Network" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.yml new file mode 100644 index 0000000000..0e56ef7bf2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.yml @@ -0,0 +1,2 @@ +asdc.nodes.Network: + derived_from: tosca.nodes.Root diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.zip new file mode 100644 index 0000000000..9b7fa35c2e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Network/asdc.nodes.Network.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.json new file mode 100644 index 0000000000..5e1dda7106 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.json @@ -0,0 +1,13 @@ +{ + "payloadName": "asdc.nodes.Root.yml", + "contactId": "jh0003", + "name": "asdc.nodes.Root", + "description": "This is the default (root) AT&T TOSCA Node Type that all other AT&T TOSCA nodes should extends. + This allows all AT&T TOSCA nodes to have a consistent set of features for modeling and management (e.g, consistent definitions for requirements, capabilities, and lifecycle interfaces).", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "asdc.nodes.Root" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.yml new file mode 100644 index 0000000000..ed8e1e46aa --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.yml @@ -0,0 +1,3 @@ +asdc.nodes.Root: + derived_from: tosca.nodes.Root + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.zip new file mode 100644 index 0000000000..8453bf3843 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.Root/asdc.nodes.Root.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.json new file mode 100644 index 0000000000..7a122a57cd --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.module.ECA_OAM.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.ECA_OAM", + "description": "Operation, Administration & Management of vMMSC ECA TRX", + "resourceIconPath": "applicationServer", + "category": "Application Layer 4+/Application Servers", + "tags": [ + "asdc.nodes.module.ECA_OAM", "MMSC OAM", "ECA", "MMSC", "vMMSC", "Mobility" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.yml new file mode 100644 index 0000000000..054c98439c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.yml @@ -0,0 +1,9 @@ +asdc.nodes.module.ECA_OAM: + derived_from: asdc.nodes.Module + requirements: + - oam_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.OAM + - internal_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Internal diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.zip new file mode 100644 index 0000000000..389ef18bae Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_OAM/asdc.nodes.module.ECA_OAM.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.json new file mode 100644 index 0000000000..338099286f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.module.ECA_TRX.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.ECA_TRX", + "description": "External Content Adaption Transcoder. Transcodes and adapts MMS content according to the capabilities of receiving MS or UE.", + "resourceIconPath": "applicationServer", + "category": "Application Layer 4+/Application Servers", + "tags": [ + "asdc.nodes.module.ECA_TRX", "Content Adaptation Transcoder", "MMSC", "vMMSC", "Mobility" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.yml new file mode 100644 index 0000000000..e2a520dc1d --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.yml @@ -0,0 +1,12 @@ +asdc.nodes.module.ECA_TRX: + derived_from: asdc.nodes.Module + requirements: + - oam_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.OAM + - traffic_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Traffic + - internal_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Internal diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.zip new file mode 100644 index 0000000000..f7911beb8f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.ECA_TRX/asdc.nodes.module.ECA_TRX.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.json new file mode 100644 index 0000000000..8ce0b8a961 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.module.F5_LTM.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.F5_LTM", + "description": "vMMSC Local Traffic Manager serves as the load balancer for traffic coming into the vMMSC. Traffic from MMSC designated to external network passes via F5. Also, internal communication between ECA and MMSC is via F5", + "resourceIconPath": "loadBalancer", + "category": "Application Layer 4+/Load Balancer", + "tags": [ + "asdc.nodes.module.F5_LTM", "F5", "Load Balancer", "vMMSC", "Mobility" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.yml new file mode 100644 index 0000000000..c50cd0a481 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.yml @@ -0,0 +1,12 @@ +asdc.nodes.module.F5_LTM: + derived_from: asdc.nodes.Module + requirements: + - core_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Core + - dmz_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.DMZ + - traffic_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Traffic diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.zip new file mode 100644 index 0000000000..2bb9bbaa03 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.F5_LTM/asdc.nodes.module.F5_LTM.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.json new file mode 100644 index 0000000000..4103880abf --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.module.MMSC.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.MMSC", + "description": "Accepts MMS messages via F5 and distributes among MMSCs. Messages are from user mobile device or from another Message Service", + "resourceIconPath": "applicationServer", + "category": "Application Layer 4+/Application Servers", + "tags": [ + "asdc.nodes.module.MMSC", "MMSC", "vMMSC", "Mobility" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.yml new file mode 100644 index 0000000000..b65b20f5b2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.yml @@ -0,0 +1,12 @@ +asdc.nodes.module.MMSC: + derived_from: asdc.nodes.Module + requirements: + - oam_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.OAM + - cinder_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Cinder + - traffic_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Traffic diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.zip new file mode 100644 index 0000000000..abf8dd8ced Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.MMSC/asdc.nodes.module.MMSC.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.json new file mode 100644 index 0000000000..a289e4dd1b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.module.NEMS_BE.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.NEMS_BE", + "description": "The Back End of a Network Message Storage allows external multimedia content to use SMTP e-mail mechanism to submit MMS messages", + "resourceIconPath": "applicationServer", + "category": "Application Layer 4+/Application Servers", + "tags": [ + "asdc.nodes.module.NEMS_BE", "MMSC", "vMMSC", "Network Message Storage", "Back End", "Mobility" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.yml new file mode 100644 index 0000000000..b460bf57a5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.yml @@ -0,0 +1,9 @@ +asdc.nodes.module.NEMS_BE: + derived_from: asdc.nodes.Module + requirements: + - oam_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.OAM + - internal_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Internal diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.zip new file mode 100644 index 0000000000..2ee35f5cde Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_BE/asdc.nodes.module.NEMS_BE.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.json new file mode 100644 index 0000000000..4d80b25712 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.json @@ -0,0 +1,11 @@ +{ + "payloadName": "asdc.nodes.module.NEMS_FE.yml", + "contactId": "jh0003", + "name": "asdc.nodes.module.NEMS_FE", + "description": "The Front End of a Network Message Storage allows external multimedia content to use SMTP e-mail mechanism to submit MMS messages", + "resourceIconPath": "objectStorage", + "category": "Application Layer 4+/Application Servers", + "tags": [ + "asdc.nodes.module.NEMS_FE", "MMSC", "vMMSC", "Network Message Storage", "Front End", "Mobility" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.yml new file mode 100644 index 0000000000..256aa7e4a3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.yml @@ -0,0 +1,15 @@ +asdc.nodes.module.NEMS_FE: + derived_from: asdc.nodes.Module + requirements: + - oam_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.OAM + - cinder_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Cinder + - traffic_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Traffic + - internal_connection: + capability: asdc.capabilities.NetworkInterface + node: asdc.nodes.network.Internal diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.zip new file mode 100644 index 0000000000..28eb1ccb60 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.module.NEMS_FE/asdc.nodes.module.NEMS_FE.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.json new file mode 100644 index 0000000000..4217cd4f07 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.network.Cinder.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.Cinder", + "description": "Represents access to cloud shared storae.", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.Cinder", "Network", "Cinder", "Cloud" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.yml new file mode 100644 index 0000000000..54b34d23fe --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.yml @@ -0,0 +1,5 @@ +asdc.nodes.network.Cinder: + derived_from: asdc.nodes.Network + capabilities: + cinder_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.zip new file mode 100644 index 0000000000..5210a39f29 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Cinder/asdc.nodes.network.Cinder.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.json new file mode 100644 index 0000000000..343a785b6f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.network.Core.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.Core", + "description": "Represents Cloud Core network which provide interface to other services.", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.Core", "Network", "Core", "Cloud" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.yml new file mode 100644 index 0000000000..ac4ceed23e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.yml @@ -0,0 +1,5 @@ +asdc.nodes.network.Core: + derived_from: asdc.nodes.Network + capabilities: + core_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.zip new file mode 100644 index 0000000000..7482fee585 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Core/asdc.nodes.network.Core.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.json new file mode 100644 index 0000000000..50041339b6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.network.DMZ.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.DMZ", + "description": "Represents DMZ network.", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.DMZ", "Network", "DMZ", "Cloud" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.yml new file mode 100644 index 0000000000..df41ae4072 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.yml @@ -0,0 +1,5 @@ +asdc.nodes.network.DMZ: + derived_from: asdc.nodes.Network + capabilities: + dmz_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.zip new file mode 100644 index 0000000000..fab96c9a64 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.DMZ/asdc.nodes.network.DMZ.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.json new file mode 100644 index 0000000000..a2cf1c8026 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.json @@ -0,0 +1,11 @@ +{ + "payloadName": "asdc.nodes.network.Internal.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.Internal", + "description": "Represents Internal Network", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.Internal", "Network", "Cloud" + ] +} diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.yml new file mode 100644 index 0000000000..01b6dece24 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.yml @@ -0,0 +1,5 @@ + asdc.nodes.network.Internal: + derived_from: asdc.nodes.Network + capabilities: + dmz_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.zip new file mode 100644 index 0000000000..2317ce5ad0 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Internal/asdc.nodes.network.Internal.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.json new file mode 100644 index 0000000000..161897ac22 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.json @@ -0,0 +1,12 @@ +{ + "payloadName": "asdc.nodes.network.OAM.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.OAM", + "description": "Represents AT&T Operation, Administration and Management (OA&M) network.", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.OAM", "Network", "OAM", "Cloud" + ] +} + diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.yml new file mode 100644 index 0000000000..0a0875ad07 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.yml @@ -0,0 +1,5 @@ +asdc.nodes.network.OAM: + derived_from: asdc.nodes.Network + capabilities: + oam_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.zip new file mode 100644 index 0000000000..b2fbb78a7c Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.OAM/asdc.nodes.network.OAM.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.json b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.json new file mode 100644 index 0000000000..fb8269039c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.json @@ -0,0 +1,11 @@ +{ + "payloadName": "asdc.nodes.network.Traffic.yml", + "contactId": "jh0003", + "name": "asdc.nodes.network.Traffic", + "description": "Represents Network Traffic", + "resourceIconPath": "network", + "category": "Generic/Network Elements", + "tags": [ + "asdc.nodes.network.Traffic", "Network", "Cloud" + ] +} diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.yml b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.yml new file mode 100644 index 0000000000..b50bc8e612 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.yml @@ -0,0 +1,5 @@ +asdc.nodes.network.Traffic: + derived_from: asdc.nodes.Network + capabilities: + dmz_connection: + type: asdc.capabilities.NetworkInterface diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.zip new file mode 100644 index 0000000000..3add4e6ade Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/asdc.nodes.network.Traffic/asdc.nodes.network.Traffic.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/capabilityTypes.zip b/asdc-tests/src/test/resources/CI/importResource-MMSC/capabilityTypes.zip new file mode 100644 index 0000000000..a1f0cdeee5 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-MMSC/capabilityTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/deleteNormative.sh b/asdc-tests/src/test/resources/CI/importResource-MMSC/deleteNormative.sh new file mode 100644 index 0000000000..fb46daa544 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/deleteNormative.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function deleteResource() { + + ELEMENT_NAME=$1 + echo -e "############### Removing Element ${ELEMENT_NAME} Start ######################" + http_code=$(curl -s -o /dev/null -w "%{http_code}" -X "DELETE" -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/resources/res_${ELEMENT_NAME}".1.0") + if [ ${http_code} -eq 204 ]; then + echo -e "\n############### Removing Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n############### Failed to remove Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + exit 1 + elif [ ${http_code} -eq 404 ]; then + echo -e "\n############### Element ${ELEMENT_NAME} not found status code:${http_code} End #######\n\n\n" + else + echo -e "\n############### Failed to remove Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + exit 1 + fi +} +if [ $# -lt 3 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + +deleteResource $3 + +exit 0 diff --git a/asdc-tests/src/test/resources/CI/importResource-MMSC/importNormative.sh b/asdc-tests/src/test/resources/CI/importResource-MMSC/importNormative.sh new file mode 100644 index 0000000000..9e568dddc3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-MMSC/importNormative.sh @@ -0,0 +1,85 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function addResource() { + + ELEMENT_NAME=$1 + echo -e "###################### Adding Element ${ELEMENT_NAME} Start ######################" + CURRENT_ZIP_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.zip + CURRENT_JSON_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.json + sed -i 's/"userId": ".*",/"userId": "'${ATT_UID}'",/' ${CURRENT_JSON_FILE} + JSON_CONTENT=`paste -s ${CURRENT_JSON_FILE}` + http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F resourceMetadata="${JSON_CONTENT}" -F resourceZip=@${CURRENT_ZIP_FILE} -H USER_ID:${ATT_UID} ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/upload/multipart) + if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding Element ${ELEMENT_NAME} End ########################\n\n\n" + elif [ ${http_code} -eq 409 ]; then + echo -e "\n###################### Already exists Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + exit 1 + fi +} +if [ $# -lt 3 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 +ATT_UID=$3 +NO_CAPS=$4 + +if [ "$NO_CAPS" = "nocaps" ]; then + echo "Skipping Caps import..." +else + #Add The CapabilityTypes + http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F capabilityTypeZip=@capabilityTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/capability) + if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The CapabilityTypes status code:${http_code} End ########################\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 + else + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 + fi + #Add The InterfaceLifecycleTypes + #http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F interfaceLifecycleTypeZip=@interfaceLifecycleTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/interfaceLifecycle) + #if [ ${http_code} -eq 201 ]; then + # echo -e "\n###################### Adding The InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + #elif [ ${http_code} -eq 409 ]; then + # echo -e "\n###################### Already exists InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + #elif [ ${http_code} -eq 500 ]; then + # echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + # exit 1 + #else + # echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + # exit 1 + #fi +fi + +addResource "asdc.nodes.Root" +addResource "asdc.nodes.Network" +addResource "asdc.nodes.network.Cinder" +addResource "asdc.nodes.network.Core" +addResource "asdc.nodes.network.DMZ" +addResource "asdc.nodes.network.OAM" +addResource "asdc.nodes.network.Traffic" +addResource "asdc.nodes.network.Internal" +addResource "asdc.nodes.Module" +addResource "asdc.nodes.module.ECA_OAM" +addResource "asdc.nodes.module.ECA_TRX" +addResource "asdc.nodes.module.F5_LTM" +addResource "asdc.nodes.module.MMSC" +addResource "asdc.nodes.module.NEMS_BE" +addResource "asdc.nodes.module.NEMS_FE" + + + + + +exit 0 diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/VCE_Brocade_Tosca.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/VCE_Brocade_Tosca.yaml new file mode 100644 index 0000000000..da71792698 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/VCE_Brocade_Tosca.yaml @@ -0,0 +1,834 @@ +tosca_definitions_version: tosca_simple_profile_for_nfv_1_0_0 +tosca_default_namespace: Need to figure out the namespace +description: vCEBrocade and Base Types for VNF, Connection Point, Virtual Link, etc based on VNF Modeling Guidelines + +metadata: + template_name: VCE_Brocade.yaml + template_author: Kazi Farooqui (KF6593) + template_version: "0.1" + +##################################################################### +############################ Data Types ########################### +##################################################################### +#data_types: + +########################################################################################### +###################### NODE TYPE DEFINITIONS ############################################ +########################################################################################### + +node_types: + ################################################################## + ################### TOSCA VNF Node ########################## + ################################################################## + tosca.nodes.nfv.VNF: + derived_from: tosca.nodes.Root + properties: + vnf_category: + type: string + description: Router, FW, LB, DNS are example categories + id: + type: string + description: ID of this VNF + vendor: + type: string + description: name of the vendor who provides this VNF + version: + type: version + description: version of the software for this VNF + #device_config: + # type: map + #entry_schema: + # type: string + #default: + # p1: 1 + # p2: 2 + #p3: 3 + #requirements: + # - virtualLink: + #capability: tosca.capabilities.nfv.VirtualLinkable + #occurrences: [1, UNBOUNDED] + + ################################################################## + ################### ASDC VNF Node ########################## + ################################################################## + org.openecomp.resource.nfv.VNF: + derived_from: tosca.nodes.nfv.VNF + + + ################################################################## + ###################### TOSCA VDU Node ########################## + ################################################################## + + tosca.nodes.nfv.VDU: + derived_from: tosca.nodes.SoftwareComponent + #properties: + + capabilities: + high_availability: + type: tosca.capabilities.nfv.HA + occurrences: [1, UNBOUNDED] # this is default + + virtual_binding: + type: tosca.capabilities.nfv.VDU.VirtualBindable + occurrences: [1, UNBOUNDED] # this is default + + requirements: + - high_availability: + capability: tosca.capabilities.nfv.HA + occurrences: [0,1] + + - host: ##Is hosted in a VM + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn + occurrences: [1, 1] #this is default + + ################################################################## + ###################### ASDC VDU Node###### ###################### + ################################################################## + org.openecomp.resource.nfv.VDU: + derived_from: tosca.nodes.nfv.VDU + description: A VDU is a compute component of VNF + + ################################################################## + ####################### TOSCA CP Node ########################## + ################################################################## + tosca.nodes.nfv.CP: + derived_from: tosca.nodes.Root + properties: + type: + type: string + required: false + requirements: + - virtualbinding: + capability: tosca.capabilities.nfv.VDU.VirtualBindable + occurrences: [1, 1] #this is default + + - virtuallink: + capability: tosca.capabilities.nfv.VirtualLinkable + occurrences: [1, 1] #this is default + + attributes: + ip_address: + type: string + # required: false + + ################################################################## + ############################ ASDC CP Node ##################### + ################################################################## + org.openecomp.resource.nfv.CP: + derived_from: tosca.nodes.nfv.CP + + ################################################################## + ############### IPAG VLAN Connector CP Node ##################### + ################################################################## + org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + ipag_network_name: + type: string + + ipag_network_type: + type: string + + ipag_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.IPAG_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.VDU.VirtualBindable + #node: org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.resource.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + + ################################################################## + ############### VPE VLAN Connector CP Node ##################### + ################################################################## + org.openecomp.resource.nfv.CP.VPE_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + vpe_network_name: + type: string + + vpe_network_type: + type: string + + vpe_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.VPE_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.VDU.VirtualBindable + #node: org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.resource.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + ################################################################## + ############### OAM VLAN Connector CP Node ##################### + ################################################################## + org.openecomp.resource.nfv.CP.OAM_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + oam_network_name: + type: string + + oam_network_type: + type: string + + oam_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.OAM_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.VDU.VirtualBindable + #node: org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.resource.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + + ################################################################## + ############## TOSCA VL Node Type ####################### + ################################################################## + tosca.nodes.nfv.VL: + derived_from: tosca.nodes.Root + properties: + vendor: + type: string + required: false + description: name of the vendor who provides this VL + + capabilities: + virtuallinkable: + type: tosca.capabilities.nfv.VirtualLinkable + occurrences: [1, UNBOUNDED] # this is default + +################################################################## +###################### ASDC VL Node TYPE ###################### +################################################################## + org.openecomp.resource.nfv.VL: + derived_from: tosca.nodes.nfv.VL + + +################################################################## +###################### ASDC VNF Node TYPE ###################### +################################################################## + org.openecomp.resource.nfv.VNF: + derived_from: tosca.nodes.nfv.VNF + +################################################################## +###################### ASDC Routing Category VDU ################# +################################################################## + + org.openecomp.resource.nfv.VDU.RoutingCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + +################################################################## +###################### vCE_Brocade_VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU:#paharoni - renamed from org.openecomp.resource.v/VCE_Brocade_VDU to keep convention + derived_from: org.openecomp.resource.nfv.VDU.RoutingCategoryVDU + description: Definition of VCE Brocade VDU + properties: + vnf_category: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + vce_type: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + vendor: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + version: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + image_id: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer -vCE image used to boot VM + flavor_id: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - VM Size, SMALL, MEDIUM, LARGE + username: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer -login user Id of Router + password: + type: string + description: I Input provided at DESIGN TIME by Service Composer or Designer - password for login + domain_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - login domain + time_zone: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - time zone to set for vCE + login_session_timeout: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - user login session timeout + ipag_vlan_bandwidth: + type: integer + description: Input provided at DESIGN TIME by Service Composer or Designer - bandwidth allocation of customer VLAN requested by customer + vpe_vlan_interface_qos_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - QoS Policy name to be applied to this interface + ipag_vlan_interface_qos_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - QoS Policy name to be applied to this interface + hostname: + type: string + description: Input provided at RUN TIME by Cloud-PO - Host VM is created first and this value is input when the vCE image is later on installed by Cloud-PO + host_ip: + type: string + description: Input provided at RUN TIME by Cloud-PO - Host VM IP + availability_zone: + type: string + description: Input provided at RUN TIME by Cloud-PO - Cloud availability zone where VM is created + oam_loopback_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - OAM Network is pre-created - already exists in Data Center + ipag_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - IPAG VLAN Network is created by Cloud-PO before the vCE is created or installed + vpe_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - VPE VLAN Network is created by Cloud-PO before the vCE is created / installed + vpe_vlan_id: + type: string + description: Input provided at RUN TIME by Cloud-PO - VLAN Id is created first by Cloud-PO. It is required to apply VPE QoS Policy + ipag_vlan_id: + type: string + description: Input provided at RUN TIME by Cloud-PO - VLAN Id is created first by Cloud-PO. It is required to apply IPAG QoS Policy + oam_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + vpe_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + ipag_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + #############ATTRIBUTES of vCE - These values are outputted by Cloud-PO when vCE is created / installed ############## + attributes: + vce_name: + type: string + description: Name assigned to vCE by Cloud-PO + oam_loopback_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to OAM VLAN + ipag_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to IPAG VLAN + vpe_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to VPE VLAN + vnf_id: + type: string + description: unique id assigned to VNF by Cloud-PO - used for AAI metadata + + #############CAPABILITIES of vCE - ######################### + capabilities: + ce_routing_capability: + type: org.openecomp.capabilities.nfv.CERouting + description: This is the base capability of vCE + occurrences: [1, UNBOUNDED] # default + + static_routing: + type: org.openecomp.capabilities.nfv.StaticRouting + description: This is the optional capability of the vCE + occurrences: [0, UNBOUNDED] + + bgp_routing: + type: org.openecomp.capabilities.nfv.BGPRouting + description: This is the optional capability of the vCE + occurrences: [0, UNBOUNDED] + + virtual_bindable: + type: org.openecomp.capabilities.nfv.VDU.VirtualBindable# paharoni - changed to org.openecomp.capabilities.nfv.vdu.VirtualBindable from tosca.capabilities.nfv.VDU.VirtualBindable - was it intentional?? + description: This is the internal capability of the VDU to support Binding to Connection Points + occurrences: [1, UNBOUNDED] + + dummy_capability: + type: org.openecomp.capabilities.nfv.VCE_Brocade_Routing + description: This capability has been introduced to model VCE VDU as a component of VCE VNF, because Node Template is not supported by ASDC Team + + #############REQUIREMENTS of vCE - ########################### + requirements: + - nat: # A vCE may have a requirement to connect to a VNF offering this capability, during service composition + capability: org.openecomp.capabilities.nfv.VNF.NetworkAddressTranslationCapability + node: org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU + relationship: org.openecomp.relationships.nfv.CnnectsToNAT + occurrences: [0, 1] + + - pat: # A vCE may have a requirement to connect to a VNF offering this capability, during service composition + capability: org.openecomp.capabilities.nfv.VNF.PortAddressTranslationCapability + node: org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU #paharoni - renamed from org.openecomp.resource.nfv.VDU.PortAddressTranslationCategoryVDU. Resource name can be up to 50 chars + relationship: org.openecomp.relationships.nfv.CnnectsToPAT + occurrences: [0, 1] + + + - firewall: # A vCE may have a requirement to connect to a VNF offering this capability, during service composition + capability: org.openecomp.capabilities.nfv.VNF.FirewallCapability + node: org.openecomp.resource.nfv.VDU.FirewallCategoryVDU + relationship: org.openecomp.relationships.nfv.CnnectsToFirewall + occurrences: [0, 1] + + - dhcp: # A vCE may have a requirement to connect to a VNF offering this capability, during service composition + capability: org.openecomp.capabilities.nfv.VNF.DHCPCapability + node: org.openecomp.resource.nfv.VDU.DHCPCategoryVDU + relationship: org.openecomp.relationships.nfv.CnnectsToDHCP + occurrences: [0, 1] + + - dns: # A vCE may have a requirement to connect to a VNF offering this capability, during service composition + capability: org.openecomp.capabilities.nfv.VNF.DNSCapability + node: org.openecomp.resource.nfv.VDU.DNSCategoryVDU + relationship: org.openecomp.relationships.nfv.CnnectsToDNS + occurrences: [0, 1] + + - hosted_on: # A vCE needs to be hosted in a VM + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn + occurrences: [1, 1] #default + + + + +######################################################################################################## +###################### vCE_Brocade_VNF Node TYPE ##################################################### +########### IN THE ABSENCE OF NODE TEMPLATE, the vCE_Brocade_VNF Node Type is modeled as REQUIRING: ##### +########### 1. vce_Brocade_VDU Node +########### 2. oam_vlan_connector Node +########### 3. ipag_vlan_connector Node +########### 4. vpe_vlan_connector Node +######################################################################################################## + + org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF: + derived_from: org.openecomp.resource.nfv.VNF + requirements: + - vce_brocade_vdu: + capability: org.openecomp.capabilities.nfv.VCE_Brocade_Routing + node: org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU + occurrences: [1, 1] + + - oam_vlan_connector: + capability: org.openecomp.capabilities.nfv.OAM_VLAN_Connector + node: org.openecomp.resource.nfv.CP.OAM_VLAN_Connector + occurrences: [1, 1] + + - vpe_vlan_connector: + capability: org.openecomp.capabilities.nfv.VPE_VLAN_Connector + node: org.openecomp.resource.nfv.CP.VPE_VLAN_Connector + occurrences: [1, 1] + + - ipag_vlan_connector: + capability: org.openecomp.capabilities.nfv.IPAG_VLAN_Connector + node: org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector + occurrences: [1, 1] + +################################################################## +###################### ASDC NAT VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU: #paharoni - renamed from org.openecomp.resource.nfv.VDU.NetworkAddressTranslationCategoryVDU. Resource name can be up to 50 chars in ASDC + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + nat: + type: org.openecomp.capabilities.nfv.VNF.NetworkAddressTranslationCapability + description: This capability has been introduced + ###############Further details described in NAT VNF TOSCA Model + +################################################################## +###################### PAT VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU: #paharoni - renamed from org.openecomp.resource.nfv.VDU.PortAddressTranslationCategoryVDU. Resource name can be up to 50 chars in ASDC + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + pat: + type: org.openecomp.capabilities.nfv.VNF.PortAddressTranslationCapability + description: This capability has been introduced + ###############Further details described in PAT VNF TOSCA Model + +################################################################## +###################### Firewall VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.FirewallCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + firewall: + type: org.openecomp.capabilities.nfv.VNF.FirewallCapability + description: This capability has been introduced + ###############Further details described in Firewall VNF TOSCA Model + +################################################################## +###################### DHCP VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.DHCPCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + dhcp: + type: org.openecomp.capabilities.nfv.VNF.DHCPCapability + description: This capability has been introduced + ###############Further details described in DHCP VNF TOSCA Model + +################################################################## +###################### DNS VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.DNSCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + dns: + type: org.openecomp.capabilities.nfv.VNF.DNSCapability + description: This capability has been introduced + ###############Further details described in DNS VNF TOSCA Model + + +########################################################################################### +###################### CAPABILITY TYPE DEFINITIONS ###################################### +########################################################################################### + +capability_types: + ##################################################################################### + ###################### TOSCA Capability: VirtualBindable ########################## + ##################################################################################### + tosca.capabilities.nfv.VDU.VirtualBindable: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VDU] + + ##################################################################################### + ############################ ASDC Capability: VirtualBindable ##################### + ##################################################################################### + org.openecomp.capabilities.nfv.VDU.VirtualBindable: + derived_from: tosca.capabilities.nfv.VDU.VirtualBindable + valid_source_types: [org.openecomp.resource.nfv.VDU] + + ##################################################################################### + ##################### TOSCA Capability: VirtualLinkable ########################## + ##################################################################################### + tosca.capabilities.nfv.VirtualLinkable: + derived_from: tosca.capabilities.Root ##paharoni - changed from tosca.capabilities.nfv.VirtualLinkable - cannot derive from itself + valid_source_types: [org.openecomp.resource.nfv.VL] + + ##################################################################################### + ############################ ASDC Capability: VirtualLinkable ##################### + ##################################################################################### + org.openecomp.capabilities.nfv.VirtualLinkable: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VL] + + ##################################################################################### + ############################ Capability: HighAvailability ########################## + ##################################################################################### + tosca.capabilities.nfv.HA: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VDU] + + ##################################################################################### + ######################Capability: Generic asdc capability ########################## + ##################################################################################### + org.openecomp.capabilities.Root: + derived_from: tosca.capabilities.Root + + ##################################################################################### + ############################ Capability: GENERIC ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.RoutingCapability: + derived_from: org.openecomp.capabilities.Root + properties: + routing_type: + type: string + description: some basic routing descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.RoutingCategoryVDU] + + ##################################################################################### + ############################ Capability: CE ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.CERouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: PE ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.PERouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: P ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.PRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: BGP ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.BGPRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: STATIC ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.StaticRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: Network Address Translation ############### + ##################################################################################### + org.openecomp.capabilities.nfv.VNF.NetworkAddressTranslationCapability: + derived_from: org.openecomp.capabilities.Root + properties: + nat_type: + type: string + description: some basic NAT descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU] + + ##################################################################################### + ############################ Capability: Port Address Translation ############### + ##################################################################################### + org.openecomp.capabilities.nfv.VNF.PortAddressTranslationCapability: + derived_from: org.openecomp.capabilities.Root + properties: + pat_type: + type: string + description: some basic PAT descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU] + + ##################################################################################### + ############################ Capability: FIREWALL ############### + ##################################################################################### + org.openecomp.capabilities.nfv.VNF.FirewallCapability: + derived_from: org.openecomp.capabilities.Root + properties: + firewall_type: + type: string + description: some basic Firewall Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.FirewallCategoryVDU] + + ##################################################################################### + ############################ Capability: DHCP ############### + ##################################################################################### + org.openecomp.capabilities.nfv.VNF.DHCPCapability: + derived_from: org.openecomp.capabilities.Root + properties: + dhcp_type: + type: string + description: some basic DHCP Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.DHCPCategoryVDU] + + ##################################################################################### + ############################ Capability: DNS ############### + ##################################################################################### + org.openecomp.capabilities.nfv.VNF.DNSCapability: + derived_from: org.openecomp.capabilities.Root + properties: + dns_type: + type: string + description: some basic DNS Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.VDU.DNSCategoryVDU] + + ##################################################################################### + ############################ Capability: vCE Brocade ROUTING ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC BROCADE VDU ########### + ##################################################################################### + org.openecomp.capabilities.nfv.vCE_Brocade_Routing: + derived_from: org.openecomp.capabilities.nfv.CERouting + valid_source_types: [org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU] + + ##################################################################################### + ############################ Capability: OAM VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.OAM_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.CP.OAM_VLAN_Connector] + + ##################################################################################### + ############################ Capability: IPAG VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.IPAG_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector] + + ##################################################################################### + ############################ Capability: VPE VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.VPE_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.CP.VPE_VLAN_Connector] + +########################################################################################### +###################### RELATIONSHIP TYPE DEFINITIONS ################################### +########################################################################################### + +relationship_types: +##################################################################################### +######################TOSCA Relationship: VirtualBindsTo ########################## +##################################################################################### + tosca.relationships.nfv.VirtualBindsTo: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between VDU and CP Node Types + valid_target_types: [tosca.capabilities.nfv.VDU.VirtualBindable] + +##################################################################################### +######################ASDC Relationship: VirtualBindsTo ########################## +##################################################################################### + org.openecomp.relationships.nfv.VirtualBindsTo: + derived_from: tosca.relationships.nfv.VirtualBindsTo + description: Represents the relationsHIP between VDU and CP Node Types + valid_target_types: [org.openecomp.capabilities.nfv.VDU.VirtualBindable] + +##################################################################################### +##################### TOSCA Relationship: VirtualLinksTo ########################## +##################################################################################### + tosca.relationships.nfv.VirtualLinksTo: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between CP and VL Node Types + valid_target_types: [tosca.capabilities.nfv.VirtualLinkable] + +##################################################################################### +##################### ASDC Relationship: VirtualLinksTo ########################## +##################################################################################### + org.openecomp.relationships.nfv.VirtualLinksTo: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between CP and VL Node Types + valid_target_types: [org.openecomp.capabilities.nfv.VirtualLinkable] + +##################################################################################### +###################### ASDC Relationship: ConnectsToNAT ########################## +##################################################################################### + org.openecomp.relationships.nfv.CnnectsToNAT: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between a VNF and NAT capable Node + #properties: + #attributes: + #interfaces: + valid_target_types: [org.openecomp.capabilities.nfv.VNF.NetworkAddressTranslationCapability] + +##################################################################################### +###################### ASDC Relationship: ConnectsToPAT ########################## +##################################################################################### + org.openecomp.relationships.nfv.CnnectsToPAT: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between a VNF and PAT capable Node + #properties: + #attributes: + #interfaces: + valid_target_types: [org.openecomp.capabilities.nfv.VNF.PortAddressTranslationCapability] + +##################################################################################### +###################### ASDC Relationship: ConnectsToFirewall ########################## +##################################################################################### + org.openecomp.relationships.nfv.CnnectsToFirewall: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between a VNF and Firewall capable Node + #properties: + #attributes: + #interfaces: + valid_target_types: [org.openecomp.capabilities.nfv.VNF.FirewallCapability] + +##################################################################################### +###################### ASDC Relationship: ConnectsToDNS ########################## +##################################################################################### + org.openecomp.relationships.nfv.CnnectsToDNS: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between a VNF and DNS capable Node + #properties: + #attributes: + #interfaces: + valid_target_types: [org.openecomp.capabilities.nfv.VNF.DNSCapability] + +##################################################################################### +###################### ASDC Relationship: ConnectsToDHCP ########################## +##################################################################################### + org.openecomp.relationships.nfv.CnnectsToDHCP: + derived_from: tosca.relationships.ConnectsTo + description: Represents the relationsHIP between a VNF and DHCP capable Node + #properties: + #attributes: + #interfaces: + valid_target_types: [org.openecomp.capabilities.nfv.VNF.DHCPCapability] + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/capabilityTypes.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/capabilityTypes.zip new file mode 100644 index 0000000000..75f56d4c76 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/capabilityTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/importVceBrocade.sh b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/importVceBrocade.sh new file mode 100644 index 0000000000..76f567bfe2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/importVceBrocade.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function addResource() { + + ELEMENT_NAME=$1 + echo -e "###################### Adding Element ${ELEMENT_NAME} Start ######################" + CURRENT_ZIP_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.zip + CURRENT_JSON_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.json + sed -i 's/"userId": ".*",/"userId": "'${ATT_UID}'",/' ${CURRENT_JSON_FILE} + JSON_CONTENT=`paste -s ${CURRENT_JSON_FILE}` + http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F resourceMetadata="${JSON_CONTENT}" -F resourceZip=@${CURRENT_ZIP_FILE} -H USER_ID:${ATT_UID} ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/upload/multipart) + if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding Element ${ELEMENT_NAME} End ########################\n\n\n" + elif [ ${http_code} -eq 409 ]; then + echo -e "\n###################### Already exists Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + exit 1 + fi +} +if [ $# -lt 3 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 +ATT_UID=$3 +NO_CAPS=$4 + +if [ "$NO_CAPS" = "nocaps" ]; then + echo "Skipping Caps import..." +else + #Add The CapabilityTypes + http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F capabilityTypeZip=@capabilityTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/capability) + if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The CapabilityTypes status code:${http_code} End ########################\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 + else + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 + fi + #Add The InterfaceLifecycleTypes + #http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F interfaceLifecycleTypeZip=@interfaceLifecycleTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/interfaceLifecycle) + #if [ ${http_code} -eq 201 ]; then + # echo -e "\n###################### Adding The InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + #elif [ ${http_code} -eq 409 ]; then + # echo -e "\n###################### Already exists InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + #elif [ ${http_code} -eq 500 ]; then + # echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + # exit 1 + #else + # echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + # exit 1 + #fi +fi + +addResource "tosca.nodes.nfv.CP" +addResource "tosca.nodes.nfv.VDU" + +addResource "org.openecomp.resource.nfv.CP" +addResource "org.openecomp.resource.nfv.VDU" + +addResource "org.openecomp.resource.nfv.vdu.RoutingCategoryVDU" +addResource "org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU" +addResource "org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector" +addResource "org.openecomp.resource.nfv.cp.OAM_VLAN_Connector" +addResource "org.openecomp.resource.nfv.cp.VPE_VLAN_Connector" + +#addResource "tosca.nodes.nfv.VL" +#addResource "tosca.nodes.nfv.VNF" +#addResource "org.openecomp.resource.nfv.VL" +#addResource "org.openecomp.resource.nfv.VNF" +#addResource "org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU" +#addResource "org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF" +#addResource "org.openecomp.resource.nfv.VDU.DHCPCategoryVDU" +#addResource "org.openecomp.resource.nfv.VDU.DNSCategoryVDU" +#addResource "org.openecomp.resource.nfv.VDU.FirewallCategoryVDU" +#addResource "org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU" + + +exit 0 diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.json new file mode 100644 index 0000000000..390fda0257 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector", + "description": "Represents a virtual or physical interface between the NFV and the LAN.", + "resourceIconPath": "port", + "category": "Network Layer 2-3/LAN Connectors", + "tags": [ + "org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector", "LAN Connector" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.yaml new file mode 100644 index 0000000000..03ecc8ea3e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.yaml @@ -0,0 +1,48 @@ +################################################################## + ############### IPAG VLAN Connector CP Node ##################### + ################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + ipag_network_name: + type: string + + ipag_network_type: + type: string + + ipag_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.IPAG_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.vdu.VirtualBindable + #node: org.openecomp.asdc.nodes.vCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.asdc.nodes.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.zip new file mode 100644 index 0000000000..31ddc8cbf6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector/org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.json new file mode 100644 index 0000000000..b4f9a8f03e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.cp.OAM_VLAN_Connector.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.cp.OAM_VLAN_Connector", + "description": "Represents a virtual or physical interface between the NFV and the OAM.", + "resourceIconPath": "port", + "category": "Network Layer 2-3/LAN Connectors", + "tags": [ + "org.openecomp.resource.nfv.cp.OAM_VLAN_Connector", "OAM Connector", "OAM" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.yaml new file mode 100644 index 0000000000..6f7c86f676 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.yaml @@ -0,0 +1,48 @@ +################################################################## + ############### OAM VLAN Connector CP Node ##################### + ################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.cp.OAM_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + oam_network_name: + type: string + + oam_network_type: + type: string + + oam_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.OAM_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.vdu.VirtualBindable + #node: org.openecomp.asdc.nodes.vCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.asdc.nodes.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.zip new file mode 100644 index 0000000000..2076fb039b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector/org.openecomp.resource.nfv.CP.OAM_VLAN_Connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.json new file mode 100644 index 0000000000..819335d0f3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.cp.VPE_VLAN_Connector.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.cp.VPE_VLAN_Connector", + "description": "Represents a virtual or physical interface between the NFV and the WAN.", + "resourceIconPath": "port", + "category": "Network Layer 2-3/WAN Connectors", + "tags": [ + "org.openecomp.resource.nfv.cp.VPE_VLAN_Connector", "WAN Connector" + ] +} diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.yaml new file mode 100644 index 0000000000..f5f7380374 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.yaml @@ -0,0 +1,48 @@ +################################################################## + ############### VPE VLAN Connector CP Node ##################### + ################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.cp.VPE_VLAN_Connector: + derived_from: org.openecomp.resource.nfv.CP + properties: + vpe_network_name: + type: string + + vpe_network_type: + type: string + + vpe_network_uuid: + type: string + + vlan_segment_ids: + type: list + entry_schema: + type: string + description: list of segmentation Ids. + + + #attributes: + capabilities: + dummy_capability: + type: org.openecomp.capabilities.nfv.VPE_VLAN_Connector + description: This capability has been introduced to model this Connector as a component of VCE VNF, because Node Template is not supported by ASDC Team + + requirements: + - virtualBindingRequirement: + capability: org.openecomp.capabilities.nfv.vdu.VirtualBindable + #node: org.openecomp.asdc.nodes.vCE_Brocade_VDU + relationship: org.openecomp.relationships.nfv.VirtualBindsTo + occurrences: [1, 1] #default + + - virtualLinkingrequirement: + capability: org.openecomp.capabilities.nfv.VirtualLinkable + #node: org.openecomp.asdc.nodes.nfv.VL + relationship: org.openecomp.relationships.nfv.VirtualLinksTo + occurrences: [1, 1] #default + + #interfaces: + #standard: + #configure: + #implementation: configure.sh + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.zip new file mode 100644 index 0000000000..5808fc9338 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector/org.openecomp.resource.nfv.CP.VPE_VLAN_Connector.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.json new file mode 100644 index 0000000000..76c3eabc26 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.CP.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.CP", + "description": "ATT CP element", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "org.openecomp.resource.nfv.CP" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.yaml new file mode 100644 index 0000000000..ba6bda0c8b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.yaml @@ -0,0 +1,7 @@ +################################################################## +############################ ASDC CP Node ##################### +################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.CP: + derived_from: tosca.nodes.nfv.CP \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.zip new file mode 100644 index 0000000000..0fd24994f9 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.CP/org.openecomp.resource.nfv.CP.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.json new file mode 100644 index 0000000000..95673b81ff --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.vdu.RoutingCategoryVDU.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.vdu.RoutingCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Infrastructure", + "tags": [ + "org.openecomp.resource.nfv.vdu.RoutingCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.yaml new file mode 100644 index 0000000000..5bbc64cb2c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.yaml @@ -0,0 +1,7 @@ +################################################################## +###################### ASDC Routing Category VDU ################# +################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.vdu.RoutingCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.zip new file mode 100644 index 0000000000..3853a341b0 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU/org.openecomp.resource.nfv.VDU.RoutingCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.json new file mode 100644 index 0000000000..91b692357b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU", + "description": "Brocade Vyatta 5600 vRouter used as Virtual Customer Edge (vCE) delivers high throughput on general-purpose x86 server. it is based on open standards, open protocols and is fully compatible with legacy networks. It has advanced functionality to be able to deploy in a variety of network environments.", + "resourceIconPath": "brocade", + "category": "Network Layer 2-3/Router", + "tags": [ + "org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU", "vCE", "Brocade", "Gamma" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.yaml new file mode 100644 index 0000000000..2ba732ab3b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.yaml @@ -0,0 +1,156 @@ +################################################################## +###################### vCE_Brocade_VDU Node TYPE ############### +################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU: + derived_from: org.openecomp.resource.nfv.vdu.RoutingCategoryVDU + description: Definition of VCE Brocade VDU + properties: + vnf_category: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + vce_type: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + vendor: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + version: + type: string + description: input provided at RESOURCE INJECTION TIME in ASDC TOOL + image_id: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer -vCE image used to boot VM + flavor_id: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - VM Size, SMALL, MEDIUM, LARGE + username: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer -login user Id of Router + password: + type: string + description: I Input provided at DESIGN TIME by Service Composer or Designer - password for login + domain_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - login domain + time_zone: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - time zone to set for vCE + login_session_timeout: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer or (perhaps pre-defined for each Cloud Region) - user login session timeout + ipag_vlan_bandwidth: + type: integer + description: Input provided at DESIGN TIME by Service Composer or Designer - bandwidth allocation of customer VLAN requested by customer + vpe_vlan_interface_qos_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - QoS Policy name to be applied to this interface + ipag_vlan_interface_qos_name: + type: string + description: Input provided at DESIGN TIME by Service Composer or Designer - QoS Policy name to be applied to this interface + hostname: + type: string + description: Input provided at RUN TIME by Cloud-PO - Host VM is created first and this value is input when the vCE image is later on installed by Cloud-PO + host_ip: + type: string + description: Input provided at RUN TIME by Cloud-PO - Host VM IP + availability_zone: + type: string + description: Input provided at RUN TIME by Cloud-PO - Cloud availability zone where VM is created + oam_loopback_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - OAM Network is pre-created - already exists in Data Center + ipag_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - IPAG VLAN Network is created by Cloud-PO before the vCE is created or installed + vpe_vlan_ip_address: + type: string + description: Input provided at RUN TIME by Cloud-PO - VPE VLAN Network is created by Cloud-PO before the vCE is created / installed + vpe_vlan_id: + type: string + description: Input provided at RUN TIME by Cloud-PO - VLAN Id is created first by Cloud-PO. It is required to apply VPE QoS Policy + ipag_vlan_id: + type: string + description: Input provided at RUN TIME by Cloud-PO - VLAN Id is created first by Cloud-PO. It is required to apply IPAG QoS Policy + oam_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + vpe_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + ipag_vlan_interface_name: + type: string + description: Input provided at RUN TIME by Cloud-PO - This interfce is created first by Cloud-PO. This is the interface to which QoS policy is applied + #############ATTRIBUTES of vCE - These values are outputted by Cloud-PO when vCE is created / installed ############## + attributes: + vce_name: + type: string + description: Name assigned to vCE by Cloud-PO + oam_loopback_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to OAM VLAN + ipag_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to IPAG VLAN + vpe_vlan_ipaddres: + type: string + description: IP Address assigned by Cloud-PO to VPE VLAN + vnf_id: + type: string + description: unique id assigned to VNF by Cloud-PO - used for AAI metadata + + #############CAPABILITIES of vCE - ######################### + capabilities: + ce_routing_capability: + type: org.openecomp.capabilities.nfv.CERouting + description: This is the base capability of vCE + occurrences: [1, UNBOUNDED] # default + + static_routing: + type: org.openecomp.capabilities.nfv.StaticRouting + description: This is the optional capability of the vCE + occurrences: [0, UNBOUNDED] + + bgp_routing: + type: org.openecomp.capabilities.nfv.BGPRouting + description: This is the optional capability of the vCE + occurrences: [0, UNBOUNDED] + + virtual_bindable: + type: org.openecomp.capabilities.nfv.vdu.VirtualBindable + description: This is the internal capability of the VDU to support Binding to Connection Points + occurrences: [1, UNBOUNDED] + + dummy_capability: + type: org.openecomp.capabilities.nfv.VCE_Brocade_Routing + description: This capability has been introduced to model VCE VDU as a component of VCE VNF, because Node Template is not supported by ASDC Team + + #############REQUIREMENTS of vdu - ########################### + requirements: + - oam_vlan_connector: + capability: org.openecomp.capabilities.nfv.OAM_VLAN_Connector + node: org.openecomp.resource.nfv.cp.OAM_VLAN_Connector + relationship: tosca.relationships.ConnectsTo + occurrences: [1, 1] + + - vpe_vlan_connector: + capability: org.openecomp.capabilities.nfv.VPE_VLAN_Connector + node: org.openecomp.resource.nfv.cp.VPE_VLAN_Connector + relationship: tosca.relationships.ConnectsTo + occurrences: [1, 1] + + - ipag_vlan_connector: + capability: org.openecomp.capabilities.nfv.IPAG_VLAN_Connector + node: org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector + relationship: tosca.relationships.ConnectsTo + occurrences: [1, 1] + + - hosted_on: # A vCE needs to be hosted in a VM + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn + occurrences: [1, 1] #default + + + diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.zip new file mode 100644 index 0000000000..1d5b041a88 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU/org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.json new file mode 100644 index 0000000000..9623090743 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.yaml", + "contactId": "jh0003", + "name": "org.openecomp.resource.nfv.VDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "org.openecomp.resource.nfv.VDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.yaml new file mode 100644 index 0000000000..f5e5aa9195 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.yaml @@ -0,0 +1,5 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.nfv.VDU: + derived_from: tosca.nodes.nfv.VDU + description: A VDU is a compute component of VNF \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.zip new file mode 100644 index 0000000000..569a8b2a44 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/org.openecomp.resource.nfv.VDU/org.openecomp.resource.nfv.VDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.json new file mode 100644 index 0000000000..e17b474385 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VDU.DHCPCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VDU.DHCPCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml new file mode 100644 index 0000000000..64f150e73e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.yaml @@ -0,0 +1,10 @@ +################################################################## +###################### DHCP VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.DHCPCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + dhcp: + type: org.openecomp.capabilities.nfv.VNF.DHCPCapability + description: This capability has been introduced + ###############Further details described in DHCP VNF TOSCA Model \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.zip new file mode 100644 index 0000000000..d60b15698c Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU/org.openecomp.resource.nfv.VDU.DHCPCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.json new file mode 100644 index 0000000000..8c419d17d3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VDU.DNSCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VDU.DNSCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml new file mode 100644 index 0000000000..58aa9f3e81 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.yaml @@ -0,0 +1,10 @@ +################################################################## +###################### DNS VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.DNSCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + dns: + type: org.openecomp.capabilities.nfv.VNF.DNSCapability + description: This capability has been introduced + ###############Further details described in DNS VNF TOSCA Model \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.zip new file mode 100644 index 0000000000..e927ad3d2a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.DNSCategoryVDU/org.openecomp.resource.nfv.VDU.DNSCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.json new file mode 100644 index 0000000000..6c0b033552 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VDU.FirewallCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VDU.FirewallCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml new file mode 100644 index 0000000000..f22dfcb35e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.yaml @@ -0,0 +1,10 @@ +################################################################## +###################### Firewall VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.FirewallCategoryVDU: + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + firewall: + type: org.openecomp.capabilities.nfv.VNF.FirewallCapability + description: This capability has been introduced + ###############Further details described in Firewall VNF TOSCA Model \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.zip new file mode 100644 index 0000000000..548b64ed17 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU/org.openecomp.resource.nfv.VDU.FirewallCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.json new file mode 100644 index 0000000000..be8f6fd133 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml new file mode 100644 index 0000000000..133ccc33b5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.yaml @@ -0,0 +1,10 @@ +################################################################## +###################### ASDC NAT VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU: #paharoni - renamed from org.openecomp.resource.nfv.VDU.NetworkAddressTranslationCategoryVDU. Resource name can be up to 50 chars in ASDC + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + nat: + type: org.openecomp.capabilities.nfv.VNF.NetworkAddressTranslationCapability + description: This capability has been introduced + ###############Further details described in NAT VNF TOSCA Model \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.zip new file mode 100644 index 0000000000..93ef2905f6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU/org.openecomp.resource.nfv.VDU.NetworkAddrCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.json new file mode 100644 index 0000000000..26a2dd9a08 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml new file mode 100644 index 0000000000..04aad2f848 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.yaml @@ -0,0 +1,10 @@ +################################################################## +###################### PAT VDU Node TYPE ############### +################################################################## + org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU: #paharoni - renamed from org.openecomp.resource.nfv.VDU.PortAddressTranslationCategoryVDU. Resource name can be up to 50 chars in ASDC + derived_from: org.openecomp.resource.nfv.VDU + capabilities: #paharoni - added to connect to VCE_Brocade_VDU + pat: + type: org.openecomp.capabilities.nfv.VNF.PortAddressTranslationCapability + description: This capability has been introduced + ###############Further details described in PAT VNF TOSCA Model \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.zip new file mode 100644 index 0000000000..0bad67331b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU/org.openecomp.resource.nfv.VDU.PortAddrCategoryVDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.json new file mode 100644 index 0000000000..7ea24e09f5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VL.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VL", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "org.openecomp.resource.nfv.VL" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.yaml new file mode 100644 index 0000000000..0709072040 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.yaml @@ -0,0 +1,7 @@ +################################################################## +###################### ASDC VL Node TYPE ###################### +################################################################## + org.openecomp.resource.nfv.VL: + derived_from: tosca.nodes.nfv.VL + + diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.zip new file mode 100644 index 0000000000..b6d19de95b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VL/org.openecomp.resource.nfv.VL.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.json new file mode 100644 index 0000000000..6e68301bcb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Network Elements", + "tags": [ + "org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml new file mode 100644 index 0000000000..bbd0fe0945 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.yaml @@ -0,0 +1,32 @@ +######################################################################################################## +###################### vCE_Brocade_VNF Node TYPE ##################################################### +########### IN THE ABSENCE OF NODE TEMPLATE, the vCE_Brocade_VNF Node Type is modeled as REQUIRING: ##### +########### 1. vce_Brocade_VDU Node +########### 2. oam_vlan_connector Node +########### 3. ipag_vlan_connector Node +########### 4. vpe_vlan_connector Node +######################################################################################################## + + org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF: + derived_from: org.openecomp.resource.nfv.VNF + requirements: + - vce_brocade_vdu: + capability: org.openecomp.capabilities.nfv.VCE_Brocade_Routing + node: org.openecomp.resource.nfv.VDU.VCE_Brocade_VDU + occurrences: [1, 1] + + - oam_vlan_connector: + capability: org.openecomp.capabilities.nfv.OAM_VLAN_Connector + node: org.openecomp.resource.nfv.CP.OAM_VLAN_Connector + occurrences: [1, 1] + + - vpe_vlan_connector: + capability: org.openecomp.capabilities.nfv.VPE_VLAN_Connector + node: org.openecomp.resource.nfv.CP.VPE_VLAN_Connector + occurrences: [1, 1] + + - ipag_vlan_connector: + capability: org.openecomp.capabilities.nfv.IPAG_VLAN_Connector + node: org.openecomp.resource.nfv.CP.IPAG_VLAN_Connector + occurrences: [1, 1] + diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.zip new file mode 100644 index 0000000000..158f917ee8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF/org.openecomp.resource.nfv.VNF.VCE_Brocade_VNF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.json new file mode 100644 index 0000000000..18ce8bbca5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "org.openecomp.resource.nfv.VNF.yaml", + "contactId": "jh0003", + "resourceName": "org.openecomp.resource.nfv.VNF", + "description": "Node Type that represents a Module", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "org.openecomp.resource.nfv.VNF" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.yaml new file mode 100644 index 0000000000..6872cfc7fb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.yaml @@ -0,0 +1,5 @@ +################################################################## +###################### ASDC VNF Node TYPE ###################### +################################################################## + org.openecomp.resource.nfv.VNF: + derived_from: tosca.nodes.nfv.VNF diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.zip new file mode 100644 index 0000000000..2b8e33d71a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/org.openecomp.resource.nfv.VNF/org.openecomp.resource.nfv.VNF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.json new file mode 100644 index 0000000000..e5bcfb204e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.json @@ -0,0 +1,11 @@ +{ + "payloadName": "tosca.nodes.nfv.VL.yaml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.nfv.VL", + "description": "TOSCA VL base element", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "tosca.nodes.nfv.VL" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.yaml new file mode 100644 index 0000000000..2fbcc9c46d --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.yaml @@ -0,0 +1,16 @@ +################################################################## + ############## TOSCA VL Node Type ####################### + ################################################################## + tosca.nodes.nfv.VL: + derived_from: tosca.nodes.Root + properties: + vendor: + type: string + required: false + description: name of the vendor who provides this VL + + capabilities: + virtuallinkable: + type: tosca.capabilities.nfv.VirtualLinkable + occurrences: [1, UNBOUNDED] # this is default + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.zip new file mode 100644 index 0000000000..fc7ba8d27b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VL/tosca.nodes.nfv.VL.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.json new file mode 100644 index 0000000000..bd6047734c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.json @@ -0,0 +1,11 @@ +{ + "payloadName": "tosca.nodes.nfv.VNF.yaml", + "contactId": "jh0003", + "resourceName": "tosca.nodes.nfv.VNF", + "description": "TOSCA VNF base element", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "tosca.nodes.nfv.VNF" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.yaml new file mode 100644 index 0000000000..5cf9453884 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.yaml @@ -0,0 +1,30 @@ +################################################################## +################### TOSCA VNF Node ########################## +################################################################## +tosca.nodes.nfv.VNF: + derived_from: tosca.nodes.Root + properties: + vnf_category: + type: string + description: Router, FW, LB, DNS are example categories + id: + type: string + description: ID of this VNF + vendor: + type: string + description: name of the vendor who provides this VNF + version: + type: version + description: version of the software for this VNF + #device_config: + # type: map + #entry_schema: + # type: string + #default: + # p1: 1 + # p2: 2 + #p3: 3 + #requirements: + # - virtualLink: + #capability: tosca.capabilities.nfv.VirtualLinkable + #occurrences: [1, UNBOUNDED] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.zip new file mode 100644 index 0000000000..3c10c5f388 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/resourcesToFix/tosca.nodes.nfv.VNF/tosca.nodes.nfv.VNF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.json new file mode 100644 index 0000000000..bf82a9a390 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.json @@ -0,0 +1,11 @@ +{ + "payloadName": "tosca.nodes.nfv.CP.yaml", + "contactId": "jh0003", + "name": "tosca.nodes.nfv.CP", + "description": "TOSCA CP base element", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "tosca.nodes.nfv.CP" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.yaml new file mode 100644 index 0000000000..271a4bf026 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.yaml @@ -0,0 +1,24 @@ + ################################################################## + ####################### TOSCA CP Node ########################## + ################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.nfv.CP: + derived_from: tosca.nodes.Root + properties: + type: + type: string + required: false + requirements: + - virtualbinding: + capability: tosca.capabilities.nfv.vdu.VirtualBindable + occurrences: [1, 1] #this is default + + - virtuallink: + capability: tosca.capabilities.nfv.VirtualLinkable + occurrences: [1, 1] #this is default + + attributes: + ip_address: + type: string + # required: false \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.zip new file mode 100644 index 0000000000..2d7281a915 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.CP/tosca.nodes.nfv.CP.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.json b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.json new file mode 100644 index 0000000000..2ab0340e59 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.json @@ -0,0 +1,11 @@ +{ + "payloadName": "tosca.nodes.nfv.VDU.yaml", + "contactId": "jh0003", + "name": "tosca.nodes.nfv.VDU", + "description": "TOSCA VDU base element", + "resourceIconPath": "defaulticon", + "category": "Generic/Abstract", + "tags": [ + "tosca.nodes.nfv.VDU" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.yaml new file mode 100644 index 0000000000..d1cba804e6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.yaml @@ -0,0 +1,28 @@ + ################################################################## + ###################### TOSCA VDU Node ########################## + ################################################################## +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.nfv.VDU: + derived_from: tosca.nodes.SoftwareComponent + #properties: + + capabilities: + high_availability: + type: tosca.capabilities.nfv.HA + occurrences: [1, UNBOUNDED] # this is default + + virtual_binding: + type: tosca.capabilities.nfv.vdu.VirtualBindable + occurrences: [1, UNBOUNDED] # this is default + + requirements: + - high_availability: + capability: tosca.capabilities.nfv.HA + occurrences: [0,1] + + - host: ##Is hosted in a VM + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn + occurrences: [1, 1] #this is default \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.zip b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.zip new file mode 100644 index 0000000000..3ba4eb7d80 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/tosca.nodes.nfv.VDU/tosca.nodes.nfv.VDU.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/vce.brocade.capabilities.yaml b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/vce.brocade.capabilities.yaml new file mode 100644 index 0000000000..af55754cf3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource-VCE-Brocade/vce.brocade.capabilities.yaml @@ -0,0 +1,191 @@ +##################################################################################### + ###################### TOSCA Capability: VirtualBindable ########################## + ##################################################################################### + tosca.capabilities.nfv.vdu.VirtualBindable: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VDU] + + ##################################################################################### + ##################### TOSCA Capability: VirtualLinkable ########################## + ##################################################################################### + tosca.capabilities.nfv.VirtualLinkable: + derived_from: tosca.capabilities.Root ##paharoni - changed from tosca.capabilities.nfv.VirtualLinkable - cannot derive from itself + valid_source_types: [org.openecomp.resource.nfv.VL] + + ##################################################################################### + ############################ Capability: HighAvailability ########################## + ##################################################################################### + tosca.capabilities.nfv.HA: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VDU] + + ##################################################################################### + ############################ ASDC Capability: VirtualBindable ##################### + ##################################################################################### + org.openecomp.capabilities.nfv.vdu.VirtualBindable: + derived_from: tosca.capabilities.nfv.vdu.VirtualBindable + valid_source_types: [org.openecomp.resource.nfv.VDU] + + + + ##################################################################################### + ############################ ASDC Capability: VirtualLinkable ##################### + ##################################################################################### + org.openecomp.capabilities.nfv.VirtualLinkable: + derived_from: tosca.capabilities.Root + valid_source_types: [tosca.nodes.nfv.VL] + + + + ##################################################################################### + ######################Capability: Generic asdc capability ########################## + ##################################################################################### + org.openecomp.capabilities.Root: + derived_from: tosca.capabilities.Root + + ##################################################################################### + ############################ Capability: GENERIC ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.RoutingCapability: + derived_from: org.openecomp.capabilities.Root + properties: + routing_type: + type: string + description: some basic routing descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.RoutingCategoryVDU] + + ##################################################################################### + ############################ Capability: CE ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.CERouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: PE ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.PERouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: P ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.PRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: BGP ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.BGPRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: STATIC ROUTING ########################## + ##################################################################################### + org.openecomp.capabilities.nfv.StaticRouting: + derived_from: org.openecomp.capabilities.nfv.RoutingCapability + + ##################################################################################### + ############################ Capability: Network Address Translation ############### + ##################################################################################### + org.openecomp.capabilities.nfv.vnf.NetworkAddressTranslationCapability: + derived_from: org.openecomp.capabilities.Root + properties: + nat_type: + type: string + description: some basic NAT descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.NetworkAddressTranslationCategoryVDU] + + ##################################################################################### + ############################ Capability: Port Address Translation ############### + ##################################################################################### + org.openecomp.capabilities.nfv.vnf.PortAddressTranslationCapability: + derived_from: org.openecomp.capabilities.Root + properties: + pat_type: + type: string + description: some basic PAT descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.PortAddressTranslationCategoryVDU] + + ##################################################################################### + ############################ Capability: FIREWALL ############### + ##################################################################################### + org.openecomp.capabilities.nfv.vnf.FirewallCapability: + derived_from: org.openecomp.capabilities.Root + properties: + firewall_type: + type: string + description: some basic Firewall Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.FirewallCategoryVDU] + + ##################################################################################### + ############################ Capability: DHCP ############### + ##################################################################################### + org.openecomp.capabilities.nfv.vnf.DHCPCapability: + derived_from: org.openecomp.capabilities.Root + properties: + dhcp_type: + type: string + description: some basic DHCP Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.DHCPCategoryVDU] + + ##################################################################################### + ############################ Capability: DNS ############### + ##################################################################################### + org.openecomp.capabilities.nfv.vnf.DNSCapability: + derived_from: org.openecomp.capabilities.Root + properties: + dns_type: + type: string + description: some basic DNS Capability descriptor, if any??? + constraints: + - valid_values: [TBD1, TBDn] + #attributes: ??? + valid_source_types: [org.openecomp.resource.nfv.vdu.DNSCategoryVDU] + + ##################################################################################### + ############################ Capability: vCE Brocade ROUTING ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC BROCADE VDU ########### + ##################################################################################### + org.openecomp.capabilities.nfv.VCE_Brocade_Routing: + derived_from: org.openecomp.capabilities.nfv.CERouting + valid_source_types: [org.openecomp.resource.nfv.vdu.VCE_Brocade_VDU] + + ##################################################################################### + ############################ Capability: OAM VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.OAM_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.cp.OAM_VLAN_Connector] + + ##################################################################################### + ############################ Capability: IPAG VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.IPAG_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.cp.IPAG_VLAN_Connector] + + ##################################################################################### + ############################ Capability: VPE VLAn Connector ################# DUMMY + ############## THIS IS CAPABILITY IS ONLY OFFERED BY SPECIFIC Connector ########### + ##################################################################################### + org.openecomp.capabilities.nfv.VPE_VLAN_Connector: + derived_from: org.openecomp.capabilities.Root + valid_source_types: [org.openecomp.resource.nfv.cp.VPE_VLAN_Connector] + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/DBMS/DBMS.json b/asdc-tests/src/test/resources/CI/importResource/DBMS/DBMS.json new file mode 100644 index 0000000000..790a30ab42 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/DBMS/DBMS.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-DBMS.yml", + "contactId": "jh0003", + "name": "DBMS", + "description": "Represents a typical relational, SQL Database Management System software component or service.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "DBMS" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.yml b/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.yml new file mode 100644 index 0000000000..28919d38e4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.DBMS: + derived_from: tosca.nodes.SoftwareComponent + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [ tosca.nodes.Database ] diff --git a/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.zip b/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.zip new file mode 100644 index 0000000000..84bddbce47 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/DBMS/normative-types-new-DBMS.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/blockStorage/blockStorage.json b/asdc-tests/src/test/resources/CI/importResource/blockStorage/blockStorage.json new file mode 100644 index 0000000000..72ef5c009b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/blockStorage/blockStorage.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-blockStorage.yml", + "contactId": "jh0003", + "name": "BlockStorage", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "objectStorage", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "BlockStorage" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.yml b/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.yml new file mode 100644 index 0000000000..a82965215f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.BlockStorage: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.zip b/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.zip new file mode 100644 index 0000000000..f690e9d8ea Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/blockStorage/normative-types-new-blockStorage.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.yml b/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.yml new file mode 100644 index 0000000000..58d661b17e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.yml @@ -0,0 +1,148 @@ +tosca.capabilities.Root: + description: The TOSCA root Capability Type all other TOSCA base Capability Types derive from +tosca.capabilities.Attachment: + derived_from: tosca.capabilities.Root +tosca.capabilities.Node: + derived_from: tosca.capabilities.Root +tosca.capabilities.Container: + derived_from: tosca.capabilities.Root + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_or_equal: 1 + cpu_frequency: + type: scalar-unit.frequency + required: false + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB + mem_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB +tosca.capabilities.Endpoint: + derived_from: tosca.capabilities.Root + properties: + protocol: + type: string + default: tcp + port: + type: PortDef + required: false + secure: + type: boolean + default: false + url_path: + type: string + required: false + port_name: + type: string + required: false + network_name: + type: string + required: false + default: PRIVATE + initiator: + type: string + default: source + constraints: + - valid_values: [ source, target, peer ] + ports: + type: map + required: false + constraints: + - min_length: 1 + entry_schema: + type: PortSpec + attributes: + ip_address: + type: string +tosca.capabilities.DatabaseEndpoint: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.Endpoint.Public: + derived_from: tosca.capabilities.Endpoint + properties: + # Change the default network_name to use the first public network found + network_name: PUBLIC + floating: + description: > + indicates that the public address should be allocated from a pool of floating IPs that are associated with the network. + type: boolean + default: false + status: experimental + dns_name: + description: The optional name to register with DNS + type: string + required: false + status: experimental +tosca.capabilities.Endpoint.Admin: + derived_from: tosca.capabilities.Endpoint + # Change Endpoint secure indicator to true from its default of false + properties: + secure: true +tosca.capabilities.Endpoint.Database: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.OperatingSystem: + derived_from: tosca.capabilities.Root + properties: + architecture: + type: string + required: false + type: + type: string + required: false + distribution: + type: string + required: false + version: + type: version + required: false +tosca.capabilities.Scalable: + derived_from: tosca.capabilities.Root + properties: + min_instances: + type: integer + default: 1 + max_instances: + type: integer + default: 1 + default_instances: + type: integer +tosca.capabilities.network.Bindable: + derived_from: tosca.capabilities.Node + + +tosca.capabilities.Container.Docker: + derived_from: tosca.capabilities.Container + properties: + version: + type: list + required: false + entry_schema: version + publish_all: + type: boolean + default: false + required: false + publish_ports: + type: list + entry_schema: PortSpec + required: false + expose_ports: + type: list + entry_schema: PortSpec + required: false + volumes: + type: list + entry_schema: string + required: false +tosca.capabilities.network.Linkable: + derived_from: tosca.capabilities.Root + + diff --git a/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.zip b/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.zip new file mode 100644 index 0000000000..50b66e61be Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/capabilityTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/capabilityTypesCi.zip b/asdc-tests/src/test/resources/CI/importResource/capabilityTypesCi.zip new file mode 100644 index 0000000000..550cd756f4 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/capabilityTypesCi.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/categoryTypes.yml b/asdc-tests/src/test/resources/CI/importResource/categoryTypes.yml new file mode 100644 index 0000000000..d88a326859 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/categoryTypes.yml @@ -0,0 +1,89 @@ +services: + Mobility: + name: "Mobility" + icons: ['mobility'] + Network_L1_3: + name: "Network L1-3" + icons: ['network_l_1-3'] + Network_L4: + name: "Network L4+" + icons: ['network_l_4'] + VoIP_Call_Control: + name: "VoIP Call Control" + icons: ['call_controll'] +resources: + NetworkLayer23: + name: "Network L2-3" + subcategories: + Router: + name: "Router" + icons: ['router','vRouter'] + Gateway: + name: "Gateway" + icons: ['gateway'] + WAN_Connectors: + name: "WAN Connectors" + icons: ['network','connector','port'] + LAN_Connectors: + name: "LAN Connectors" + icons: ['network','connector','port'] + Infrastructure: + name: "Infrastructure" + icons: ['ucpe'] + NetworkLayer4: + name: "Network L4+" + subcategories: + Common_Network_Resources: + name: "Common Network Resources" + icons: ['network'] + ApplicationLayer4: + name: "Application L4+" + subcategories: + Border_Element: + name: "Border Element" + icons: ['borderElement'] + Application_Server: + name: "Application Server" + icons: ['applicationServer'] + Web_Server: + name: "Web Server" + icons: ['applicationServer'] + Call_Control: + name: "Call Control" + icons: ['call_controll'] + Media_Servers: + name: "Media Servers" + icons: ['applicationServer'] + Load_Balancer: + name: "Load Balancer" + icons: ['loadBalancer'] + Database: + name: "Database" + icons: ['database'] + Firewall: + name: "Firewall" + icons: ['firewall'] + Generic: + name: "Generic" + subcategories: + Infrastructure: + name: "Infrastructure" + icons: ['connector'] + Abstract: + name: "Abstract" + icons: ['objectStorage', 'compute'] + Network_Elements: + name: "Network Elements" + icons: ['network', 'connector'] + Database: + name: "Database" + icons: ['database'] + NetworkConnectivity: + name: "Network Connectivity" + subcategories: + ConnectionPoints: + name: "Connection Points" + icons: ['cp'] + VirtualLinks: + name: "Virtual Links" + icons: ['vl'] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/categoryTypes.zip b/asdc-tests/src/test/resources/CI/importResource/categoryTypes.zip new file mode 100644 index 0000000000..29984b8a06 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/categoryTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/compute/compute.json b/asdc-tests/src/test/resources/CI/importResource/compute/compute.json new file mode 100644 index 0000000000..48775d0f14 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/compute/compute.json @@ -0,0 +1,24 @@ +{ + "payloadName": "normative-types-new-compute.yml", + "contactId": "jh0003", + "name": "Compute", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "compute", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "Compute" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.yml b/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.yml new file mode 100644 index 0000000000..00b07fb908 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Compute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.zip b/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.zip new file mode 100644 index 0000000000..f7a7c31bf0 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/compute/normative-types-new-compute.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/containerApplication/containerApplication.json b/asdc-tests/src/test/resources/CI/importResource/containerApplication/containerApplication.json new file mode 100644 index 0000000000..1713e56cb4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/containerApplication/containerApplication.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-containerApplication.yml", + "contactId": "jh0003", + "name": "Application", + "description": "Represents an application that requires Container-level virtualization technology.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Application" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.yml b/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.yml new file mode 100644 index 0000000000..8813f26e04 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Container.Application: + derived_from: tosca.nodes.Root + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Container + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.zip b/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.zip new file mode 100644 index 0000000000..1da3bc1707 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/containerApplication/normative-types-new-containerApplication.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/containerRuntime/containerRuntime.json b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/containerRuntime.json new file mode 100644 index 0000000000..233bf39bce --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/containerRuntime.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-containerRuntime.yml", + "contactId": "jh0003", + "name": "Runtime", + "description": "Represents operating system-level virtualization technology used to run multiple application services on a single Compute host.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Runtime" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.yml b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.yml new file mode 100644 index 0000000000..86a10a0185 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Container.Runtime: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + host: + type: tosca.capabilities.Container + scalable: + type: tosca.capabilities.Scalable diff --git a/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.zip b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.zip new file mode 100644 index 0000000000..5140472147 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/containerRuntime/normative-types-new-containerRuntime.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/database/database.json b/asdc-tests/src/test/resources/CI/importResource/database/database.json new file mode 100644 index 0000000000..0f09e278c0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/database/database.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-database.yml", + "contactId": "jh0003", + "name": "Database", + "description": "Represents a logical database that can be managed and hosted by a DBMS node.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Database" + } + ] + } +], + "tags": [ + "Database" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.yml b/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.yml new file mode 100644 index 0000000000..5166150c73 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.yml @@ -0,0 +1,27 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Database: + derived_from: tosca.nodes.Root + properties: + name: + type: string + description: the logical name of the database + port: + type: integer + description: the port the underlying database service will listen to for data + user: + type: string + description: the optional user account name for DB administration + required: false + password: + type: string + description: the optional password for the DB user account + required: false + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.DBMS + relationship: tosca.relationships.HostedOn + capabilities: + database_endpoint: + type: tosca.capabilities.Endpoint.Database diff --git a/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.zip b/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.zip new file mode 100644 index 0000000000..9e8b178554 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/database/normative-types-new-database.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/deleteNormative.sh b/asdc-tests/src/test/resources/CI/importResource/deleteNormative.sh new file mode 100644 index 0000000000..fb70f71418 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/deleteNormative.sh @@ -0,0 +1,49 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function deleteResource() { + + ELEMENT_NAME=$1 + echo -e "############### Removing Element ${ELEMENT_NAME} Start ######################" + http_code=$(curl -s -o /dev/null -w "%{http_code}" -X "DELETE" -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/resources/res_${ELEMENT_NAME}".1.0") + if [ ${http_code} -eq 204 ]; then + echo -e "\n############### Removing Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n############### Failed to remove Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + exit 1 + elif [ ${http_code} -eq 404 ]; then + echo -e "\n############### Element ${ELEMENT_NAME} not found status code:${http_code} End #######\n\n\n" + else + echo -e "\n############### Failed to remove Element ${ELEMENT_NAME} status code:${http_code} End #######\n\n\n" + exit 1 + fi +} +if [ $# -lt 2 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 + +deleteResource "tosca.nodes.Root" +deleteResource "tosca.nodes.Compute" +deleteResource "tosca.nodes.SoftwareComponent" +deleteResource "tosca.nodes.WebServer" +deleteResource "tosca.nodes.WebApplication" +deleteResource "tosca.nodes.DBMS" +deleteResource "tosca.nodes.Database" +deleteResource "tosca.nodes.ObjectStorage" +deleteResource "tosca.nodes.BlockStorage" +deleteResource "tosca.nodes.Container.Runtime" +deleteResource "tosca.nodes.Container.Application" +deleteResource "tosca.nodes.LoadBalancer" +deleteResource "tosca.nodes.network.Port" +deleteResource "tosca.nodes.network.Network" + +exit 0 + diff --git a/asdc-tests/src/test/resources/CI/importResource/importNormative.sh b/asdc-tests/src/test/resources/CI/importResource/importNormative.sh new file mode 100644 index 0000000000..7c420ceb43 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/importNormative.sh @@ -0,0 +1,89 @@ +#!/bin/bash + +function usage { + echo "Usage: $0 " +} + +function addResource() { + + ELEMENT_NAME=$1 + echo -e "###################### Adding Element ${ELEMENT_NAME} Start ######################" + CURRENT_ZIP_FILE=./${ELEMENT_NAME}/normative-types-new-${ELEMENT_NAME}.zip + CURRENT_JSON_FILE=./${ELEMENT_NAME}/${ELEMENT_NAME}.json + sed -i 's/"userId": ".*",/"userId": "'${ATT_UID}'",/' ${CURRENT_JSON_FILE} + JSON_CONTENT=`paste -s ${CURRENT_JSON_FILE}` + http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F resourceMetadata="${JSON_CONTENT}" -F resourceZip=@${CURRENT_ZIP_FILE} -H USER_ID:${ATT_UID} ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/upload/multipart) + if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding Element ${ELEMENT_NAME} End ########################\n\n\n" + elif [ ${http_code} -eq 409 ]; then + echo -e "\n###################### Already exists Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add Element ${ELEMENT_NAME} status code:${http_code} End ########################\n\n\n" + exit 1 + fi +} +if [ $# -lt 3 ] +then + usage + exit 2 +fi + +HOST_IP=$1 +HOST_PORT=$2 +ATT_UID=$3 + +#Add The CapabilityTypes +http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F capabilityTypeZip=@capabilityTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/capability) +if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The CapabilityTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 +else + echo -e "\n###################### Failed to add CapabilityTypes status code:${http_code} End ########################\n\n\n" + exit 1 +fi +#Add The InterfaceLifecycleTypes +http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F interfaceLifecycleTypeZip=@interfaceLifecycleTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/interfaceLifecycle) +if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 409 ]; then + echo -e "\n###################### Already exists InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + exit 1 +else + echo -e "\n###################### Failed to add InterfaceLifecycleTypes status code:${http_code} End ########################\n\n\n" + exit 1 +fi +#Add The CategoryTypes +http_code=$(curl -s -o /dev/null -w "%{http_code}" -v -F categoriesZip=@categoryTypes.zip -H "USER_ID: jh0003" ${HOST_IP}:${HOST_PORT}/sdc2/rest/v1/catalog/uploadType/categories) +if [ ${http_code} -eq 201 ]; then + echo -e "\n###################### Adding The CategoryTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 409 ]; then + echo -e "\n###################### Already exists CategoryTypes status code:${http_code} End ########################\n\n\n" +elif [ ${http_code} -eq 500 ]; then + echo -e "\n###################### Failed to add CategoryTypes status code:${http_code} End ########################\n\n\n" + exit 1 +else + echo -e "\n###################### Failed to add CategoryTypes status code:${http_code} End ########################\n\n\n" + exit 1 +fi + +addResource "root" +addResource "compute" +addResource "softwareComponent" +addResource "webServer" +addResource "webApplication" +addResource "DBMS" +addResource "database" +addResource "objectStorage" +addResource "blockStorage" +addResource "containerRuntime" +addResource "containerApplication" +addResource "loadBalancer" +addResource "port" +addResource "network" + +exit 0 + diff --git a/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.yml b/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.yml new file mode 100644 index 0000000000..1b67118934 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.yml @@ -0,0 +1,11 @@ +tosca.interfaces.node.lifecycle.Standard: + create: + description: Standard lifecycle create operation. + configure: + description: Standard lifecycle configure operation. + start: + description: Standard lifecycle start operation. + stop: + description: Standard lifecycle stop operation. + delete: + description: Standard lifecycle delete operation. \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.zip b/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.zip new file mode 100644 index 0000000000..9bcf93ab7d Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/interfaceLifecycleTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/loadBalancer/loadBalancer.json b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/loadBalancer.json new file mode 100644 index 0000000000..fbddc18c07 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/loadBalancer.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-loadBalancer.yml", + "contactId": "jh0003", + "name": "LoadBalancer", + "description": "Represents logical function that be used in conjunction with a Floating Address to distribute an application’s traffic (load) across a number of instances of the application (e.g., for a clustered or scaled application).", + "resourceIconPath": "loadBalancer", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "LoadBalancer" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.yml b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.yml new file mode 100644 index 0000000000..86857656ad --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.LoadBalancer: + derived_from: tosca.nodes.Root + properties: + # TBD + algorithm : + type: string + required: false + status: experimental + capabilities : + client: + type: tosca.capabilities.Endpoint.Public + description: the Floating (IP) client’s on the public network can connect to + requirements: + - application: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.RoutesTo diff --git a/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.zip b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.zip new file mode 100644 index 0000000000..fefed6f0f4 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/loadBalancer/normative-types-new-loadBalancer.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/network/network.json b/asdc-tests/src/test/resources/CI/importResource/network/network.json new file mode 100644 index 0000000000..cf1eb03ff0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/network/network.json @@ -0,0 +1,21 @@ +{ + "payloadName": "normative-types-new-network.yml", + "contactId": "jh0003", + "name": "Network", + "description": "Represents a simple , logical network service.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "Network" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.yml b/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.yml new file mode 100644 index 0000000000..e1f9d3db70 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.yml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.Network: + derived_from: tosca.nodes.Root + properties: + ip_version: + type: integer + required: false + default: 4 + constraints: + - valid_values: [ 4, 6 ] + cidr: + type: string + required: false + start_ip: + type: string + required: false + end_ip: + type: string + required: false + gateway_ip: + type: string + required: false + network_name: + type: string + required: false + network_id: + type: string + required: false + segmentation_id: + type: string + required: false + network_type: + type: string + required: false + physical_network: + type: string + required: false + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.zip b/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.zip new file mode 100644 index 0000000000..b10daebb2b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/network/normative-types-new-network.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.yml b/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.yml new file mode 100644 index 0000000000..2d1540b27b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.yml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.network.Port: + derived_from: tosca.nodes.Root + properties: + ip_address: + type: string + required: false + order: + type: integer + required: true + default: 0 + constraints: + - greater_or_equal: 0 + is_default: + type: boolean + required: false + default: false + ip_range_start: + type: string + required: false + ip_range_end: + type: string + required: false + requirements: + - link: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + - binding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo diff --git a/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.zip b/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.zip new file mode 100644 index 0000000000..f6903ea8ee Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/normative-port/normative-types-new-port.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/normative-port/port.json b/asdc-tests/src/test/resources/CI/importResource/normative-port/port.json new file mode 100644 index 0000000000..7b62d7ff0a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/normative-port/port.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-port.yml", + "contactId": "jh0003", + "name": "Port", + "description": "Represents a logical entity that associates between Compute and Network normative types.", + "resourceIconPath": "port", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "Port" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/notmative-network/network.json b/asdc-tests/src/test/resources/CI/importResource/notmative-network/network.json new file mode 100644 index 0000000000..636499fba4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/notmative-network/network.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-network.yml", + "contactId": "jh0003", + "name": "Network", + "description": "Represents a simple , logical network service.", + "resourceIconPath": "network", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "Network" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.yml b/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.yml new file mode 100644 index 0000000000..e92e87716f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.yml @@ -0,0 +1,41 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.network.Network: + derived_from: tosca.nodes.Root + properties: + ip_version: + type: integer + required: false + default: 4 + constraints: + - valid_values: [ 4, 6 ] + cidr: + type: string + required: false + start_ip: + type: string + required: false + end_ip: + type: string + required: false + gateway_ip: + type: string + required: false + network_name: + type: string + required: false + network_id: + type: string + required: false + segmentation_id: + type: string + required: false + network_type: + type: string + required: false + physical_network: + type: string + required: false + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.zip b/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.zip new file mode 100644 index 0000000000..79c5fb2573 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/notmative-network/normative-types-new-network.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.yml b/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.yml new file mode 100644 index 0000000000..9c338c3400 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.ObjectStorage: + derived_from: tosca.nodes.Root + properties: + name: + type: string + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 0 GB + maxsize: + type: scalar-unit.size + constraints: + - greater_or_equal: 0 GB + capabilities: + storage_endpoint: + type: tosca.capabilities.Endpoint diff --git a/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.zip b/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.zip new file mode 100644 index 0000000000..b9046c1a66 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/objectStorage/normative-types-new-objectStorage.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/objectStorage/objectStorage.json b/asdc-tests/src/test/resources/CI/importResource/objectStorage/objectStorage.json new file mode 100644 index 0000000000..247b468952 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/objectStorage/objectStorage.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-objectStorage.yml", + "contactId": "jh0003", + "name": "ObjectStorage", + "description": "Represents storage that provides the ability to store data as objects (or BLOBs of data) without consideration for the underlying filesystem or devices.", + "resourceIconPath": "objectStorage", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "ObjectStorage" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.yml b/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.yml new file mode 100644 index 0000000000..7cd71360f2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.yml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.cp.Port: + derived_from: tosca.nodes.Root + properties: + ip_address: + type: string + required: false + order: + type: integer + required: true + default: 0 + constraints: + - greater_or_equal: 0 + is_default: + type: boolean + required: false + default: false + ip_range_start: + type: string + required: false + ip_range_end: + type: string + required: false + requirements: + - link: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + - binding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo diff --git a/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.zip b/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.zip new file mode 100644 index 0000000000..e1688a7304 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/port/normative-types-new-port.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/port/port.json b/asdc-tests/src/test/resources/CI/importResource/port/port.json new file mode 100644 index 0000000000..38106903e3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/port/port.json @@ -0,0 +1,21 @@ +{ + "payloadName": "normative-types-new-port.yml", + "contactId": "jh0003", + "name": "Port", + "description": "Represents a logical entity that associates between Compute and Network normative types.", + "resourceIconPath": "port", + "resourceType": "CP", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "Port" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.yml b/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.yml new file mode 100644 index 0000000000..e9b1de9518 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.yml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Root: + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature: + type: tosca.capabilities.Node + requirements: + - dependency : + capability: tosca.capabilities.Node + node: tosca.nodes.Root + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + interfaces: + Standard: + type: tosca.interfaces.node.lifecycle.Standard diff --git a/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.zip b/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.zip new file mode 100644 index 0000000000..07583e89f5 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/root/normative-types-new-root.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/root/root.json b/asdc-tests/src/test/resources/CI/importResource/root/root.json new file mode 100644 index 0000000000..53f709bdca --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/root/root.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-root.yml", + "contactId": "jh0003", + "name": "Root", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Root" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.yml b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.yml new file mode 100644 index 0000000000..a154632c74 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.SoftwareComponent: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.zip b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.zip new file mode 100644 index 0000000000..ea61eec01f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/normative-types-new-softwareComponent.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/softwareComponent/softwareComponent.json b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/softwareComponent.json new file mode 100644 index 0000000000..43012d7adc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/softwareComponent/softwareComponent.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-softwareComponent.yml", + "contactId": "jh0003", + "name": "SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.yml b/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.yml new file mode 100644 index 0000000000..5f9a775fe0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.yml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.WebApplication: + derived_from: tosca.nodes.Root + properties: + context_root: + type: string + capabilities: + app_endpoint: + type: tosca.capabilities.Endpoint + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.WebServer + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.zip b/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.zip new file mode 100644 index 0000000000..516d9d9feb Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/webApplication/normative-types-new-webApplication.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/webApplication/webApplication.json b/asdc-tests/src/test/resources/CI/importResource/webApplication/webApplication.json new file mode 100644 index 0000000000..fc25c6966b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/webApplication/webApplication.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-webApplication.yml", + "contactId": "jh0003", + "name": "WebApplication", + "description": "Represents a software application that can be managed and run by a Web Server node. Specific types of web applications such as Java, etc. could be derived from this type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "WebApplication" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.yml b/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.yml new file mode 100644 index 0000000000..7c957b5247 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.yml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.WebServer: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + # Private, layer 4 endpoints + data_endpoint: tosca.capabilities.Endpoint + admin_endpoint: tosca.capabilities.Endpoint.Admin + host: + type: tosca.capabilities.Container + valid_source_types: [ tosca.nodes.WebApplication ] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.zip b/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.zip new file mode 100644 index 0000000000..a88761fa5f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResource/webServer/normative-types-new-webServer.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResource/webServer/webServer.json b/asdc-tests/src/test/resources/CI/importResource/webServer/webServer.json new file mode 100644 index 0000000000..bd74fb18f8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResource/webServer/webServer.json @@ -0,0 +1,20 @@ +{ + "payloadName": "normative-types-new-webServer.yml", + "contactId": "jh0003", + "name": "WebServer", + "description": "Represents an abstract software component or service that is capable of hosting and providing management operations for one or more Web Application nodes.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "WebServer" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/VSPPackage.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/VSPPackage.csar new file mode 100644 index 0000000000..b4aa77511b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/VSPPackage.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_1.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_1.csar new file mode 100644 index 0000000000..4b167cfa69 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_1.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_2.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_2.csar new file mode 100644 index 0000000000..1f7bc5ac8d Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/caseSensitiveTest_2.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/csars.zip b/asdc-tests/src/test/resources/CI/importResourceTests/csars/csars.zip new file mode 100644 index 0000000000..8a7f5de6e3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/csars.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/fiveLinesAsBlock0.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/fiveLinesAsBlock0.csar new file mode 100644 index 0000000000..870a777c66 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/fiveLinesAsBlock0.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion.csar new file mode 100644 index 0000000000..273fab3a0b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion2.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion2.csar new file mode 100644 index 0000000000..aa0027f48e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion2.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion3.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion3.csar new file mode 100644 index 0000000000..ce9a80b240 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion3.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion4.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion4.csar new file mode 100644 index 0000000000..88ccb448e7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion4.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion5.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion5.csar new file mode 100644 index 0000000000..a429110ea1 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/invalidCsarVersion5.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile1.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile1.csar new file mode 100644 index 0000000000..3361bfd867 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile1.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile2.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile2.csar new file mode 100644 index 0000000000..200fbd95af Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile2.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile3.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile3.csar new file mode 100644 index 0000000000..5ffdf6c4c4 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile3.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile4.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile4.csar new file mode 100644 index 0000000000..30da05f951 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile4.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile5.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile5.csar new file mode 100644 index 0000000000..e5a3fb862b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/longNamesInToscaMetaFile5.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingEntryDefintionPair.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingEntryDefintionPair.csar new file mode 100644 index 0000000000..63a58bcd27 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingEntryDefintionPair.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingOneLineInToscaMeta.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingOneLineInToscaMeta.csar new file mode 100644 index 0000000000..ac949ce734 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/missingOneLineInToscaMeta.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf.csar new file mode 100644 index 0000000000..4b37f44c73 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf2.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf2.csar new file mode 100644 index 0000000000..ec1a65ebb9 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/mock_vf2.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThanOneMetaFile.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThanOneMetaFile.csar new file mode 100644 index 0000000000..084ada11cb Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThanOneMetaFile.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThenOneYamlFile.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThenOneYamlFile.csar new file mode 100644 index 0000000000..9615c62e73 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/moreThenOneYamlFile.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCSARVersion.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCSARVersion.csar new file mode 100644 index 0000000000..65a21c12b8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCSARVersion.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCreatedByValue.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCreatedByValue.csar new file mode 100644 index 0000000000..cb08b19463 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noCreatedByValue.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/noEntryDefinitionsValue.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noEntryDefinitionsValue.csar new file mode 100644 index 0000000000..a3a0e8fd1f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noEntryDefinitionsValue.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/noNewLineAfterBLock0.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noNewLineAfterBLock0.csar new file mode 100644 index 0000000000..4b37f44c73 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noNewLineAfterBLock0.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/noTOSCAMetaFileVersionValue.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noTOSCAMetaFileVersionValue.csar new file mode 100644 index 0000000000..c2f4d0442a Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/noTOSCAMetaFileVersionValue.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlAndMetaFiles.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlAndMetaFiles.csar new file mode 100644 index 0000000000..74058d5f82 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlAndMetaFiles.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlFile.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlFile.csar new file mode 100644 index 0000000000..31cc2942d5 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/notContainYamlFile.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/someValueAfterBlock0.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/someValueAfterBlock0.csar new file mode 100644 index 0000000000..e600a39693 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/someValueAfterBlock0.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaFolderNotExists.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaFolderNotExists.csar new file mode 100644 index 0000000000..17a7e5e39f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaFolderNotExists.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaFileNotExists.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaFileNotExists.csar new file mode 100644 index 0000000000..55e7179505 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaFileNotExists.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaOutsideTheFolder.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaOutsideTheFolder.csar new file mode 100644 index 0000000000..53d6987ac7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/toscaMetaOutsideTheFolder.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/underscoreInsteadOfDash.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/underscoreInsteadOfDash.csar new file mode 100644 index 0000000000..c217dd5006 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/underscoreInsteadOfDash.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/validCsarVersion.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/validCsarVersion.csar new file mode 100644 index 0000000000..60ac6e3dd2 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/validCsarVersion.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf.csar b/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf.csar new file mode 100644 index 0000000000..01bf159071 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf.csar differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf_zip.zip b/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf_zip.zip new file mode 100644 index 0000000000..66922ae15e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/csars/valid_vf_zip.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/empty_category.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/empty_category.json new file mode 100644 index 0000000000..7ce1fd5e5f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/empty_category.json @@ -0,0 +1,22 @@ +{ + "payloadName": "normative-types-new-empty_category.yml", + "contactId": "adminid", + "name": "tosca.nodes.empty_category", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.empty_category" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.yml new file mode 100644 index 0000000000..0ab5ac9322 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.yml @@ -0,0 +1,16 @@ +tosca.nodes.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.zip new file mode 100644 index 0000000000..537787f955 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_category/normative-types-new-empty_category.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/empty_contact.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/empty_contact.json new file mode 100644 index 0000000000..6e043f5606 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/empty_contact.json @@ -0,0 +1,22 @@ +{ + "payloadName": "normative-types-new-empty_contact.yml", + "contactId": "", + "name": "tosca.nodes.empty_contact", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", +"categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.empty_contact" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.yml new file mode 100644 index 0000000000..3d9c111871 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_contact: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.zip new file mode 100644 index 0000000000..bee0ffef8f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_contact/normative-types-new-empty_contact.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/empty_desc.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/empty_desc.json new file mode 100644 index 0000000000..7aa4c167b4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/empty_desc.json @@ -0,0 +1,22 @@ +{ + "payloadName": "normative-types-new-empty_desc.yml", + "contactId": "adminid", + "name": "tosca.nodes.empty_desc", + "description": "", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.empty_desc" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.yml new file mode 100644 index 0000000000..0ab5ac9322 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.yml @@ -0,0 +1,16 @@ +tosca.nodes.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.zip new file mode 100644 index 0000000000..c105c0989f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_desc/normative-types-new-empty_desc.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/empty_icon.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/empty_icon.json new file mode 100644 index 0000000000..e1980cee79 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/empty_icon.json @@ -0,0 +1,22 @@ +{ + "payloadName": "normative-types-new-empty_icon.yml", + "contactId": "jh0003", + "name": "tosca.nodes.empty_icon", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.empty_icon" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.yml new file mode 100644 index 0000000000..0ab5ac9322 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.yml @@ -0,0 +1,16 @@ +tosca.nodes.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.zip new file mode 100644 index 0000000000..a500656ff7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_icon/normative-types-new-empty_icon.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/empty_payloadName.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/empty_payloadName.json new file mode 100644 index 0000000000..2e46c69243 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/empty_payloadName.json @@ -0,0 +1,22 @@ +{ + "payloadName": "", + "contactId": "adminid", + "name": "tosca.nodes.empty_payloadName", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.empty_payloadName" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.yml new file mode 100644 index 0000000000..0ab5ac9322 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.yml @@ -0,0 +1,16 @@ +tosca.nodes.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.zip new file mode 100644 index 0000000000..901d2de441 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_payloadName/normative-types-new-empty_payloadName.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/empty_resource_name.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/empty_resource_name.json new file mode 100644 index 0000000000..dff8e13ad5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/empty_resource_name.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-empty_resource_name.yml", + "contactId": "adminid", + "name": "", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["empty_resource_name"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.zip new file mode 100644 index 0000000000..940a74ab05 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_resource_name/normative-types-new-empty_resource_name.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/empty_tag.json b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/empty_tag.json new file mode 100644 index 0000000000..5028baa786 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/empty_tag.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-empty_tag.yml", + "contactId": "adminid", + "name": "tosca.nodes.empty_tag", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": [""], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.yml b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.zip b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.zip new file mode 100644 index 0000000000..cd75d64a89 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/empty_tag/normative-types-new-empty_tag.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/import _multiple_tags.json b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/import _multiple_tags.json new file mode 100644 index 0000000000..ec361827b0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/import _multiple_tags.json @@ -0,0 +1,18 @@ +{ + "payloadName": "normative-types-new-import _multiple_tags.yml", + "contactId": "adminid", + "name": "tosca.nodes.import _multiple_tags", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.import _multiple_tags", + "import _multiple_tags", + "import _multiple_tags2"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.yml b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.yml new file mode 100644 index 0000000000..0ab5ac9322 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.yml @@ -0,0 +1,16 @@ +tosca.nodes.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.zip b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.zip new file mode 100644 index 0000000000..1de1fac68c Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/import _multiple_tags/normative-types-new-import _multiple_tags.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/importResource4test.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/importResource4test.json new file mode 100644 index 0000000000..c6a4b47903 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/importResource4test.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-importResource4test.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.yml new file mode 100644 index 0000000000..bce6af3db4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.zip new file mode 100644 index 0000000000..eb69428cf1 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4test/normative-types-new-importResource4test.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/importResource4testCP.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/importResource4testCP.json new file mode 100644 index 0000000000..417d8a2854 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/importResource4testCP.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testCP.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "resourceType" : "VFC", + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.yml new file mode 100644 index 0000000000..fb0cef1068 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.CP.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.zip new file mode 100644 index 0000000000..be77395250 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testCP/normative-types-new-importResource4testCP.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/importResource4testMissingNameSpace.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/importResource4testMissingNameSpace.json new file mode 100644 index 0000000000..3a14cfc1c8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/importResource4testMissingNameSpace.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testMissingNameSpace.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "resourceType" : "VFC", + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.yml new file mode 100644 index 0000000000..693ec75b51 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.vfc.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.zip new file mode 100644 index 0000000000..3160c73fe7 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testMissingNameSpace/normative-types-new-importResource4testMissingNameSpace.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/importResource4testUnknown.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/importResource4testUnknown.json new file mode 100644 index 0000000000..3059d99eec --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/importResource4testUnknown.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testUnknown.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "resourceType" : "VFC", + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.yml new file mode 100644 index 0000000000..115a61a12b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.Unknown.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.zip new file mode 100644 index 0000000000..67b81c3d7f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUnknown/normative-types-new-importResource4testUnknown.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/importResource4testUpdateVendorNameAndCategory.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/importResource4testUpdateVendorNameAndCategory.json new file mode 100644 index 0000000000..4e9affe462 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/importResource4testUpdateVendorNameAndCategory.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-importResource4testUpdateVendorNameAndCategory.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Network L2-3", + "subcategories": [{ + "name": "Router" + }] + }], + "tags": ["importResource4test"], + "vendorName": "ATT (Tosaaaaaaaaaaaaa)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.yml new file mode 100644 index 0000000000..69d88984ac --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.yml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.importResource4test: + derived_from: tosca.nodes.Root + description: update update + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.zip new file mode 100644 index 0000000000..a092a1c14b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateVendorNameAndCategory/normative-types-new-importResource4testUpdateVendorNameAndCategory.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/importResource4testUpdateWithoutReqCap.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/importResource4testUpdateWithoutReqCap.json new file mode 100644 index 0000000000..f6ab834378 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/importResource4testUpdateWithoutReqCap.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testUpdateWithoutReqCap.yml", + "contactId": "cs0004", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.Update", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test", + "updatedTag"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.3.33" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.yml new file mode 100644 index 0000000000..a580e8b7c6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.yml @@ -0,0 +1,12 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.zip new file mode 100644 index 0000000000..3005f9231f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testUpdateWithoutReqCap/normative-types-new-importResource4testUpdateWithoutReqCap.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/importResource4testVF.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/importResource4testVF.json new file mode 100644 index 0000000000..6ebba43604 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/importResource4testVF.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testVF.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "resourceType" : "VFC", + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.yml new file mode 100644 index 0000000000..2879ab8cc8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vF.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.zip new file mode 100644 index 0000000000..46c652fd24 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVF/normative-types-new-importResource4testVF.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/importResource4testVFC.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/importResource4testVFC.json new file mode 100644 index 0000000000..b5e2e329bd --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/importResource4testVFC.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testVFC.yml", + "contactId": "jh0003", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "vendorName": "ATT (Tosca)", + "resourceType" : "VFC", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.yml new file mode 100644 index 0000000000..cdf347e872 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.VFC.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.zip new file mode 100644 index 0000000000..0ca8098ff9 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVFC/normative-types-new-importResource4testVFC.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/importResource4testVL.json b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/importResource4testVL.json new file mode 100644 index 0000000000..158530a3e5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/importResource4testVL.json @@ -0,0 +1,17 @@ +{ + "payloadName": "normative-types-new-importResource4testVL.yml", + "contactId": "jh0003", + "resourceType" : "VFC", + "name": "importResource4test", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["importResource4test"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.yml b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.yml new file mode 100644 index 0000000000..55888da2bc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.yml @@ -0,0 +1,30 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.Vl.importResource4test: + derived_from: tosca.nodes.Root + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature2: + type: tosca.capabilities.Node + requirements: + - dependency2 : + capability: tosca.capabilities.Node + node: tosca.nodes.importResource4test + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.zip b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.zip new file mode 100644 index 0000000000..9a1a28b1f6 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/importResource4testVL/normative-types-new-importResource4testVL.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.yml b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.yml new file mode 100644 index 0000000000..72fe26e0d1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.yml @@ -0,0 +1,141 @@ +tosca.capabilities.Root: + description: The TOSCA root Capability Type all other TOSCA base Capability Types derive from +tosca.capabilities.Node: + derived_from: tosca.capabilities.Root +tosca.capabilities.Container: + derived_from: tosca.capabilities.Root + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_or_equal: 1 + cpu_frequency: + type: scalar-unit.frequency + required: false + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB + mem_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB +tosca.capabilities.Endpoint: + derived_from: tosca.capabilities.Root + properties: + protocol: + type: string + default: tcp + port: + type: PortDef + required: false + secure: + type: boolean + default: false + url_path: + type: string + required: false + port_name: + type: string + required: false + network_name: + type: string + required: false + default: PRIVATE + initiator: + type: string + default: source + constraints: + - valid_values: [ source, target, peer ] + ports: + type: map + required: false + constraints: + - min_length: 1 + entry_schema: + type: PortSpec + attributes: + ip_address: + type: string +tosca.capabilities.Endpoint.Public: + derived_from: tosca.capabilities.Endpoint + properties: + # Change the default network_name to use the first public network found + network_name: PUBLIC + floating: + description: > + indicates that the public address should be allocated from a pool of floating IPs that are associated with the network. + type: boolean + default: false + status: experimental + dns_name: + description: The optional name to register with DNS + type: string + required: false + status: experimental +tosca.capabilities.Endpoint.Admin: + derived_from: tosca.capabilities.Endpoint + # Change Endpoint secure indicator to true from its default of false + properties: + secure: true +tosca.capabilities.Endpoint.Database: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.OperatingSystem: + derived_from: tosca.capabilities.Root + properties: + architecture: + type: string + required: false + type: + type: string + required: false + distribution: + type: string + required: false + version: + type: version + required: false +tosca.capabilities.Scalable: + derived_from: tosca.capabilities.Root + properties: + min_instances: + type: integer + default: 1 + max_instances: + type: integer + default: 1 + default_instances: + type: integer +tosca.capabilities.network.Bindable: + derived_from: tosca.capabilities.Node + + +tosca.capabilities.Container.Docker: + derived_from: tosca.capabilities.Container + properties: + version: + type: list + required: false + entry_schema: version + publish_all: + type: boolean + default: false + required: false + publish_ports: + type: list + entry_schema: PortSpec + required: false + expose_ports: + type: list + entry_schema: PortSpec + required: false + volumes: + type: list + entry_schema: string + required: false + diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.zip b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.zip new file mode 100644 index 0000000000..4f945a7d1f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypes.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi.zip b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi.zip new file mode 100644 index 0000000000..550cd756f4 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_MissingDerivedFrom.yml b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_MissingDerivedFrom.yml new file mode 100644 index 0000000000..31fac955e3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_MissingDerivedFrom.yml @@ -0,0 +1,132 @@ +tosca.capabilities.Root: + description: The TOSCA root Capability Type all other TOSCA base Capability Types derive from +tosca.capabilities.Node: +tosca.capabilities.Container: + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_or_equal: 1 + cpu_frequency: + type: scalar-unit.frequency + required: false + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB + mem_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB +tosca.capabilities.Test.Ci: +tosca.capabilities.Endpoint: + properties: + protocol: + type: string + default: tcp + port: + type: PortDef + required: false + secure: + type: boolean + default: false + url_path: + type: string + required: false + port_name: + type: string + required: false + network_name: + type: string + required: false + default: PRIVATE + initiator: + type: string + default: source + constraints: + - valid_values: [ source, target, peer ] + ports: + type: map + required: false + constraints: + - min_length: 1 + entry_schema: + type: PortSpec + attributes: + ip_address: + type: string +tosca.capabilities.Endpoint.Public: + properties: + # Change the default network_name to use the first public network found + network_name: PUBLIC + floating: + description: > + indicates that the public address should be allocated from a pool of floating IPs that are associated with the network. + type: boolean + default: false + status: experimental + dns_name: + description: The optional name to register with DNS + type: string + required: false + status: experimental +tosca.capabilities.Endpoint.Admin: + # Change Endpoint secure indicator to true from its default of false + properties: + secure: true +tosca.capabilities.Endpoint.Database: +tosca.capabilities.OperatingSystem: + properties: + architecture: + type: string + required: false + type: + type: string + required: false + distribution: + type: string + required: false + version: + type: version + required: false +tosca.capabilities.Scalable: + properties: + min_instances: + type: integer + default: 1 + max_instances: + type: integer + default: 1 + default_instances: + type: integer +tosca.capabilities.network.Bindable: + + +tosca.capabilities.Container.Docker: + properties: + version: + type: list + required: false + entry_schema: version + publish_all: + type: boolean + default: false + required: false + publish_ports: + type: list + entry_schema: PortSpec + required: false + expose_ports: + type: list + entry_schema: PortSpec + required: false + volumes: + type: list + entry_schema: string + required: false + diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_WithoutRoot.yml b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_WithoutRoot.yml new file mode 100644 index 0000000000..12c7d5a977 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/import_capabilitiesTypes/capabilityTypesCi_WithoutRoot.yml @@ -0,0 +1,141 @@ +tosca.capabilities.Node: + derived_from: tosca.capabilities.Root +tosca.capabilities.Container: + derived_from: tosca.capabilities.Root + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_or_equal: 1 + cpu_frequency: + type: scalar-unit.frequency + required: false + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB + mem_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB +tosca.capabilities.Test.Ci: + derived_from: tosca.capabilities.Root +tosca.capabilities.Endpoint: + derived_from: tosca.capabilities.Root + properties: + protocol: + type: string + default: tcp + port: + type: PortDef + required: false + secure: + type: boolean + default: false + url_path: + type: string + required: false + port_name: + type: string + required: false + network_name: + type: string + required: false + default: PRIVATE + initiator: + type: string + default: source + constraints: + - valid_values: [ source, target, peer ] + ports: + type: map + required: false + constraints: + - min_length: 1 + entry_schema: + type: PortSpec + attributes: + ip_address: + type: string +tosca.capabilities.Endpoint.Public: + derived_from: tosca.capabilities.Endpoint + properties: + # Change the default network_name to use the first public network found + network_name: PUBLIC + floating: + description: > + indicates that the public address should be allocated from a pool of floating IPs that are associated with the network. + type: boolean + default: false + status: experimental + dns_name: + description: The optional name to register with DNS + type: string + required: false + status: experimental +tosca.capabilities.Endpoint.Admin: + derived_from: tosca.capabilities.Endpoint + # Change Endpoint secure indicator to true from its default of false + properties: + secure: true +tosca.capabilities.Endpoint.Database: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.OperatingSystem: + derived_from: tosca.capabilities.Root + properties: + architecture: + type: string + required: false + type: + type: string + required: false + distribution: + type: string + required: false + version: + type: version + required: false +tosca.capabilities.Scalable: + derived_from: tosca.capabilities.Root + properties: + min_instances: + type: integer + default: 1 + max_instances: + type: integer + default: 1 + default_instances: + type: integer +tosca.capabilities.network.Bindable: + derived_from: tosca.capabilities.Node + + +tosca.capabilities.Container.Docker: + derived_from: tosca.capabilities.Container + properties: + version: + type: list + required: false + entry_schema: version + publish_all: + type: boolean + default: false + required: false + publish_ports: + type: list + entry_schema: PortSpec + required: false + expose_ports: + type: list + entry_schema: PortSpec + required: false + volumes: + type: list + entry_schema: string + required: false + diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/missing_category.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/missing_category.json new file mode 100644 index 0000000000..23a7d76103 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/missing_category.json @@ -0,0 +1,12 @@ +{ + "payloadName": "normative-types-new-missing_category.yml", + "contactId": "jh0003", + "name": "tosca.nodes.missing_category", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "tags": [ + "tosca.nodes.missing_category" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.zip new file mode 100644 index 0000000000..51a01c1bb9 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_category/normative-types-new-missing_category.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/missing_contact.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/missing_contact.json new file mode 100644 index 0000000000..8f3e5ae2e2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/missing_contact.json @@ -0,0 +1,21 @@ +{ + "payloadName": "normative-types-new-missing_contact.yml", + "name": "tosca.nodes.missing_contact", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.missing_contact" + ], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.yml new file mode 100644 index 0000000000..3d9c111871 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_contact: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.zip new file mode 100644 index 0000000000..21d14a9a73 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_contact/normative-types-new-missing_contact.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/missing_derived_from.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/missing_derived_from.json new file mode 100644 index 0000000000..37a55bf17a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/missing_derived_from.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-missing_derived_from.yml", + "contactId": "jh0003", + "name": "tosca.nodes.missing_derived_from", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.missing_derived_from"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.yml new file mode 100644 index 0000000000..82069ecb7b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.yml @@ -0,0 +1,15 @@ +tosca.nodes.missing_userId: + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.zip new file mode 100644 index 0000000000..22e3d4da29 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_derived_from/normative-types-new-missing_derived_from.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/missing_desc.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/missing_desc.json new file mode 100644 index 0000000000..bec3896cfd --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/missing_desc.json @@ -0,0 +1,15 @@ +{ + "payloadName": "normative-types-new-missing_desc.yml", + "contactId": "jh0003", + "name": "tosca.nodes.missing_desc", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.missing_desc"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.zip new file mode 100644 index 0000000000..bd5174df62 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_desc/normative-types-new-missing_desc.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/missing_icon.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/missing_icon.json new file mode 100644 index 0000000000..9e9b7572bc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/missing_icon.json @@ -0,0 +1,15 @@ +{ + "payloadName": "normative-types-new-missing_icon.yml", + "contactId": "jh0003", + "name": "tosca.nodes.missing_icon", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.missing_icon"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.zip new file mode 100644 index 0000000000..45d8e192f1 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_icon/normative-types-new-missing_icon.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/missing_payloadName.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/missing_payloadName.json new file mode 100644 index 0000000000..58df0f7400 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/missing_payloadName.json @@ -0,0 +1,15 @@ +{ + "contactId": "jh0003", + "name": "tosca.nodes.missing_payloadName", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.missing_payloadName"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.zip new file mode 100644 index 0000000000..3a72360c25 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_payloadName/normative-types-new-missing_payloadName.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/missing_resource_name.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/missing_resource_name.json new file mode 100644 index 0000000000..dbf7ef82f1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/missing_resource_name.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-missing_resource_name.yml", + "contactId": "jh0003", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "category": "Generic/Infrastructure", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["missing_resource_name"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.zip new file mode 100644 index 0000000000..24294b9647 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_resource_name/normative-types-new-missing_resource_name.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/missing_tags.json b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/missing_tags.json new file mode 100644 index 0000000000..36c845f001 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/missing_tags.json @@ -0,0 +1,15 @@ +{ + "payloadName": "normative-types-new-missing_tags.yml", + "contactId": "jh0003", + "name": "tosca.nodes.missing_tags", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.yml b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.yml new file mode 100644 index 0000000000..bad0c73a1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.missing_userId: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.zip b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.zip new file mode 100644 index 0000000000..1d619e8c93 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/missing_tags/normative-types-new-missing_tags.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/myCompute.json b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/myCompute.json new file mode 100644 index 0000000000..af216b7c21 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/myCompute.json @@ -0,0 +1,24 @@ +{ + "payloadName": "normative-types-new-myCompute.yml", + "contactId": "jh0003", + "name": "tosca.nodes.MyCompute", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.MyCompute" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.yml b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.yml new file mode 100644 index 0000000000..dff93f621a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.zip b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.zip new file mode 100644 index 0000000000..a4fb8979fc Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/myCompute/normative-types-new-myCompute.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.yml b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.yml new file mode 100644 index 0000000000..eccfd4ddc5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.yml @@ -0,0 +1,29 @@ +tosca.nodes.network.PortInvalidDefaultValue: + derived_from: tosca.nodes.Root + properties: + ip_address: + type: string + required: false + order: + type: integer + required: true + default: 1.5 + constraints: + - greater_or_equal: 0 + is_default: + type: boolean + required: false + default: false + ip_range_start: + type: string + required: false + ip_range_end: + type: string + required: false + requirements: + - link: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + - binding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.zip b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.zip new file mode 100644 index 0000000000..fed020cdd3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/normative-types-new-portInvalidDefaultValue.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/portInvalidDefaultValue.json b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/portInvalidDefaultValue.json new file mode 100644 index 0000000000..6b6e064a30 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/portInvalidDefaultValue/portInvalidDefaultValue.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-portInvalidDefaultValue.yml", + "contactId": "jh0003", + "name": "tosca.nodes.network.PortInvalidDefaultValue", + "description": "Represents a logical entity that associates between Compute and Network normative types.", + "resourceIconPath": "port", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Network Elements" + }] + }], + "tags": ["tosca.nodes.network.PortInvalidDefaultValue"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.yml b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.yml new file mode 100644 index 0000000000..de109820a9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.Compute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.zip b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.zip new file mode 100644 index 0000000000..bda162b32f Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/normative-types-new-userCompute.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/userCompute.json b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/userCompute.json new file mode 100644 index 0000000000..ab10c0b523 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/userCompute/userCompute.json @@ -0,0 +1,26 @@ +{ + "payloadName": "normative-types-new-userCompute.yml", + "contactId": "jh0003", + "name": "tosca.nodes.userCompute", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "tosca.nodes.userCompute" + ], + "vendorName": "UserVendor", + "vendorRelease": "1.1.1" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.yml b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.yml new file mode 100644 index 0000000000..5c73365640 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.yml @@ -0,0 +1,29 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.Compute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.zip b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.zip new file mode 100644 index 0000000000..3ecead7579 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/normative-types-new-userUpdateCompute.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/userUpdateCompute.json b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/userUpdateCompute.json new file mode 100644 index 0000000000..6e63c434fb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/userUpdateCompute/userUpdateCompute.json @@ -0,0 +1,22 @@ +{ + "payloadName": "normative-types-new-userUpdateCompute.yml", + "contactId": "jh0003", + "name": "tosca.nodes.userCompute", + "description": "Short description", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "vendorName": "UpdatedVendor", + "vendorRelease": "1.1.2", + "tags": [ + "tosca.nodes.userCompute" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.yml new file mode 100644 index 0000000000..af70663fbe --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.yml @@ -0,0 +1,39 @@ +validateProporties_happyScenarios: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test1: + type: boolean + required: false + default: true + validation_test2: + type: boolean + required: false + default: false + validation_test3: + type: integer + required: false + default: 1234 + validation_test4: + type: float + required: false + default: 123.123 + validation_test5: + type: string + required: false + default: cooolString + validation_test6: + type: scalar-unit.size + required: false + default: cooolString + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.zip new file mode 100644 index 0000000000..4104dc3618 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/normative-types-new-validateProporties_happyScenarios.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/validateProporties_happyScenarios.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/validateProporties_happyScenarios.json new file mode 100644 index 0000000000..1235ba57e6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_happyScenarios/validateProporties_happyScenarios.json @@ -0,0 +1,14 @@ +{ + "payloadName": "normative-types-new-validateProporties_happyScenarios.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["tosca.nodes.SoftwareComponent"] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.yml new file mode 100644 index 0000000000..14778745ef --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeBoolean_valueInit: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: boolean + required: false + default: 123456 + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.zip new file mode 100644 index 0000000000..6eb2d7e7af Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/normative-types-new-validateProporties_typeBoolean_valueInit.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/validateProporties_typeBoolean_valueInit.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/validateProporties_typeBoolean_valueInit.json new file mode 100644 index 0000000000..c4f4b37911 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueInit/validateProporties_typeBoolean_valueInit.json @@ -0,0 +1,14 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeBoolean_valueInit.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["tosca.nodes.SoftwareComponent"] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.yml new file mode 100644 index 0000000000..4d529ad285 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeBoolean_valueString: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: boolean + required: false + default: abcd + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.zip new file mode 100644 index 0000000000..538ba0e3ef Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/normative-types-new-validateProporties_typeBoolean_valueString.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/validateProporties_typeBoolean_valueString.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/validateProporties_typeBoolean_valueString.json new file mode 100644 index 0000000000..f1ff279a84 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeBoolean_valueString/validateProporties_typeBoolean_valueString.json @@ -0,0 +1,14 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeBoolean_valueString.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["tosca.nodes.SoftwareComponent"] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.yml new file mode 100644 index 0000000000..fee8c9b68e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeFloat_valueBoolean: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: float + required: false + default: true + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.zip new file mode 100644 index 0000000000..a577aeb1e3 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/normative-types-new-validateProporties_typeFloat_valueBoolean.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/validateProporties_typeFloat_valueBoolean.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/validateProporties_typeFloat_valueBoolean.json new file mode 100644 index 0000000000..f1769769d4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueBoolean/validateProporties_typeFloat_valueBoolean.json @@ -0,0 +1,14 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeFloat_valueBoolean.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["tosca.nodes.SoftwareComponent"] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.yml new file mode 100644 index 0000000000..88e5bb85c3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeFloat_valueString: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: float + required: false + default: abcd + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.zip new file mode 100644 index 0000000000..a9ec4d791e Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/normative-types-new-validateProporties_typeFloat_valueString.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/validateProporties_typeFloat_valueString.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/validateProporties_typeFloat_valueString.json new file mode 100644 index 0000000000..3eab4bb311 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeFloat_valueString/validateProporties_typeFloat_valueString.json @@ -0,0 +1,14 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeFloat_valueString.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["tosca.nodes.SoftwareComponent"] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.yml new file mode 100644 index 0000000000..69bd3ba41e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeInit_valueBoolean: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: integer + required: false + default: true + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.zip new file mode 100644 index 0000000000..9e76fbee46 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/normative-types-new-validateProporties_typeInit_valueBoolean.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/validateProporties_typeInit_valueBoolean.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/validateProporties_typeInit_valueBoolean.json new file mode 100644 index 0000000000..bb145d2f28 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueBoolean/validateProporties_typeInit_valueBoolean.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeInit_valueBoolean.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.yml new file mode 100644 index 0000000000..60ae3b6333 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeInit_valueFloat: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: integer + required: false + default: 0.123 + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.zip new file mode 100644 index 0000000000..91b69dd746 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/normative-types-new-validateProporties_typeInit_valueFloat.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/validateProporties_typeInit_valueFloat.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/validateProporties_typeInit_valueFloat.json new file mode 100644 index 0000000000..2e7f5f232a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueFloat/validateProporties_typeInit_valueFloat.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeInit_valueFloat.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.yml new file mode 100644 index 0000000000..7bd723e915 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.yml @@ -0,0 +1,21 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeInit_valueString: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: integer + required: false + default: abcd + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.zip new file mode 100644 index 0000000000..747e215071 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/normative-types-new-validateProporties_typeInit_valueString.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/validateProporties_typeInit_valueString.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/validateProporties_typeInit_valueString.json new file mode 100644 index 0000000000..29e4b29be0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeInit_valueString/validateProporties_typeInit_valueString.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeInit_valueString.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.yml new file mode 100644 index 0000000000..217f3405e2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.yml @@ -0,0 +1,50 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeList_valueUrlCredential: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: list + required: false + default: + - protocol: protocol1~!#@~$%^*()[];:'"|\/ + token: token1 + - protocol: protocol2~!#@~$%^*()[];:'"|\/ + token: token2 + entry_schema: + type: tosca.datatypes.Credential + attributes: + validation_test_list: + type: list + required: false + default: + - protocol: protocol1~!#@~$%^*()[];:'"|\/ + token: token1 + - protocol: protocol2~!#@~$%^*()[];:'"|\/ + token: token2 + entry_schema: + type: tosca.datatypes.Credential + validation_test_map: + type: map + required: false + default: + key1: + protocol: protocol1~!#@~$%^*()[];:'"|\/ + token: token1 + key2: + protocol: protocol2~!#@~$%^*()[];:'"|\/ + token: token2 + entry_schema: + type: tosca.datatypes.Credential + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.zip new file mode 100644 index 0000000000..10b1ce10ac Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/normative-types-new-validateProporties_typeList_valueUrlCredential.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/validateProporties_typeList_valueUrlCredential.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/validateProporties_typeList_valueUrlCredential.json new file mode 100644 index 0000000000..59d6bbff21 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeList_valueUrlCredential/validateProporties_typeList_valueUrlCredential.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeList_valueUrlCredential.yml", + "contactId": "jh0003", + "name": "resourceListValueCredential", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["resourceListValueCredential"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.yml new file mode 100644 index 0000000000..2ce14b21a9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.yml @@ -0,0 +1,29 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_typeMap_valueUrlCredential: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: map + required: false + default: + key1: + protocol: protocol1 + token: token1 + key2: + protocol: protocol2 + token: token2 + entry_schema: + type: tosca.datatypes.Credential + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.zip new file mode 100644 index 0000000000..9a8f093d95 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/normative-types-new-validateProporties_typeMap_valueUrlCredential.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/validateProporties_typeMap_valueUrlCredential.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/validateProporties_typeMap_valueUrlCredential.json new file mode 100644 index 0000000000..3fb0bec243 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeMap_valueUrlCredential/validateProporties_typeMap_valueUrlCredential.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeMap_valueUrlCredential.yml", + "contactId": "jh0003", + "name": "resourceMapValueCredential", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["resourceMapValueCredential"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/normative-types-new-validateProporties_typeString_valueString_special_chars.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/normative-types-new-validateProporties_typeString_valueString_special_chars.yml new file mode 100644 index 0000000000..cc109d1528 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/normative-types-new-validateProporties_typeString_valueString_special_chars.yml @@ -0,0 +1,19 @@ +validateProporties_typeString_valueString_special_chars: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: string + required: false + default: ~!#@~ + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/validateProporties_typeString_valueString_special_chars.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/validateProporties_typeString_valueString_special_chars.json new file mode 100644 index 0000000000..90f66e800e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_special_chars/validateProporties_typeString_valueString_special_chars.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeString_valueString_special_chars.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/normative-types-new-validateProporties_typeString_valueString_trimming.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/normative-types-new-validateProporties_typeString_valueString_trimming.yml new file mode 100644 index 0000000000..4ecd161682 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/normative-types-new-validateProporties_typeString_valueString_trimming.yml @@ -0,0 +1,19 @@ +validateProporties_typeBoolean_valueInit: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + validation_test: + type: boolean + required: false + default: true + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/validateProporties_typeString_valueString_trimming.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/validateProporties_typeString_valueString_trimming.json new file mode 100644 index 0000000000..34d9321b7e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeString_valueString_trimming/validateProporties_typeString_valueString_trimming.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeBoolean_valueInit.yml", + "contactId": "jh0003", + "name": "tosca.nodes.SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": [ + "tosca.nodes.SoftwareComponent" + ] +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.yml b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.yml new file mode 100644 index 0000000000..feb13b367f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.yml @@ -0,0 +1,32 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.validateProporties_type: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + myprop: + type: tosca.datatypes.network.PortInfoComplex + default: + addressesMap: + key1: + protocol: protocol1 + token: token1 + key2: + protocol: protocol2 + token: token2 + addressesList: + - protocol: protocol1~!#@~$%^*()[];:'"|\/ + token: token1 + - protocol: protocol2~!#@~$%^*()[];:'"|\/ + token: token2 + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.zip b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.zip new file mode 100644 index 0000000000..e8f0470948 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/normative-types-new-validateProporties_typeMap.zip differ diff --git a/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/validateProporties_typeTestDataType.json b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/validateProporties_typeTestDataType.json new file mode 100644 index 0000000000..b751545f11 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importResourceTests/validateProporties_typeTestDataType/validateProporties_typeTestDataType.json @@ -0,0 +1,16 @@ +{ + "payloadName": "normative-types-new-validateProporties_typeMap.yml", + "contactId": "jh0003", + "name": "resourceMapValueTest", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Abstract" + }] + }], + "tags": ["resourceMapValueTest"], + "vendorName": "ATT (Tosca)", + "vendorRelease": "1.0.0.wd03" +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.yml b/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.yml new file mode 100644 index 0000000000..120f33d5f1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.yml @@ -0,0 +1,23 @@ +services: + Mobility: + name: "Mobility1" + icons: ['mobility'] + Network_L1_3: + name: "Network L1-31" + icons: ['network_l_1-3'] +resources: + NetworkLayer23: + name: "Network Layer 2-31" + subcategories: + Router: + name: "Router" + icons: ['router'] + Gateway: + name: "Gateway" + icons: ['gateway'] + WAN_Connectors: + name: "WAN Connectors" + icons: ['connector'] + LAN_Connectors: + name: "LAN Connectors" + icons: ['connector'] diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.zip b/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.zip new file mode 100644 index 0000000000..68b7aa9114 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importTypesTest/categoryTypesTest.zip differ diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.yml b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.yml new file mode 100644 index 0000000000..484ed4dff6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.yml @@ -0,0 +1,13 @@ +org.openecomp.groups.MyHeatStack1: + derived_from: tosca.groups.Root + description: Grouped all heat resources which are in the same heat stack + properties: + heat_files: + type: list + description: Heat files which associate to this group/heat stack + required: true + status: SUPPORTED + entry_schema: + type: string + url_credential: + type: tosca.datatypes.Credential \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.zip b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.zip new file mode 100644 index 0000000000..ee57b02826 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack1/myHeatStack1.zip differ diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.yml b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.yml new file mode 100644 index 0000000000..94fbb0451e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.yml @@ -0,0 +1,14 @@ +org.openecomp.groups.MyHeatStack2: + derived_from: tosca.groups.Root + description: Grouped all heat resources which are in the same heat stack + members: [ tosca.nodes.Compute ] + properties: + heat_files: + type: list + description: Heat files which associate to this group/heat stack + required: true + status: SUPPORTED + entry_schema: + type: string + url_credential: + type: tosca.datatypes.Credential \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.zip b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.zip new file mode 100644 index 0000000000..1d75c7f4d0 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/importTypesTest/myHeatStack2/myHeatStack2.zip differ diff --git a/asdc-tests/src/test/resources/CI/other/mapping.json b/asdc-tests/src/test/resources/CI/other/mapping.json new file mode 100644 index 0000000000..3310d776b9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/other/mapping.json @@ -0,0 +1,182 @@ +{ "order": 1, "template": "auditingevents-*", "settings": {}, "mappings": +{ +"distributiondownloadevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "auditinggetuebclusterevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "distributionstatusevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, +"distributionengineevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ROLE": { "include_in_all": true, "type": "string" }, + "API_KEY": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "D_ENV": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "useraccessevent": { + "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER": { "include_in_all": true, "type": "string" }}, + "_all": { "enabled": true }}, +"resourceadminevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "PREV_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "PREV_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DPREV_STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DCURR_STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOSCA_NODE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "COMMENT": { "include_in_all": true, "type": "string" }, + "ARTIFACT_DATA": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "PREV_ARTIFACT_UUID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_ARTIFACT_UUID": { "include_in_all": true, "index": "not_analyzed", "type": "string" } }, + "_all": { "enabled": true }} , +"useradminevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_AFTER": { "include_in_all": true, "type": "string" }, + "USER_BEFORE": { "include_in_all": true, "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }}, + "_all": { "enabled": true } }, +"distributionnotificationevent": + {"properties":{ + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "categoryevent": + { "properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CATEGORY_NAME": { "include_in_all": true, "type": "string" }, + "SUB_CATEGORY_NAME": { "include_in_all": true, "type": "string" }, + "GROUPING_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "authevent": { + "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER": { "include_in_all": true, "type": "string" }, + "AUTH_STATUS": { "include_in_all": true, "index": "not_analyzed","type": "string" } , + "REALM": { "include_in_all": true, "index": "not_analyzed","type": "string" }} , + "_all": { "enabled": true }}, + "consumerevent": + { "properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ECOMP_USER": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "getuserslistevent": + { "properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DETAILS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "getcategoryhierarchyevent": + { "properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DETAILS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "distributiondeployevent": + { "properties": { + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS z", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }}, + "aliases": { "last_3_months": {}}} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/addYangXmlArtifactToResource.xml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/addYangXmlArtifactToResource.xml new file mode 100644 index 0000000000..0415385bd0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/addYangXmlArtifactToResource.xml @@ -0,0 +1,32 @@ + + + + + Lionel Andres Messi + 1987-06-24T00:00:00-00:00 + + + Cristiano Ronaldo + 1985-02-05T00:00:00-00:00 + + + FC Barcelona + + Lionel Andres Messi + Champions League 2014-2015 + 10 + 43 + + + + Real Madrid + + Cristiano Ronaldo + Champions League 2014-2015 + 7 + 48 + + + + + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.yaml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.yaml new file mode 100644 index 0000000000..6835485ca1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.yaml @@ -0,0 +1,787 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.zip b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.zip new file mode 100644 index 0000000000..c8a2726421 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat 0 2.zip differ diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat_net 0 2.yaml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat_net 0 2.yaml new file mode 100644 index 0000000000..6835485ca1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/asc_heat_net 0 2.yaml @@ -0,0 +1,787 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatEnvfile.env b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatEnvfile.env new file mode 100644 index 0000000000..6835485ca1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatEnvfile.env @@ -0,0 +1,787 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatInvalidFormat.yaml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatInvalidFormat.yaml new file mode 100644 index 0000000000..b70d5a4b0a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heatInvalidFormat.yaml @@ -0,0 +1,9 @@ +heat_template_version: 2013-05-23 + +parameters: + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heat_mini.yaml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heat_mini.yaml new file mode 100644 index 0000000000..a545569129 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/heat_mini.yaml @@ -0,0 +1,13 @@ +heat_template_version: 2013-05-23 + +parameters: + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + +resources: + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidJson.json b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidJson.json new file mode 100644 index 0000000000..48a3e89deb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidJson.json @@ -0,0 +1,11 @@ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYamlFormat.yaml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYamlFormat.yaml new file mode 100644 index 0000000000..5c51039931 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYamlFormat.yaml @@ -0,0 +1,787 @@ + heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYangXml.xml b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYangXml.xml new file mode 100644 index 0000000000..8978e0d5ed --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/invalidYangXml.xml @@ -0,0 +1,35 @@ + + + + + Lionel Andr�s Messi + 1987-06-24T00:00:00-00:00 + + + Cristiano Ronaldo + 1985-02-05T00:00:00-00:00 + + + FC Barcelona + + Lionel Andr�s Messi + Champions League 2014/2015 + 10 + 43 + + + + Real Madrid + + Cristiano Ronaldo + Champions League 2014/2015 + 7 + 48 + + + + + + + + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/jsonArtifact.json b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/jsonArtifact.json new file mode 100644 index 0000000000..d5ca56d195 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/jsonArtifact.json @@ -0,0 +1,22 @@ +{ + "glossary": { + "title": "example glossary", + "GlossDiv": { + "title": "S", + "GlossList": { + "GlossEntry": { + "ID": "SGML", + "SortAs": "SGML", + "GlossTerm": "Standard Generalized Markup Language", + "Acronym": "SGML", + "Abbrev": "ISO 8879:1986", + "GlossDef": { + "para": "A meta-markup language, used to create markup languages such as DocBook.", + "GlossSeeAlso": ["GML", "XML"] + }, + "GlossSee": "markup" + } + } + } + } +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/other.txt b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/other.txt new file mode 100644 index 0000000000..5f8f77ca2c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/HeatDeploymentArtifacts/other.txt @@ -0,0 +1,3 @@ +cmd1 +cmd2 +cmd3 \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/bluePrintSampleArtifact.xml b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/bluePrintSampleArtifact.xml new file mode 100644 index 0000000000..10c46b7269 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/bluePrintSampleArtifact.xml @@ -0,0 +1,3 @@ + + dfsfsdfsdf + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/docSampleArtifact.docx b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/docSampleArtifact.docx new file mode 100644 index 0000000000..c281f532f8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/docSampleArtifact.docx differ diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.emf b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.emf new file mode 100644 index 0000000000..9c478f6ce1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.emf @@ -0,0 +1,2 @@ +This is sample EMF file +We currently not checking the file content. \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.xml b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.xml new file mode 100644 index 0000000000..10c46b7269 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/emfSampleArtifact.xml @@ -0,0 +1,3 @@ + + dfsfsdfsdf + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/eventSampleArtifact.xml b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/eventSampleArtifact.xml new file mode 100644 index 0000000000..10c46b7269 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/eventSampleArtifact.xml @@ -0,0 +1,3 @@ + + dfsfsdfsdf + \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/jsonSampleArtifact.json b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/jsonSampleArtifact.json new file mode 100644 index 0000000000..b749a9e89c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/jsonSampleArtifact.json @@ -0,0 +1,3 @@ +{ + "test": "This is test" +} diff --git a/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/toscaSampleArtifact.yml b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/toscaSampleArtifact.yml new file mode 100644 index 0000000000..10ccf71d51 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/ResourceInstanceArtifacts/toscaSampleArtifact.yml @@ -0,0 +1,5 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.CP: + derived_from: org.openecomp.resource.cp.root \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/addHeatArtifactToServiceAndSertify/asc_heat 0 2.yaml b/asdc-tests/src/test/resources/CI/tests/addHeatArtifactToServiceAndSertify/asc_heat 0 2.yaml new file mode 100644 index 0000000000..6835485ca1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/addHeatArtifactToServiceAndSertify/asc_heat 0 2.yaml @@ -0,0 +1,787 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/downloadResourceArtifactSuccess/org.openstack.Rally.zip b/asdc-tests/src/test/resources/CI/tests/downloadResourceArtifactSuccess/org.openstack.Rally.zip new file mode 100644 index 0000000000..0951d5cef8 Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/downloadResourceArtifactSuccess/org.openstack.Rally.zip differ diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/mysql.yml new file mode 100644 index 0000000000..f512f8071e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getResourceArtifactFileContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getResourceArtifactFileContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactFileContentTest/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListNoContentTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListNoContentTest/mysql.yml new file mode 100644 index 0000000000..180e247ea2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListNoContentTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getResourceArtifactListNoContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getResourceArtifactListNoContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/mysql.yml new file mode 100644 index 0000000000..b8f9bbdc69 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-GetResourceArtifactListTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-GetResourceArtifactListTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactListTest/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataNoContentTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataNoContentTest/mysql.yml new file mode 100644 index 0000000000..72ff4f37e0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataNoContentTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getResourceArtifactMetadataNoContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getResourceArtifactMetadataNoContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/mysql.yml new file mode 100644 index 0000000000..527e4a0081 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getResourceArtifactMetadataTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getResourceArtifactMetadataTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactMetadataTest/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getResourceArtifactPayloadNoContentTest/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactPayloadNoContentTest/mysql.yml new file mode 100644 index 0000000000..7177a65387 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getResourceArtifactPayloadNoContentTest/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getResourceArtifactPayloadNoContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getResourceArtifactPayloadNoContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/mysql.yml new file mode 100644 index 0000000000..e0a0c6458e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource1/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/mysql.yml new file mode 100644 index 0000000000..dc5ff158c8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest2 +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest2: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest2 + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest2: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest2: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/install_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/install_mysql2.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/install_mysql2.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/start_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/start_mysql2.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/resource2/scripts/start_mysql2.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topology.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topology.txt new file mode 100644 index 0000000000..cb3c3e8546 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topology.txt @@ -0,0 +1 @@ +{"id":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7","delegateId":"9c063349-2259-40fe-97f1-7c40e659e1b0","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-DBMS","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest2","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-database","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Mysql-getServiceArtifactListTest","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}},{"key":"Mysql-getServiceArtifactListTest2","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest2","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest2","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topologyTemplate.txt new file mode 100644 index 0000000000..f0d0849db8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListInvalidVersionNotFoundTest/topologyTemplate.txt @@ -0,0 +1,2 @@ +{"id":"9c063349-2259-40fe-97f1-7c40e659e1b0","name":"Andrey","description":null,"topologyId":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7"} + diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/mysql.yml new file mode 100644 index 0000000000..4ee2c8ca88 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource1/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListNoContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListNoContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListNoContentTest: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/mysql.yml new file mode 100644 index 0000000000..b564dd0c4e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/resource2/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListNoContentTest2 +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListNoContentTest2: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2 + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListNoContentTest2: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topology.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topology.txt new file mode 100644 index 0000000000..279351879a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topology.txt @@ -0,0 +1 @@ +{"id":"3293c9c8-a162-43fc-b8d1-431399f89cb7","delegateId":"25845cce-05c8-4502-b5fe-abfd6bd6f28e","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-DBMS","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListNoContentTest2","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-database","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Mysql-getServiceArtifactListNoContentTest2","value":{"type":"alien.nodes.Mysql-getServiceArtifactListNoContentTest2","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":{"dependsOnMysql-getServiceArtifactListNoContentTest2":{"type":"tosca.relationships.DependsOn","target":"Mysql-getServiceArtifactListNoContentTest2","requirementName":"dependency","requirementType":"tosca.capabilities.Root","targetedCapabilityName":"root"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topologyTemplate.txt new file mode 100644 index 0000000000..3c342f6cd1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListNoContentTest/topologyTemplate.txt @@ -0,0 +1,2 @@ +{"id":"25845cce-05c8-4502-b5fe-abfd6bd6f28e","name":"ServiceArtListNoContent","description":null,"topologyId":"3293c9c8-a162-43fc-b8d1-431399f89cb7"} + diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/mysql.yml new file mode 100644 index 0000000000..e0a0c6458e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource1/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/mysql.yml new file mode 100644 index 0000000000..dc5ff158c8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest2 +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest2: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest2 + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest2: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest2: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/install_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/install_mysql2.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/install_mysql2.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/start_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/start_mysql2.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/resource2/scripts/start_mysql2.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topology.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topology.txt new file mode 100644 index 0000000000..cb3c3e8546 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topology.txt @@ -0,0 +1 @@ +{"id":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7","delegateId":"9c063349-2259-40fe-97f1-7c40e659e1b0","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-DBMS","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest2","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-database","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Mysql-getServiceArtifactListTest","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}},{"key":"Mysql-getServiceArtifactListTest2","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest2","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest2","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topologyTemplate.txt new file mode 100644 index 0000000000..f0d0849db8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceArtifactListTest/topologyTemplate.txt @@ -0,0 +1,2 @@ +{"id":"9c063349-2259-40fe-97f1-7c40e659e1b0","name":"Andrey","description":null,"topologyId":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7"} + diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/mysql.yml new file mode 100644 index 0000000000..e0a0c6458e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource1/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/mysql.yml new file mode 100644 index 0000000000..dc5ff158c8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListTest2 +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListTest2: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListTest2 + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListTest2: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListTest2: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/install_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/install_mysql2.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/install_mysql2.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/start_mysql2.sh b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/start_mysql2.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/resource2/scripts/start_mysql2.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topology.txt b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topology.txt new file mode 100644 index 0000000000..cb3c3e8546 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topology.txt @@ -0,0 +1 @@ +{"id":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7","delegateId":"9c063349-2259-40fe-97f1-7c40e659e1b0","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-DBMS","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest2","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListTest","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-database","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Mysql-getServiceArtifactListTest","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}},{"key":"Mysql-getServiceArtifactListTest2","value":{"type":"alien.nodes.Mysql-getServiceArtifactListTest2","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"hostedOnCompute":{"type":"tosca.relationships.HostedOn","target":"Compute","requirementName":"host","requirementType":"tosca.nodes.Compute","targetedCapabilityName":"host"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListTest2","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topologyTemplate.txt new file mode 100644 index 0000000000..f0d0849db8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service1/topologyTemplate.txt @@ -0,0 +1,2 @@ +{"id":"9c063349-2259-40fe-97f1-7c40e659e1b0","name":"Andrey","description":null,"topologyId":"6a4b2f9d-7fe1-482d-af11-97f483dff5b7"} + diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/mysql.yml new file mode 100644 index 0000000000..4ee2c8ca88 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource1/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListNoContentTest +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListNoContentTest: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListNoContentTest: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/mysql.yml b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/mysql.yml new file mode 100644 index 0000000000..b564dd0c4e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/resource2/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-getServiceArtifactListNoContentTest2 +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-getServiceArtifactListNoContentTest2: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2 + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript-getServiceArtifactListNoContentTest2: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topology.txt b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topology.txt new file mode 100644 index 0000000000..279351879a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topology.txt @@ -0,0 +1 @@ +{"id":"3293c9c8-a162-43fc-b8d1-431399f89cb7","delegateId":"25845cce-05c8-4502-b5fe-abfd6bd6f28e","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-DBMS","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"mysql-getServiceArtifactListNoContentTest2","version":"1.1.1-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-database","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Mysql-getServiceArtifactListNoContentTest2","value":{"type":"alien.nodes.Mysql-getServiceArtifactListNoContentTest2","name":null,"properties":{"bind_address":"true","storage_path":"/mountedStorage","db_port":"3306","db_name":"wordpress","db_user":"pass","db_password":"pass"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"database_endpoint":{"type":"tosca.capabilities.DatabaseEndpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.MysqlDatabase-getServiceArtifactListNoContentTest2","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":{"scripts":{"artifactType":"tosca.artifacts.File","artifactRef":"scripts","artifactName":"scripts","artifactRepository":null}}}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":{"dependsOnMysql-getServiceArtifactListNoContentTest2":{"type":"tosca.relationships.DependsOn","target":"Mysql-getServiceArtifactListNoContentTest2","requirementName":"dependency","requirementType":"tosca.capabilities.Root","targetedCapabilityName":"root"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topologyTemplate.txt new file mode 100644 index 0000000000..3c342f6cd1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/getServiceListTest/Service2/topologyTemplate.txt @@ -0,0 +1,2 @@ +{"id":"25845cce-05c8-4502-b5fe-abfd6bd6f28e","name":"ServiceArtListNoContent","description":null,"topologyId":"3293c9c8-a162-43fc-b8d1-431399f89cb7"} + diff --git a/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDefault.yaml b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDefault.yaml new file mode 100644 index 0000000000..6aad589bdb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDefault.yaml @@ -0,0 +1,603 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_missing_default: + type: string + description: Unique name for this VNF instance + label: be4 port 5 OAM ip address + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDesc.yaml b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDesc.yaml new file mode 100644 index 0000000000..d51a20d77f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingDesc.yaml @@ -0,0 +1,603 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_missing_desc: + type: string + default: This_is_the_SCP_name + label: be4 port 5 OAM ip address + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingType.yaml b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingType.yaml new file mode 100644 index 0000000000..29527495f7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithParamsMissingType.yaml @@ -0,0 +1,603 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_missing_desc: + description: Unique name for this VNF instance + default: This_is_the_SCP_name + label: be4 port 5 OAM ip address + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithValidParams.yaml b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithValidParams.yaml new file mode 100644 index 0000000000..6835485ca1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatArtifactParameters/heatWithValidParams.yaml @@ -0,0 +1,787 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +# availability_zone_smp0: +# type: string +# default: nova +# availability_zone_smp1: +# type: string +# default: nova +# availability_zone_fe0: +# type: string +# default: nova +# availability_zone_fe1: +# type: string +# default: nova +# availability_zone_db0: +# type: string +# default: nova +# availability_zone_db1: +# type: string +# default: nova +# availability_zone_be0: +# type: string +# default: nova +# availability_zone_be1: +# type: string +# default: nova +# availability_zone_be2: +# type: string +# default: nova +# availability_zone_be3: +# type: string +# default: nova +# availability_zone_be4: +# type: string +# default: nova + + vnf_name: + type: string + description: Unique name for this VNF instance + default: This_is_the_SCP_name + vnf_id: + type: string + description: Unique ID for this VNF instance + default: This_is_ths_SCP_id + + flavor_scp_be_id: + type: string + description: flavor type + default: a1.Small + flavor_scp_fe_id: + type: string + description: flavor type + default: a1.Small + flavor_smp_id: + type: string + description: flavor type + default: a1.Small + flavor_db_id: + type: string + description: flavor type + default: a1.Small + image_scp_be_id: + type: string + description: Image use to boot a server + default: asc_base_image_be + image_scp_fe_id: + type: string + description: Image use to boot a server + default: asc_base_image_fe + image_smp_id: + type: string + description: Image use to boot a server + default: asc_base_image_smp + image_db_id: + type: string + description: Image use to boot a server + default: asc_base_image_db + + int_vscp_fe_cluster_net_id: + type: string + description: LAN2 FE Cluster/KA + int_vscp_fe_cluster_cidr: + type: string + description: Private Network2 Address (CIDR notation) + int_vscp_cluster_net_id: + type: string + description: LAN3 Cluster + int_vscp_cluster_cidr: + type: string + description: Private Network3 Address (CIDR notation) + int_vscp_db_network_net_id: + type: string + description: LAN4 DB + int_vscp_db_network_cidr: + type: string + description: Private Network4 Address (CIDR notation) + SIGNET_vrf_A1_direct_net_id: + type: string + description: Network name for SIGTRAN_A + SIGNET_vrf_B1_direct_net_id: + type: string + description: Network name for SIGTRAN_B + Cricket_OCS_protected_net_id: + type: string + description: Network name for CRICKET_OCS + OAM_direct_net_id: + type: string + description: Network name for OAM + be0_Cricket_OCS_protected_ips: + type: string + label: be0 port 5 OAM ip address + description: be0 port 5 OAM ip address + be1_Cricket_OCS_protected_ips: + type: string + label: be1 port 5 OAM ip address + description: be1 port 5 OAM ip address + be2_Cricket_OCS_protected_ips: + type: string + label: be2 port 5 OAM ip address + description: be2 port 5 OAM ip address + be3_Cricket_OCS_protected_ips: + type: string + label: be3 port 5 OAM ip address + description: be3 port 5 OAM ip address + be4_Cricket_OCS_protected_ips: + type: string + label: be4 port 5 OAM ip address + description: be4 port 5 OAM ip address + be0_OAM_direct_ips: + type: string + label: be0 port 7 OAM ip address + description: be0 port 7 OAM ip address + be1_OAM_direct_ips: + type: string + label: be1 port 7 OAM ip address + description: be1 port 7 OAM ip address + be2_OAM_direct_ips: + type: string + label: be2 port 7 OAM ip address + description: be2 port 7 OAM ip address + be3_OAM_direct_ips: + type: string + label: be3 port 7 OAM ip address + description: be3 port 7 OAM ip address + be4_OAM_direct_ips: + type: string + label: be4 port 7 OAM ip address + description: be4 port 7 OAM ip address + fe0_SIGNET_vrf_A1_direct_ips: + type: string + label: fe0 port 0 SIGTRAN ip address + description: fe0 port 0 SIGTRAN ip address + fe0_OAM_direct_ips: + type: string + label: fe0 port 7 OAM ip address + description: fe0 port 7 OAM ip address + fe1_SIGNET_vrf_B1_direct_ips: + type: string + label: fe1 port 1 SIGTRAN ip address + description: fe1 port 1 SIGTRAN ip address + fe1_OAM_direct_ips: + type: string + label: fe1 port 7 OAM ip address + description: fe1 port 7 OAM ip address + smp0_OAM_direct_ips: + type: string + label: smp0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + smp1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: smp1 port 7 OAM ip address + db0_OAM_direct_ips: + type: string + label: db0 port 7 OAM ip address + description: smp0 port 7 OAM ip address + db1_OAM_direct_ips: + type: string + label: smp1 port 7 OAM ip address + description: db1 port 7 OAM ip address + vm_scp_be0_name: + type: string + default: vSCP_BE0 + description: name of VM + vm_scp_be1_name: + type: string + default: vSCP_BE1 + description: name of VM + vm_scp_be2_name: + type: string + default: vSCP_BE2 + description: name of VM + vm_scp_be3_name: + type: string + default: vSCP_BE3 + description: name of VM + vm_scp_be4_name: + type: string + default: vSCP_BE4 + description: name of VM + vm_scp_fe0_name: + type: string + default: vSCP_FE0 + description: name of VM + vm_scp_fe1_name: + type: string + default: vSCP_FE1 + description: name of VM + vm_smp0_name: + type: string + default: vSMP0 + description: name of VM + vm_smp1_name: + type: string + default: vSMP1 + description: name of VM + vm_db0_name: + type: string + default: vDB0 + description: name of VM + vm_db1_name: + type: string + default: vDB1 + description: name of VM + +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_1.yaml b/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_1.yaml new file mode 100644 index 0000000000..7d4a85c2b6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_1.yaml @@ -0,0 +1,144 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: string + description: city name + default: Hulon + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 + private_building: + type: boolean + description: home_number + default: true +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_2.yaml b/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_2.yaml new file mode 100644 index 0000000000..2c404f0721 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatEnv/artifact_2.yaml @@ -0,0 +1,469 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: +parameters: + city_name: + type: string + description: city name + default: Hulon + address: + type: string + description: address + default: Narkis + home_number: + type: number + description: home_number + default: 14 + private_building: + type: boolean + description: home_number + default: true +resources: + be0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be0_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be0_Cricket_OCS_protected_ips}}] + + be0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be0_OAM_direct_ips}}] + + server_scp_be1: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be1_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be1 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be1_port_3 } + - port: { get_resource: be1_port_4 } + - port: { get_resource: be1_port_5 } + - port: { get_resource: be1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be1_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be1_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be1_Cricket_OCS_protected_ips}}] + + be1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be1_OAM_direct_ips}}] + + server_scp_be2: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be2_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be2 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be2_port_3 } + - port: { get_resource: be2_port_4 } + - port: { get_resource: be2_port_5 } + - port: { get_resource: be2_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be2_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be2_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be2_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be2_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be2_Cricket_OCS_protected_ips}}] + + be2_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be2_OAM_direct_ips}}] + + server_scp_be3: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be3_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be3 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be3_port_3 } + - port: { get_resource: be3_port_4 } + - port: { get_resource: be3_port_5 } + - port: { get_resource: be3_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be3_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be3_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be3_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be3_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be3_Cricket_OCS_protected_ips}}] + + be3_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be3_OAM_direct_ips}}] + + server_scp_be4: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be4_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be4 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be4_port_3 } + - port: { get_resource: be4_port_4 } + - port: { get_resource: be4_port_5 } + - port: { get_resource: be4_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be4_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } + + be4_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + be4_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + be4_port_5: + type: OS::Neutron::Port + properties: + network: { get_param: Cricket_OCS_protected_net_id } + fixed_ips: [{"ip_address": {get_param: be4_Cricket_OCS_protected_ips}}] + + be4_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: be4_OAM_direct_ips}}] + + server_scp_fe0: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe0_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe0 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe0_port_0 } + - port: { get_resource: fe0_port_2 } + - port: { get_resource: fe0_port_3 } + - port: { get_resource: fe0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe0_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe0_port_0: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_A1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_SIGNET_vrf_A1_direct_ips}}] + + fe0_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe0_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe0_OAM_direct_ips}}] + + server_scp_fe1: + type: OS::Nova::Server +# depends on: scp_be_wait_condition + properties: + name: { get_param: vm_scp_fe1_name } + image: { get_param: image_scp_fe_id } +# availability_zone: { get_param: availability_zone_fe1 } + flavor: { get_param: flavor_scp_fe_id } + scheduler_hints: { group: { get_resource: FE_Affinity } } + networks: + - port: { get_resource: fe1_port_1 } + - port: { get_resource: fe1_port_2 } + - port: { get_resource: fe1_port_3 } + - port: { get_resource: fe1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_fe1_name} +# wc_notify: { get_attr: ['scp_fe_wait_handle', 'curl_cli'] } + + fe1_port_1: + type: OS::Neutron::Port + properties: + network: { get_param: SIGNET_vrf_B1_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_SIGNET_vrf_B1_direct_ips}}] + + fe1_port_2: + type: OS::Neutron::Port + properties: + network_id: { get_resource: FE_Clustering_KA } + + fe1_port_3: + type: OS::Neutron::Port + properties: + network_id: { get_resource: Clustering_Network } + + fe1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: fe1_OAM_direct_ips}}] + + server_smp0: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp0_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp0 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp0_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp0_OAM_direct_ips}}] + + server_smp1: + type: OS::Nova::Server + properties: + name: { get_param: vm_smp1_name } + image: { get_param: image_smp_id } +# availability_zone: { get_param: availability_zone_smp1 } + flavor: { get_param: flavor_smp_id } + scheduler_hints: { group: { get_resource: SMP_Affinity } } + networks: + - port: { get_resource: smp1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_smp1_name} +# wc_notify: { get_attr: ['smp_wait_handle', 'curl_cli'] } + + smp1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: smp1_OAM_direct_ips}}] + + server_db0: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db0_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db0 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db0_port_4 } + - port: { get_resource: db0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db0_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db0_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db0_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db0_OAM_direct_ips}}] + + server_db1: + type: OS::Nova::Server +# depends_on: smp_wait_condition + properties: + name: { get_param: vm_db1_name } + image: { get_param: image_db_id } +# availability_zone: { get_param: availability_zone_db1 } + flavor: { get_param: flavor_db_id } + scheduler_hints: { group: { get_resource: DB_Affinity } } + networks: + - port: { get_resource: db1_port_4 } + - port: { get_resource: db1_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_db1_name} +# wc_notify: { get_attr: ['db_wait_handle', 'curl_cli'] } + + db1_port_4: + type: OS::Neutron::Port + properties: + network_id: { get_resource: DB_Network } + + db1_port_7: + type: OS::Neutron::Port + properties: + network: { get_param: OAM_direct_net_id } + fixed_ips: [{"ip_address": {get_param: db1_OAM_direct_ips}}] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/heatEnv/yuli.yaml b/asdc-tests/src/test/resources/CI/tests/heatEnv/yuli.yaml new file mode 100644 index 0000000000..7d4a85c2b6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/heatEnv/yuli.yaml @@ -0,0 +1,144 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: string + description: city name + default: Hulon + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 + private_building: + type: boolean + description: home_number + default: true +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/BindingAsset.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/BindingAsset.yml new file mode 100644 index 0000000000..5117247373 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/BindingAsset.yml @@ -0,0 +1,14 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp: + derived_from: tosca.nodes.Root + properties: + type: + type: string + required: false + requirements: + - VirtualBinding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo + occurrences: [0, UNBOUNDED] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap.yml new file mode 100644 index 0000000000..8309df24b5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.CP: + derived_from: tosca.nodes.Compute + properties: + type: + type: string + required: false \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap_DerivedFromMyCompute1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap_DerivedFromMyCompute1.yml new file mode 100644 index 0000000000..478e742bc5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPHasNoReqCap_DerivedFromMyCompute1.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.CP: + derived_from: org.openecomp.resource.MyCompute1 + properties: + type: + type: string + required: false \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPWithAttributes.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPWithAttributes.yml new file mode 100644 index 0000000000..afafe7510b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CPWithAttributes.yml @@ -0,0 +1,59 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.CP: + derived_from: tosca.nodes.Root + properties: + type: + type: string + required: false + ip_address: + type: string + required: false + description: Allow the user to set a static IP. + order: + type: integer + required: false + default: 0 + description: The order of the NIC on the compute instance (e.g. eth2). + is_default: + type: boolean + required: false + default: false + description: “If is_default=true this port will be used for the default gateway route. Only one port that is associated to single compute node can set as is_default=true.†+ ip_range_start: + type: string + required: false + description: “Defines the starting IP of a range to be allocated for the VFC instances that are associated with this Port.†+ ip_range_end: + type: string + required: false + description: “Defines the ending IP of a range to be allocated for the compute instances that are associated with this Port.†+ is_tagged: + type: boolean + required: false + default: false + description: + attributes: + private_address: + type: string + default: "Hello" + value: "HelloWord" + public_address: + default: "DefaultValuePublicAddress" + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - virtualLink: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + - virtualbinding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_1.yml new file mode 100644 index 0000000000..b9e6c4f9b5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_1.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + capaBility: + type: tosca.capabilities.OperatingSystem diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_2.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_2.yml new file mode 100644 index 0000000000..230e4fa924 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveCapTest_2.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute2: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + Capability: + type: tosca.capabilities.OperatingSystem diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_1.yml new file mode 100644 index 0000000000..0d097a8f20 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_1.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - requirEment: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_2.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_2.yml new file mode 100644 index 0000000000..9cc1f2737b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/CaseInsensitiveReqTest_2.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute2: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - Requirement: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromCPWithOwnReq.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromCPWithOwnReq.yml new file mode 100644 index 0000000000..3514acfe9f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromCPWithOwnReq.yml @@ -0,0 +1,14 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.LAN: + derived_from: org.openecomp.resource.cp.CP + properties: + type: + type: string + required: false + requirements: + - virtualLink: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + occurrences: [0, UNBOUNDED] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromWebApplication_HasNoReqType.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromWebApplication_HasNoReqType.yml new file mode 100644 index 0000000000..7fbf4ec132 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DerivedFromWebApplication_HasNoReqType.yml @@ -0,0 +1,27 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyChildWebApplication: + derived_from: tosca.nodes.WebApplication + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - diff: + capability: + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + deff: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentCapFromRoot.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentCapFromRoot.yml new file mode 100644 index 0000000000..fe79bb3af9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentCapFromRoot.yml @@ -0,0 +1,26 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyAsset: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - test: + capability: tosca.capabilities.Scalable + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqAndCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqAndCap.yml new file mode 100644 index 0000000000..798cd5b9cd --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqAndCap.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - DependencY: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + FeaTurE: + type: tosca.capabilities.OperatingSystem \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute1.yml new file mode 100644 index 0000000000..c72d0ee62a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute1.yml @@ -0,0 +1,22 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute2: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - diff: + capability: tosca.capabilities.Container + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute2.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute2.yml new file mode 100644 index 0000000000..7132ca493a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqCapFromCompute2.yml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute3: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - diff: + capability: tosca.capabilities.Container + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + deff: + type: tosca.capabilities.Container diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqFromCompute.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqFromCompute.yml new file mode 100644 index 0000000000..e9438bae3c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/DifferentReqFromCompute.yml @@ -0,0 +1,32 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - test: + capability: tosca.capabilities.Scalable + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/FatherHasNoReqCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/FatherHasNoReqCap.yml new file mode 100644 index 0000000000..039ab61939 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/FatherHasNoReqCap.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.cp.CP: + derived_from: tosca.nodes.Root + properties: + type: + type: string + required: false \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure01.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure01.yml new file mode 100644 index 0000000000..f20a9eb48f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure01.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_boolean: + type: list + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: booolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure02.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure02.yml new file mode 100644 index 0000000000..f1af89ca6a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure02.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - false + - truee + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure03.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure03.yml new file mode 100644 index 0000000000..974d96ba5b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure03.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - false + - 3 + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure04.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure04.yml new file mode 100644 index 0000000000..52377e4b02 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure04.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - false + - 3.56 + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure05.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure05.yml new file mode 100644 index 0000000000..c66b4347f6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure05.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10000 + - 3.56 + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure06.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure06.yml new file mode 100644 index 0000000000..79b3c03cdf --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure06.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10000 + - aaaa + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure07.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure07.yml new file mode 100644 index 0000000000..5556e9ddfb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure07.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10000 + - true + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure08.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure08.yml new file mode 100644 index 0000000000..a3b21a64a3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure08.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10.50 + - true + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure09.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure09.yml new file mode 100644 index 0000000000..dc28591499 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure09.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10.50 + - asdc + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure10.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure10.yml new file mode 100644 index 0000000000..e465448064 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure10.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10.50 + - 500 + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure11.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure11.yml new file mode 100644 index 0000000000..a428b51974 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure11.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10.50 + - 500.0@ + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure12.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure12.yml new file mode 100644 index 0000000000..d840253120 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure12.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10000 + - 3# + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure13.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure13.yml new file mode 100644 index 0000000000..4eb59886e4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure13.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - false + - true% + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure14.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure14.yml new file mode 100644 index 0000000000..ad263f3d00 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure14.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - false + - falsee + - true + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure15.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure15.yml new file mode 100644 index 0000000000..93e8caa0a3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure15.yml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: list + description : another description + default: + - 10.5 + - 10.6x + - 20.5 + - 30.5 + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure16.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure16.yml new file mode 100644 index 0000000000..ed8ea4d70c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/ListPropertyFalure16.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_boolean: + type: koko + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure01.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure01.yml new file mode 100644 index 0000000000..c7ff0743f2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure01.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_boolean: + type: map + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: booolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure02.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure02.yml new file mode 100644 index 0000000000..d9abb87db8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure02.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - false + - truee + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure03.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure03.yml new file mode 100644 index 0000000000..e8f9b6eaa9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure03.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - false + - 3 + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure04.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure04.yml new file mode 100644 index 0000000000..d9dc4f955b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure04.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - false + - 3.56 + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure05.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure05.yml new file mode 100644 index 0000000000..aba6ff1992 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure05.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10000 + - 3.56 + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure06.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure06.yml new file mode 100644 index 0000000000..f27904d6e6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure06.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10000 + - aaaa + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure07.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure07.yml new file mode 100644 index 0000000000..ea123f3b1b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure07.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10000 + - true + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure08.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure08.yml new file mode 100644 index 0000000000..87b51fb2de --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure08.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10.50 + - true + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure09.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure09.yml new file mode 100644 index 0000000000..2fc8ded544 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure09.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10.50 + - asdc + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure10.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure10.yml new file mode 100644 index 0000000000..3ab449d72e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure10.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10.50 + - 500 + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure11.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure11.yml new file mode 100644 index 0000000000..e437de822e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure11.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10.50 + - 500.0@ + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure12.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure12.yml new file mode 100644 index 0000000000..f2fbc7c435 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure12.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10000 + - 3# + entry_schema: + description: This is my property + type: integer + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure13.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure13.yml new file mode 100644 index 0000000000..e375aae197 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure13.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - false + - true% + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure14.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure14.yml new file mode 100644 index 0000000000..e087212f1b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure14.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - false + - falsee + - true + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure15.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure15.yml new file mode 100644 index 0000000000..3923ee18d7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure15.yml @@ -0,0 +1,19 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_property: + type: map + description : another description + default: + - 10.5 + - 10.6x + - 20.5 + - 30.5 + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure16.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure16.yml new file mode 100644 index 0000000000..ed8ea4d70c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MapPropertyFalure16.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_boolean: + type: koko + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MyFatherCompute_NoReqCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MyFatherCompute_NoReqCap.yml new file mode 100644 index 0000000000..dfc564b458 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/MyFatherCompute_NoReqCap.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyFatherCompute: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameCapAsCompute.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameCapAsCompute.yml new file mode 100644 index 0000000000..533333ee09 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameCapAsCompute.yml @@ -0,0 +1,26 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + capabilities: + host: + type: tosca.capabilities.Container + endpoint : + type: tosca.capabilities.Endpoint.Admin + OS: + type: tosca.capabilities.OperatingSystem + BINDING: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute.yml new file mode 100644 index 0000000000..9d8b2d8375 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute.yml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - LOCAL_STORAGE: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, 1] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute_DerivedFromMyCompute1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute_DerivedFromMyCompute1.yml new file mode 100644 index 0000000000..a5413e516f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/SameReqAsCompute_DerivedFromMyCompute1.yml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute2: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - LOCAL_STORAGE: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, 2] \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap11.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap11.yml new file mode 100644 index 0000000000..9cea0b9dc8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap11.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.vfc3: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + occurrences: [1, 1] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap1UNBOUNDED.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap1UNBOUNDED.yml new file mode 100644 index 0000000000..24efc27711 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/computeCap1UNBOUNDED.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.vfc2: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, 1] + capabilities: + host: + type: tosca.capabilities.Container + occurrences: [1, UNBOUNDED] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromMyCompute.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromMyCompute.yml new file mode 100644 index 0000000000..237bec1f0c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromMyCompute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.DerivedFromMyCompute: + derived_from: org.openecomp.resource.MyCompute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromWebAppDerivedReqCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromWebAppDerivedReqCap.yml new file mode 100644 index 0000000000..0679bff4b1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/derivedFromWebAppDerivedReqCap.yml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyWebApp: + derived_from: tosca.nodes.WebApplication + properties: + context_root: + type: string + capabilities: + app_endpoint: + type: tosca.capabilities.Endpoint.Admin #derived from WebApplication's tosca.capabilities.Endpoint "app_endpoint" + requirements: + - host: + capability: tosca.capabilities.Container.Docker #derived from WebApplication's tosca.capabilities.Container "host" + node: tosca.nodes.WebServer + relationship: tosca.relationships.HostedOn diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importAttributeSuccessFlow.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importAttributeSuccessFlow.yml new file mode 100644 index 0000000000..0fa9a302f2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importAttributeSuccessFlow.yml @@ -0,0 +1,53 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyComputeTest: + derived_from: tosca.nodes.Root + properties: + myProp: + type: tosca.datatypes.Credential + descritpion: hey Desc + default: + "protocol" : hey1 + "token_type" : hey2 + "token" : hey3 + "keys" : {"keyA" : "val1" , keyB : val2} + "user" : hey4 + attributes: + private_address: + type: string + status: supported + default: myDefault + public_address: + type: string + networks: + type: map + default: {keyA : val1 , keyB : val2} + entry_schema: + type: string + ports: + type: tosca.datatypes.Credential + description: this is my description + default: + "protocol" : hey1 + "token_type" : hey2 + "token" : hey3 + "keys" : {"keyA" : "val1" , keyB : val2} + "user" : hey4 + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importCapabilityNameExistsOnParent.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importCapabilityNameExistsOnParent.yml new file mode 100644 index 0000000000..4d6db6c8c0 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importCapabilityNameExistsOnParent.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + Binding: #"binding" exists on parent + type: tosca.capabilities.OperatingSystem diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateCapability.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateCapability.yml new file mode 100644 index 0000000000..fcc3952f94 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateCapability.yml @@ -0,0 +1,42 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + - LOCAL_Storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + Scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateRequirements.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateRequirements.yml new file mode 100644 index 0000000000..7cab3ac590 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importDuplicateRequirements.yml @@ -0,0 +1,40 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + - LOCAL_Storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyBadDefault.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyBadDefault.yml new file mode 100644 index 0000000000..a3ff088a35 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyBadDefault.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.TestResource: + derived_from: tosca.nodes.Root + properties: + my_prop: + type: list + description : another description + default: + - 12 + - true + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyGoodDefault.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyGoodDefault.yml new file mode 100644 index 0000000000..2f864a727e --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertyGoodDefault.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_prop: + type: list + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: string + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertySuccessFlow.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertySuccessFlow.yml new file mode 100644 index 0000000000..fd52df5f9b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importListPropertySuccessFlow.yml @@ -0,0 +1,198 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + my_boolean: + type: list + description : another description + default: + - false + - true + entry_schema: + description: This is my property + type: boolean + my_boolean_array: + type: list + description : another description + default: [ true , false ] + entry_schema: + description: This is my property + type: boolean + duplicate_boolean_values: + type: list + description : another description + default: [ true , false , true ] + entry_schema: + description: This is my property + type: boolean + boolean_null_value: + type: list + description : another description + default: + - true + - + - false + entry_schema: + description: This is my property + type: boolean + my_integers: + type: list + description : another description + default: + - 0 + - 1000 + - -1000 + - 50 + entry_schema: + description: This is my property + type: integer + my_integers_array: + type: list + description : another description + default: [ 10 , -1000, 0 ] + entry_schema: + description: This is my property + type: integer + duplicate_integers_values: + type: list + description : another description + default: [ 10 , 10, -1000, 0 ] + entry_schema: + description: This is my property + type: integer + integer_null_value: + type: list + description : another description + default: + - 1000 + - + - 2000 + entry_schema: + description: This is my property + type: integer + my_string: + type: list + description : another description + default: + - asdc + - $?^@ecomp$!#%()_-~@+*^...;;/w# + - uc + entry_schema: + description: This is my property + type: string + my_string_array: + type: list + description : another description + default: [ AAA, ~$~#bbb%^*_-, qwe , 1.3 , 500 , true ] + entry_schema: + description: This is my property + type: string + string_null_value: + type: list + description : another description + default: + - asdc + - + - uc + entry_schema: + description: This is my property + type: string + string_space_value: + type: list + description : another description + default: + - asdc + - + - uc + entry_schema: + description: This is my property + type: string + duplicate_string_values: + type: list + description : another description + default: + - asdc + - asdc + - uc + entry_schema: + description: This is my property + type: string + my_float: + type: list + description : another description + default: + - 6 + - 1000.000001 + - -3.0f + entry_schema: + description: This is my property + type: float + my_float_array: + type: list + description : another description + default: [ 0.01 , -5.0 , 2.1f ] + entry_schema: + description: This is my property + type: float + duplicate_float_values: + type: list + description : another description + default: + - 0.0 + - 0.0 + - 4.555555 + entry_schema: + description: This is my property + type: float + float_no_default_values: + type: list + description : another description + default: + entry_schema: + description: This is my property + type: float + float_null_value: + type: list + description : another description + default: + - 6 + - + - -3.0f + entry_schema: + description: This is my property + type: float + float_space_value: + type: list + description : another description + default: + - 6 + - + - -3.0f + entry_schema: + description: This is my property + type: float + integer_no_default_values: + type: list + description : another description + default: + entry_schema: + description: This is my property + type: integer + string_no_default_values: + type: list + description : another description + default: + entry_schema: + description: This is my property + type: string + boolean_no_default_values: + type: list + description : another description + default: + entry_schema: + description: This is my property + type: boolean + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importMapPropertySuccessFlow.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importMapPropertySuccessFlow.yml new file mode 100644 index 0000000000..f856603397 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importMapPropertySuccessFlow.yml @@ -0,0 +1,452 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.LinkTest: + derived_from: tosca.nodes.Root + properties: + string_prop01: + type: map + description : another description + default: {keyA : val1 , keyB : val2} + entry_schema: + description: This is my property + type: string + string_prop02: + type: map + description : another description + default: {keyA : "val1" , keyB : "val2"} + entry_schema: + description: This is my property + type: string + string_prop03: + type: map + description : another description + default: {"keyA" : "val1" , keyB : val2} + entry_schema: + description: This is my property + type: string + string_prop04: + type: map + description : another description + default: {"keyA" : 10 , keyB : true } + entry_schema: + description: This is my property + type: string + string_prop05: + type: map + description : another description + default: {"keyA" : , keyB : "Big" } + entry_schema: + description: This is my property + type: string + string_prop06: + type: map + description : another description + default: {"keyA" : aaaA , keyB : null } + entry_schema: + description: This is my property + type: string + string_prop07: + type: map + description : another description + default: {"keyA" : NULL , keyB : Null } + entry_schema: + description: This is my property + type: string + string_prop08: + type: map + description : another description + default: {"keyA" : "" , keyB : "abcd" } + entry_schema: + description: This is my property + type: string + string_prop09: + type: map + description : another description + default: {"keyA" : " " , keyB : "abcd" } + entry_schema: + description: This is my property + type: string + string_prop10: + type: map + description : another description + default: {"keyA" : " aaaa" , keyB : " bbbb" } + entry_schema: + description: This is my property + type: string + string_prop11: + type: map + description : another description + default: {"keyA" : "aaaa " , keyB : "bbbb " } + entry_schema: + description: This is my property + type: string + string_prop12: + type: map + description : another description + default: {"keyA" : " aaaa " , keyB : " bbbb ccccc " } + entry_schema: + description: This is my property + type: string + string_prop13: + type: map + description : another description + default: + keyA : "aaaa" + entry_schema: + description: This is my property + type: string + string_prop14: + type: map + description : another description + default: + keyA : " aaaa " + entry_schema: + description: This is my property + type: string + string_prop15: + type: map + description : another description + default: + keyA : AbcD + entry_schema: + description: This is my property + type: string + string_prop16: + type: map + description : another description + default: + keyA : AbcD + entry_schema: + description: This is my property + type: string + string_prop17: + type: map + description : another description + default: + keyA : AbcD + entry_schema: + description: This is my property + type: string + string_prop18: + type: map + description : another description + default: + keyA : AbcD + entry_schema: + description: This is my property + type: string + string_prop19: + type: map + description : another description + default: + keyA : AbcD + entry_schema: + description: This is my property + type: string + string_prop20: + type: map + description : another description + default: + keyA : aaaa + keya : aaaa + Keya : Aaaa + KEYA : nnnn + entry_schema: + description: This is my property + type: string + string_prop21: + type: map + description : another description + default: + keyA : NULL + keyB : null + keyC : Null + entry_schema: + description: This is my property + type: string + string_prop22: + type: map + description : another description + default: + entry_schema: + description: This is my property + type: string + integer_prop01: + type: map + description : another description + default: {keyA : 1 , keyB : 1000} + entry_schema: + description: This is my property + type: integer + integer_prop02: + type: map + description : another description + default: {keyA : Null , keyB : NULL ,keyC : null } + entry_schema: + description: This is my property + type: integer + integer_prop03: + type: map + description : another description + default: {keyA : , keyB : -600} + entry_schema: + description: This is my property + type: integer + integer_prop03: + type: map + description : another description + default: {keyA : 800 , keyB : -600} + entry_schema: + description: This is my property + type: integer + integer_prop04: + type: map + description : another description + default: {keyA : , keyB : -600} + entry_schema: + description: This is my property + type: integer + integer_prop05: + type: map + description : another description + default: {keyA : 100 , keyB : 0 } + entry_schema: + description: This is my property + type: integer + integer_prop06: + type: map + description : another description + default: {keyA : 100 , keyB : 00} + entry_schema: + description: This is my property + type: integer + integer_prop07: + type: map + description : another description + default: {keyA : 100 , keyB : 100 } + entry_schema: + description: This is my property + type: integer + integer_prop08: + type: map + description : another description + default: + keyA : 100 + keyB : 200 + entry_schema: + description: This is my property + type: integer + integer_prop09: + type: map + description : another description + default: + keyA : 100 + keyB : 200 + entry_schema: + description: This is my property + type: integer + integer_prop10: + type: map + description : another description + default: + keyA : null + keyA : Null + keyB : 1111 + keyB : 2222 + entry_schema: + description: This is my property + type: integer + integer_prop11: + type: map + description : another description + default: + keyA : null + keyB : Null + keyC : NULL + keyD : + entry_schema: + description: This is my property + type: integer + integer_prop12: + type: map + description : another description + default: + entry_schema: + description: This is my property + type: integer + integer_prop13: + type: map + description : another description + default: {keyA : 100 , keyA : 200} + entry_schema: + description: This is my property + type: integer + boolean_prop01: + type: map + description : another description + default: {keyA : true , keyB : false , keyC : false } + entry_schema: + description: This is my property + type: boolean + boolean_prop02: + type: map + description : another description + default: {keyA : TRUE , keyB : FALSE , keyC : False } + entry_schema: + description: This is my property + type: boolean + boolean_prop03: + type: map + description : another description + default: + keyA : null + keyB : Null + keyC : NULL + keyD : + entry_schema: + description: This is my property + type: boolean + boolean_prop04: + type: map + description : another description + default: {keyA : Null , keyB : NULL ,keyC : null ,keyD : } + entry_schema: + description: This is my property + type: boolean + boolean_prop05: + type: map + description : another description + default: {keyA : true , keyB : false , keyC : false } + entry_schema: + description: This is my property + type: boolean + boolean_prop06: + type: map + description : another description + default: + keyA : true + keyB : true + keyC : false + entry_schema: + description: This is my property + type: boolean + boolean_prop07: + type: map + description : another description + default: + entry_schema: + description: This is my property + type: boolean + boolean_prop08: + type: map + description : another description + default: + keyA : false + keyA : true + keyB : true + keyB : false + entry_schema: + description: This is my property + type: boolean + boolean_prop09: + type: map + description : another description + default: {keyA : true,keyA : false,keyB : false,keyB : true} + entry_schema: + description: This is my property + type: boolean + float_prop01: + type: map + description : another description + default: {keyA : 1.20 , keyB : 3.56f , keyC : 33} + entry_schema: + description: This is my property + type: float + float_prop02: + type: map + description : another description + default: {keyA : 0.00, keyB : 0.0 , keyC : 0 } + entry_schema: + description: This is my property + type: float + float_prop03: + type: map + description : another description + default: {keyA : null, keyB : Null , keyC : NULL , keyD : } + entry_schema: + description: This is my property + type: float + float_prop04: + type: map + description : another description + default: {keyA : 1.20 , keyB : 3.56f , keyC : 33 } + entry_schema: + description: This is my property + type: float + float_prop05: + type: map + description : another description + default: + keyA : 33 + keyB : 1.2000 + keyC : 3.607f + keyD : 0 + entry_schema: + description: This is my property + type: float + float_prop06: + type: map + description : another description + default: + keyA : 33 + keyB : 1.2000 + keyC : 3.607f + entry_schema: + description: This is my property + type: float + float_prop07: + type: map + description : another description + default: + keyA : null + keyB : Null + keyC : NULL + keyD : + entry_schema: + description: This is my property + type: float + float_prop08: + type: map + description : another description + default: + entry_schema: + description: This is my property + type: float + float_prop09: + type: map + description : another description + default: + keyA : 3.5 + keyA : 0.01 + keyB : 3.6 + keyB : + entry_schema: + description: This is my property + type: float + float_prop10: + type: map + description : another description + default: {keyA : 0.0002} + entry_schema: + description: This is my property + type: float + float_prop11: + type: map + description : another description + default: {keyA : 0.000 , keyA : 003.56f, keyB : 33} + entry_schema: + description: This is my property + type: float + capabilities: + link: + type: tosca.capabilities.network.Linkable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent.yml new file mode 100644 index 0000000000..e4d626fca6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - Local_Storage: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent_DerivedFromMyCompute1.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent_DerivedFromMyCompute1.yml new file mode 100644 index 0000000000..7ae9552d6a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/importRequirementNameExistsOnParent_DerivedFromMyCompute1.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute2: + derived_from: org.openecomp.resource.MyCompute1 + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - Local_Storage: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInCapDefinition.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInCapDefinition.yml new file mode 100644 index 0000000000..301116c985 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInCapDefinition.yml @@ -0,0 +1,37 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +description: Template for vSCP -- connectable to OCS-FW -- temporary model for 1602 demo + +############################ +# The model capture four sub-components (VDUs) and their connectivity to six +# networks. +############################ + +node_types: + +#The node type for vSCP +#used for substitution mapping, or to describe vSCP resource in ASDC studio + org.openecomp.resource.vSCP-03-16: + derived_from: tosca.nodes.Root + requirements: + - sigtran_connection1: + capability: tosca.capabilities.Node + - sigtran_connection2: + capability: tosca.capabilities.Node + - ocs_connection: + capability: tosca.capabilities.Node + - oam_connection: + capability: tosca.capabilities.Node + - firewall: + capability: tosca.capabilities.Node + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: org.openecomp.capabilities.networkInterfaceNotFound \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInReqDefinition.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInReqDefinition.yml new file mode 100644 index 0000000000..d100dafdf9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/missingCapInReqDefinition.yml @@ -0,0 +1,25 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +description: Template for vSCP -- connectable to OCS-FW -- temporary model for 1602 demo + +############################ +# The model capture four sub-components (VDUs) and their connectivity to six +# networks. +############################ + +node_types: + +#The node type for vSCP +#used for substitution mapping, or to describe vSCP resource in ASDC studio + org.openecomp.resource.vSCP-03-16: + derived_from: tosca.nodes.Root + requirements: + - sigtran_connection1: + capability: org.openecomp.capabilities.networkInterfaceNotFound + - sigtran_connection2: + capability: tosca.capabilities.Node + - ocs_connection: + capability: tosca.capabilities.Node + - oam_connection: + capability: tosca.capabilities.Node + - firewall: + capability: tosca.capabilities.Node \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildCompute_NoReqCap.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildCompute_NoReqCap.yml new file mode 100644 index 0000000000..cc5b202bc7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildCompute_NoReqCap.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyChildCompute: + derived_from: org.openecomp.resource.MyFatherCompute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildWebApp_DerivedFromContainer.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildWebApp_DerivedFromContainer.yml new file mode 100644 index 0000000000..b7859d4c14 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myChildWebApp_DerivedFromContainer.yml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyChildWebApp: + derived_from: org.openecomp.resource.MyWebApp + properties: + context_root: + type: string + capabilities: + app_endpoint: + type: tosca.capabilities.Endpoint + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.WebServer + relationship: tosca.relationships.HostedOn \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myCompute.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myCompute.yml new file mode 100644 index 0000000000..98bf9b7902 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myCompute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeDerivedFromNotExists.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeDerivedFromNotExists.yml new file mode 100644 index 0000000000..2b2807395a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeDerivedFromNotExists.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.RootNotExists + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectDefenitionVersionValue.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectDefenitionVersionValue.yml new file mode 100644 index 0000000000..2fa3ad0c08 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectDefenitionVersionValue.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: toscaSimpleYaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectNameSpaceFormat.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectNameSpaceFormat.yml new file mode 100644 index 0000000000..d1a613fff2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeIncorrectNameSpaceFormat.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource2.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeNoDefenitionVersion.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeNoDefenitionVersion.yml new file mode 100644 index 0000000000..8084d049db --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeNoDefenitionVersion.yml @@ -0,0 +1,34 @@ +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeOccurencySuccess.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeOccurencySuccess.yml new file mode 100644 index 0000000000..40ae610c06 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeOccurencySuccess.yml @@ -0,0 +1,77 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, UNBOUNDED] + - local_storage200: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, 1] + - local_storage300: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, 10] + - local_storage400: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, 10000000] + - local_storage500: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [2, 3] + - local_storageNoOccurrences600: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpointNoOccurrence : + type: tosca.capabilities.Endpoint.Admin + endpoint200 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [1, 2] + endpoint300 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [1, 1] + endpoint400 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [1, 10] + endpoint500 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [1, 10000000] + endpoint600 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [1, UNBOUNDED ] + endpoint700 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [2, 4 ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeParssingFalure.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeParssingFalure.yml new file mode 100644 index 0000000000..b243add14a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeParssingFalure.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requiremens: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilitis: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeReqNameExistsOnDerived.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeReqNameExistsOnDerived.yml new file mode 100644 index 0000000000..43d92d1681 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeReqNameExistsOnDerived.yml @@ -0,0 +1,34 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute1: + derived_from: tosca.nodes.Compute + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - Local_Storage: #"local_storage" exists on parent + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeVF.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeVF.yml new file mode 100644 index 0000000000..90e771dab1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeVF.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.VF.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithNodeTypesTwice.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithNodeTypesTwice.yml new file mode 100644 index 0000000000..73b201eab4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithNodeTypesTwice.yml @@ -0,0 +1,42 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable + + org.openecomp.resource.example.TransactionSubsystem: + derived_from: tosca.nodes.Root + capabilities: + message_receiver: tosca.capabilities.Endpoint + requirements: + - database_endpoint: tosca.capabilities.Endpoint.Database \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithTopologyTemplate.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithTopologyTemplate.yml new file mode 100644 index 0000000000..c451eb2514 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myComputeWithTopologyTemplate.yml @@ -0,0 +1,44 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +topology_template: + description: Template of an application connecting to a database. + + node_templates: + web_app: + type: tosca.nodes.WebApplication.MyWebApp + requirements: + - host: web_server + - database_endpoint: db +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myFatherWebApp_derviedFromDocker.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myFatherWebApp_derviedFromDocker.yml new file mode 100644 index 0000000000..43a9a174f8 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myFatherWebApp_derviedFromDocker.yml @@ -0,0 +1,16 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyWebApp: + derived_from: tosca.nodes.WebApplication + properties: + context_root: + type: string + capabilities: + app_endpoint: + type: tosca.capabilities.Endpoint + requirements: + - HOSt: + capability: tosca.capabilities.Container.Docker + node: tosca.nodes.WebServer + relationship: tosca.relationships.HostedOn + occurrences: [ 1, 2 ] diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myLinkVL.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myLinkVL.yml new file mode 100644 index 0000000000..7c796d2801 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myLinkVL.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vl.MyLink: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myPortCP.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myPortCP.yml new file mode 100644 index 0000000000..ff255f2394 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/myPortCP.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.cp.MyPort: + derived_from: org.openecomp.resource.cp.Port + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.network.Bindable + node: org.openecomp.resource.vl.MyLink + relationship: tosca.relationships.BindTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/noContent.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/noContent.yml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure01.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure01.yml new file mode 100644 index 0000000000..f007a0fed2 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure01.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [2, 0] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure02.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure02.yml new file mode 100644 index 0000000000..0487b63cb3 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure02.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [-1, 2] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure03.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure03.yml new file mode 100644 index 0000000000..7afdffa59d --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure03.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [1, -2] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure04.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure04.yml new file mode 100644 index 0000000000..f8a582f401 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure04.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ , 2] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure05.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure05.yml new file mode 100644 index 0000000000..f1c6a93e1f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure05.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ 1, ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure06.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure06.yml new file mode 100644 index 0000000000..b0ef54b0eb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure06.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ 0 , 0 ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure07.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure07.yml new file mode 100644 index 0000000000..afd999f575 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure07.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ @ , 1 ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure08.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure08.yml new file mode 100644 index 0000000000..60efc99273 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure08.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ 1.0 , 2.0 ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure09.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure09.yml new file mode 100644 index 0000000000..d6ec7eabe6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure09.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ "1" , "2" ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure10.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure10.yml new file mode 100644 index 0000000000..27de429186 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure10.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure11.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure11.yml new file mode 100644 index 0000000000..5bdae3a5f5 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure11.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [ UNBOUNDED , UNBOUNDED ] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure31.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure31.yml new file mode 100644 index 0000000000..8c3034afce --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure31.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 2, 1] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure32.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure32.yml new file mode 100644 index 0000000000..4b5eba9110 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure32.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ -1, 2] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure33.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure33.yml new file mode 100644 index 0000000000..9c42e22aa1 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure33.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 1, -2] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure34.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure34.yml new file mode 100644 index 0000000000..49953b5834 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure34.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ , 2] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure35.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure35.yml new file mode 100644 index 0000000000..8d8985d7f7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure35.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 1 , ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure36.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure36.yml new file mode 100644 index 0000000000..12944507f6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure36.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 0 , 0 ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure37.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure37.yml new file mode 100644 index 0000000000..618c980e16 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure37.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 0 , # ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure38.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure38.yml new file mode 100644 index 0000000000..d0c4575c83 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure38.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ 1.0 , 2.0 ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure39.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure39.yml new file mode 100644 index 0000000000..024338d380 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure39.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ "1" , "2" ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure40.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure40.yml new file mode 100644 index 0000000000..a4a32ba772 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure40.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure41.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure41.yml new file mode 100644 index 0000000000..c3024a3ee4 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/occurencyFalure41.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.MyCompute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage100: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint100 : + type: tosca.capabilities.Endpoint.Admin + occurrences: [ UNBOUNDED, UNBOUNDED ] + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq11.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq11.yml new file mode 100644 index 0000000000..b9bda183e6 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq11.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.vfc4: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + requirements: + - host: + capability: tosca.capabilities.Container + relationship: tosca.relationships.HostedOn + occurrences: [1, 1] diff --git a/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq12.yml b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq12.yml new file mode 100644 index 0000000000..9676bcdb6c --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/importToscaResourceByCreateUrl/softwareComponentReq12.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + org.openecomp.resource.vfc.vfc1: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + requirements: + - host: + capability: tosca.capabilities.Container + relationship: tosca.relationships.HostedOn + occurrences: [1, 2] diff --git a/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topology.txt b/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topology.txt new file mode 100644 index 0000000000..f46af26605 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topology.txt @@ -0,0 +1 @@ +{"id":"c25811fc-e03f-401d-93ca-45d9bd312703","delegateId":"17710a88-f3d8-483d-aded-afee2906a8c1","delegateType":"topologytemplate","dependencies":[{"name":"tosca-normative-types-softwareComponent","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-webServer","version":"1.0.0.wd03-SNAPSHOT"},{"name":"apache-type","version":"2.0.0-SNAPSHOT"},{"name":"tosca-normative-types-compute","version":"1.0.0.wd03-SNAPSHOT"},{"name":"tosca-normative-types-root","version":"1.0.0.wd03-SNAPSHOT"}],"nodeTemplates":[{"key":"Compute_2","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}},{"key":"Apache","value":{"type":"alien.nodes.Apache","name":null,"properties":{"port":"80","document_root":"/var/www","version":"2.4"},"attributes":{"tosca_id":null,"tosca_name":null},"relationships":{"attachToCompute_2":{"type":"tosca.relationships.AttachTo","target":"Compute_2","requirementName":"dependency","requirementType":"tosca.capabilities.Root","targetedCapabilityName":"attach"}},"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"host":{"type":"tosca.nodes.Compute","properties":null}},"capabilities":{"secure_endpoint":{"type":"tosca.capabilities.Endpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"app_endpoint":{"type":"tosca.capabilities.Endpoint","properties":{"port":null,"protocol":{"value":"tcp","definition":false},"url_path":null,"secure":{"value":"false","definition":false}}},"host":{"type":"alien.capabilities.ApacheContainer","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null}},"artifacts":null}},{"key":"Compute","value":{"type":"tosca.nodes.Compute","name":null,"properties":{"disk_size":null,"num_cpus":null,"os_distribution":null,"os_arch":null,"mem_size":null,"os_type":null,"os_version":null},"attributes":{"ip_address":null,"tosca_id":null,"tosca_name":null},"relationships":null,"requirements":{"dependency":{"type":"tosca.capabilities.Root","properties":null},"network":{"type":"tosca.capabilities.Connectivity","properties":null}},"capabilities":{"host":{"type":"tosca.capabilities.Container","properties":{"valid_node_types":null}},"root":{"type":"tosca.capabilities.Root","properties":null},"attach":{"type":"tosca.capabilities.Attachment","properties":null},"scalable":{"type":"tosca.capabilities.Scalable","properties":{"max_intances":{"value":"1","definition":false},"default_instances":{"value":"1","definition":false},"min_intances":{"value":"1","definition":false}}}},"artifacts":null}}]} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topologyTemplate.txt b/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topologyTemplate.txt new file mode 100644 index 0000000000..f3fdf0297b --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/testCsarAPI/topologyTemplate.txt @@ -0,0 +1 @@ +{"id":"17710a88-f3d8-483d-aded-afee2906a8c1","name":"MichaelTest2","description":null,"topologyId":"c25811fc-e03f-401d-93ca-45d9bd312703"} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool10_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool10_false.yaml new file mode 100644 index 0000000000..b6faadd4f9 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool10_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: NO + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool11_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool11_false.yaml new file mode 100644 index 0000000000..7fb2923b04 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool11_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: 0 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool12_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool12_false.yaml new file mode 100644 index 0000000000..fd451aa3af --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool12_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: OFF + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool1_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool1_true.yaml new file mode 100644 index 0000000000..a253e4c8d7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool1_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: t + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool2_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool2_true.yaml new file mode 100644 index 0000000000..ce273b3522 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool2_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: true + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool3_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool3_true.yaml new file mode 100644 index 0000000000..4680eb6996 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool3_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: on + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool4_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool4_true.yaml new file mode 100644 index 0000000000..1ed7781831 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool4_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: y + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool5_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool5_true.yaml new file mode 100644 index 0000000000..c0b42e6288 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool5_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: yes + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool6_true.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool6_true.yaml new file mode 100644 index 0000000000..24b862b751 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool6_true.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: 1 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool7_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool7_false.yaml new file mode 100644 index 0000000000..7bad8efd6f --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool7_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: F + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool8_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool8_false.yaml new file mode 100644 index 0000000000..8b35e2adf7 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool8_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: FALSE + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool9_false.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool9_false.yaml new file mode 100644 index 0000000000..2768e0d480 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_bool9_false.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: N + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number1.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number1.yaml new file mode 100644 index 0000000000..fc7f84ca81 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number1.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: number + description: city name + default: 12 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number2.yaml b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number2.yaml new file mode 100644 index 0000000000..28ec3358be --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/tmp/positive_artifact_number2.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: number + description: city name + default: 12.12 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/uploadComponent/images/mysql.png b/asdc-tests/src/test/resources/CI/tests/uploadComponent/images/mysql.png new file mode 100644 index 0000000000..8e02f49b7b Binary files /dev/null and b/asdc-tests/src/test/resources/CI/tests/uploadComponent/images/mysql.png differ diff --git a/asdc-tests/src/test/resources/CI/tests/uploadComponent/mysql.yml b/asdc-tests/src/test/resources/CI/tests/uploadComponent/mysql.yml new file mode 100644 index 0000000000..a2eb4d423a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/uploadComponent/mysql.yml @@ -0,0 +1,85 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0_wd03 +description: MySQL RDBMS installation on a specific mounted volume path. +template_name: mysql-uploadComponent +template_version: 1.1.1-SNAPSHOT +template_author: FastConnect + +imports: + - "tosca-normative-types-root:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-compute:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-database:1.0.0.wd03-SNAPSHOT" + - "tosca-normative-types-DBMS:1.0.0.wd03-SNAPSHOT" + +node_types: + alien.nodes.Mysql-uploadComponent: + derived_from: tosca.nodes.Database + description: > + A node to install MySQL v5.5 database with data + on a specific attached volume. + capabilities: + host: + type: alien.capabilities.MysqlDatabase + properties: + valid_node_types: [ tosca.nodes.WebApplication ] + requirements: + - host: tosca.nodes.Compute + type: tosca.relationships.HostedOn + tags: + icon: /images/mysql.png + properties: + db_port: + type: integer + default: 3306 + description: The port on which the underlying database service will listen to data. + db_name: + type: string + required: true + default: wordpress + description: The logical name of the database. + db_user: + type: string + default: pass + description: The special user account used for database administration. + db_password: + type: string + default: pass + description: The password associated with the user account provided in the ‘db_user’ property. + bind_address: + type: boolean + default: true + required: false + description: If true,the server accepts TCP/IP connections on all server host IPv4 interfaces. + storage_path: + type: string + default: /mountedStorage + constraints: + - valid_values: [ "/mountedStorage", "/var/mysql" ] + interfaces: + Standard: + create: scripts/install_mysql.sh + start: + inputs: + VOLUME_HOME: { get_property: [SELF, storage_path] } + PORT: { get_property: [SELF, db_port] } + DB_NAME: { get_property: [SELF, db_name] } + DB_USER: { get_property: [SELF, db_user] } + DB_PASSWORD: { get_property: [SELF, db_password] } + BIND_ADRESS: { get_property: [SELF, bind_address] } + implementation: scripts/start_mysql.sh + fastconnect.cloudify.extensions: + start_detection: + inputs: + PORT: { get_property: [SELF, db_port] } + implementation: scripts/mysql_start_detection.groovy + artifacts: + - scripts: scripts + type: tosca.artifacts.File + +capability_types: + alien.capabilities.MysqlDatabase: + derived_from: tosca.capabilities.Container + +artifact_types: + tosca.artifacts.GroovyScript: + description: A groovy script (.groovy file) + file_ext: [groovy] diff --git a/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/install_mysql.sh b/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/install_mysql.sh new file mode 100644 index 0000000000..400bcf40cb --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/install_mysql.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +echo "Debian based MYSQL install 5..." +LOCK="/tmp/lockaptget" + +while true; do + if mkdir "${LOCK}" &>/dev/null; then + echo "MySQL take the lock" + break; + fi + echo "Waiting the end of one of our recipes..." + sleep 0.5 +done + +while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 ; do + echo "Waiting for other software managers to finish..." + sleep 0.5 +done +sudo rm -f /var/lib/dpkg/lock + +sudo apt-get update || (sleep 15; sudo apt-get update || exit ${1}) +sudo DEBIAN_FRONTEND=noninteractive apt-get -y install mysql-server-5.5 pwgen || exit ${1} +rm -rf "${LOCK}" + +sudo /etc/init.d/mysql stop +sudo rm -rf /var/lib/apt/lists/* +sudo rm -rf /var/lib/mysql/* +echo "MySQL Installation complete." \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/start_mysql.sh b/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/start_mysql.sh new file mode 100644 index 0000000000..648bd45756 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/uploadComponent/scripts/start_mysql.sh @@ -0,0 +1,105 @@ +#!/bin/bash + +echo "------------------------ ENV ------------------------" +echo "ENV VAR USED VOLUME_HOME : $VOLUME_HOME" +echo "ENV VAR USED PORT : $PORT" +echo "ENV VAR USED DB_NAME : $DB_NAME" +echo "ENV VAR USED DB_USER : $DB_USER" +echo "ENV VAR USED DB_PASSWORD : $DB_PASSWORD" +echo "---------------------------- ------------------------" + +CURRENT_PATH=`dirname "$0"` + +function StartMySQL { + echo "Starting MYSQL..." + sudo /etc/init.d/mysql stop + sudo /usr/bin/mysqld_safe > /dev/null 2>&1 & + RET=1 + while [[ RET -ne 0 ]]; do + echo "=> Waiting for confirmation of MySQL service startup" + sleep 5 + sudo mysql -uroot -e "status" > /dev/null 2>&1 + RET=$? + done +} + +function AllowFileSystemToMySQL { + MYSQL_DATA_DIR=$VOLUME_HOME/data + MYSQL_LOG=$VOLUME_HOME/logs + + echo "Setting data directory to $MYSQL_DATA_DIR an logs to $MYSQL_LOG ..." + if sudo test ! -d $MYSQL_DATA_DIR; then + echo "Creating DATA dir > $MYSQL_DATA_DIR ..." + sudo mkdir -p $MYSQL_DATA_DIR + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_DATA_DIR + fi + if sudo test ! -d $MYSQL_LOG; then + echo "Creating LOG dir > $MYSQL_LOG ..." + sudo mkdir -p $MYSQL_LOG + # mysql as owner and group owner + sudo chown -R mysql:mysql $MYSQL_LOG + fi + + # edit app mysql permission in : /etc/apparmor.d/usr.sbin.mysqld + COUNT_LINE=`sudo cat /etc/apparmor.d/usr.sbin.mysqld | wc -l` + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_DATA_DIR/** rwk," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/ r," /etc/apparmor.d/usr.sbin.mysqld + sudo sed -i "$(($COUNT_LINE)) i $MYSQL_LOG/** rwk," /etc/apparmor.d/usr.sbin.mysqld + + # reload app permission manager service + sudo service apparmor reload +} + +function UpdateMySQLConf { + echo "Updating MySQL conf files [DATA, LOGS]..." + sudo sed -i "s:/var/lib/mysql:$MYSQL_DATA_DIR:g" /etc/mysql/my.cnf + sudo sed -i "s:/var/log/mysql/error.log:$MYSQL_LOG/error.log:g" /etc/mysql/my.cnf + sudo sed -i "s:3306:$PORT:g" /etc/mysql/my.cnf + + if sudo test ! -f /usr/share/mysql/my-default.cnf; then + sudo cp /etc/mysql/my.cnf /usr/share/mysql/my-default.cnf + fi + if sudo test ! -f /etc/mysql/conf.d/mysqld_charset.cnf; then + sudo cp $configs/mysqld_charset.cnf /etc/mysql/conf.d/mysqld_charset.cnf + fi + + if [ "$BIND_ADRESS" == "true" ]; then + sudo sed -i "s/bind-address.*/bind-address = 0.0.0.0/" /etc/mysql/my.cnf + fi +} + +function InitMySQLDb { + # create database DB_NAME + if [ "$DB_NAME" ]; then + echo "INIT DATABASE $DB_NAME" + sudo mysql -u root -e "CREATE DATABASE $DB_NAME"; + fi + + # create user and give rights + if [ "$DB_USER" ]; then + echo "CREATE USER $DB_USER WITH PASSWORD $DB_PASSWORD AND GRAND RIGHTS ON $DB_NAME" + sudo mysql -uroot -e "CREATE USER '${DB_USER}'@'%' IDENTIFIED BY '$DB_PASSWORD'" + sudo mysql -uroot -e "GRANT ALL PRIVILEGES ON ${DB_NAME}.* TO '${DB_USER}'@'%' WITH GRANT OPTION" + sudo mysql -uroot -e "FLUSH PRIVILEGES" + fi +} + +# Create a new database path to the attched volume +if sudo test ! -d $VOLUME_HOME/data; then + echo "=> An empty or uninitialized MySQL volume is detected in $VOLUME_HOME/data" + AllowFileSystemToMySQL + UpdateMySQLConf + echo "=> Init new database path to $MYSQL_DATA_DIR" + sudo mysql_install_db --basedir=/usr --datadir=$MYSQL_DATA_DIR + echo "=> MySQL database initialized !" +else + echo "=> Using an existing volume of MySQL" + AllowFileSystemToMySQL + UpdateMySQLConf +fi + +# Finally start MySQL with new configuration +StartMySQL +InitMySQLDb \ No newline at end of file diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/artifact_unsupported.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/artifact_unsupported.yaml new file mode 100644 index 0000000000..764b8d4c58 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/artifact_unsupported.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: number123 + description: city name + default: 12.12 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool1.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool1.yaml new file mode 100644 index 0000000000..19119f3d9a --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool1.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: K + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool2.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool2.yaml new file mode 100644 index 0000000000..f9c09a4fed --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_bool2.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: boolean + description: city name + default: 11 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number1.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number1.yaml new file mode 100644 index 0000000000..9a489879cc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number1.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: number + description: city name + default: 1.2Noo + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number2.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number2.yaml new file mode 100644 index 0000000000..4c0e07affc --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_number2.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: number + description: city name + default: 1 2 3 + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_string1.yaml b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_string1.yaml new file mode 100644 index 0000000000..f52ef04712 --- /dev/null +++ b/asdc-tests/src/test/resources/CI/tests/yamlFieldsValidation/negative_artifact_string1.yaml @@ -0,0 +1,140 @@ +heat_template_version: 2013-05-23 +################################# +# +# Changes in v0.2: +# - Unique availability zone for each VM +# - LAN8 and SLAN networks removed according to latest Prod/Type I diagram +# - 2 DB VMs added +# - Images corrected +# - VM start-up order: SMP->DB->BE->FE (no error handling yet) +# - Provisioning scripts placeholders +# +################################# + +description: ASC Template + +parameters: + city_name: + type: string + description: city name + default: ×©×œ×•× + address: + type: string + description: address + default: Alonim + home_number: + type: number + description: home_number + default: 8 +resources: +# scp_be_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_be_wait_handle } +# count: 5 +# timeout: 300 +# scp_be_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# scp_fe_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: scp_fe_wait_handle } +# count: 2 +# timeout: 300 +# scp_fe_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# smp_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: smp_wait_handle } +# count: 2 +# timeout: 300 +# smp_wait_handle: +# type: OS::Heat::WaitConditionHandle +# +# db_wait_condition: +# type: OS::Heat::WaitCondition +# properties: +# handle: { get_resource: db_wait_handle } +# count: 2 +# timeout: 300 +# db_wait_handle: +# type: OS::Heat::WaitConditionHandle + + FE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + BE_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + SMP_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + DB_Affinity: + type: OS::Nova::ServerGroup + properties: + policies: ["anti-affinity"] + + FE_Clustering_KA: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_fe_cluster_net_id } + + FE_Clustering_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: FE_Clustering_KA } + cidr: { get_param: int_vscp_fe_cluster_cidr } + + Clustering_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_cluster_net_id } + + Clustering_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: Clustering_Network } + cidr: { get_param: int_vscp_cluster_cidr } + + DB_Network: + type: OS::Contrail::VirtualNetwork + properties: + name: { get_param: int_vscp_db_network_net_id } + + DB_Network_subnet: + type: OS::Neutron::Subnet + properties: + network_id: { get_resource: DB_Network } + cidr: { get_param: int_vscp_db_network_cidr } + + server_scp_be0: + type: OS::Nova::Server +# depends on: db_wait_condition + properties: + name: { get_param: vm_scp_be0_name } + image: { get_param: image_scp_be_id } +# availability_zone: { get_param: availability_zone_be0 } + flavor: { get_param: flavor_scp_be_id } + scheduler_hints: { group: { get_resource: BE_Affinity } } + networks: + - port: { get_resource: be0_port_3 } + - port: { get_resource: be0_port_4 } + - port: { get_resource: be0_port_5 } + - port: { get_resource: be0_port_7 } + metadata: + vnf_id: { get_param: vnf_id } + user_data: + str_replace: + template: | + #!/bin/bash + #todo: provision $vm_name + wc_notify --data-binary '{"status": "SUCCESS"}' + params: + $vm_name: {get_param: vm_scp_be0_name} +# wc_notify: { get_attr: ['scp_be_wait_handle', 'curl_cli'] } diff --git a/asdc-tests/src/test/resources/config.json b/asdc-tests/src/test/resources/config.json new file mode 100644 index 0000000000..71c9d35e59 --- /dev/null +++ b/asdc-tests/src/test/resources/config.json @@ -0,0 +1,12 @@ +{ + +catalogBeHost: behost, +catalogFeHost: fehost, +esHost: eshost, +catalogFePort: 8080, +catalogBePort: 8080, +esPort: 9200, +resourceConfigDir: "src/test/resources/CI/tests", +componentsConfigDir: "src/test/resources/CI/components" + +} \ No newline at end of file diff --git a/asdc-tests/src/test/resources/logback-test.xml b/asdc-tests/src/test/resources/logback-test.xml new file mode 100644 index 0000000000..03ce9d1243 --- /dev/null +++ b/asdc-tests/src/test/resources/logback-test.xml @@ -0,0 +1,13 @@ + + + + + + %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n + + + + + + + \ No newline at end of file diff --git a/asdc-tests/tarball.xml b/asdc-tests/tarball.xml new file mode 100644 index 0000000000..18bc00854f --- /dev/null +++ b/asdc-tests/tarball.xml @@ -0,0 +1,71 @@ + + bin + + tar + + + + ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar + ./ + ${project.artifactId}-${project.version}-jar-with-dependencies.jar + + + src/main/resources/ci/scripts/startTest.sh + ./ + startTest.sh + + + + src/main/resources/ci/conf/sdc.yaml + conf + sdc.yaml + + + src/main/resources/ci/conf/sdc-packages.yaml + conf + sdc-packages.yaml + + + src/main/resources/ci/conf/log4j.properties + conf + log4j.properties + + + src/main/resources/ci/conf/titan.properties + conf + titan.properties + + + ${project.basedir}/../catalog-be/src/main/resources/config/error-configuration.yaml + conf + error-configuration.yaml + + + ${project.basedir}/../catalog-be/src/main/resources/config/configuration.yaml + conf + configuration.yaml + + + + + + + + + src/test/resources + ./ + + + src/main/resources/ci/testSuites + ./testSuites + + + + + diff --git a/asdc-tests/testng.xml b/asdc-tests/testng.xml new file mode 100644 index 0000000000..8a47ef6d62 --- /dev/null +++ b/asdc-tests/testng.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/asdc-tests/testngLifeCycle.xml b/asdc-tests/testngLifeCycle.xml new file mode 100644 index 0000000000..aa390dc213 --- /dev/null +++ b/asdc-tests/testngLifeCycle.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/asdctool/.gitignore b/asdctool/.gitignore new file mode 100644 index 0000000000..72f53d03cf --- /dev/null +++ b/asdctool/.gitignore @@ -0,0 +1,3 @@ +/bin/ +/build/ +/target/ diff --git a/asdctool/.pydevproject b/asdctool/.pydevproject new file mode 100644 index 0000000000..40e9f40a0a --- /dev/null +++ b/asdctool/.pydevproject @@ -0,0 +1,5 @@ + + +Default +python 2.7 + diff --git a/asdctool/pom.xml b/asdctool/pom.xml new file mode 100644 index 0000000000..0166c88c2f --- /dev/null +++ b/asdctool/pom.xml @@ -0,0 +1,434 @@ + + 4.0.0 + + sdctool + jar + + + org.openecomp.sdc + sdc-main + 1.0.0-SNAPSHOT + + + + + + + org.openecomp.sdc.be + common-be + ${common-be.version} + compile + + + org.openecomp.sdc + common-app-api + ${common-app-api.version} + compile + + + + org.openecomp.sdc.be + catalog-dao + ${catalog-dao.version} + compile + + + + org.openecomp.sdc.be + catalog-model + ${catalog-model.version} + compile + + + + org.openecomp.sdc + catalog-be + ${asdc.full.version} + + + classes + + compile + + + + + + org.eclipse.jetty + jetty-server + 9.2.10.v20150310 + compile + + + + + org.apache.commons + commons-jci-core + compile + + + + org.eclipse.jetty + jetty-servlet + 9.2.10.v20150310 + compile + + + + org.glassfish.jersey.core + jersey-server + compile + + + + org.glassfish.jersey.containers + jersey-container-servlet-core + compile + + + + org.glassfish.jersey.containers + jersey-container-jetty-http + compile + + + + org.glassfish.jersey.media + jersey-media-moxy + compile + + + + org.glassfish.jersey.media + jersey-media-multipart + 2.14 + compile + + + + + org.slf4j + slf4j-api + compile + + + + ch.qos.logback + logback-classic + compile + + + + ch.qos.logback + logback-core + compile + + + + org.codehaus.groovy + groovy-all + compile + + + org.apache.commons + commons-configuration2 + 2.1 + compile + + + + + + com.thinkaurelius.titan + titan-core + ${titan.version} + compile + + + org.json + json + + + + + + com.thinkaurelius.titan + titan-cassandra + ${titan.version} + compile + + + + org.apache.tinkerpop + tinkergraph-gremlin + 3.0.1-incubating + compile + + + + org.apache.tinkerpop + gremlin-groovy + 3.0.1-incubating + compile + + + + com.tinkerpop.blueprints + blueprints-sail-graph + 2.5.0 + true + compile + + + + com.tinkerpop.blueprints + blueprints-graph-sail + 2.6.0 + true + compile + + + + + commons-logging + commons-logging + compile + + + + commons-codec + commons-codec + compile + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + compile + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + compile + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + compile + + + com.google.code.gson + gson + compile + + + org.apache.httpcomponents + httpclient + compile + + + org.apache.httpcomponents + httpcore + compile + + + + org.springframework + spring-core + compile + + + + org.springframework + spring-context + compile + + + org.springframework + spring-expression + compile + + + org.springframework + spring-beans + 4.0.7.RELEASE + compile + + + org.springframework + spring-aop + compile + + + + + cglib + cglib + 3.2.4 + compile + + + org.yaml + snakeyaml + compile + + + org.functionaljava + functionaljava + compile + + + + + org.elasticsearch + elasticsearch + compile + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${jackson.version} + compile + + + org.elasticsearch.plugin + shield + ${elastic-search.version} + compile + + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra.driver.version} + compile + + + com.datastax.cassandra + cassandra-driver-mapping + ${cassandra.driver.version} + compile + + + + org.apache.poi + com.springsource.org.apache.poi + 3.9.0.FINAL + compile + + + org.jdom + jdom + 2.0.2 + compile + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + + de.ruedigermoeller + fst + 2.47 + compile + + + + + junit + junit + 4.12 + test + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + true + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.5.5 + + + create.jar.with.dependencies + package + + single + + + + + jar-with-dependencies + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.6 + + + + ${project.artifactId} + false + ${project.basedir}/tarball.xml + + assemble-file + package + + single + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + + copy-sdctool-cassandra + install + + copy-resources + + + ${project.parent.basedir}/sdc-os-chef/sdc-cassandra/chef-repo/cookbooks/cassandra-actions/files/default + + + ./target + + sdctool.tar + + + + + + + + + + diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/Utils.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/Utils.java new file mode 100644 index 0000000000..3b7d3ec11d --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/Utils.java @@ -0,0 +1,152 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import org.apache.commons.configuration.Configuration; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; + +//import org.openecomp.sdc.be.auditing.impl.AuditingManager; + +//import org.openecomp.sdc.be.info.errors.ResponseFormat; + +public class Utils { + + private static Logger log = LoggerFactory.getLogger(Utils.class.getName()); + + public static String NEW_LINE = System.getProperty("line.separator"); + + public static Response buildOkResponse( + /* + * ResponseFormat errorResponseWrapper, + */int status, Object entity, Map additionalHeaders) { + // int status = errorResponseWrapper.getStatus(); + ResponseBuilder responseBuilder = Response.status(status); + if (entity != null) { + log.trace("returned entity is {}", entity.toString()); + responseBuilder = responseBuilder.entity(entity); + } + if (additionalHeaders != null) { + for (Entry additionalHeader : additionalHeaders.entrySet()) { + String headerName = additionalHeader.getKey(); + String headerValue = additionalHeader.getValue(); + log.trace("Adding header {} with value {} to the response", headerName, headerValue); + responseBuilder.header(headerName, headerValue); + } + } + return responseBuilder.build(); + } + + public static TitanGraph openGraph(Configuration conf) { + + TitanGraph graph = null; + try { + + graph = TitanFactory.open(conf); + + } catch (Exception e) { + log.error("Failed to start open graph", e); + } + + return graph; + + } + + public static boolean vertexLeftContainsRightProps(Map leftProps, Map rightProps) { + + if (rightProps != null) { + + for (Entry entry : rightProps.entrySet()) { + String key = entry.getKey(); + Object leftValue = leftProps.get(key); + Object rightValue = entry.getValue(); + if (leftValue == null) { + if (rightValue == null) { + continue; + } else { + log.debug("The key {} cannot be found in the properties {}", key, leftProps); + return false; + } + } + + // if (false == leftValue instanceof Map && false == leftValue + // instanceof List) { + if (false == leftValue.equals(rightValue)) { + log.trace("The value of key {} is different between properties {} vs {}", key, leftValue, rightValue); + return false; + } + // } + } + + } + + return true; + } + + public static void setProperties(Element element, Map properties) { + + if (properties != null && false == properties.isEmpty()) { + + Object[] propertyKeyValues = new Object[properties.size() * 2]; + int i = 0; + for (Entry entry : properties.entrySet()) { + propertyKeyValues[i++] = entry.getKey(); + propertyKeyValues[i++] = entry.getValue(); + } + + ElementHelper.attachProperties(element, propertyKeyValues); + + } + + } + + public static Map getProperties(Element element) { + + Map result = new HashMap(); + ; + + if (element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, + element.keys().toArray(new String[element.keys().size()])); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/DataMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/DataMigration.java new file mode 100644 index 0000000000..a78ea9bc18 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/DataMigration.java @@ -0,0 +1,830 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import com.carrotsearch.hppc.cursors.ObjectCursor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import com.google.gson.reflect.TypeToken; +import fj.data.Either; +import org.apache.commons.lang.SystemUtils; +import org.elasticsearch.action.search.SearchResponse; +import org.elasticsearch.cluster.metadata.IndexMetaData; +import org.elasticsearch.common.collect.ImmutableOpenMap; +import org.elasticsearch.common.settings.Settings; +import org.elasticsearch.common.unit.TimeValue; +import org.elasticsearch.index.query.QueryBuilder; +import org.elasticsearch.index.query.QueryBuilders; +import org.elasticsearch.search.SearchHit; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.cassandra.schema.Table; +import org.openecomp.sdc.be.dao.es.ElasticSearchClient; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.resources.data.auditing.*; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.io.*; +import java.lang.reflect.Type; +import java.net.MalformedURLException; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.EnumMap; +import java.util.Map; +import java.util.TimeZone; + +/** + * Created by mlando on 5/16/2016. + */ +public class DataMigration { + + private Gson gson = new Gson(); + + private ObjectMapper jsonMapper = new ObjectMapper(); + + private static Logger log = LoggerFactory.getLogger(DataMigration.class.getName()); + + protected ElasticSearchClient elasticSearchClient; + @Autowired + protected AuditCassandraDao auditCassandraDao; + @Autowired + protected ArtifactCassandraDao artifactCassandraDao; + private static final String dateFormatPattern = "yyyy-MM-dd HH:mm:ss.SSS z"; + private static SimpleDateFormat simpleDateFormat; + + /** + * the method exports and imports the records from ES to cassandra the flow + * will check to see if the files are not empty if the files are not empty + * the export will be skiped and the flow will use the existing files. the + * flow will check if the tables in cassandra are empty, if the tables are + * not empty the proces will stop and exit. if the tables are empty the + * method will import the records from the files. in case of a fail the flow + * will exit and clear all the Cassandra tables. + * + * @param appConfigDir + * the location of the dir in wich the output files will be + * stored + * @param exportFromEs + * should the es be exported again and overwrite the old export + * @param importToCassandra + * should we import the data into cassandra + * @return true in case the operation was successful. + */ + public boolean migrateDataESToCassndra(String appConfigDir, boolean exportFromEs, boolean importToCassandra) { + initFormater(); + if (!initEsClient()) + return false; + Map files = createOutPutFiles(appConfigDir, exportFromEs); + if (files == null) { + return false; + } + if (exportFromEs && filesEmpty(files)) { + Map printerWritersMap = createWriters(files); + if (printerWritersMap == null) { + return false; + } + try { + ImmutableOpenMap indexData = getIndexData(); + for (ObjectCursor key : indexData.keys()) { + if ("resources".equalsIgnoreCase(key.value)) { + if (!exportArtifacts(key.value, printerWritersMap)) { + return false; + } + } else if (key.value.startsWith("auditingevents")) { + if (!exportAudit(key.value, printerWritersMap)) { + return false; + } + } + } + } finally { + if (elasticSearchClient != null) { + elasticSearchClient.close(); + } + for (PrintWriter writer : printerWritersMap.values()) { + writer.close(); + } + } + } + if (importToCassandra && !importToCassndra(files)) { + return false; + } + + return true; + } + + private void initFormater() { + simpleDateFormat = new SimpleDateFormat(dateFormatPattern); + simpleDateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + } + + private boolean initEsClient() { + String configHome = System.getProperty("config.home"); + URL url = null; + Settings settings = null; + try { + if (SystemUtils.IS_OS_WINDOWS) { + url = new URL("file:///" + configHome + "/elasticsearch.yml"); + } else { + url = new URL("file:" + configHome + "/elasticsearch.yml"); + } + log.debug("URL {}", url); + settings = Settings.settingsBuilder().loadFromPath(Paths.get(url.toURI())).build(); + } catch (MalformedURLException | URISyntaxException e1) { + log.error("Failed to create URL in order to load elasticsearch yml", e1); + return true; + } + + this.elasticSearchClient = new ElasticSearchClient(); + this.elasticSearchClient.setClusterName(settings.get("cluster.name")); + this.elasticSearchClient.setLocal(settings.get("elasticSearch.local")); + this.elasticSearchClient.setTransportClient(settings.get("elasticSearch.transportclient")); + try { + elasticSearchClient.initialize(); + } catch (URISyntaxException e) { + e.printStackTrace(); + return false; + } + return true; + } + + /** + * the method clears all the cassandra tables + */ + private void truncateCassandraTable() { + log.info("import failed. truncating Cassandra tables."); + artifactCassandraDao.deleteAllArtifacts(); + auditCassandraDao.deleteAllAudit(); + } + + /** + * the method imports the records from the files into cassandra + * + * @param files + * a map of files holding + * @return true if the operation was successful + */ + private boolean importToCassndra(Map files) { + log.info("starting to import date into Cassandra."); + if (!validtaTablsNotEmpty(files)) + return true; + for (Table table : files.keySet()) { + log.info("importing recordes into {}", table.getTableDescription().getTableName()); + if (!handleImport(files, table)) { + truncateCassandraTable(); + return false; + } + } + log.info("finished to import date into Cassandra."); + return true; + } + + private boolean validtaTablsNotEmpty(Map files) { + for (Table table : files.keySet()) { + Either isTableEmptyRes = checkIfTableIsEmpty(table); + if (isTableEmptyRes.isRight() || !isTableEmptyRes.left().value()) { + log.error("Cassandra table {} is not empty operation aborted.", + table.getTableDescription().getTableName()); + return false; + } + } + return true; + } + + /** + * the method retrieves the fields from the given map and praprs them for + * storage as an audit according to the table name + * + * @param map + * the map from which we will retrive the fields enum values + * @param table + * the table we are going to store the record in. + * @return a enummap representing the audit record that is going to be + * created. + */ + private EnumMap createAuditMap(Map map, Table table) { + EnumMap auditingFields = new EnumMap<>(AuditingFieldsKeysEnum.class); + switch (table) { + case USER_ADMIN_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_AFTER, map.get("USER_AFTER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_BEFORE, map.get("USER_BEFORE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + break; + case USER_ACCESS_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_UID, map.get("USER")); + break; + case RESOURCE_ADMIN_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, map.get("INVARIANT_UUID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, map.get("CURR_VERSION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, map.get("CURR_STATE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, map.get("DID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, map.get("PREV_VERSION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, map.get("PREV_STATE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, map.get("RESOURCE_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, map.get("RESOURCE_TYPE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, map.get("DPREV_STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, map.get("DCURR_STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TOSCA_NODE_TYPE, map.get("TOSCA_NODE_TYPE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, map.get("COMMENT")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, map.get("ARTIFACT_DATA")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, map.get("PREV_ARTIFACT_UUID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, map.get("CURR_ARTIFACT_UUID")); + break; + case DISTRIBUTION_DOWNLOAD_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, map.get("RESOURCE_URL")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, map.get("CONSUMER_ID")); + break; + case DISTRIBUTION_ENGINE_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + if (map.get("TOPIC_NAME") != null) { + if (map.get("TOPIC_NAME").contains("-STATUS-")) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TOPIC_NAME, + map.get("TOPIC_NAME")); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_NOTIFICATION_TOPIC_NAME, + map.get("TOPIC_NAME")); + } + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TOPIC_NAME, + map.get("DSTATUS_TOPIC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_NOTIFICATION_TOPIC_NAME, + map.get("DNOTIF_TOPIC")); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, map.get("TOPIC_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ROLE, map.get("ROLE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, map.get("API_KEY")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, map.get("D_ENV")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, map.get("CONSUMER_ID")); + break; + case DISTRIBUTION_NOTIFICATION_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, map.get("CURR_STATE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, map.get("CURR_VERSION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, map.get("DID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, map.get("RESOURCE_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, map.get("RESOURCE_TYPE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, map.get("TOPIC_NAME")); + break; + case DISTRIBUTION_STATUS_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, map.get("RESOURCE_URL")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, map.get("DID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, map.get("TOPIC_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, map.get("CONSUMER_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME, map.get("STATUS_TIME")); + break; + case DISTRIBUTION_DEPLOY_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, map.get("DID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, map.get("RESOURCE_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, map.get("RESOURCE_TYPE")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, map.get("CURR_VERSION")); + break; + case DISTRIBUTION_GET_UEB_CLUSTER_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + if (map.get("STATUS_DESC") != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("STATUS_DESC")); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, map.get("CONSUMER_ID")); + break; + case AUTH_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_USER, map.get("USER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_URL, map.get("URL")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_STATUS, map.get("AUTH_STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_REALM, map.get("REALM")); + break; + case CONSUMER_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ECOMP_USER, map.get("ECOMP_USER")); + break; + case CATEGORY_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, map.get("SERVICE_INSTANCE_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_CATEGORY_NAME, map.get("CATEGORY_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SUB_CATEGORY_NAME, map.get("SUB_CATEGORY_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_GROUPING_NAME, map.get("GROUPING_NAME")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, map.get("RESOURCE_TYPE")); + break; + case GET_USERS_LIST_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DETAILS, map.get("DETAILS")); + break; + case GET_CATEGORY_HIERARCHY_EVENT: + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, map.get("TIMESTAMP")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, map.get("ACTION")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, map.get("DESC")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, map.get("STATUS")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, map.get("MODIFIER")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, map.get("REQUEST_ID")); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DETAILS, map.get("DETAILS")); + break; + default: + auditingFields = null; + break; + } + return auditingFields; + } + + /** + * the method reads the content of the file intended for a given table, and + * sores them in cassandra + * + * @param files + * a map of files from which the recordes will be retrieved. + * @param table + * the name of the table we want to look up in the files and sore + * in Cassandra // * @param store the function to call when + * storing recordes in cassndra + * @return true if the operation was successful + */ + private boolean handleImport(Map files, Table table) { + BufferedReader br = null; + try { + br = new BufferedReader(new FileReader(files.get(table))); + String line = null; + while ((line = br.readLine()) != null) { + CassandraOperationStatus res = null; + if (Table.ARTIFACT.equals(table)) { + res = artifactCassandraDao.saveArtifact(jsonMapper.readValue(line, ESArtifactData.class)); + } else { + Type type = new TypeToken>() { + }.getType(); + Map map = gson.fromJson(line, type); + EnumMap auditingFields = createAuditMap(map, table); + AuditingGenericEvent recordForCassandra = null; + try { + recordForCassandra = createAuditRecord(auditingFields); + } catch (ParseException e) { + log.error("filed to parse time stemp in recored {}", auditingFields); + return false; + } + + res = auditCassandraDao.saveRecord(recordForCassandra); + } + if (!res.equals(CassandraOperationStatus.OK)) { + log.error("save recored to cassndra {} failed with status {} aborting.", + table.getTableDescription().getTableName(), res); + return false; + } + } + return true; + } catch (IOException e) { + log.error("failed to read file", e); + return false; + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + log.error("failed to close file reader", e); + } + } + } + } + + /** + * the method checks if the given table is empty + * + * @param table + * the name of the table we want to check + * @return true if the table is empty + */ + private Either checkIfTableIsEmpty(Table table) { + if (Table.ARTIFACT.equals(table)) { + return artifactCassandraDao.isTableEmpty(table.getTableDescription().getTableName()); + } else { + return auditCassandraDao.isTableEmpty(table.getTableDescription().getTableName()); + } + } + + private boolean filesEmpty(Map files) { + for (Table table : files.keySet()) { + File file = files.get(table); + if (file.length() != 0) { + log.info("file:{} is not empty skipping export", table.getTableDescription().getTableName()); + return false; + } + } + return true; + } + + /** + * the method reads the records from es index of audit's into a file as + * json's. + * + * @param value + * the name of the index we want + * @param printerWritersMap + * a map of the writers we use to write to a file. + * @return true in case the export was successful. + */ + private boolean exportAudit(String value, Map printerWritersMap) { + log.info("stratng to export audit data from es index{} to file.", value); + QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); + SearchResponse scrollResp = elasticSearchClient.getClient().prepareSearch(value).setScroll(new TimeValue(60000)) + .setQuery(queryBuilder).setSize(100).execute().actionGet(); + while (true) { + for (SearchHit hit : scrollResp.getHits().getHits()) { + PrintWriter out = printerWritersMap.get(TypeToTableMapping.getTableByType(hit.getType())); + out.println(hit.getSourceAsString()); + } + scrollResp = elasticSearchClient.getClient().prepareSearchScroll(scrollResp.getScrollId()) + .setScroll(new TimeValue(60000)).execute().actionGet(); + if (scrollResp.getHits().getHits().length == 0) { + break; + + } + } + + log.info("export audit data from es to file. finished succsesfully"); + return true; + } + + /** + * the method reads the records from es index of resources into a file as + * json's. + * + * @param index + * the name of the index we want to read + * @param printerWritersMap + * a map of the writers we use to write to a file. + * @return true in case the export was successful. + */ + private boolean exportArtifacts(String index, Map printerWritersMap) { + log.info("stratng to export artifact data from es to file."); + PrintWriter out = printerWritersMap.get(Table.ARTIFACT); + QueryBuilder queryBuilder = QueryBuilders.matchAllQuery(); + SearchResponse scrollResp = elasticSearchClient.getClient().prepareSearch(index).setScroll(new TimeValue(60000)) + .setQuery(queryBuilder).setSize(100).execute().actionGet(); + while (true) { + for (SearchHit hit : scrollResp.getHits().getHits()) { + ; + out.println(hit.getSourceAsString()); + } + scrollResp = elasticSearchClient.getClient().prepareSearchScroll(scrollResp.getScrollId()) + .setScroll(new TimeValue(60000)).execute().actionGet(); + if (scrollResp.getHits().getHits().length == 0) { + break; + + } + } + + log.info("export artifact data from es to file. finished succsesfully"); + return true; + } + + /** + * the method retrieves all the indexes from elasticsearch + * + * @return a map of indexes and there metadata + */ + private ImmutableOpenMap getIndexData() { + return elasticSearchClient.getClient().admin().cluster().prepareState().get().getState().getMetaData() + .getIndices(); + } + + /** + * the method creates all the files and dir which holds them. in case the + * files exist they will not be created again. + * + * @param appConfigDir + * the base path under which the output dir will be created and + * the export result files the created filesa are named according + * to the name of the table into which it will be imported. + * @param exportToEs + * if true all the export files will be recreated + * @returnthe returns a map of tables and the files representing them them + */ + private Map createOutPutFiles(String appConfigDir, boolean exportToEs) { + Map result = new EnumMap(Table.class); + File outputDir = new File(appConfigDir + "/output/"); + if (!createOutPutFolder(outputDir)) { + return null; + } + for (Table table : Table.values()) { + File file = new File(outputDir + "/" + table.getTableDescription().getTableName()); + if (exportToEs) { + try { + if (file.exists()) { + Files.delete(file.toPath()); + } + } catch (IOException e) { + log.error("failed to delete output file " + file.getAbsolutePath(), e); + return null; + } + file = new File(outputDir + "/" + table.getTableDescription().getTableName()); + } + if (!file.exists()) { + try { + file.createNewFile(); + } catch (IOException e) { + log.error("failed to create output file " + file.getAbsolutePath(), e); + return null; + } + } + result.put(table, file); + + } + return result; + } + + /** + * the method create the writers to each file + * + * @param files + * a map of the files according to table + * @return returns a map of writers according to table. + */ + private Map createWriters(Map files) { + Map printerWritersMap = new EnumMap<>(Table.class); + try { + for (Table table : files.keySet()) { + log.info("creating writer for {}", table); + File file = files.get(table); + FileWriter fw = new FileWriter(file, true); + BufferedWriter bw = new BufferedWriter(fw); + PrintWriter out = new PrintWriter(bw); + printerWritersMap.put(table, out); + log.info("creating writer for {} was successful", table); + } + } catch (IOException e) { + log.error("create writer to file failed", e); + return null; + } + return printerWritersMap; + } + + /** + * the method creates the output dir in case it does not exist + * + * @param outputDir + * the path under wich the directory will be created. + * @return true in case the create was succsesful or the dir already exists + */ + private boolean createOutPutFolder(File outputDir) { + if (!outputDir.exists()) { + log.info("creating output dir" + outputDir.getAbsolutePath()); + try { + Files.createDirectories(outputDir.toPath()); + } catch (IOException e) { + log.error("failed to create output dir" + outputDir.getAbsolutePath(), e); + return false; + } + } + return true; + } + + public enum TypeToTableMapping { + USER_ADMIN_EVENT_TYPE(AuditingTypesConstants.USER_ADMIN_EVENT_TYPE, + Table.USER_ADMIN_EVENT), USER_ACCESS_EVENT_TYPE(AuditingTypesConstants.USER_ACCESS_EVENT_TYPE, + Table.USER_ACCESS_EVENT), RESOURCE_ADMIN_EVENT_TYPE( + AuditingTypesConstants.RESOURCE_ADMIN_EVENT_TYPE, + Table.RESOURCE_ADMIN_EVENT), DISTRIBUTION_DOWNLOAD_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_DOWNLOAD_EVENT_TYPE, + Table.DISTRIBUTION_DOWNLOAD_EVENT), DISTRIBUTION_ENGINE_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_ENGINE_EVENT_TYPE, + Table.DISTRIBUTION_ENGINE_EVENT), DISTRIBUTION_NOTIFICATION_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_NOTIFICATION_EVENT_TYPE, + Table.DISTRIBUTION_NOTIFICATION_EVENT), DISTRIBUTION_STATUS_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_STATUS_EVENT_TYPE, + Table.DISTRIBUTION_STATUS_EVENT), DISTRIBUTION_DEPLOY_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_DEPLOY_EVENT_TYPE, + Table.DISTRIBUTION_DEPLOY_EVENT), DISTRIBUTION_GET_UEB_CLUSTER_EVENT_TYPE( + AuditingTypesConstants.DISTRIBUTION_GET_UEB_CLUSTER_EVENT_TYPE, + Table.DISTRIBUTION_GET_UEB_CLUSTER_EVENT), AUTH_EVENT_TYPE( + AuditingTypesConstants.AUTH_EVENT_TYPE, + Table.AUTH_EVENT), CONSUMER_EVENT_TYPE( + AuditingTypesConstants.CONSUMER_EVENT_TYPE, + Table.CONSUMER_EVENT), CATEGORY_EVENT_TYPE( + AuditingTypesConstants.CATEGORY_EVENT_TYPE, + Table.CATEGORY_EVENT), GET_USERS_LIST_EVENT_TYPE( + AuditingTypesConstants.GET_USERS_LIST_EVENT_TYPE, + Table.GET_USERS_LIST_EVENT), GET_CATEGORY_HIERARCHY_EVENT_TYPE( + AuditingTypesConstants.GET_CATEGORY_HIERARCHY_EVENT_TYPE, + Table.GET_CATEGORY_HIERARCHY_EVENT); + + String typeName; + Table table; + + TypeToTableMapping(String typeName, Table table) { + this.typeName = typeName; + this.table = table; + } + + public String getTypeName() { + return typeName; + } + + public Table getTable() { + return table; + } + + public static Table getTableByType(String type) { + for (TypeToTableMapping mapping : TypeToTableMapping.values()) { + if (mapping.getTypeName().equalsIgnoreCase(type)) { + return mapping.getTable(); + } + } + return null; + } + } + + public static AuditingGenericEvent createAuditRecord(EnumMap auditingFields) + throws ParseException { + AuditingActionEnum actionEnum = AuditingActionEnum + .getActionByName((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_ACTION)); + String tableName = actionEnum.getAuditingEsType(); + AuditingGenericEvent event = null; + Date date = null; + switch (tableName) { + case AuditingTypesConstants.USER_ADMIN_EVENT_TYPE: + UserAdminEvent userAdminEvent = new UserAdminEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + userAdminEvent.setTimestamp1(date); + event = userAdminEvent; + break; + case AuditingTypesConstants.AUTH_EVENT_TYPE: + AuthEvent authEvent = new AuthEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + authEvent.setTimestamp1(date); + event = authEvent; + break; + case AuditingTypesConstants.CATEGORY_EVENT_TYPE: + CategoryEvent categoryEvent = new CategoryEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + categoryEvent.setTimestamp1(date); + event = categoryEvent; + break; + case AuditingTypesConstants.RESOURCE_ADMIN_EVENT_TYPE: + ResourceAdminEvent resourceAdminEvent = new ResourceAdminEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + resourceAdminEvent.setTimestamp1(date); + event = resourceAdminEvent; + break; + case AuditingTypesConstants.USER_ACCESS_EVENT_TYPE: + event = new UserAccessEvent(auditingFields); + UserAccessEvent userAccessEvent = new UserAccessEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + userAccessEvent.setTimestamp1(date); + event = userAccessEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_STATUS_EVENT_TYPE: + DistributionStatusEvent distributionStatusEvent = new DistributionStatusEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + distributionStatusEvent.setTimestamp1(date); + event = distributionStatusEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_DOWNLOAD_EVENT_TYPE: + DistributionDownloadEvent distributionDownloadEvent = new DistributionDownloadEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + distributionDownloadEvent.setTimestamp1(date); + event = distributionDownloadEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_ENGINE_EVENT_TYPE: + DistributionEngineEvent distributionEngineEvent = new DistributionEngineEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + distributionEngineEvent.setTimestamp1(date); + event = distributionEngineEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_NOTIFICATION_EVENT_TYPE: + DistributionNotificationEvent distributionNotificationEvent = new DistributionNotificationEvent( + auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + distributionNotificationEvent.setTimestamp1(date); + event = distributionNotificationEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_DEPLOY_EVENT_TYPE: + DistributionDeployEvent distributionDeployEvent = new DistributionDeployEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + distributionDeployEvent.setTimestamp1(date); + event = distributionDeployEvent; + break; + case AuditingTypesConstants.DISTRIBUTION_GET_UEB_CLUSTER_EVENT_TYPE: + AuditingGetUebClusterEvent auditingGetUebClusterEvent = new AuditingGetUebClusterEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + auditingGetUebClusterEvent.setTimestamp1(date); + event = auditingGetUebClusterEvent; + break; + case AuditingTypesConstants.CONSUMER_EVENT_TYPE: + ConsumerEvent consumerEvent = new ConsumerEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + consumerEvent.setTimestamp1(date); + event = consumerEvent; + break; + case AuditingTypesConstants.GET_USERS_LIST_EVENT_TYPE: + GetUsersListEvent getUsersListEvent = new GetUsersListEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + getUsersListEvent.setTimestamp1(date); + event = getUsersListEvent; + break; + case AuditingTypesConstants.GET_CATEGORY_HIERARCHY_EVENT_TYPE: + GetCategoryHierarchyEvent getCategoryHierarchyEvent = new GetCategoryHierarchyEvent(auditingFields); + date = simpleDateFormat.parse((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP)); + getCategoryHierarchyEvent.setTimestamp1(date); + event = getCategoryHierarchyEvent; + break; + + } + return event; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/EsToCassandraDataMigrationConfig.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/EsToCassandraDataMigrationConfig.java new file mode 100644 index 0000000000..2c0471fb17 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/EsToCassandraDataMigrationConfig.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraClient; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class EsToCassandraDataMigrationConfig { + @Bean(name = "DataMigrationBean") + public DataMigration dataMigration() { + return new DataMigration(); + } + + @Bean(name = "artifact-cassandra-dao") + public ArtifactCassandraDao artifactCassandraDao() { + return new ArtifactCassandraDao(); + } + + @Bean(name = "audit-cassandra-dao") + public AuditCassandraDao auditCassandraDao() { + return new AuditCassandraDao(); + } + + @Bean(name = "cassandra-client") + public CassandraClient cassandraClient() { + return new CassandraClient(); + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLConverter.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLConverter.java new file mode 100644 index 0000000000..bf62072235 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLConverter.java @@ -0,0 +1,694 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.commons.configuration.BaseConfiguration; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Element; +import org.apache.tinkerpop.gremlin.structure.Graph; +import org.apache.tinkerpop.gremlin.structure.Property; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.io.IoCore; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONMapper; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONReader; +import org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONWriter; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.asdctool.Utils; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanGraphQuery; +import com.thinkaurelius.titan.core.TitanVertex; +//import com.tinkerpop.blueprints.Direction; +//import com.tinkerpop.blueprints.Edge; +//import com.tinkerpop.blueprints.Vertex; +//import com.tinkerpop.blueprints.util.ElementHelper; +//import com.tinkerpop.blueprints.util.io.graphson.GraphSONReader; +//import com.tinkerpop.blueprints.util.io.graphson.GraphSONWriter; + +public class GraphMLConverter { + + private static Logger log = LoggerFactory.getLogger(GraphMLConverter.class.getName()); + + private Gson gson = new Gson(); + + public boolean importGraph(String[] args) { + + TitanGraph graph = null; + try { + String titanFileLocation = args[1]; + String inputFile = args[2]; + graph = openGraph(titanFileLocation); + + List> propertiesCriteriaToDelete = new ArrayList<>(); + ImmutablePair immutablePair1 = new ImmutablePair("healthcheckis", "GOOD"); + ImmutablePair immutablePair2 = new ImmutablePair("nodeLabel", "user"); + ImmutablePair immutablePair3 = new ImmutablePair("nodeLabel", + "resourceCategory"); + ImmutablePair immutablePair4 = new ImmutablePair("nodeLabel", + "serviceCategory"); + + propertiesCriteriaToDelete.add(immutablePair1); + propertiesCriteriaToDelete.add(immutablePair2); + propertiesCriteriaToDelete.add(immutablePair3); + propertiesCriteriaToDelete.add(immutablePair4); + + boolean result = importJsonGraph(graph, inputFile, propertiesCriteriaToDelete); + + return result; + + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + if (graph != null) { + // graph.shutdown(); + graph.close(); + } + } + + } + + public boolean exportGraph(String[] args) { + + TitanGraph graph = null; + try { + String titanFileLocation = args[1]; + String outputDirectory = args[2]; + graph = openGraph(titanFileLocation); + + String result = exportJsonGraph(graph, outputDirectory); + + if (result == null) { + return false; + } + + System.out.println("Exported file=" + result); + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + if (graph != null) { + // graph.shutdown(); + graph.close(); + } + } + + return true; + } + + public String exportGraphMl(String[] args) { + + TitanGraph graph = null; + String result = null; + try { + String titanFileLocation = args[1]; + String outputDirectory = args[2]; + graph = openGraph(titanFileLocation); + + result = exportGraphMl(graph, outputDirectory); + + System.out.println("Exported file=" + result); + } catch (Exception e) { + e.printStackTrace(); + return null; + } finally { + if (graph != null) { + graph.close(); + } + } + + return result; + } + + public boolean findErrorInJsonGraph(String[] args) { + + TitanGraph graph = null; + try { + String titanFileLocation = args[1]; + String outputDirectory = args[2]; + graph = openGraph(titanFileLocation); + + String result = findErrorInJsonGraph(graph, outputDirectory); + + if (result == null) { + return false; + } + + System.out.println("Exported file=" + result); + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + if (graph != null) { + // graph.shutdown(); + graph.close(); + } + } + + return true; + } + + public TitanGraph openGraph(String titanFileLocation) { + + TitanGraph graph = TitanFactory.open(titanFileLocation); + + return graph; + + } + + public String exportJsonGraph(TitanGraph graph, String outputDirectory) { + + String result = null; + + // GraphMLWriter graphMLWriter = new GraphMLWriter(graph); + + String outputFile = outputDirectory + File.separator + "exportGraph." + System.currentTimeMillis() + ".json"; + + OutputStream out = null; + try { + out = new BufferedOutputStream(new FileOutputStream(outputFile)); + + // GraphSONWriter.outputGraph(graph, outputFile); + final GraphSONWriter.Builder builder = GraphSONWriter.build(); + final GraphSONMapper mapper = newGraphSONMapper(graph); + builder.mapper(mapper); + final GraphSONWriter writer = builder.create(); + writer.writeGraph(out, graph); + + // GraphSONWriter create = GraphSONWriter.build(). create(); + // create.writeGraph(out, graph); + + // graph.commit(); + graph.tx().commit(); + + result = outputFile; + + } catch (Exception e) { + e.printStackTrace(); + graph.tx().rollback(); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + + } + + public String exportGraphMl(TitanGraph graph, String outputDirectory) { + String result = null; + String outputFile = outputDirectory + File.separator + "exportGraph." + System.currentTimeMillis() + ".graphml"; + try { + try (final OutputStream os = new BufferedOutputStream(new FileOutputStream(outputFile))) { + graph.io(IoCore.graphml()).writer().normalize(true).create().writeGraph(os, graph); + } + result = outputFile; + graph.tx().commit(); + } catch (Exception e) { + graph.tx().rollback(); + e.printStackTrace(); + } + return result; + + } + + private static GraphSONMapper newGraphSONMapper(final Graph graph) { + final GraphSONMapper.Builder builder = graph.io(IoCore.graphson()).mapper(); + // Different failure with embedded type info. + // builder.embedTypes(true); + return builder.create(); + } + + public boolean importJsonGraph(TitanGraph graph, String graphJsonFile, + List> propertiesCriteriaToDelete) { + + boolean result = false; + + InputStream is = null; + + try { + + if (propertiesCriteriaToDelete != null) { + for (Entry entry : propertiesCriteriaToDelete + + ) { + + String key = entry.getKey(); + String value = entry.getValue(); + Iterator iterator = graph.query().has(key, value).vertices().iterator(); + while (iterator.hasNext()) { + Vertex vertex = (Vertex) iterator.next(); + vertex.remove(); + System.out.println("Remove vertex of type " + key + " and value " + value); + } + + } + } + File file = new File(graphJsonFile); + if (false == file.isFile()) { + System.out.println("File " + graphJsonFile + " cannot be found."); + return result; + } + + is = new BufferedInputStream(new FileInputStream(graphJsonFile)); + System.out.println("Before importing file " + graphJsonFile); + + // GraphSONReader.inputGraph(graph, graphJsonFile); + GraphSONReader create = GraphSONReader.build().create(); + create.readGraph(is, graph); + + // graph.commit(); + graph.tx().commit(); + + result = true; + + } catch (Exception e) { + System.out.println("Failed to import graph " + e.getMessage()); + e.printStackTrace(); + // graph.rollback(); + graph.tx().rollback(); + } finally { + try { + if (is != null) { + is.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + return result; + + } + + public String findErrorInJsonGraph(TitanGraph graph, String outputDirectory) { + + boolean runVertexScan = false; + boolean runEdgeScan = false; + + String result = null; + + // GraphMLWriter graphMLWriter = new GraphMLWriter(graph); + + String outputFile = outputDirectory + File.separator + "exportGraph." + System.currentTimeMillis() + ".json"; + + OutputStream out = null; + try { + out = new BufferedOutputStream(new FileOutputStream(outputFile)); + + if (runEdgeScan) { + + Vertex vertexFrom = null; + Vertex vertexTo = null; + Edge edge = null; + + // Iterable edges = graph.getEdges(); + // Iterable edges = graph.query().edges(); + Iterable edges = graph.query().edges(); + // Iterator iterator = edges.iterator(); + Iterator iterator = edges.iterator(); + while (iterator.hasNext()) { + + try { + + edge = iterator.next(); + + // vertexFrom = edge.getVertex(Direction.OUT); + // vertexTo = edge.getVertex(Direction.IN); + vertexFrom = edge.outVertex(); + vertexTo = edge.inVertex(); + + BaseConfiguration conf = new BaseConfiguration(); + conf.setProperty("storage.backend", "inmemory"); + TitanGraph openGraph = Utils.openGraph(conf); + + TitanVertex addVertexFrom = openGraph.addVertex(); + // ElementHelper.setProperties(addVertexFrom, + // ElementHelper.getProperties(vertexFrom)); + Utils.setProperties(addVertexFrom, Utils.getProperties(vertexFrom)); + + TitanVertex addVertexTo = openGraph.addVertex(); + // ElementHelper.setProperties(addVertexTo, + // ElementHelper.getProperties(vertexTo)); + Utils.setProperties(addVertexTo, Utils.getProperties(vertexTo)); + + // Edge addEdge = openGraph.addEdge(null, addVertexFrom, + // addVertexTo, edge.getLabel()); + + // Edge edge = tGraph.addEdge(null, + // fromV.left().value(), toV.left().value(), type); + + Edge addEdge = addVertexFrom.addEdge(edge.label(), addVertexTo); + // ElementHelper.setProperties(addEdge, + // ElementHelper.getProperties(edge)); + Utils.setProperties(addEdge, Utils.getProperties(edge)); + + // log.info("fromVertex=" + + // ElementHelper.getProperties(vertexFrom)); + log.info("fromVertex=" + Utils.getProperties(vertexFrom)); + // log.info("toVertex=" + + // ElementHelper.getProperties(vertexTo)); + log.info("toVertex=" + Utils.getProperties(vertexTo)); + // log.info("edge=" + edge.getLabel() + " " + + // ElementHelper.getProperties(edge)); + log.info("edge=" + edge.label() + " " + Utils.getProperties(edge)); + + // GraphSONWriter.outputGraph(openGraph, outputFile); + GraphSONWriter create = GraphSONWriter.build().create(); + create.writeGraph(out, openGraph); + + // openGraph.rollback(); + openGraph.tx().rollback(); + + } catch (Exception e) { + e.printStackTrace(); + + // log.error("fromVertex=" + + // ElementHelper.getProperties(vertexFrom)); + log.error("fromVertex=" + Utils.getProperties(vertexFrom)); + // log.error("toVertex=" + + // ElementHelper.getProperties(vertexTo)); + log.error("toVertex=" + Utils.getProperties(vertexTo)); + // log.error("edge=" + edge.getLabel() + " " + + // ElementHelper.getProperties(edge)); + log.error("edge=" + edge.label() + " " + Utils.getProperties(edge)); + + break; + + } + } + + // graph.rollback(); + graph.tx().rollback(); + + } + + if (runVertexScan) { + + Vertex vertex = null; + // Iterable vertices = graph.getVertices(); + + // Iterator iteratorVertex = vertices.iterator(); + Iterator iteratorVertex = graph.vertices(); + while (iteratorVertex.hasNext()) { + + try { + + vertex = iteratorVertex.next(); + + // Iterable edges2 = + // vertex.getEdges(Direction.BOTH); + + // Iterator iterator2 = edges2.iterator(); + Iterator iterator2 = vertex.edges(Direction.BOTH); + if (false == iterator2.hasNext()) { + + BaseConfiguration conf = new BaseConfiguration(); + conf.setProperty("storage.backend", "inmemory"); + TitanGraph openGraph = Utils.openGraph(conf); + + TitanVertex addVertexFrom = openGraph.addVertex(); + // ElementHelper.setProperties(addVertexFrom, + // ElementHelper.getProperties(vertex)); + Utils.setProperties(addVertexFrom, Utils.getProperties(vertex)); + + // log.info("fromVertex=" + + // ElementHelper.getProperties(addVertexFrom)); + log.info("fromVertex=" + Utils.getProperties(addVertexFrom)); + + // GraphSONWriter.outputGraph(openGraph, + // outputFile); + GraphSONWriter create = GraphSONWriter.build().create(); + create.writeGraph(out, openGraph); + + // openGraph.rollback(); + openGraph.tx().rollback(); + + } + + } catch (Exception e) { + e.printStackTrace(); + + // log.error("vertex=" + + // ElementHelper.getProperties(vertex)); + + GraphPropertiesDictionary[] values = GraphPropertiesDictionary.values(); + + // Object property1 = + // vertex.getProperty(GraphPropertiesDictionary.HEALTH_CHECK.getProperty()); + Object property1 = vertex.value(GraphPropertiesDictionary.HEALTH_CHECK.getProperty()); + System.out.println(property1); + + // Object property2 = vertex.getProperty("healthcheck"); + Object property2 = vertex.value("healthcheck"); + System.out.println(property2); + + // for (GraphPropertiesDictionary value : values) { + // + // System.out.println(property); + // } + + break; + + } + } + + // graph.rollback(); + graph.tx().rollback(); + + } + + // Iterable vertices2 = + // graph.getVertices(GraphPropertiesDictionary.HEALTH_CHECK.getProperty(), + // "GOOD"); + Iterable vertices2 = graph.query() + .has(GraphPropertiesDictionary.HEALTH_CHECK.getProperty(), "GOOD").vertices(); + ; + Vertex next = vertices2.iterator().next(); + + BaseConfiguration conf = new BaseConfiguration(); + conf.setProperty("storage.backend", "inmemory"); + TitanGraph openGraph = Utils.openGraph(conf); + + // TitanVertex addVertexFrom = openGraph.addVertex(); + // + // addVertexFrom.setProperty(GraphPropertiesDictionary.HEALTH_CHECK.getProperty(), + // "GOOD"); + // addVertexFrom.setProperty("healthcheck", + // next.getProperty("healthcheck")); + // + // //next.remove(); + // + // next.removeProperty("healthcheck"); + // next.removeProperty("healthcheckis"); + // + // next.remove(); + + // GraphSONWriter.outputGraph(openGraph, outputFile); + + for (NodeTypeEnum nodeTypeEnum : NodeTypeEnum.values()) { + removeNodesByLabel(graph, nodeTypeEnum.getName()); + } + + // GraphSONWriter.outputGraph(graph, outputFile); + + GraphSONWriter create = GraphSONWriter.build().create(); + create.writeGraph(out, graph); + + // graph.rollback(); + graph.tx().rollback(); + + } catch (Exception e) { + e.printStackTrace(); + // graph.rollback(); + graph.tx().rollback(); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + + } + + private void removeNodesByLabel(TitanGraph graph, String label) { + Iterable vertices = graph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), label) + .vertices(); + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex next2 = iterator.next(); + next2.remove(); + } + } + + public static void clearGraph(TitanGraph graph) { + + Iterable vertices = graph.query().vertices(); + + long erased = 0; + + if (vertices != null) { + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + Vertex vertex = iterator.next(); + // graph.removeVertex(vertex); + vertex.remove(); + erased++; + } + + } + + System.out.println("After erasing " + erased + " vertices."); + // graph.commit(); + graph.tx().commit(); + } + + public String exportUsers(TitanGraph graph, String outputDirectory) { + + List> users = new ArrayList<>(); + String result = null; + + // GraphMLWriter graphMLWriter = new GraphMLWriter(graph); + + String outputFile = outputDirectory + File.separator + "users." + System.currentTimeMillis() + ".json"; + + FileWriter fileWriter = null; + try { + + TitanGraphQuery graphQuery = graph.query().has(GraphPropertiesDictionary.LABEL.getProperty(), + NodeTypeEnum.User.getName()); + + @SuppressWarnings("unchecked") + Iterable vertices = graphQuery.vertices(); + + if (vertices != null) { + for (Vertex v : vertices) { + Map properties = getProperties(v); + properties.remove(GraphPropertiesDictionary.LABEL.getProperty()); + users.add(properties); + } + } + + graph.tx().commit(); + + String jsonUsers = gson.toJson(users); + + fileWriter = new FileWriter(outputFile); + fileWriter.write(jsonUsers); + + result = outputFile; + + } catch (Exception e) { + e.printStackTrace(); + graph.tx().rollback(); + } finally { + try { + if (fileWriter != null) { + fileWriter.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + return result; + + } + + public Map getProperties(Element element) { + + Map result = new HashMap(); + ; + + if (element.keys() != null && element.keys().size() > 0) { + Map propertyMap = ElementHelper.propertyMap(element, + element.keys().toArray(new String[element.keys().size()])); + + for (Entry entry : propertyMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue().value(); + + result.put(key, value); + } + } + return result; + } + + public boolean exportUsers(String[] args) { + + TitanGraph graph = null; + try { + String titanFileLocation = args[1]; + String outputDirectory = args[2]; + graph = openGraph(titanFileLocation); + + String result = exportUsers(graph, outputDirectory); + + if (result == null) { + return false; + } + + System.out.println("Exported file=" + result); + } catch (Exception e) { + e.printStackTrace(); + return false; + } finally { + if (graph != null) { + // graph.shutdown(); + graph.close(); + } + } + + return true; + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java new file mode 100644 index 0000000000..77163b4cc5 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/GraphMLDataAnalyzer.java @@ -0,0 +1,364 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import java.io.File; +import java.io.FileOutputStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.filter.ElementFilter; +import org.jdom2.input.SAXBuilder; +import org.jdom2.util.IteratorIterable; + +public class GraphMLDataAnalyzer { + + private static final String[] COMPONENT_SHEET_HEADER = { "uniqueId", "type", "name", "toscaResourceName", + "resourceType", "version", "deleted", "hasNonCalculatedReqCap" }; + private static final String[] COMPONENT_INSTANCES_SHEET_HEADER = { "uniqueId", "name", "originUid", "originType", + "containerUid" }; + + public String analyzeGraphMLData(String[] args) { + String result = null; + try { + String mlFileLocation = args[0]; + result = _analyzeGraphMLData(mlFileLocation); + System.out.println("Analyzed ML file=" + mlFileLocation + ", XLS result=" + result); + } catch (Exception e) { + e.printStackTrace(); + return null; + } + return result; + } + + private String _analyzeGraphMLData(String mlFileLocation) throws Exception { + + // Parse ML file + SAXBuilder builder = new SAXBuilder(); + File xmlFile = new File(mlFileLocation); + Document document = (Document) builder.build(xmlFile); + + // XLS data file name + String outputFile = mlFileLocation.replace(".graphml", ".xls"); + Workbook wb = new HSSFWorkbook(); + FileOutputStream fileOut = new FileOutputStream(outputFile); + writeComponents(wb, document); + writeComponentInstances(wb, document); + wb.write(fileOut); + fileOut.close(); + return outputFile; + } + + private void writeComponents(Workbook wb, Document document) { + Sheet componentsSheet = wb.createSheet("Components"); + Row currentRow = componentsSheet.createRow(0); + for (int i = 0; i < COMPONENT_SHEET_HEADER.length; i++) { + currentRow.createCell(i).setCellValue(COMPONENT_SHEET_HEADER[i]); + } + + List components = getComponents(document); + int rowNum = 1; + for (ComponentRow row : components) { + currentRow = componentsSheet.createRow(rowNum++); + currentRow.createCell(0).setCellValue(row.getUniqueId()); + currentRow.createCell(1).setCellValue(row.getType()); + currentRow.createCell(2).setCellValue(row.getName()); + currentRow.createCell(3).setCellValue(row.getToscaResourceName()); + currentRow.createCell(4).setCellValue(row.getResourceType()); + currentRow.createCell(5).setCellValue(row.getVersion()); + currentRow.createCell(6).setCellValue(row.getIsDeleted() != null ? row.getIsDeleted().toString() : "false"); + currentRow.createCell(7).setCellValue(row.getHasNonCalculatedReqCap()); + } + } + + private void writeComponentInstances(Workbook wb, Document document) { + Sheet componentsSheet = wb.createSheet("ComponentInstances"); + Row currentRow = componentsSheet.createRow(0); + for (int i = 0; i < COMPONENT_INSTANCES_SHEET_HEADER.length; i++) { + currentRow.createCell(i).setCellValue(COMPONENT_INSTANCES_SHEET_HEADER[i]); + } + List components = getComponentInstances(document); + int rowNum = 1; + for (ComponentInstanceRow row : components) { + currentRow = componentsSheet.createRow(rowNum++); + currentRow.createCell(0).setCellValue(row.getUniqueId()); + currentRow.createCell(1).setCellValue(row.getName()); + currentRow.createCell(2).setCellValue(row.getOriginUid()); + currentRow.createCell(3).setCellValue(row.getOriginType()); + currentRow.createCell(4).setCellValue(row.getContainerUid()); + } + } + + private List getComponents(Document document) { + List res = new ArrayList<>(); + Element root = document.getRootElement(); + ElementFilter filter = new ElementFilter("graph"); + Element graph = root.getDescendants(filter).next(); + filter = new ElementFilter("edge"); + IteratorIterable edges = graph.getDescendants(filter); + Set componentsHavingReqOrCap = new HashSet<>(); + filter = new ElementFilter("data"); + for (Element edge : edges) { + IteratorIterable dataNodes = edge.getDescendants(filter); + for (Element data : dataNodes) { + String attributeValue = data.getAttributeValue("key"); + switch (attributeValue) { + case "labelE": + String edgeLabel = data.getText(); + if (edgeLabel.equals("REQUIREMENT") || edgeLabel.equals("CAPABILITY")) { + componentsHavingReqOrCap.add(edge.getAttributeValue("source")); + } + break; + } + } + } + + filter = new ElementFilter("node"); + IteratorIterable nodes = graph.getDescendants(filter); + filter = new ElementFilter("data"); + for (Element element : nodes) { + IteratorIterable dataNodes = element.getDescendants(filter); + ComponentRow componentRow = new ComponentRow(); + boolean isComponent = false; + for (Element data : dataNodes) { + String attributeValue = data.getAttributeValue("key"); + switch (attributeValue) { + case "nodeLabel": + String nodeLabel = data.getText(); + if (nodeLabel.equals("resource") || nodeLabel.equals("service")) { + isComponent = true; + componentRow.setType(nodeLabel); + String componentId = element.getAttributeValue("id"); + componentRow.setHasNonCalculatedReqCap(componentsHavingReqOrCap.contains(componentId)); + } + break; + case "uid": + componentRow.setUniqueId(data.getText()); + break; + case "name": + componentRow.setName(data.getText()); + break; + case "toscaResourceName": + componentRow.setToscaResourceName(data.getText()); + break; + case "resourceType": + componentRow.setResourceType(data.getText()); + break; + case "version": + componentRow.setVersion(data.getText()); + break; + case "deleted": + componentRow.setIsDeleted(Boolean.parseBoolean(data.getText())); + break; + default: + break; + } + } + if (isComponent) { + res.add(componentRow); + } + } + return res; + } + + private List getComponentInstances(Document document) { + List res = new ArrayList<>(); + Element root = document.getRootElement(); + ElementFilter filter = new ElementFilter("graph"); + Element graph = root.getDescendants(filter).next(); + filter = new ElementFilter("node"); + IteratorIterable nodes = graph.getDescendants(filter); + filter = new ElementFilter("data"); + for (Element element : nodes) { + IteratorIterable dataNodes = element.getDescendants(filter); + ComponentInstanceRow componentInstRow = new ComponentInstanceRow(); + boolean isComponentInst = false; + for (Element data : dataNodes) { + String attributeValue = data.getAttributeValue("key"); + switch (attributeValue) { + case "nodeLabel": + String nodeLabel = data.getText(); + if (nodeLabel.equals("resourceInstance")) { + isComponentInst = true; + } + break; + case "uid": + componentInstRow.setUniqueId(data.getText()); + break; + case "name": + componentInstRow.setName(data.getText()); + break; + case "originType": + componentInstRow.setOriginType(data.getText()); + break; + default: + break; + } + } + if (isComponentInst) { + // Assuming the uid is in standard form of + // .. + String uniqueId = componentInstRow.getUniqueId(); + if (uniqueId != null) { + String[] split = uniqueId.split("\\."); + if (split.length == 3) { + componentInstRow.setContainerUid(split[0]); + componentInstRow.setOriginUid(split[1]); + } + } + res.add(componentInstRow); + } + } + return res; + } + + private class ComponentRow { + + private String uniqueId; + private String type; + private String name; + private String toscaResourceName; + private String resourceType; + private String version; + private Boolean isDeleted; + private Boolean hasNonCalculatedReqCap; + + public Boolean getHasNonCalculatedReqCap() { + return hasNonCalculatedReqCap; + } + + public void setHasNonCalculatedReqCap(Boolean hasNonCalculatedReqCap) { + this.hasNonCalculatedReqCap = hasNonCalculatedReqCap; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getToscaResourceName() { + return toscaResourceName; + } + + public void setToscaResourceName(String toscaResourceName) { + this.toscaResourceName = toscaResourceName; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Boolean getIsDeleted() { + return isDeleted; + } + + public void setIsDeleted(Boolean deleted) { + this.isDeleted = deleted; + } + } + + private class ComponentInstanceRow { + private String uniqueId; + private String name; + private String originUid; + private String originType; + private String containerUid; + + public String getContainerUid() { + return containerUid; + } + + public void setContainerUid(String containerUid) { + this.containerUid = containerUid; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getOriginUid() { + return originUid; + } + + public void setOriginUid(String componentUid) { + this.originUid = componentUid; + } + + public String getOriginType() { + return originType; + } + + public void setOriginType(String originType) { + this.originType = originType; + } + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/PopulateComponentCache.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/PopulateComponentCache.java new file mode 100644 index 0000000000..812d534f49 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/PopulateComponentCache.java @@ -0,0 +1,388 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.Iterator; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Future; + +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.cassandra.ComponentCassandraDao; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.resources.data.ComponentCacheData; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.util.SerializationUtils; +import org.openecomp.sdc.common.util.ZipUtil; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +/** + * Created by esofer on 9/1/2016. + */ +public class PopulateComponentCache { + + private static Logger log = LoggerFactory.getLogger(PopulateComponentCache.class.getName()); + + @Autowired + protected ComponentCassandraDao componentCassandraDao; + + @Autowired + protected ResourceOperation resourceOperation; + + @Autowired + protected ServiceOperation serviceOperation; + + @Autowired + protected ProductOperation productOperation; + + @Autowired + protected ComponentCache componentCache; + + private void exit(String stage, int i) { + log.error("Failed on " + stage); + System.exit(i); + + } + + public void populateCache() { + populateCache(ComponentTypeEnum.RESOURCE); + populateCache(ComponentTypeEnum.SERVICE); + populateCache(ComponentTypeEnum.PRODUCT); + } + + private void populateCache(ComponentTypeEnum componentTypeEnum) { + + List list = new ArrayList<>(); + Either graph = resourceOperation.getTitanGenericDao().getGraph(); + TitanGraph titanGraph = graph.left().value(); + Iterable vertices = titanGraph.query() + .has(GraphPropertiesDictionary.LABEL.getProperty(), componentTypeEnum.name().toLowerCase()).vertices(); + + Iterator iterator = vertices.iterator(); + while (iterator.hasNext()) { + TitanVertex vertex = (TitanVertex) iterator.next(); + + // VertexProperty state = + // vertex.property(GraphPropertiesDictionary.STATE.getProperty()); + // String stateValue = (String)state.value(); + + // if (false == + // stateValue.equalsIgnoreCase(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()) + // ) { + VertexProperty uid = vertex.property(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + String uidValue = (String) uid.value(); + + list.add(uidValue); + // } + } + + int counter = 0; + for (String componentUid : list) { + + long time1 = System.currentTimeMillis(); + + ///////////////////////////////////////////////////////////////////////////////////// + // Pay attention. The component is fetched from the cache in case it + ///////////////////////////////////////////////////////////////////////////////////// is + ///////////////////////////////////////////////////////////////////////////////////// already + ///////////////////////////////////////////////////////////////////////////////////// there. + ///////////////////////////////////////////////////////////////////////////////////// + Component component = null; + switch (componentTypeEnum) { + case RESOURCE: + Either resourceRes = resourceOperation.getComponent(componentUid, + false); + if (resourceRes.isRight()) { + exit("get resource", 1); + } + component = resourceRes.left().value(); + break; + case SERVICE: + Either serviceRes = serviceOperation.getComponent(componentUid, false); + if (serviceRes.isRight()) { + exit("get service", 1); + } + component = serviceRes.left().value(); + break; + case PRODUCT: + Either productRes = productOperation.getComponent(componentUid, false); + if (productRes.isRight()) { + exit("get product", 1); + } + component = productRes.left().value(); + break; + default: + break; + } + + if (component == null) { + exit("get component", 1); + } + + long time2 = System.currentTimeMillis(); + // System.out.println("fetch resource " + resource.getName()); + // System.out.println("fetch resource time is " + (time2 - time1) + + // " ms"); + + boolean setComponent = componentCache.setComponent(component, componentTypeEnum.getNodeType()); + if (setComponent) { + counter++; + } + + /* + * Either valueRes = + * SerializationUtils.serializeExt(component); + * + * if (valueRes.isRight()) { exit("serialize component " + + * component.getName(), 2); } byte[] value = + * valueRes.left().value(); log.info("byte[] size is " + + * value.length); //System.out.println("byte[] size is " + + * value.length); + * + * byte[] zipped = null; try { zipped = ZipUtil.zipBytes(value); + * //System.out.println("byte[] size after zip is " + + * zipped.length); + * + * ComponentCacheData componentCacheData = new ComponentCacheData(); + * componentCacheData.setDataAsArray(zipped); + * componentCacheData.setIsZipped(true); + * componentCacheData.setId(componentUid); + * componentCacheData.setModificationTime(new + * Date(component.getLastUpdateDate())); + * componentCacheData.setType(component.getComponentType().name(). + * toLowerCase()); + * + * long averageInsertTimeInMilli = + * writeResourceToCassandraComponent(componentCacheData); log. + * info("After adding component {} to cassandra. Insert time is {} ms." + * , componentUid, averageInsertTimeInMilli); + * + * } catch (IOException e) { // TODO Auto-generated catch block + * e.printStackTrace(); } + */ + + } + + log.debug("The number of saved components of type {} is {}. Total size is {}", componentTypeEnum, counter, + list.size()); + + } + + private long writeResourceToCassandraComponent(ComponentCacheData componentCacheData) { + + long startTime = System.currentTimeMillis(); + + // call to cassandra read + CassandraOperationStatus saveArtifact = componentCassandraDao.saveComponent(componentCacheData); + if (saveArtifact != CassandraOperationStatus.OK) { + exit("writeResourceToCassandra", 3); + } + + long endTime = System.currentTimeMillis(); + + return (endTime - startTime); + } + + private void deserializeByThreads(List list, ExecutorService executor, int threadNumber) { + + long fullSearchStart = System.currentTimeMillis(); + // for (int k =0; k < parts; k++) { + + List> lists = new ArrayList<>(); + for (int i = 0; i < threadNumber; i++) { + lists.add(new ArrayList<>()); + } + + List>> results = new ArrayList<>(); + for (int i = 0; i < list.size(); i++) { + lists.get(i % threadNumber).add(list.get(i)); + } + + for (int i = 0; i < threadNumber; i++) { + + // Callable> worker = new + // MyDesrializabletCallable(lists.get(i), i); + Callable> worker = new My3rdPartyDesrializabletCallable(lists.get(i), i); + Future> submit = executor.submit(worker); + results.add(submit); + } + + long fullSearchStart2 = System.currentTimeMillis(); + for (Future> future : results) { + try { + while (false == future.isDone()) { + Thread.sleep(1); + } + + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + long fullSearchEnd2 = System.currentTimeMillis(); + log.info("esofer time wait to threads finish " + ((fullSearchEnd2 - fullSearchStart2)) + " ms"); + // } + long fullSearchEnd = System.currentTimeMillis(); + + log.info("esofer full desrialize time " + ((fullSearchEnd - fullSearchStart)) + " ms"); + System.out.println("esofer full desrialize time " + ((fullSearchEnd - fullSearchStart)) + " ms"); + } + + public class MyDesrializabletCallable implements Callable> { + + List list; + int i; + + public MyDesrializabletCallable(List list, int i) { + super(); + this.list = list; + this.i = i; + } + + @Override + public List call() throws Exception { + List resources = new ArrayList<>(); + long startSer = System.currentTimeMillis(); + long endSer = System.currentTimeMillis(); + long startUnzip = System.currentTimeMillis(); + long endUnzip = System.currentTimeMillis(); + + long avgUnzip = 0; + long avgSer = 0; + for (ESArtifactData esArtifactData : list) { + + byte[] dataAsArray = esArtifactData.getDataAsArray(); + startUnzip = System.nanoTime(); + dataAsArray = ZipUtil.unzip(dataAsArray); + endUnzip = System.nanoTime(); + avgUnzip += (endUnzip - startUnzip); + + startSer = System.nanoTime(); + Either deserialize = SerializationUtils.deserialize(dataAsArray); + endSer = System.nanoTime(); + avgSer += (endSer - startSer); + // Either deserialize = + // SerializationUtils.deserialize(esArtifactData.getDataAsArray()); + if (deserialize.isRight()) { + exit("convertByteArrayToResource " + deserialize.right().value(), 5); + } + + Resource resource = (Resource) deserialize.left().value(); + resources.add(resource); + // System.out.println("After desrialize T[" + i + "]resource " + + // resource.getUniqueId()); + } + + System.out.println("After desrialize average desrialize " + list.size() + " T[" + i + "] " + + (avgSer / 1000 / list.size()) + " micro"); + System.out.println( + "After desrialize average unzip T[" + i + "] " + (avgUnzip / 1000 / list.size()) + " micro"); + + //////////////////////// + // maybe register most frequently used classes on conf + // write + // byte barray[] = conf.asByteArray(mySerializableObject); + // read + // MyObject object = (MyObject)conf.asObject(barray); + + return resources; + } + } + + public class My3rdPartyDesrializabletCallable implements Callable> { + + List list; + int i; + + public My3rdPartyDesrializabletCallable(List list, int i) { + super(); + this.list = list; + this.i = i; + } + + @Override + public List call() throws Exception { + List resources = new ArrayList<>(); + long startSer = System.currentTimeMillis(); + long endSer = System.currentTimeMillis(); + long startUnzip = System.currentTimeMillis(); + long endUnzip = System.currentTimeMillis(); + + long avgUnzip = 0; + long avgSer = 0; + for (ESArtifactData esArtifactData : list) { + + byte[] dataAsArray = esArtifactData.getDataAsArray(); + startUnzip = System.nanoTime(); + dataAsArray = ZipUtil.unzip(dataAsArray); + endUnzip = System.nanoTime(); + avgUnzip += (endUnzip - startUnzip); + + startSer = System.nanoTime(); + + Either deserializeExt = SerializationUtils.deserializeExt(dataAsArray, + Resource.class, ""); + + if (deserializeExt.isLeft()) { + Resource resource = deserializeExt.left().value(); + // System.out.println("============================================="); + // System.out.println(resource.getCapabilities().size()); + // System.out.println(resource.getRequirements().size()); + endSer = System.nanoTime(); + avgSer += (endSer - startSer); + resources.add(resource); + // System.out.println("After desrialize T[" + i + "]resource + // " + resource.getUniqueId()); + } + } + + System.out.println("After desrialize average desrialize " + list.size() + " T[" + i + "] " + + (avgSer / 1000 / list.size()) + " micro"); + System.out.println( + "After desrialize average unzip T[" + i + "] " + (avgUnzip / 1000 / list.size()) + " micro"); + + return resources; + } + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/ProductLogic.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/ProductLogic.java new file mode 100644 index 0000000000..9f15c83dd8 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/ProductLogic.java @@ -0,0 +1,103 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +/** + * Created by mlando on 2/23/2016. + */ +public class ProductLogic { + + private static Logger log = LoggerFactory.getLogger(ProductLogic.class.getName()); + + public boolean deleteAllProducts(String titanFile, String beHost, String bePort, String adminUser) { + log.debug("retrieving all products from graph"); + RestUtils restUtils = null; + try { + List productList = getAllProducts(titanFile); + restUtils = new RestUtils(); + if (productList != null) { + for (String productUid : productList) { + Integer status = restUtils.deleteProduct(productUid, beHost, bePort, adminUser); + } + return true; + } else { + log.error("failed to get products from graph"); + return false; + } + } finally { + if (restUtils != null) { + restUtils.closeClient(); + } + } + } + + private List getAllProducts(String titanFile) { + TitanGraph graph = null; + try { + graph = openGraph(titanFile); + List productsToDelete = new ArrayList(); + Iterable vertices = graph.query() + .has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Product.getName()).vertices(); + if (vertices != null) { + Iterator iter = vertices.iterator(); + while (iter.hasNext()) { + Vertex vertex = iter.next(); + String id = vertex.value(GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + productsToDelete.add(id); + } + } + + graph.tx().commit(); + return productsToDelete; + } catch (Exception e) { + e.printStackTrace(); + graph.tx().rollback(); + return null; + + } finally { + if (graph != null) { + graph.close(); + } + } + } + + private TitanGraph openGraph(String titanFileLocation) { + + TitanGraph graph = TitanFactory.open(titanFileLocation); + + return graph; + + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/RestUtils.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/RestUtils.java new file mode 100644 index 0000000000..c256ca09a4 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/RestUtils.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpUriRequest; + +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.io.IOException; + +/** + * Created by mlando on 2/23/2016. + */ +public class RestUtils { + + final String DELETE_PRODUCT = "http://%s:%s/sdc2/rest/v1/catalog/products/%s"; + final Integer DELETE_SUCCSES_RESPONSE = 200; + + private static Logger log = LoggerFactory.getLogger(RestUtils.class.getName()); + CloseableHttpClient httpClient; + + public RestUtils() { + this.httpClient = HttpClients.createDefault(); + } + + private CloseableHttpResponse exacuteRequest(HttpUriRequest httpRequest) throws IOException { + log.debug("received http request: {}", httpRequest.toString()); + return httpClient.execute(httpRequest); + } + + public void closeClient() { + log.debug("closing http client"); + try { + this.httpClient.close(); + log.debug("closed http client"); + } catch (IOException e) { + log.debug("close http client failed", e); + + } + } + + public Integer deleteProduct(String productUid, String beHost, String bePort, String adminUser) { + String url = String.format(DELETE_PRODUCT, beHost, bePort, productUid); + HttpDelete deleteRequest = new HttpDelete(url); + deleteRequest.setHeader("USER_ID", adminUser); + try (CloseableHttpResponse response = this.httpClient.execute(deleteRequest)) { + int status = response.getStatusLine().getStatusCode(); + if (DELETE_SUCCSES_RESPONSE.equals(status)) { + log.debug("Product uid:{} succsesfully deleted", productUid); + } else { + log.error("Product uid:{} delete failed status {}", productUid, status); + } + return status; + } catch (IOException e) { + log.error("Product uid:" + productUid + " delete failed with exception", e); + } + return null; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/UpdatePropertyOnVertex.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/UpdatePropertyOnVertex.java new file mode 100644 index 0000000000..b480091723 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/UpdatePropertyOnVertex.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl; + +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.asdctool.Utils; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.thinkaurelius.titan.core.TitanFactory; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanGraphQuery; + +public class UpdatePropertyOnVertex { + + private static Logger log = LoggerFactory.getLogger(UpdatePropertyOnVertex.class.getName()); + + public Integer updatePropertyOnServiceAtLeastCertified(String titanFile, Map keyValueToSet, + List> orCriteria) { + + TitanGraph graph = null; + + Integer numberOfUpdatedVertexes = 0; + + try { + graph = openGraph(titanFile); + + if (orCriteria != null && false == orCriteria.isEmpty()) { + + for (Map criteria : orCriteria) { + + TitanGraphQuery query = graph.query(); + + if (criteria != null && !criteria.isEmpty()) { + for (Map.Entry entry : criteria.entrySet()) { + query = query.has(entry.getKey(), entry.getValue()); + } + } + + Iterator iterator = query + .has(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()) + .vertices().iterator(); + + boolean isFoundAtLeastOneCertifiedService = false; + while (iterator.hasNext()) { + Vertex vertex = (Vertex) iterator.next(); + + Map leftProps = Utils.getProperties(vertex); + boolean vertexLeftContainsRightProps = Utils.vertexLeftContainsRightProps(leftProps, criteria); + if (false == vertexLeftContainsRightProps) { + log.debug("Ignore vertex since properties it does not contains properties {}. Vertex properties are: {}", criteria, leftProps); + continue; + } + + isFoundAtLeastOneCertifiedService = true; + break; + } + + if (true == isFoundAtLeastOneCertifiedService) { + + Integer currentNumberOfUpdates = updateVertexes(keyValueToSet, graph, criteria); + + if (currentNumberOfUpdates != null) { + numberOfUpdatedVertexes += currentNumberOfUpdates; + } + + } else { + log.debug("No certified service was found for criteria {}", criteria); + } + } + + } + + // graph.commit(); + graph.tx().commit(); + + return numberOfUpdatedVertexes; + + } catch (Exception e) { + e.printStackTrace(); + // graph.rollback(); + graph.tx().rollback(); + + return null; + + } finally { + if (graph != null) { + // graph.shutdown(); + graph.close(); + } + } + + } + + private Integer updateVertexes(Map keyValueToSet, TitanGraph graph, Map criteria) { + Integer numberOfUpdatedVertexesPerService = 0; + + TitanGraphQuery updateQuery = graph.query(); + + if (criteria != null && !criteria.isEmpty()) { + for (Map.Entry entry : criteria.entrySet()) { + updateQuery = updateQuery.has(entry.getKey(), entry.getValue()); + } + } + Iterator updateIterator = updateQuery.vertices().iterator(); + + while (updateIterator.hasNext()) { + + Vertex vertex = (Vertex) updateIterator.next(); + + Map leftProps = Utils.getProperties(vertex); + + boolean vertexLeftContainsRightProps = Utils.vertexLeftContainsRightProps(leftProps, criteria); + if (false == vertexLeftContainsRightProps) { + log.debug("Ignore vertex since properties it does not contains properties {}. Vertex properties are {}", criteria, leftProps); + continue; + } + + if (keyValueToSet != null) { + for (Entry entry : keyValueToSet.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + // vertex.setProperty(key, value); + vertex.property(key, value); + //if(log.isDebugEnabled()){ + // log.debug("After setting vertex: {} {} with key value: {}, {}", + // vertex.getProperty(GraphPropertiesDictionary.NAME.getProperty()), + // vertex.getProperty(GraphPropertiesDictionary.VERSION.getProperty()), + // key, value); + //} + log.debug("After setting vertex: {} {} with key value: {}, {}", + vertex.property(GraphPropertiesDictionary.NAME.getProperty()), + vertex.property(GraphPropertiesDictionary.VERSION.getProperty()), + key, value); + numberOfUpdatedVertexesPerService++; + } + } + + } + + log.info( + "The number of updated services for criteria " + criteria + " is " + numberOfUpdatedVertexesPerService); + return numberOfUpdatedVertexesPerService; + } + + public TitanGraph openGraph(String titanFileLocation) { + + TitanGraph graph = TitanFactory.open(titanFileLocation); + + return graph; + + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AddGroupUuid.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AddGroupUuid.java new file mode 100644 index 0000000000..db8fee0fa2 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AddGroupUuid.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.GroupData; +import org.slf4j.Logger; + +import fj.data.Either; + +public class AddGroupUuid { + + public static boolean addGroupUuids(TitanGenericDao titanGenericDao, Logger log, boolean inTrsansaction) { + + boolean result = true; + + try { + + log.debug("========================================================"); + log.debug("Before find all groups"); + + Either, TitanOperationStatus> allGroups = titanGenericDao.getByCriteria(NodeTypeEnum.Group, + null, null, GroupData.class); + + if (allGroups.isRight()) { + TitanOperationStatus status = allGroups.right().value(); + log.debug("After finding all groups. Status is {}", status); + if (status != TitanOperationStatus.NOT_FOUND && status != TitanOperationStatus.OK) { + result = false; + return result; + } else { + return result; + } + } + + List groups = allGroups.left().value(); + + log.info("The number of groups fetched is {}", groups == null ? 0 : groups.size()); + + int numberOfUpdates = 0; + if (false == groups.isEmpty()) { + Map> invariantIdToGroups = groups.stream() + .collect(Collectors.groupingBy(p -> p.getGroupDataDefinition().getInvariantUUID())); + + // All the groups with the same invariantUUID should have the + // same group UUID since update VF flow with CSAR was not + // supported in the E2E environment. + + log.info("The number of different invariantUuids is {}", + invariantIdToGroups == null ? 0 : invariantIdToGroups.size()); + + for (Entry> entry : invariantIdToGroups.entrySet()) { + + String invariantUuid = entry.getKey(); + List groupsData = entry.getValue(); + + StringBuilder builder = new StringBuilder(); + groupsData.forEach(p -> builder.append(p.getGroupDataDefinition().getUniqueId() + ",")); + + String groupUUID = groupsData.get(0).getGroupDataDefinition().getGroupUUID(); + + if (groupUUID == null) { + + groupUUID = UniqueIdBuilder.generateUUID(); + + log.debug("Before updating groups {} with groupUUID {}", builder.toString(), groupUUID); + + for (GroupData groupData : groupsData) { + + numberOfUpdates++; + groupData.getGroupDataDefinition().setGroupUUID(groupUUID); + Either updateNode = titanGenericDao.updateNode(groupData, + GroupData.class); + if (updateNode.isRight()) { + log.error("Failed to update group " + groupData + ". Error is {}", + updateNode.right().value().toString()); + result = false; + return result; + } + + } + + log.debug("After updating groups {} with groupUUID {}", builder.toString(), groupUUID); + } + + } + } + + log.info("The number of groups updated with groupUUID is " + numberOfUpdates); + + return result; + + } finally { + log.info("Finish updating groupUUIDs. Status is {}.", result); + if (inTrsansaction == false) { + if (result == false) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AllowMultipleHeats.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AllowMultipleHeats.java new file mode 100644 index 0000000000..561cfb5a5b --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AllowMultipleHeats.java @@ -0,0 +1,144 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.slf4j.Logger; + +import fj.data.Either; + +public class AllowMultipleHeats { + + public static boolean removeAndUpdateHeatPlaceHolders(TitanGenericDao titanGenericDao, Logger log, + boolean inTrsansaction) { + + boolean result = true; + + try { + + List artifactsToDelete = new ArrayList<>(); + List artifactsToUpdate = new ArrayList<>(); + + String[] phLabels = { "heat", "heatvol", "heatnet" }; + + for (String artifactLabel : phLabels) { + Map properties = new HashMap<>(); + + properties.put(GraphPropertiesDictionary.ARTIFACT_LABEL.getProperty(), artifactLabel); + + Either, TitanOperationStatus> allHeatArtifacts = titanGenericDao + .getByCriteria(NodeTypeEnum.ArtifactRef, properties, null, ArtifactData.class); + + if (allHeatArtifacts.isRight()) { + TitanOperationStatus status = allHeatArtifacts.right().value(); + if (status == TitanOperationStatus.NOT_FOUND) { + continue; + } else { + result = false; + return result; + } + + } + + List list = allHeatArtifacts.left().value(); + log.debug("Found {} artifacts with label {}", (list == null ? 0 : list.size()), artifactLabel); + + if (list != null && false == list.isEmpty()) { + + for (ArtifactData artifactData : list) { + String esId = artifactData.getArtifactDataDefinition().getEsId(); + if (esId == null || true == esId.isEmpty()) { + artifactsToDelete.add(artifactData); + } else { + artifactsToUpdate.add(artifactData); + } + } + } + } + + if (false == artifactsToDelete.isEmpty()) { + for (ArtifactData artifactData : artifactsToDelete) { + // System.out.println("Going to delete artifact " + + // artifactData); + log.debug("Going to delete artifact {}", artifactData); + Either deleteNode = titanGenericDao.deleteNode(artifactData, + ArtifactData.class); + if (deleteNode.isRight()) { + log.error("Failed to delete artifact node {}", deleteNode.left().value()); + result = false; + return result; + } else { + log.debug("Delete artifact node {}", deleteNode.left().value()); + } + } + } + + log.debug("Number of deleted artifacts is {}", artifactsToDelete.size()); + + int counter = 0; + if (false == artifactsToUpdate.isEmpty()) { + for (ArtifactData artifactData : artifactsToUpdate) { + // System.out.println("Going to update artifact " + + // artifactData); + + if (artifactData.getArtifactDataDefinition().getMandatory() != null + && true == artifactData.getArtifactDataDefinition().getMandatory()) { + log.debug("Going to update artifact {}", artifactData); + counter++; + artifactData.getArtifactDataDefinition().setMandatory(false); + Either updatedNode = titanGenericDao + .updateNode(artifactData, ArtifactData.class); + if (updatedNode.isRight()) { + log.error("Failed to update artifact node {}", updatedNode.left().value()); + result = false; + return result; + } else { + log.debug("Update artifact node {}", updatedNode.left().value()); + } + } + } + } + + log.debug("Number of updated artifacts is {}", counter); + + return result; + + } finally { + if (inTrsansaction == false) { + if (result == false) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AppConfig.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AppConfig.java new file mode 100644 index 0000000000..b529935a38 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/AppConfig.java @@ -0,0 +1,538 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import org.openecomp.sdc.asdctool.impl.PopulateComponentCache; +import org.openecomp.sdc.asdctool.impl.migration.v1607.CsarMigration; +import org.openecomp.sdc.asdctool.impl.migration.v1610.TitanFixUtils; +import org.openecomp.sdc.asdctool.impl.migration.v1610.ToscaArtifactsAlignment; +import org.openecomp.sdc.be.auditing.api.IAuditingManager; +import org.openecomp.sdc.be.auditing.impl.AuditingManager; +import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine; +import org.openecomp.sdc.be.components.distribution.engine.ServiceDistributionArtifactsBuilder; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.CompositionBusinessLogic; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; +import org.openecomp.sdc.be.components.impl.ProductComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.VFComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraClient; +import org.openecomp.sdc.be.dao.cassandra.ComponentCassandraDao; +import org.openecomp.sdc.be.dao.es.ElasticSearchClient; +import org.openecomp.sdc.be.dao.impl.AuditingDao; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanGraphClient; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +import org.openecomp.sdc.be.model.operations.impl.AdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.impl.ArtifactOperation; +import org.openecomp.sdc.be.model.operations.impl.AttributeOperation; +import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation; +import org.openecomp.sdc.be.model.operations.impl.CapabilityInstanceOperation; +import org.openecomp.sdc.be.model.operations.impl.CapabilityOperation; +import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation; +import org.openecomp.sdc.be.model.operations.impl.ComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.impl.CsarOperation; +import org.openecomp.sdc.be.model.operations.impl.ElementOperation; +import org.openecomp.sdc.be.model.operations.impl.GraphLockOperation; +import org.openecomp.sdc.be.model.operations.impl.GroupOperation; +import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation; +import org.openecomp.sdc.be.model.operations.impl.HeatParametersOperation; +import org.openecomp.sdc.be.model.operations.impl.InputsOperation; +import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.LifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.OnboardingClient; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.impl.RequirementOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.model.operations.impl.UserAdminOperation; +import org.openecomp.sdc.be.tosca.CsarUtils; +import org.openecomp.sdc.be.tosca.ToscaExportHandler; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class AppConfig { + @Bean(name = "serviceMigrationBean") + public ServiceMigration serviceMigration() { + return new ServiceMigration(); + } + + @Bean(name = "vfcNamingAlignmentBean") + public VfcNamingAlignment vfcNamingAlignment() { + return new VfcNamingAlignment(); + } + + @Bean(name = "derivedFromAlignment") + public DerivedFromAlignment derivedFromAlignment() { + return new DerivedFromAlignment(); + } + + @Bean(name = "groupsAlignment") + public GroupsAlignment groupsAlignment() { + return new GroupsAlignment(); + } + + @Bean(name = "csarMigration") + public CsarMigration csarMigration() { + return new CsarMigration(); + } + + @Bean(name = "titan-generic-dao") + public TitanGenericDao titanGenericDao() { + return new TitanGenericDao(); + } + + @Bean(name = "titan-client", initMethod = "createGraph") + public TitanGraphClient titanClient() { + return new TitanGraphClient(); + } + + @Bean(name = "resource-operation") + public ResourceOperation resourceOperation() { + return new ResourceOperation(); + } + + @Bean(name = "service-operation") + public ServiceOperation serviceOperation() { + return new ServiceOperation(); + } + + @Bean(name = "component-instance-operation") + public ComponentInstanceOperation componentInstanceOperation() { + return new ComponentInstanceOperation(); + } + + @Bean(name = "capability-instanceOperation") + public CapabilityInstanceOperation capabilityInstanceOperation() { + return new CapabilityInstanceOperation(); + } + + @Bean(name = "property-operation") + public PropertyOperation propertyOperation() { + return new PropertyOperation(); + } + + @Bean(name = "attribute-operation") + public AttributeOperation attribueOperation() { + return new AttributeOperation(); + } + + @Bean(name = "application-datatype-cache") + public ApplicationDataTypeCache applicationDataTypeCache() { + return new ApplicationDataTypeCache(); + } + + @Bean(name = "requirement-operation") + public RequirementOperation requirementOperation() { + return new RequirementOperation(); + } + + @Bean(name = "capability-operation") + public CapabilityOperation capabilityOperation() { + return new CapabilityOperation(); + } + + @Bean(name = "interface-operation") + public InterfaceLifecycleOperation interfaceLifecycleOperation() { + return new InterfaceLifecycleOperation(); + } + + @Bean(name = "element-operation") + public IElementOperation elementOperation() { + return new ElementOperation(); + } + + @Bean(name = "additional-information-operation") + public IAdditionalInformationOperation addioAdditionalInformationOperation() { + return new AdditionalInformationOperation(); + } + + @Bean(name = "capability-type-operation") + public CapabilityTypeOperation capabilityTypeOperation() { + return new CapabilityTypeOperation(); + } + + @Bean(name = "artifact-operation") + public ArtifactOperation artifactOperation() { + return new ArtifactOperation(); + } + + @Bean(name = "heat-parameter-operation") + public HeatParametersOperation heatParametersOperation() { + return new HeatParametersOperation(); + } + + @Bean(name = "product-operation") + public ProductOperation productOperation() { + return new ProductOperation(); + } + + @Bean(name = "lifecycle-operation") + public LifecycleOperation lifecycleOperation() { + return new LifecycleOperation(); + } + + @Bean(name = "group-operation") + public GroupOperation groupOperation() { + return new GroupOperation(); + } + + @Bean(name = "group-type-operation") + public GroupTypeOperation groupTypeOperation() { + return new GroupTypeOperation(); + } + + @Bean(name = "attribute-operation") + public AttributeOperation attributeOperation() { + return new AttributeOperation(); + } + + @Bean(name = "titanFixUtils") + public TitanFixUtils titanFixUtils() { + return new TitanFixUtils(); + } + + @Bean(name = "populateComponentCache") + public PopulateComponentCache populateComponentCache() { + return new PopulateComponentCache(); + } + + @Bean(name = "artifact-cassandra-dao") + public ArtifactCassandraDao artifactCassandraDao() { + return new ArtifactCassandraDao(); + } + + @Bean(name = "component-cassandra-dao") + public ComponentCassandraDao componentCassandraDao() { + return new ComponentCassandraDao(); + } + + @Bean(name = "cassandra-client") + public CassandraClient cassandraClient() { + return new CassandraClient(); + } + + @Bean(name = "cacheManger-operation") + public CacheMangerOperation cacheMangerOperation() { + return new CacheMangerOperation(); + } + + @Bean(name = "component-cache") + public ComponentCache componentCache() { + return new ComponentCache(); + } + + @Bean(name = "input-operation") + public InputsOperation inputsOperation() { + return new InputsOperation(); + } + + /** + * Returns new instance of AuditCassandraDao + * + * @return + */ + @Bean(name = "audit-cassandra-dao") + public AuditCassandraDao auditCassandraDao() { + return new AuditCassandraDao(); + } + + /** + * Returns new instance of UserBusinessLogic + * + * @return + */ + @Bean(name = "userBusinessLogic") + public IUserBusinessLogic userBusinessLogic() { + return new UserBusinessLogic(); + } + + /** + * Returns new instance of UserAdminOperation + * + * @return + */ + @Bean(name = "user-operation") + public IUserAdminOperation userOperation() { + return new UserAdminOperation(); + } + + /** + * Returns new instance of GraphLockOperation + * + * @return + */ + @Bean(name = "graph-lock-operation") + public IGraphLockOperation graphLockOperation() { + return new GraphLockOperation(); + } + + /** + * Returns new instance of AuditingDao + * + * @return + */ + @Bean(name = "auditingDao") + public AuditingDao auditingDao() { + return new AuditingDao(); + } + + /** + * Returns new instance of AuditingManager + * + * @return + */ + @Bean(name = "auditingManager") + public IAuditingManager auditingManager() { + return new AuditingManager(); + } + + /** + * Returns new instance of ServiceBusinessLogic + * + * @return + */ + @Bean(name = "serviceBusinessLogic") + public ServiceBusinessLogic serviceBusinessLogic() { + return new ServiceBusinessLogic(); + } + + /** + * Returns new instance of ComponentsUtils + * + * @return + */ + @Bean(name = "componentUtils") + public ComponentsUtils componentUtils() { + return new ComponentsUtils(); + } + + /** + * Returns new instance of ToscaArtifactsAlignment + * + * @return + */ + @Bean(name = "toscaArtifactsAlignment") + public ToscaArtifactsAlignment toscaArtifactsAlignment() { + return new ToscaArtifactsAlignment(); + } + + /** + * Returns new instance of ArtifactsBusinessLogic + * + * @return + */ + @Bean(name = "artifactBusinessLogic") + public ArtifactsBusinessLogic artifactBusinessLogic() { + return new ArtifactsBusinessLogic(); + } + + /** + * Returns new instance of ResourceBusinessLogic + * + * @return + */ + @Bean(name = "resourceBusinessLogic") + public ResourceBusinessLogic resourceBusinessLogic() { + return new ResourceBusinessLogic(); + } + + /** + * Returns new instance of LifecycleBusinessLogic + * + * @return + */ + @Bean(name = "lifecycleBusinessLogic") + public LifecycleBusinessLogic lifecycleBusinessLogic() { + return new LifecycleBusinessLogic(); + } + + /** + * Returns new instance of ServiceDistributionArtifactsBuilder + * + * @return + */ + @Bean(name = "serviceDistributionArtifactsBuilder") + public ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder() { + return new ServiceDistributionArtifactsBuilder(); + } + + /** + * Returns new instance of DistributionEngine + * + * @return + */ + @Bean(name = "distributionEngine") + public IDistributionEngine distributionEngine() { + // This dependency is needed for initializing context but is not used + return null; + } + + /** + * Returns new instance of ElasticSearchClient + * + * @return + */ + @Bean(name = "elasticsearch-client") + public ElasticSearchClient elasticsearchClient() { + // This dependency is needed for initializing context but is not used + return null; + } + + /** + * Returns new instance of ProductBusinessLogic + * + * @return + */ + @Bean(name = "productBusinessLogic") + public ProductBusinessLogic productBusinessLogic() { + return new ProductBusinessLogic(); + } + + /** + * Returns new instance of ProductComponentInstanceBusinessLogic + * + * @return + */ + @Bean(name = "productComponentInstanceBusinessLogic") + public ProductComponentInstanceBusinessLogic productComponentInstanceBusinessLogic() { + return new ProductComponentInstanceBusinessLogic(); + } + + /** + * Returns new instance of ToscaExportHandler + * + * @return + */ + @Bean(name = "tosca-export-handler") + public ToscaExportHandler toscaExportHandler() { + return new ToscaExportHandler(); + } + + /** + * Returns new instance of CsarOperation + * + * @return + */ + @Bean(name = "csar-operation") + public CsarOperation csarOperation() { + return new CsarOperation(); + } + + /** + * Returns new instance of OnboardingClient + * + * @return + */ + @Bean(name = "onboarding-client") + public OnboardingClient onboardingClient() { + return new OnboardingClient(); + } + + /** + * Returns new instance of VFComponentInstanceBusinessLogic + * + * @return + */ + @Bean(name = "vfComponentInstanceBusinessLogic") + public VFComponentInstanceBusinessLogic vfComponentInstanceBusinessLogic() { + return new VFComponentInstanceBusinessLogic(); + } + + /** + * Returns new instance of ResourceImportManager + * + * @return + */ + @Bean(name = "resourceImportManager") + public ResourceImportManager resourceImportManager() { + return new ResourceImportManager(); + } + + /** + * Returns new instance of GroupBusinessLogic + * + * @return + */ + @Bean(name = "groupBusinessLogic") + public GroupBusinessLogic groupBusinessLogic() { + return new GroupBusinessLogic(); + } + + /** + * Returns new instance of InputsBusinessLogic + * + * @return + */ + @Bean(name = "inputsBusinessLogic") + public InputsBusinessLogic inputsBusinessLogic() { + return new InputsBusinessLogic(); + } + + /** + * Returns new instance of CompositionBusinessLogic + * + * @return + */ + @Bean(name = "compositionBusinessLogic") + public CompositionBusinessLogic compositionBusinessLogic() { + return new CompositionBusinessLogic(); + } + + /** + * Returns new instance of CsarUtils + * + * @return + */ + @Bean(name = "csar-utils") + public CsarUtils csarUtils() { + return new CsarUtils(); + } + + /** + * Returns new instance of ServiceComponentInstanceBusinessLogic + * + * @return + */ + @Bean(name = "serviceComponentInstanceBusinessLogic") + public ServiceComponentInstanceBusinessLogic serviceComponentInstanceBusinessLogic() { + return new ServiceComponentInstanceBusinessLogic(); + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/DerivedFromAlignment.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/DerivedFromAlignment.java new file mode 100644 index 0000000000..c1ddc4fee0 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/DerivedFromAlignment.java @@ -0,0 +1,232 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.io.BufferedReader; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public class DerivedFromAlignment { + private static Logger log = LoggerFactory.getLogger(VfcNamingAlignment.class.getName()); + private Map newDerivedFromValuesHM = new HashMap(); + @Autowired + protected TitanGenericDao titanGenericDao; + + public boolean alignDerivedFrom1604(String appConfigDir, String dataInputFileDir) { + log.debug("Started alignDerivedFrom1604 procedure.."); + boolean result = false; + try { + if (!getDerivedFromValuesFromFile(dataInputFileDir)) { + log.error("Started alignDerivedFrom1604 procedure was failed. Missing data in the input data file."); + return result; + } + result = changeDerivedFrom(); + } finally { + if (!result) { + titanGenericDao.rollback(); + log.debug("**********************************************"); + log.debug("alignDerivedFrom1604 procedure FAILED!!"); + log.debug("**********************************************"); + } else { + titanGenericDao.commit(); + log.debug("**********************************************"); + log.debug("alignDerivedFrom1604 procedure ended successfully!"); + log.debug("**********************************************"); + } + } + return result; + } + + private boolean changeDerivedFrom() { + Map resourcesHM = getLatestVersionsOfResources(); + if (resourcesHM == null) + return false; + Map derivedFromResourcesHM = getLatestCertifiedVersionsOfDerivedFromResources(); + if (derivedFromResourcesHM == null) + return false; + return updateEdges(resourcesHM, derivedFromResourcesHM); + } + + private boolean updateEdges(Map resourcesHM, + Map derivedFromResourcesHM) { + log.debug("Updating of Edges has been started.."); + for (Entry pair : resourcesHM.entrySet()) { + ResourceMetadataData curResource = pair.getValue(); + String uniqeID = (String) curResource.getUniqueId(); + Either, TitanOperationStatus> parentResourceRes = titanGenericDao + .getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), uniqeID, + GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Resource, ResourceMetadataData.class); + if (parentResourceRes.isLeft()) { + ImmutablePair value = parentResourceRes.left().value(); + ResourceMetadataData parentResourceData = value.getKey(); + log.debug("Deleting old relation.."); + Either deletingRelationRes = titanGenericDao + .deleteRelation(curResource, parentResourceData, GraphEdgeLabels.DERIVED_FROM); + if (deletingRelationRes.isRight()) { + log.error("Couldn't delete relation from resource {} to resource {}, error: {}", + curResource.getMetadataDataDefinition().getName(), + parentResourceData.getMetadataDataDefinition().getName(), + deletingRelationRes.right().value()); + return false; + } + ResourceMetadataData newDerivedFromResource = derivedFromResourcesHM.get(pair.getKey()); + Either creatingRelationRes = titanGenericDao + .createRelation(curResource, newDerivedFromResource, GraphEdgeLabels.DERIVED_FROM, null); + if (creatingRelationRes.isRight()) { + log.error("Couldn't create relation from resource {} to resource {}, error: {}", + curResource.getMetadataDataDefinition().getName(), + newDerivedFromResource.getMetadataDataDefinition().getName(), + creatingRelationRes.right().value()); + return false; + } + } else { + log.error("Couldn't get derived from resource for child resource {}, error: {}", pair.getKey(), + parentResourceRes.right().value()); + return false; + } + } + return true; + } + + private Map getLatestCertifiedVersionsOfDerivedFromResources() { + log.debug("Getting latest certified versions of derived from resources according input file"); + Map resourcesHM = new HashMap(); + Map props = null; + for (Entry pair : newDerivedFromValuesHM.entrySet()) { + props = new HashMap(); + props.put(GraphPropertiesDictionary.TOSCA_RESOURCE_NAME.getProperty(), pair.getValue()); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + Either, TitanOperationStatus> highestVersionResource = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestVersionResource.isRight()) { + log.error("Couldn't get resource {} from DB, error: {}", pair.getValue(), + highestVersionResource.right().value()); + return null; + } + List highestVersionResourceAL = highestVersionResource.left().value(); + if (highestVersionResourceAL == null) { + log.error("Couldn't get resource {}. No resource found", pair.getValue()); + return null; + } + ResourceMetadataData resource = highestVersionResourceAL.get(0); + String state = resource.getMetadataDataDefinition().getState(); + if (!state.equals(LifecycleStateEnum.CERTIFIED.name())) { + log.error( + "alignDerivedFrom1604 procedure FAILED!! Derived from resource {} is not certified. Please certify manually and repeat the procedure.", + pair.getValue()); + return null; + } + resourcesHM.put(pair.getKey(), resource); + } + return resourcesHM; + } + + private Map getLatestVersionsOfResources() { + log.debug("Getting latest versions of resources according input file"); + Map resourcesHM = new HashMap(); + ResourceMetadataData foundResource = null; + Map props = null; + for (Entry pair : newDerivedFromValuesHM.entrySet()) {// filter + props = new HashMap(); + props.put(GraphPropertiesDictionary.NAME.getProperty(), pair.getKey()); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + Either, TitanOperationStatus> highestVersionResource = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (highestVersionResource.isRight()) { + log.error("Couldn't get resource {} from DB, error: {}", pair.getKey(), + highestVersionResource.right().value()); + return null; + } + List highestVersionResourceAL = highestVersionResource.left().value(); + if (highestVersionResourceAL == null) { + log.error("Couldn't get resource {}. No resource found", pair.getKey()); + return null; + } + if (highestVersionResourceAL.size() > 2) { + log.error("Invalid response. Found more than two highest version resources with name {}.", + pair.getKey()); + return null; + } + foundResource = highestVersionResourceAL.get(0); + if (highestVersionResourceAL.size() == 2) { + foundResource = foundResource.getMetadataDataDefinition().getState() + .equals(LifecycleStateEnum.CERTIFIED.name()) ? highestVersionResourceAL.get(1) : foundResource; + } + resourcesHM.put(pair.getKey(), foundResource); + } + return resourcesHM; + } + + private boolean getDerivedFromValuesFromFile(String dataInputFileDir) { + BufferedReader br = null; + String curPair = null; + try { + br = new BufferedReader(new FileReader(dataInputFileDir)); + while ((curPair = br.readLine()) != null) { + String[] pair = curPair.split(" "); + if (pair.length < 2) { + log.error( + "Expected at least two tokens in every line. Usage: "); + return false; + } + String derivedFrom = pair[pair.length - 1]; + String name = curPair.substring(0, curPair.length() - derivedFrom.length() - 1); + newDerivedFromValuesHM.put(name, derivedFrom); + } + return true; + } catch (FileNotFoundException e) { + log.error("Started alignDerivedFrom1604 procedure was failed. Missing input data file.", e); + } catch (IOException e) { + log.error("Started alignDerivedFrom1604 procedure was failed. The input data file is empty.", e); + } finally { + if (br != null) { + try { + br.close(); + } catch (IOException e) { + log.debug("failed to close file reader", e); + } + } + } + return false; + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/GroupsAlignment.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/GroupsAlignment.java new file mode 100644 index 0000000000..aebcddfee2 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/GroupsAlignment.java @@ -0,0 +1,201 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public class GroupsAlignment { + + private static Logger log = LoggerFactory.getLogger(ServiceMigration.class.getName()); + + public static String INITIAL_VERSION = "1.0"; + private static final String DEFAULT_GROUP_VF_MODULE = "org.openecomp.groups.VfModule"; + private static final String MODULE = "::module-"; + + @Autowired + protected TitanGenericDao titanGenericDao; + @Autowired + protected IArtifactOperation artifactOperation; + @Autowired + protected IGroupOperation groupOperation; + @Autowired + protected GroupTypeOperation groupTypeOperation; + + public boolean alignGroups(String appConfigDir) { + + log.debug("Started the align groups procedure ..."); + log.debug("Getting all resources with resources"); + boolean result = false; + try { + + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + Either, TitanOperationStatus> allVfResources = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, properties, ResourceMetadataData.class); + + if (allVfResources.isRight()) { + log.error("Couldn't get VF resources from DB, error: {}", allVfResources.right().value()); + result = false; + return result; + } + List resourcesList = allVfResources.left().value(); + if (resourcesList == null) { + log.error("Couldn't get VF resources from DB, no resources found"); + result = false; + return result; + } + log.debug("Found {} VF resources", resourcesList.size()); + for (ResourceMetadataData resource : resourcesList) { + result = createGroupIfContainsArtifacts(resource); + } + } finally { + if (!result) { + titanGenericDao.rollback(); + log.debug("**********************************************"); + log.debug("The align groups procedure FAILED!!"); + log.debug("**********************************************"); + } else { + titanGenericDao.commit(); + log.debug("**********************************************"); + log.debug("The align groups procedure ended successfully!"); + log.debug("**********************************************"); + } + } + + return result; + } + + private boolean createGroupIfContainsArtifacts(ResourceMetadataData resource) { + + String uniqueId = resource.getMetadataDataDefinition().getUniqueId(); + StorageOperationStatus result = StorageOperationStatus.OK; + Either, StorageOperationStatus> allArtifactsRes = artifactOperation + .getArtifacts(uniqueId, NodeTypeEnum.Resource, true); + if (allArtifactsRes.isRight()) { + log.error("Couldn't get resource artifacts from DB, error: {}", allArtifactsRes.right().value()); + return false; + } + Map artifactsHM = allArtifactsRes.left().value(); + ArrayList foundArtifactsAL = new ArrayList(); + for (ArtifactDefinition curArtifact : artifactsHM.values()) { + String atrifactType = curArtifact.getArtifactType(); + if (atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()) + || atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) + || atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + foundArtifactsAL.add(curArtifact.getUniqueId()); + } + } + if (foundArtifactsAL.size() > 0) { + Either, TitanOperationStatus> allGroupsRes = groupOperation + .getAllGroupsFromGraph(uniqueId, NodeTypeEnum.Resource); + int groupCounter = 1; + if (allGroupsRes.isRight()) { + if (allGroupsRes.right().value().name().equals(TitanOperationStatus.OK.name()) + || allGroupsRes.right().value().name().equals(TitanOperationStatus.NOT_FOUND.name())) { + log.debug("Not found groups resource related to resource {}, response: {}", + resource.getMetadataDataDefinition().getName(), allGroupsRes.right().value()); + } else { + log.error("Not found groups resource related to resource {}, DB error: {}", + resource.getMetadataDataDefinition().getName(), allGroupsRes.right().value()); + return false; + } + } else if (allGroupsRes.left().value() != null && allGroupsRes.left().value().size() > 0) { + groupCounter += allGroupsRes.left().value().size(); + for (GroupDefinition curGroup : allGroupsRes.left().value()) { + for (String curGroupArtifact : curGroup.getArtifacts()) { + if (foundArtifactsAL.contains(curGroupArtifact)) { + foundArtifactsAL.remove(curGroupArtifact); + } + } + } + } + if (foundArtifactsAL.size() > 0) { + GroupDefinition groupDefinition = new GroupDefinition(); + groupDefinition.setName(resource.getMetadataDataDefinition().getName() + MODULE + groupCounter); + groupDefinition.setType(DEFAULT_GROUP_VF_MODULE); + groupDefinition.setArtifacts(foundArtifactsAL); + log.debug("Creating new group {} for VF resource {}", groupDefinition.getName(), + resource.getMetadataDataDefinition().getName()); + return createGroup(resource.getUniqueId(), ComponentTypeEnum.RESOURCE, groupDefinition); + + } + } + return true; + } + + private boolean createGroup(Object uniqueId, ComponentTypeEnum componentType, GroupDefinition groupDefinition) { + + NodeTypeEnum nodeTypeEnum = componentType.getNodeType(); + String groupType = groupDefinition.getType(); + + Either getGroupTypeRes = groupTypeOperation + .getLatestGroupTypeByType(groupType, true); + if (getGroupTypeRes.isRight()) { + log.error("Couldn't get grouptype by type {} from DB, error: {}", groupType, + getGroupTypeRes.right().value()); + return false; + } + + GroupTypeDefinition groupTypeDefinition = getGroupTypeRes.left().value(); + + String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + groupDefinition.setInvariantUUID(invariantUUID); + groupDefinition.setVersion(INITIAL_VERSION); + groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId()); + + Either addGroupToGraphRes = groupOperation.addGroup(nodeTypeEnum, + (String) uniqueId, groupDefinition, true); + + if (addGroupToGraphRes.isRight()) { + log.error("Couldn't add group {} to graph, error: {}", groupDefinition.getName(), + addGroupToGraphRes.right().value()); + return false; + } + log.debug("The group {} has been created", groupDefinition.getName()); + return true; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationCategory.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationCategory.java new file mode 100644 index 0000000000..5605f0980d --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationCategory.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.util.List; + +import org.openecomp.sdc.be.datatypes.category.CategoryDataDefinition; + +public class MigrationCategory extends CategoryDataDefinition { + private String oldName; + + List subcategories; + + public String getOldName() { + return oldName; + } + + public void setOldName(String oldName) { + this.oldName = oldName; + } + + public List getSubcategories() { + return subcategories; + } + + public void setSubcategories(List subcategories) { + this.subcategories = subcategories; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationSubCategory.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationSubCategory.java new file mode 100644 index 0000000000..f1886622be --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/MigrationSubCategory.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import org.openecomp.sdc.be.datatypes.category.SubCategoryDataDefinition; + +public class MigrationSubCategory extends SubCategoryDataDefinition { + private String oldName; + + public String getOldName() { + return oldName; + } + + public void setOldName(String oldName) { + this.oldName = oldName; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java new file mode 100644 index 0000000000..cb7f05ddfd --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/ServiceMigration.java @@ -0,0 +1,1703 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import static java.nio.file.Files.readAllBytes; +import static java.nio.file.Paths.get; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.UUID; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Direction; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation; +import org.openecomp.sdc.be.dao.graph.datatype.RelationEndPoint; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgePropertiesDictionary; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.ComponentInstanceDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.AdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.impl.ComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.LifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.ComponentInstanceData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ProductMetadataData; +import org.openecomp.sdc.be.resources.data.RelationshipInstData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.resources.data.category.CategoryData; +import org.openecomp.sdc.be.resources.data.category.SubCategoryData; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.yaml.snakeyaml.Yaml; + +import com.thinkaurelius.titan.core.TitanEdge; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public class ServiceMigration { + + private static final String[] NORMATIVE_OLD_NAMES = { + "tosca.nodes.network.Network", "tosca.nodes.network.Port", + "tosca.nodes.BlockStorage", "tosca.nodes.Compute", "tosca.nodes.Container.Application", + "tosca.nodes.Container.Runtime", "tosca.nodes.Database", "tosca.nodes.DBMS", "tosca.nodes.LoadBalancer", + "tosca.nodes.ObjectStorage", "tosca.nodes.Root", "tosca.nodes.SoftwareComponent", + "tosca.nodes.WebApplication", "tosca.nodes.WebServer", }; + + private static Logger log = LoggerFactory.getLogger(ServiceMigration.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + @Autowired + protected ResourceOperation resourceOperation; + @Autowired + protected ServiceOperation serviceOperation; + @Autowired + protected ProductOperation productOperation; + @Autowired + protected LifecycleOperation lifecycleOperaion; + @Autowired + protected PropertyOperation propertyOperation; + @Autowired + protected AdditionalInformationOperation additionalInformationOperation; + @Autowired + protected ComponentInstanceOperation componentInstanceOperaion; + @Autowired + protected IElementOperation elementOperation; + + public boolean migrate1602to1604(String appConfigDir) { + + boolean result = false; + + try { + + if (!addResourceCounterToResources()) { + log.debug("Failed to update resource instance counter on resources"); + result = false; + return result; + } + if (!updateComponentInstanceType()) { + log.debug("Failed to update component instance type"); + result = false; + return result; + } + // fix VF + if (!fixDerivedVf()) { + log.debug("Failed to fix VFs"); + result = false; + return result; + } + // update instances and relation + if (!updateCalculatedEdges()) { + log.debug("Failed to update calculated edges for VF instances"); + result = false; + return result; + } + // update instances and relation + if (!updateRelations()) { + log.debug("Failed to update Instance And Relations in services"); + result = false; + return result; + } + if (!updateCategories(appConfigDir)) { + log.debug("Failed to update categories"); + result = false; + return result; + } + + if (!AllowMultipleHeats.removeAndUpdateHeatPlaceHolders(titanGenericDao, log, true)) { + log.error("Failed to update heat place holders"); + result = false; + return result; + } + + if (!AddGroupUuid.addGroupUuids(titanGenericDao, log, true)) { + log.error("Failed to update group UUIDs"); + result = false; + return result; + } + + result = true; + } finally { + if (!result) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + return result; + } + + private boolean updateCategories(String appConfigDir) { + // String categoryMigrationFile = appConfigDir + File.separator + + // "categoryMigration.yaml"; + String categoryMigrationFile = appConfigDir + "categoryMigration.yaml"; + + Map> categoriesFromYml; + try { + categoriesFromYml = createCategoriesFromYml(categoryMigrationFile); + if (categoriesFromYml == null || categoriesFromYml.isEmpty()) { + log.debug("updateCategories failed to load categories form migration file {}", categoryMigrationFile); + return false; + } + } catch (Exception e) { + log.debug("Failed to load category migration file :{} error: {}",categoryMigrationFile, e); + return false; + } + for (Map.Entry> entry : categoriesFromYml.entrySet()) { + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(entry.getKey()); + if (componentType != null) { + switch (componentType) { + case RESOURCE: + if (updateResourceCategories(entry.getValue()) == false) { + log.debug("updateCategories failed to update resource categories"); + return false; + } + break; + case SERVICE: + if (updateServiceCategories(entry.getValue()) == false) { + log.debug("updateCategories failed to update service categories"); + return false; + } + break; + default: + log.debug("updateCategories no changes for categories from type {}", componentType); + } + } else { + log.debug("updateCategories failed not supported component file in migration categories file {}", entry.getKey()); + return false; + } + } + return true; + } + + private boolean updateServiceCategories(List categories) { + log.debug("updateServiceCategories STARTED"); + Either, ActionStatus> serviceCategories = elementOperation + .getAllCategories(NodeTypeEnum.ServiceNewCategory, true); + if (serviceCategories.isRight()) { + log.debug("updateServiceCategories failed fetch all service categories ,error: {}", serviceCategories.right().value()); + return false; + } + for (MigrationCategory newCat : categories) { + + if (newCat.getOldName() == null) { + // add new + boolean exist = false; + for (CategoryDefinition catInDB : serviceCategories.left().value()) { + if (newCat.getName().equals(catInDB.getName())) { + exist = true; + break; + } + } + if (!exist) { + CategoryDefinition categoryDefinition = new CategoryDefinition(newCat); + Either result = elementOperation + .createCategory(categoryDefinition, NodeTypeEnum.ServiceNewCategory, true); + if (result.isRight()) { + log.debug("Failed to create service category {}, error: {}", categoryDefinition, result.right().value()); + return false; + } + log.debug("service category {} created", categoryDefinition); + } + } else { + // update exist + for (CategoryDefinition catInDB : serviceCategories.left().value()) { + if (newCat.getOldName().equals(catInDB.getName())) { + Either updateSingleResult = updateSingleResourceCategory( + newCat, NodeTypeEnum.ServiceNewCategory); + if (updateSingleResult.isRight()) { + return false; + } + break; + } + } + } + } + log.debug("updateServiceCategories ENDED"); + return true; + } + + private Either updateSingleResourceCategory(MigrationCategory newCat, + NodeTypeEnum nodetype) { + Map properties = new HashMap<>(); + properties.put(GraphPropertiesDictionary.NAME.getProperty(), newCat.getOldName()); + Either, TitanOperationStatus> categoryEither = titanGenericDao.getByCriteria(nodetype, + properties, CategoryData.class); + if (categoryEither.isRight() && categoryEither.right().value() != TitanOperationStatus.NOT_FOUND) { + log.debug("Failed to get {} categories, for name {} error {}", nodetype, newCat.getOldName(), + categoryEither.right().value()); + return Either.right(categoryEither.right().value()); + } + List categoryList = (categoryEither.isLeft() ? categoryEither.left().value() : null); + if (categoryList == null) { + log.debug("No {} categories, for name {} error {}", nodetype, newCat.getOldName()); + return Either.right(TitanOperationStatus.NOT_FOUND); + } + CategoryData categoryData = categoryList.get(0); + categoryData.getCategoryDataDefinition().setName(newCat.getName()); + categoryData.getCategoryDataDefinition().setIcons(newCat.getIcons()); + categoryData.getCategoryDataDefinition() + .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(newCat.getName())); + Either updateNode = titanGenericDao.updateNode(categoryData, + CategoryData.class); + if (updateNode.isRight()) { + log.debug("Failed to update {} category {} error {}", nodetype, categoryData, updateNode.right().value()); + return Either.right(updateNode.right().value()); + } + log.debug("Update {} category {} ", nodetype, categoryData); + return Either.left(updateNode.left().value()); + } + + private boolean updateResourceCategories(List categories) { + log.debug("updateResourceCategories STARTED"); + Either, ActionStatus> resourceCategories = elementOperation + .getAllCategories(NodeTypeEnum.ResourceNewCategory, true); + if (resourceCategories.isRight()) { + log.debug("updateResourceCategories failed fetch all resource categories ,error " + + resourceCategories.right().value()); + return false; + } + for (MigrationCategory newCat : categories) { + if (newCat.getOldName() == null) { + // add new + // check if already created in previous running + boolean exist = false; + for (CategoryDefinition catInDB : resourceCategories.left().value()) { + if (newCat.getName().equals(catInDB.getName())) { + exist = true; + } + } + if (!exist) { + CategoryDefinition categoryDefinition = new CategoryDefinition(newCat); + Either resultCat = elementOperation + .createCategory(categoryDefinition, NodeTypeEnum.ResourceNewCategory, true); + if (resultCat.isRight()) { + log.debug("Failed to create resource category {}, error: {}", categoryDefinition, resultCat.right().value()); + return false; + } + log.debug("resource category {} created", categoryDefinition); + + List nSubCat = newCat.getSubcategories(); + List newSubcat = nSubCat; + List subcategories = newSubcat; + for (MigrationSubCategory msubcat : subcategories) { + SubCategoryDefinition subcat = new SubCategoryDefinition(msubcat); + Either resultSubcat = elementOperation.createSubCategory( + resultCat.left().value().getUniqueId(), subcat, NodeTypeEnum.ResourceSubcategory, true); + if (resultSubcat.isRight()) { + log.debug("Failed to create resource sub category {} error: {}", subcat, resultSubcat.right().value()); + return false; + } + log.debug("resource sub category {} created for category {}", categoryDefinition, resultCat.left().value().getName()); + } + } + } else { + // update exist + for (CategoryDefinition catInDB : resourceCategories.left().value()) { + if (newCat.getOldName().equals(catInDB.getName())) { + Either updateSingleResult = updateSingleResourceCategory( + newCat, NodeTypeEnum.ResourceNewCategory); + if (updateSingleResult.isRight()) { + return false; + } + + CategoryData categoryData = updateSingleResult.left().value(); + for (MigrationSubCategory migSubCat : newCat.getSubcategories()) { + if (migSubCat.getOldName() == null) { + // create new one + boolean existSub = false; + for (SubCategoryDefinition subCatInDb : catInDB.getSubcategories()) { + if (subCatInDb.getName().equals(migSubCat.getName())) { + existSub = true; + } + } + if (!existSub) { + SubCategoryDefinition subcat = new SubCategoryDefinition(migSubCat); + + Either resultSubcat = elementOperation + .createSubCategory((String) categoryData.getUniqueId(), subcat, + NodeTypeEnum.ResourceSubcategory, true); + if (resultSubcat.isRight()) { + log.debug("Failed to create resource sub category {} error: {}", subcat, resultSubcat.right().value()); + return false; + } + log.debug("resource sub category {}", categoryData, resultSubcat.left().value().getName()); + } + } else { + if (updateSingleSubCategory(newCat, migSubCat, + updateSingleResult.left().value()) == false) { + return false; + } + } + } + break; + } + } + } + } + return true; + } + + private boolean updateSingleSubCategory(MigrationCategory newCat, MigrationSubCategory migSubCat, + CategoryData categoryData) { + + Either>, TitanOperationStatus> subcategories = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceNewCategory), + (String) categoryData.getUniqueId(), GraphEdgeLabels.SUB_CATEGORY, + NodeTypeEnum.ResourceSubcategory, SubCategoryData.class); + + if (subcategories.isRight()) { + log.debug("Failed to get resource sub categories, for name {} error {}", newCat.getOldName(), + subcategories.right().value()); + return false; + } + + for (ImmutablePair pair : subcategories.left().value()) { + if (pair.getKey().getSubCategoryDataDefinition().getName().equals(migSubCat.getOldName())) { + SubCategoryData subCategoryData = pair.getKey(); + subCategoryData.getSubCategoryDataDefinition().setName(migSubCat.getName()); + subCategoryData.getSubCategoryDataDefinition().setIcons(migSubCat.getIcons()); + subCategoryData.getSubCategoryDataDefinition() + .setNormalizedName(ValidationUtils.normalizeCategoryName4Uniqueness(migSubCat.getName())); + Either updateSubNode = titanGenericDao + .updateNode(subCategoryData, SubCategoryData.class); + if (updateSubNode.isRight()) { + log.debug("Failed to update resource sub category {} error {}", subCategoryData, + updateSubNode.right().value()); + return false; + } + log.debug("Update resource subcategory category {} ", subCategoryData); + break; + } + } + return true; + } + + private Map> createCategoriesFromYml(String categoriesTypesYml) { + String yamlAsString; + try { + yamlAsString = new String(readAllBytes(get(categoriesTypesYml))); + } catch (Exception e) { + log.debug("Failed to load category import file exception : ", e); + return null; + } + + log.debug("received yaml: {}", yamlAsString); + + Map toscaJson = (Map) new Yaml().load(yamlAsString); + Map> allCategories = new HashMap<>(); + + Iterator> categoryEntryItr = toscaJson.entrySet().iterator(); + while (categoryEntryItr.hasNext()) { + Entry categoryTypeEntry = categoryEntryItr.next(); + String categoryType = categoryTypeEntry.getKey(); + List categoriesPerType = null; + Map categoryPerType = null; + switch (categoryType) { + case ComponentTypeEnum.SERVICE_PARAM_NAME: + categoryPerType = (Map) categoryTypeEntry.getValue(); + categoriesPerType = createServiceCategories(categoryPerType); + break; + case ComponentTypeEnum.RESOURCE_PARAM_NAME: + categoryPerType = (Map) categoryTypeEntry.getValue(); + categoriesPerType = createResourceCategories(categoryPerType); + break; + case ComponentTypeEnum.PRODUCT_PARAM_NAME: + // TODO + break; + default: + log.debug("Not supported category type - {}", categoryType); + break; + } + if (categoriesPerType != null) { + allCategories.put(categoryType, categoriesPerType); + } + } + return allCategories; + } + + private List createServiceCategories(Map categories) { + List categroiesDef = new ArrayList<>(); + String catName = null; + List icons = null; + String oldName = null; + for (Entry entry : categories.entrySet()) { + MigrationCategory catDef = new MigrationCategory(); + Map category = (Map) entry.getValue(); + catName = (String) category.get("name"); + catDef.setName(catName); + icons = (List) category.get("icons"); + catDef.setIcons(icons); + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(catName); + catDef.setNormalizedName(normalizedName); + oldName = (String) category.get("oldName"); + catDef.setOldName(oldName); + categroiesDef.add(catDef); + } + + return categroiesDef; + } + + private List createResourceCategories(Map categoryPerType) { + List categroiesDef = new ArrayList<>(); + for (Map.Entry entry : categoryPerType.entrySet()) { + Map category = (Map) entry.getValue(); + MigrationCategory catDef = new MigrationCategory(); + String catName = (String) category.get("name"); + catDef.setName(catName); + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(catName); + catDef.setNormalizedName(normalizedName); + String oldName = (String) category.get("oldName"); + catDef.setOldName(oldName); + + Map subcategories = (Map) category.get("subcategories"); + List subcateDef = new ArrayList<>(); + for (Entry subcategory : subcategories.entrySet()) { + Map subcategoryInfo = (Map) subcategory.getValue(); + MigrationSubCategory subDef = new MigrationSubCategory(); + String subcategoryName = (String) subcategoryInfo.get("name"); + subDef.setName(subcategoryName); + List subcategoryIcons = (List) subcategoryInfo.get("icons"); + subDef.setIcons(subcategoryIcons); + normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subcategoryName); + subDef.setNormalizedName(normalizedName); + oldName = (String) subcategoryInfo.get("oldName"); + subDef.setOldName(oldName); + + subcateDef.add(subDef); + } + + catDef.setSubcategories(subcateDef); + categroiesDef.add(catDef); + } + return categroiesDef; + } + + private boolean updateCalculatedEdges() { + log.debug("update calculated edges STARTED"); + + Either, TitanOperationStatus> allInstances = titanGenericDao + .getByCriteria(NodeTypeEnum.ResourceInstance, null, ComponentInstanceData.class); + if (allInstances.isRight() && !allInstances.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug( + "updateCalculatedEdges failed fetch all resource instances ,error " + allInstances.right().value()); + return false; + } + if (allInstances.isRight() && allInstances.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("updateCalculatedEdges - no VFs"); + return true; + } + List listOfInstances = allInstances.left().value(); + for (ComponentInstanceData instance : listOfInstances) { + // check if already have calculated edges + log.debug("start handle instance {}", instance.getUniqueId()); + boolean needProcess = true; + Either>, TitanOperationStatus> vfci = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), + instance.getUniqueId(), GraphEdgeLabels.CALCULATED_CAPABILITY, NodeTypeEnum.Capability, + CapabilityData.class); + if (vfci.isRight()) { + if (!vfci.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("createCalculatedCapabilitiesForInstance failed to fetch instance for resource {} error: {}", + instance.getComponentInstDataDefinition().getComponentUid(), + vfci.right().value()); + return false; + } + } else { + if (vfci.left().value().size() > 0) { + needProcess = false; + } + } + Either>, TitanOperationStatus> vfciReq = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), + instance.getUniqueId(), GraphEdgeLabels.CALCULATED_REQUIREMENT, NodeTypeEnum.Requirement, + RequirementData.class); + if (vfciReq.isRight()) { + if (!vfciReq.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("createCalculatedCapabilitiesForInstance failed to fetch instance for resource {} error: {}", + instance.getComponentInstDataDefinition().getComponentUid(), + vfciReq.right().value()); + return false; + } + } else { + if (vfciReq.left().value().size() > 0) { + needProcess = false; + } + } + Either>, TitanOperationStatus> vfciReqFF = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), + instance.getUniqueId(), GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED, + NodeTypeEnum.Requirement, RequirementData.class); + if (vfciReqFF.isRight()) { + + if (!vfciReqFF.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("createCalculatedCapabilitiesForInstance failed to fetch instance for resource " + + instance.getComponentInstDataDefinition().getComponentUid() + " error " + + vfciReqFF.right().value()); + return false; + } + } else { + if (vfciReqFF.left().value().size() > 0) { + needProcess = false; + } + } + + if (needProcess == false) { + log.debug("updateCalculatedEdges : for instance {} calculated capabilty/requirement already created", instance.getUniqueId()); + continue; + } + String originId = instance.getComponentInstDataDefinition().getComponentUid(); + Either resourceE = resourceOperation.getResource(originId, true); + if (resourceE.isRight()) { + log.debug("updateCalculatedEdges failed to fetch origin resource with id {} error: {}", originId, resourceE.right().value()); + return false; + } + Resource resource = resourceE.left().value(); + Map> requirements = resource.getRequirements(); + if (createCalculatedRequirementsForInstance(instance, requirements) != true) { + return false; + } + Map> capabilities = resource.getCapabilities(); + if (createCalculatedCapabilitiesForInstance(instance, capabilities) != true) { + return false; + } + log.debug("finish handle instance {}", instance.getUniqueId()); + } + log.debug("update calculated edges ENDED"); + return true; + } + + private boolean createCalculatedCapabilitiesForInstance(ComponentInstanceData instance, + Map> capabilities) { + for (Map.Entry> entry : capabilities.entrySet()) { + for (CapabilityDefinition capability : entry.getValue()) { + Either capNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Capability), capability.getUniqueId(), + CapabilityData.class); + if (capNode.isRight()) { + log.debug("createCalculatedCapabilitiesForInstance failed to fetch capability node with id " + + capability.getUniqueId() + " error " + capNode.right().value()); + return false; + } + Map props = new HashMap<>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capability.getName()); + if (fillEdgeProperties(instance, props) != true) { + return false; + } + + Either createRelation = titanGenericDao.createRelation(instance, + capNode.left().value(), GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug( + "Failed to create calculated requirement from component instance {} to requirement {}, error: {}", + instance.getUniqueId(), capNode.left().value().getUniqueId(), titanOperationStatus); + return false; + } + log.debug("CALCULATED_CAPABILITY was created from {} to {} with props: {}", capNode.left().value().getUniqueId(), instance.getUniqueId(), props); + } + } + return true; + } + + private boolean fillEdgeProperties(ComponentInstanceData instance, Map props) { + if (instance.getComponentInstDataDefinition().getOriginType().equals(OriginTypeEnum.VF)) { + Either>, TitanOperationStatus> vfci = titanGenericDao + .getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + instance.getComponentInstDataDefinition().getComponentUid(), GraphEdgeLabels.RESOURCE_INST, + NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + if (vfci.isRight()) { + log.debug("createCalculatedCapabilitiesForInstance failed to fetch instance for resource {} error: {}", + instance.getComponentInstDataDefinition().getComponentUid(), + vfci.right().value()); + return false; + } + ImmutablePair immutablePair = vfci.left().value().get(0); + String vfciId = immutablePair.getLeft().getUniqueId(); + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), vfciId); + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), + immutablePair.getLeft().getComponentInstDataDefinition().getComponentUid()); + + } else { + props.put(GraphEdgePropertiesDictionary.OWNER_ID.getProperty(), instance.getUniqueId()); + props.put(GraphEdgePropertiesDictionary.SOURCE.getProperty(), + instance.getComponentInstDataDefinition().getComponentUid()); + } + return true; + } + + private boolean createCalculatedRequirementsForInstance(ComponentInstanceData instance, + Map> requirements) { + for (Map.Entry> entry : requirements.entrySet()) { + for (RequirementDefinition requirement : entry.getValue()) { + Either reqNode = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Requirement), requirement.getUniqueId(), + RequirementData.class); + if (reqNode.isRight()) { + log.debug("updateCalculatedEdges failed to fetch requirement node with id {} error: {}", requirement.getUniqueId(), reqNode.right().value()); + return false; + } + Map props = new HashMap<>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), requirement.getName()); + + if (fillEdgeProperties(instance, props) != true) { + return false; + } + + Either createRelation = titanGenericDao.createRelation(instance, + reqNode.left().value(), GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (createRelation.isRight()) { + TitanOperationStatus titanOperationStatus = createRelation.right().value(); + log.debug( + "Failed to create calculated requirement from component instance {} to requirement {}, error: {}", + instance.getUniqueId(), reqNode.left().value().getUniqueId(), titanOperationStatus); + return false; + } + log.debug("CALCULATED_REQUIREMENT was created from {} to {} with props: {}", reqNode.left().value().getUniqueId(), instance.getUniqueId(), props); + } + } + return true; + } + + private boolean updateRelations() { + log.debug("update relations and edges STARTED"); + Either, TitanOperationStatus> allRelations = titanGenericDao + .getByCriteria(NodeTypeEnum.RelationshipInst, null, RelationshipInstData.class); + if (allRelations.isRight()) { + if (allRelations.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("updateRelations : No relations to update. updateRelations ENDED"); + return true; + } + log.debug("updateRelations : failed to fetch all relation nodes , error ", allRelations.right().value()); + return false; + } + for (RelationshipInstData rel : allRelations.left().value()) { + // rel.set + if (rel.getCapabilityOwnerId() != null && rel.getRequirementOwnerId() != null) { + log.debug("updateRelations : for relation {} all fields alredy fixed -> {}", rel.getUniqueId(), rel); + continue; + } + // update capability parameters + if (updateCapabiltyFieldsInRelation(rel) != true) { + return false; + } + + // update requirement parameters and set calculated edge to full + // filled + if (updateRequirementFieldsInRelation(rel) != true) { + return false; + } + + Either updateNode = titanGenericDao.updateNode(rel, + RelationshipInstData.class); + if (updateNode.isRight()) { + log.debug("updateRelations : failed to update relation node with id {}, error: {}", rel.getUniqueId(), updateNode.right().value()); + return false; + } + log.debug("Relations was updated with values {}", rel); + } + log.debug("update relations and edges ENDED"); + return true; + } + + private boolean updateRequirementFieldsInRelation(RelationshipInstData rel) { + Either, TitanOperationStatus> reqInst = titanGenericDao + .getParentNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipInst), rel.getUniqueId(), + GraphEdgeLabels.RELATIONSHIP_INST, NodeTypeEnum.ResourceInstance, ComponentInstanceData.class); + if (reqInst.isRight()) { + log.debug("updateRelations : failed to fetch capabilty component instance for relation {}, error: {}", rel.getUniqueId(), reqInst.right().value()); + return false; + } + ComponentInstanceData requirementInstanceData = reqInst.left().value().getLeft(); + ComponentInstanceDataDefinition reqRI = requirementInstanceData.getComponentInstDataDefinition(); + if (reqRI.getOriginType().equals(OriginTypeEnum.VF)) { + Either, TitanOperationStatus> vfcInstInOrigVf = titanGenericDao + .getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + reqRI.getComponentUid(), GraphEdgeLabels.RESOURCE_INST, NodeTypeEnum.ResourceInstance, + ComponentInstanceData.class, null); + if (vfcInstInOrigVf.isRight()) { + log.debug("updateRelations : failed to fetch VFC instance in origin VF with id {}, error: {}", reqRI.getComponentUid(), vfcInstInOrigVf.right().value()); + return false; + } + rel.setRequirementOwnerId(vfcInstInOrigVf.left().value().getLeft().getUniqueId()); + } else { + rel.setRequirementOwnerId(reqRI.getUniqueId()); + } + // get vertex + Either vertexReqRI = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), requirementInstanceData.getUniqueId()); + if (vertexReqRI.isRight()) { + log.debug("updateRelations : failed to fetch veterx for instance {}, error: {}", requirementInstanceData.getUniqueId(), vertexReqRI.right().value()); + return false; + } + String[] splitIds = rel.getUniqueId().split("\\."); + String reqName = splitIds[splitIds.length - 1]; + Map props = new HashMap<>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), reqName); + Either, TitanOperationStatus> edgesForNode = titanGenericDao + .getOutgoingEdgesByCriteria(vertexReqRI.left().value(), GraphEdgeLabels.CALCULATED_REQUIREMENT, props); + if (edgesForNode.isRight()) { + log.debug("updateRelations : failed to fetch edges for instance {}, error: {}", requirementInstanceData.getUniqueId(), edgesForNode.right().value()); + return false; + } + Edge edge = edgesForNode.left().value().get(0); + String reqId = (String) titanGenericDao.getProperty((TitanVertex) edge.inVertex(), + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + rel.setRequirementId(reqId); + + // change edge label + TitanEdge newEdge = (TitanEdge) vertexReqRI.left().value() + .addEdge(GraphEdgeLabels.CALCULATED_REQUIREMENT_FULLFILLED.getProperty(), edge.inVertex()); + titanGenericDao.setProperties(newEdge, titanGenericDao.getProperties(edge)); + edge.remove(); + + log.debug("Edge was changed to CALCULATED_REQUIREMENT_FULLFILLED for relation between {} and {}", reqId, requirementInstanceData.getUniqueId()); + + return true; + } + + public boolean updateCapabiltyFieldsInRelation(RelationshipInstData rel) { + // update capability parameters + Either, TitanOperationStatus> capInst = titanGenericDao + .getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.RelationshipInst), + rel.getUniqueId(), GraphEdgeLabels.CAPABILITY_NODE, NodeTypeEnum.ResourceInstance, + ComponentInstanceData.class, null); + if (capInst.isRight()) { + log.debug("updateRelations : failed to fetch capabilty component instance for relation {}, error: {}", rel.getUniqueId(), capInst.right().value()); + return false; + } + ComponentInstanceData capabiltyInstanceData = capInst.left().value().getLeft(); + ComponentInstanceDataDefinition capRI = capabiltyInstanceData.getComponentInstDataDefinition(); + if (capRI.getOriginType().equals(OriginTypeEnum.VF)) { + Either, TitanOperationStatus> vfcInstInOrigVf = titanGenericDao + .getChildByEdgeCriteria(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), + capRI.getComponentUid(), GraphEdgeLabels.RESOURCE_INST, NodeTypeEnum.ResourceInstance, + ComponentInstanceData.class, null); + if (vfcInstInOrigVf.isRight()) { + log.debug("updateRelations : failed to fetch VFC instance in origin VF with id {}, error: {}", capRI.getComponentUid(), vfcInstInOrigVf.right().value()); + return false; + } + rel.setCapabilityOwnerId(vfcInstInOrigVf.left().value().getLeft().getUniqueId()); + } else { + rel.setCapabilityOwnerId(capRI.getUniqueId()); + } + + // get vertex + Either vertexCapRI = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ResourceInstance), capabiltyInstanceData.getUniqueId()); + if (vertexCapRI.isRight()) { + log.debug("updateRelations : failed to fetch veterx for instance {}, error: {}", capabiltyInstanceData.getUniqueId(), vertexCapRI.right().value()); + return false; + } + // String[] splitIds = rel.getUniqueId().split("\\."); + String capName = (String) capInst.left().value().getRight().getProperties() + .get(GraphEdgePropertiesDictionary.NAME.getProperty());// splitIds[splitIds.length + // - 1]; + Map props = new HashMap<>(); + props.put(GraphEdgePropertiesDictionary.NAME.getProperty(), capName); + Either, TitanOperationStatus> edgesForNode = titanGenericDao + .getOutgoingEdgesByCriteria(vertexCapRI.left().value(), GraphEdgeLabels.CALCULATED_CAPABILITY, props); + if (edgesForNode.isRight()) { + log.debug("updateRelations : failed to fetch edges for instance {}, error: {}", capabiltyInstanceData.getUniqueId(), edgesForNode.right().value()); + return false; + } + Edge edge = edgesForNode.left().value().get(0); + String capId = (String) titanGenericDao.getProperty((TitanVertex) edge.inVertex(), + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + rel.setCapabiltyId(capId); + + return true; + } + + // private boolean fixDerivedFv() { + // Map props = new HashMap(); + // props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), + // ResourceTypeEnum.VF.name()); + // Either, TitanOperationStatus> allVF = + // titanGenericDao.getByCriteria(NodeTypeEnum.Resource, props, + // ResourceMetadataData.class); + // if (allVF.isRight() && + // !allVF.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + // log.debug("fixDerivedFv failed fetch all VF resources,error {}", allVF.right().value()); + // return false; + // } + // if ( allVF.right().value().equals(TitanOperationStatus.NOT_FOUND) ){ + // log.debug("fixDerivedFv - no VF"); + // return true; + // } + // Set finishedResources = new HashSet<>(); + // + // for (ResourceMetadataData metadata : allVF.left().value()) { + // ComponentMetadataDataDefinition metadataDD = + // metadata.getMetadataDataDefinition(); + // + // if (!finishedResources.contains(metadataDD.getUniqueId())) { + // Either, StorageOperationStatus> processedIds = + // handleVfGroup(metadata); + // if (processedIds.isRight()) { + // log.debug("fixDerivedFv failed to process FV group {}", processedIds.right().value()); + // return false; + // } + // finishedResources.addAll(processedIds.left().value()); + // } + // } + // return true; + // } + + private Either, StorageOperationStatus> handleVfGroup(ResourceMetadataData metadata) { + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + props.put(GraphPropertiesDictionary.NAME.getProperty(), metadata.getMetadataDataDefinition().getName()); + + List finished = new ArrayList<>(); + + Either, TitanOperationStatus> allVFByName = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (allVFByName.isRight()) { + log.debug("fixDerivedFv failed fetch all VF resources,error {}", allVFByName.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + Set nonDuplicatedId = new HashSet<>(); + String uuid10 = null; + for (ResourceMetadataData mdata : allVFByName.left().value()) { + String version = mdata.getMetadataDataDefinition().getVersion(); + if (version.equals("1.0")) { + uuid10 = mdata.getMetadataDataDefinition().getUUID(); + // break; + } + nonDuplicatedId.add((String) mdata.getUniqueId()); + } + if (uuid10 == null) { + uuid10 = allVFByName.left().value().get(0).getMetadataDataDefinition().getUUID(); + } + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + props.put(GraphPropertiesDictionary.UUID.getProperty(), uuid10); + + Either, TitanOperationStatus> allVFByUUID = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (allVFByUUID.isRight()) { + log.debug("fixDerivedFv failed fetch all VF resources by UUID {}, error: {}", uuid10, allVFByUUID.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + for (ResourceMetadataData mdata : allVFByUUID.left().value()) { + nonDuplicatedId.add((String) mdata.getUniqueId()); + } + Either graph = titanGenericDao.getGraph(); + if (graph.isRight()) { + log.debug("fixDerivedFv failed - No titan graph ,error {}", graph.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + // Map derivedMapping = new HashMap<>(); + for (String resourceId : nonDuplicatedId) { + // StorageOperationStatus handleSingleVfResult = + // handleSingleVf(finished, derivedMapping, resourceId); + StorageOperationStatus handleSingleVfResult = handleSingleVf(finished, resourceId); + if (!handleSingleVfResult.equals(StorageOperationStatus.OK)) { + log.debug("fixDerivedFv failed - handleSingleVfResult failed for resource {}, error: {}", resourceId, handleSingleVfResult); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + return Either.left(finished); + } + + // private StorageOperationStatus handleSingleVf(List finished, + // Map derivedMapping, String resourceId) { + private StorageOperationStatus handleSingleVf(List finished, String resourceId) { + Either vertexByProperty = titanGenericDao + .getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), resourceId); + if (vertexByProperty.isRight()) { + log.debug("fixDerivedFv failed to fetch resource by id {}, error: {}", resourceId, vertexByProperty.right().value()); + return StorageOperationStatus.GENERAL_ERROR; + } + Vertex vertexR = vertexByProperty.left().value(); + Iterator vertexDIter = vertexR.vertices(Direction.OUT, GraphEdgeLabels.DERIVED_FROM.getProperty()); + if (vertexDIter != null && vertexDIter.hasNext()) { + // move edges + // must be only one + TitanVertex vertexD = (TitanVertex) vertexDIter.next(); + String idDerived = (String) titanGenericDao.getProperty(vertexD, + GraphPropertiesDictionary.UNIQUE_ID.getProperty()); + + // TODO clone resource + + // TODO add instance of new resource to VF + + // add to vf instance of vfc + finished.add(resourceId); + } else { + log.debug("No derived edges for resource id {}", resourceId); + } + return StorageOperationStatus.OK; + } + + private boolean updateComponentInstanceType() { + log.debug("update component instances type STARTED"); + Either, TitanOperationStatus> allInstances = titanGenericDao + .getByCriteria(NodeTypeEnum.ResourceInstance, null, ComponentInstanceData.class); + if (allInstances.isRight()) { + if (allInstances.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("updateComponentInstanceType: no instances ti update "); + return true; + } + log.debug("updateComponentInstanceType failed fetch all resource instances ,error {}", allInstances.right().value()); + return false; + } + + List listOfInstances = allInstances.left().value(); + for (ComponentInstanceData instance : listOfInstances) { + String originId = instance.getComponentInstDataDefinition().getComponentUid(); + Either nodeResource = titanGenericDao.getNode( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), originId, ComponentMetadataData.class); + if (nodeResource.isRight()) { + log.debug("updateComponentInstanceType failed to fetch origin resource with id {}, error: {}", originId, nodeResource.right().value()); + return false; + } + ResourceTypeEnum resourceType = ((ResourceMetadataDataDefinition) nodeResource.left().value() + .getMetadataDataDefinition()).getResourceType(); + if (resourceType == null) { + log.debug("updateComponentInstanceType failed, no resource type for origin resource with id {}", originId); + return false; + } + OriginTypeEnum originType; + switch (resourceType) { + case VF: + originType = OriginTypeEnum.VF; + break; + case VFC: + originType = OriginTypeEnum.VFC; + break; + case VL: + originType = OriginTypeEnum.VL; + break; + case CP: + originType = OriginTypeEnum.CP; + break; + default: + log.debug("updateComponentInstanceType failed, no supported resource type {} for origin resource with id {}", resourceType, originId); + return false; + } + instance.getComponentInstDataDefinition().setOriginType(originType); + + Either updateNode = titanGenericDao.updateNode(instance, + ComponentInstanceData.class); + if (updateNode.isRight()) { + log.debug("updateComponentInstanceType failed, failed to update component instance node with id {}, error: {}", instance.getUniqueId(), updateNode.right().value()); + return false; + } + log.debug("For instance with id {} the origin type was detected as {}", instance.getUniqueId(), originType); + } + log.debug("update component instances type ENDED"); + return true; + } + + private boolean addResourceCounterToResources() { + + Either, TitanOperationStatus> allResources = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, null, ResourceMetadataData.class); + if (allResources.isRight()) { + if (allResources.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("addResourceCounterToResources - no resources"); + return true; + } + log.debug("addResourceCounterToResources failed fetch all resources,error {}", allResources.right().value()); + return false; + } + for (ResourceMetadataData resource : allResources.left().value()) { + Either vertexByProperty = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), resource.getUniqueId()); + if (vertexByProperty.isRight()) { + log.error("failed to add instanceCounter to VF {} . error is: {}", resource.getUniqueId(), + vertexByProperty.right().value().name()); + return false; + } + Vertex vfVertex = vertexByProperty.left().value(); + if (!vfVertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty()).isPresent()) { + vfVertex.property(GraphPropertiesDictionary.INSTANCE_COUNTER.getProperty(), 0); + } + } + return true; + } + + private boolean fixDerivedVf() { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + Either, TitanOperationStatus> allVF = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (allVF.isRight()) { + if (allVF.right().value().equals(TitanOperationStatus.NOT_FOUND)) { + log.debug("fixDerivedVf - no VFs"); + return true; + } + log.debug("fixDerivedFv failed fetch all VF resources,error {}", allVF.right().value()); + return false; + } + + Map vfUuidToVfcUuid = new HashMap(); + for (ResourceMetadataData metadata : allVF.left().value()) { + Either eitherResource = resourceOperation + .getResource(metadata.getMetadataDataDefinition().getUniqueId(), true); + if (eitherResource.isRight()) { + log.error("failed to migrate VF {} from version 1602 to version 1604. error is: {}", + metadata.getMetadataDataDefinition().getUniqueId(), eitherResource.right().value().name()); + return false; + } + Resource vfResource = eitherResource.left().value(); + if (vfResource.getDerivedFrom() == null || vfResource.getDerivedFrom().isEmpty()) { + continue; + } + Boolean isVfDeleted = vfResource.getIsDeleted(); + String vfUUID = vfResource.getUUID(); + String vfcUUID = vfUuidToVfcUuid.getOrDefault(vfUUID, null); + if (vfcUUID == null) { + vfcUUID = UUID.randomUUID().toString(); + vfUuidToVfcUuid.put(vfUUID, vfcUUID); + } + + // handle lifecycle + String vfUniqueId = vfResource.getUniqueId(); + LifecycleStateEnum vfcTargetState = vfResource.getLifecycleState(); + if (vfcTargetState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION) + || vfcTargetState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS)) { + User user = new User(); + user.setUserId(vfResource.getLastUpdaterUserId()); + Either checkinComponent = lifecycleOperaion + .checkinComponent(NodeTypeEnum.Resource, vfResource, user, user, true); + if (checkinComponent.isRight()) { + log.error("failed to checkin VF {}. error={}", vfUniqueId, checkinComponent.right().value().name()); + return false; + } + } else if (vfcTargetState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + vfcTargetState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN; + } + + // delete VF Properties + List properties = vfResource.getProperties(); + if (properties != null && !properties.isEmpty()) { + Either, StorageOperationStatus> deleteAllProperties = propertyOperation + .deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, vfUniqueId); + if (deleteAllProperties.isRight() + && !deleteAllProperties.right().value().equals(StorageOperationStatus.NOT_FOUND) + && !deleteAllProperties.right().value().equals(StorageOperationStatus.OK)) { + log.error("failed to delete properties of VF {} . error is: {}", + metadata.getMetadataDataDefinition().getUniqueId(), + deleteAllProperties.right().value().name()); + return false; + } + } + // delete VF Additional Info + List additionalInformation = vfResource.getAdditionalInformation(); + if (additionalInformation != null && !additionalInformation.isEmpty()) { + Either deleteAllAdditionalInformationParameters = additionalInformationOperation + .deleteAllAdditionalInformationParameters(NodeTypeEnum.Resource, vfUniqueId, true); + if (deleteAllAdditionalInformationParameters.isRight() + && !deleteAllAdditionalInformationParameters.right().value().equals(StorageOperationStatus.OK) + && !deleteAllAdditionalInformationParameters.right().value() + .equals(StorageOperationStatus.NOT_FOUND)) { + log.error("failed to delete properties of VF {} . error is: {}", + metadata.getMetadataDataDefinition().getUniqueId(), + deleteAllAdditionalInformationParameters.right().value().name()); + return false; + } + } + // delete VF derivedFrom + GraphRelation derivedFromRelation = new GraphRelation(GraphEdgeLabels.DERIVED_FROM.getProperty()); + derivedFromRelation.setFrom(new RelationEndPoint(NodeTypeEnum.Resource, + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), vfUniqueId)); + Either deleteDerivedFromRelation = titanGenericDao + .deleteOutgoingRelation(derivedFromRelation); + if (deleteDerivedFromRelation.isRight()) { + log.error("failed to delete derivedFrom relation of VF {} . error is: {}", + metadata.getMetadataDataDefinition().getUniqueId(), + deleteDerivedFromRelation.right().value().name()); + return false; + } + + // create VFC + Either createVFC = createVFC(metadata, vfResource, vfcUUID, + vfcTargetState); + if (createVFC.isRight()) { + log.error("failed to split VF {} to VFC. error is: {}", + metadata.getMetadataDataDefinition().getUniqueId(), createVFC.right().value().name()); + return false; + } + Resource vfcResource = createVFC.left().value(); + if (!createVfcInstanceOnVf(vfcResource, vfUniqueId)) { + return false; + } + // update VFC to deleted if required + if (isVfDeleted != null && isVfDeleted) { + Either markResourceToDelete = resourceOperation + .markComponentToDelete(vfcResource, true); + if (markResourceToDelete.isRight()) { + log.error("failed to mark isDeleted on VFC {} . error is: {}", vfcResource.getUniqueId(), + markResourceToDelete.right().value().name()); + return false; + } + } + + } + return true; + } + + private Either createVFC(ResourceMetadataData metadata, Resource vfcResource, + String uuid, LifecycleStateEnum vfcTargetState) { + + Boolean highestVersion = vfcResource.isHighestVersion(); + // Resource vfcResource = new Resource((ResourceMetadataDefinition) + // vfResource.getComponentMetadataDefinition()); + // String componentName = vfcResource.getName()+"VFC"; + // vfcResource.setName(componentName); + // vfcResource.setNormalizedName(ValidationUtils.normaliseComponentName(componentName)); + // vfcResource.setSystemName(ValidationUtils.convertToSystemName(componentName)); + vfcResource.setUniqueId(null); + vfcResource.setUUID(uuid); + vfcResource.setAllVersions(null); + vfcResource.setArtifacts(null); + vfcResource.setDeploymentArtifacts(null); + vfcResource.setComponentInstances(null); + vfcResource.setComponentInstancesProperties(null); + vfcResource.setComponentInstancesRelations(null); + vfcResource.setResourceType(ResourceTypeEnum.VFC); + vfcResource.setIsDeleted(false); + + vfcResource.setLifecycleState(vfcTargetState); + // vfcResource.setDerivedFrom(vfResource.getDerivedFrom()); + // vfcResource.setProperties(vfResource.getProperties()); + // vfcResource.setAdditionalInformation(vfResource.getAdditionalInformation()); + // vfcResource.setCategories(vfResource.getCategories()); + // vfcResource.setTags(vfResource.getTags()); + + Either createResource = resourceOperation.createResource(vfcResource, true); + if (createResource.isRight()) { + return createResource; + } + Resource afterCreateResource = createResource.left().value(); + Either vertexByProperty = titanGenericDao.getVertexByProperty( + UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Resource), afterCreateResource.getUniqueId()); + if (vertexByProperty.isRight()) { + return createResource; + } + Vertex newVfcVertex = vertexByProperty.left().value(); + newVfcVertex.property(GraphPropertiesDictionary.UUID.getProperty(), uuid); + if (!highestVersion) { + newVfcVertex.property(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), false); + } + return createResource; + } + + private boolean createVfcInstanceOnVf(Resource vfcResource, String vfUniqueId) { + // create VFC instance on VF + ComponentInstance componentInstance = new ComponentInstance(); + componentInstance.setComponentUid(vfcResource.getUniqueId()); + componentInstance.setPosX("550"); + componentInstance.setPosY("300"); + componentInstance.setName(vfcResource.getName()); + componentInstance.setIcon(vfcResource.getIcon()); + componentInstance.setToscaComponentName(vfcResource.getToscaResourceName()); + Either handleNameLogic = handleNameLogic(componentInstance, vfUniqueId, vfcResource.getName()); + if (handleNameLogic.isRight()) { + log.error("failed to create logical name for vfc instance"); + return false; + } + Either createComponentInstance = componentInstanceOperaion + .createComponentInstance(vfUniqueId, NodeTypeEnum.Resource, handleNameLogic.left().value(), + componentInstance, NodeTypeEnum.Resource, true); + + if (createComponentInstance.isRight()) { + log.error("failed to create vfc instance on vf {}. error: {}", vfUniqueId, + createComponentInstance.right().value().name()); + return false; + } + return true; + } + + private Either handleNameLogic(ComponentInstance componentInstance, String containerComponentId, + String resourceName) { + + Either componentInNumberStatus = resourceOperation + .increaseAndGetComponentInstanceCounter(containerComponentId, true); + + if (componentInNumberStatus.isRight()) { + log.debug("Failed to get component instance number for container component {} ", containerComponentId); + return Either.right(false); + } + String resourceInNumber = componentInNumberStatus.left().value().toString(); + componentInstance.setComponentName(resourceName); + componentInstance.setName(resourceName); + String logicalName = componentInstanceOperaion.createComponentInstLogicalName(resourceInNumber, resourceName); + + Boolean eitherValidation = validateComponentInstanceName(logicalName, componentInstance, true); + if (!eitherValidation) { + return Either.right(false); + } + + return Either.left(resourceInNumber); + } + + private Boolean validateComponentInstanceName(String resourceInstanceName, ComponentInstance resourceInstance, + boolean isCreate) { + + if (!ValidationUtils.validateStringNotEmpty(resourceInstanceName)) { + return false; + } + resourceInstance.setNormalizedName(ValidationUtils.normaliseComponentInstanceName(resourceInstanceName)); + if (!isCreate) { + if (!ValidationUtils.validateResourceInstanceNameLength(resourceInstanceName)) { + return false; + } + if (!ValidationUtils.validateResourceInstanceName(resourceInstanceName)) { + return false; + } + } + + return true; + + } + + public boolean migrate1604to1607(String appConfigDir) { + log.debug("Started the migration procedure from version 1604 to version 1607 ..."); + log.debug("Getting all resources with resources"); + boolean result = false; + Either resourceEither = null; + try { + Either, TitanOperationStatus> allResources = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, null, ResourceMetadataData.class); + if (allResources.isRight()) { + log.error("Couldn't get resources from DB, error: {}", allResources.right().value()); + result = false; + return result; + } + List resourcesList = allResources.left().value(); + if (resourcesList == null) { + log.error("Couldn't get resources from DB, no resources found"); + result = false; + return result; + } + log.debug("Found {} resources", resourcesList.size()); + for (ResourceMetadataData resource : resourcesList) { + String resourceName = resource.getMetadataDataDefinition().getName(); + log.debug("Checking resource {}", resourceName); + if (isNormative(resourceName)) { + resourceEither = changeNormativeTypeName(resource); + if (resourceEither.isRight()) { + log.error("DB error during name changing"); + result = false; + return result; + } + } + if (((ResourceMetadataDataDefinition) resource.getMetadataDataDefinition()).getResourceType().name() + .equals("VF")) { + resourceEither = setVfToscaResourceName(resource); + if (resourceEither.isRight()) { + log.error("DB error during tosca resource name setting"); + result = false; + return result; + } + } + } + result = addInvariantUUIDs(appConfigDir); + } finally { + if (!result) { + titanGenericDao.rollback(); + log.debug("**********************************************"); + log.debug("The migration procedure from version 1604 to version 1607 FAILED!!"); + log.debug("**********************************************"); + } else { + titanGenericDao.commit(); + log.debug("**********************************************"); + log.debug("The migration procedure from version 1604 to version 1607 ended successfully!"); + log.debug("**********************************************"); + } + } + + return result; + } + + private boolean addInvariantUUIDs(String appConfigDir) { + log.debug("Started adding of InvariantUUID ..."); + log.debug("Getting all resources with highest version"); + + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true); + + List fullComponentList = new ArrayList(); + + // getting resources + Either, TitanOperationStatus> allHighestVersionResources = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (allHighestVersionResources.isRight()) { + log.error("Couldn't get resources with highest version from DB, error: {}", + allHighestVersionResources.right().value()); + return false; + } + List allHighestVersionResourcesAL = allHighestVersionResources.left().value(); + if (allHighestVersionResourcesAL == null) { + log.error("Couldn't get resources with highest version from DB, no resources found"); + return false; + } + log.debug("Found {} resources", allHighestVersionResourcesAL.size()); + fullComponentList.addAll(allHighestVersionResourcesAL); + + // getting services + Either, TitanOperationStatus> allHighestVersionServices = titanGenericDao + .getByCriteria(NodeTypeEnum.Service, props, ServiceMetadataData.class); + if (allHighestVersionServices.isRight()) { + log.error("Couldn't get services with highest version from DB, error: {}", + allHighestVersionServices.right().value()); + return false; + } + List allHighestVersionServicesAL = allHighestVersionServices.left().value(); + if (allHighestVersionServicesAL == null) { + log.error("Couldn't get services with highest version from DB, no services found"); + return false; + } + log.debug("Found {} services", allHighestVersionServicesAL.size()); + fullComponentList.addAll(allHighestVersionServicesAL); + + List reducedComponentsAL = reduceHighestVersionResourcesList(fullComponentList); + + // getting products + Either, TitanOperationStatus> allHighestVersionProducts = titanGenericDao + .getByCriteria(NodeTypeEnum.Product, props, ProductMetadataData.class); + if (allHighestVersionProducts.isRight()) { + log.error("Couldn't get products with highest version from DB, error: {}", + allHighestVersionProducts.right().value()); + return false; + } + List allHighestVersionProductsAL = allHighestVersionProducts.left().value(); + if (allHighestVersionProductsAL == null) { + log.error("Couldn't get products with highest version from DB, no products found"); + return false; + } + log.debug("Found {} products", allHighestVersionProductsAL.size()); + + List fullProductList = new ArrayList(); + fullProductList.addAll(allHighestVersionProductsAL); + List reducedProductAL = reduceHighestVersionResourcesList(fullProductList); + + for (ComponentMetadataData product : reducedProductAL) { + if (!setProductInvariantUUIDIfExists((ProductMetadataData) product)) { + return false; + } + } + reducedComponentsAL.addAll(reducedProductAL); + + log.debug("Reduced list of Highest Version Components contains {} components", reducedComponentsAL.size()); + for (ComponentMetadataData componentMetaData : reducedComponentsAL) { + + String invariantUUID = componentMetaData.getMetadataDataDefinition().getInvariantUUID(); + log.debug("old invariantUUID {}", invariantUUID); + if (invariantUUID == null || invariantUUID.isEmpty()) { + invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + componentMetaData.getMetadataDataDefinition().setInvariantUUID(invariantUUID); + } + log.debug("new invariantUUID {}", componentMetaData.getMetadataDataDefinition().getInvariantUUID()); + Either updateNode = titanGenericDao + .updateNode(componentMetaData, ComponentMetadataData.class); + if (updateNode.isRight()) { + log.error("DB error during while updating component {}, error: {}", + componentMetaData.getMetadataDataDefinition().getName(), updateNode.right().value()); + return false; + } + log.debug("updated invariantUUID {}", + updateNode.left().value().getMetadataDataDefinition().getInvariantUUID()); + if (!isOnlyVersion(componentMetaData)) { + ComponentOperation componentOperation = null; + switch (NodeTypeEnum.getByName(componentMetaData.getLabel())) { + case Resource: + componentOperation = resourceOperation; + break; + case Service: + componentOperation = serviceOperation; + break; + case Product: + componentOperation = productOperation; + break; + default: + break; + } + Either getComponentResult = componentOperation + .getComponent((String) componentMetaData.getUniqueId(), true); + if (getComponentResult.isRight()) { + log.error("DB error during while getting component with uniqueID {}, error: {}", + componentMetaData.getUniqueId(), getComponentResult.right().value()); + return false; + } + Component component = getComponentResult.left().value(); + if (component == null) { + log.error("The component received from DB is empty"); + return false; + } + + Map allVersions = component.getAllVersions(); + log.debug("found {} versions for component {}", allVersions.size(), component.getName()); + Either resEither = updateAllVersions(allVersions, invariantUUID); + if (resEither.isRight()) { + log.error("DB error during invariantUUID adding"); + return false; + } + } + } + return true; + } + + private boolean isOnlyVersion(ComponentMetadataData componentMetaData) { + String version = componentMetaData.getMetadataDataDefinition().getVersion(); + if (version.equals("0.1")) + return true; + return false; + } + + private boolean setProductInvariantUUIDIfExists(ProductMetadataData product) { + Either getVertexRes = titanGenericDao + .getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), product.getUniqueId()); + if (getVertexRes.isRight()) { + log.error("DB error during retrieving product vertex {}", product.getMetadataDataDefinition().getName()); + return false; + } + Vertex productVertex = getVertexRes.left().value(); + String invariantUUID = productVertex.value(GraphPropertiesDictionary.CONSTANT_UUID.getProperty()); + if (invariantUUID != null && !invariantUUID.isEmpty()) { + product.getMetadataDataDefinition().setInvariantUUID(invariantUUID); + } + return true; + } + + private Either updateAllVersions(Map allVersions, + String invariantUUID) { + + if (allVersions != null) { + for (String uniqueID : allVersions.values()) { + Either getNodeResult = titanGenericDao.getNode( + GraphPropertiesDictionary.UNIQUE_ID.getProperty(), uniqueID, ComponentMetadataData.class); + if (getNodeResult.isRight()) { + log.error("DB error during while getting component with uniqueID {}, error: {}", uniqueID, + getNodeResult.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + ComponentMetadataData component = getNodeResult.left().value(); + component.getMetadataDataDefinition().setInvariantUUID(invariantUUID); + Either updateNodeResult = titanGenericDao + .updateNode(component, ComponentMetadataData.class); + log.debug("updated child invariantUUID {}", + updateNodeResult.left().value().getMetadataDataDefinition().getInvariantUUID()); + if (updateNodeResult.isRight()) { + log.error("DB error during while updating component {}, error: {}", + component.getMetadataDataDefinition().getName(), updateNodeResult.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + } + } + return Either.left(true); + } + + private List reduceHighestVersionResourcesList( + List allHighestVersionResources) { + List resultList = null; + Map resultHM = new HashMap(); + for (ComponentMetadataData resource : allHighestVersionResources) { + if (resource.getMetadataDataDefinition().getInvariantUUID() != null + && !resource.getMetadataDataDefinition().getInvariantUUID().isEmpty()) { + log.debug("invariantUUID {} ", resource.getMetadataDataDefinition().getInvariantUUID()); + continue; + } + String curUUID = resource.getMetadataDataDefinition().getUUID(); + if (resultHM.containsKey(curUUID)) { + int isHighest = resultHM.get(curUUID).getMetadataDataDefinition().getVersion() + .compareTo(resource.getMetadataDataDefinition().getVersion()); + if (isHighest > 0) { + log.debug("version {} is great than {} ", + resultHM.get(curUUID).getMetadataDataDefinition().getVersion(), + resource.getMetadataDataDefinition().getVersion()); + continue; + } + } + resultHM.put(curUUID, resource); + } + resultList = new ArrayList(resultHM.values()); + return resultList; + } + + private boolean isNormative(String resourceName) { + for (int i = 0; i < NORMATIVE_OLD_NAMES.length; ++i) { + if (NORMATIVE_OLD_NAMES[i].equals(resourceName)) + return true; + } + return false; + } + + private Either changeNormativeTypeName(ResourceMetadataData resource) { + + String resourceName = resource.getMetadataDataDefinition().getName(); + + if (resourceName != null && !resourceName.isEmpty()) { + log.debug("Found normative type to change - {}", resourceName); + String oldName = resourceName; + String[] splitedName = resourceName.split("\\."); + String newName = splitedName[splitedName.length - 1]; + String newSystemName = ValidationUtils.convertToSystemName(newName); + String newNormalizedName = ValidationUtils.normaliseComponentName(newName); + log.debug("Setting name to be {}", newName); + + resource.getMetadataDataDefinition().setName(newName); + log.debug("Setting system name to be {}", newSystemName); + resource.getMetadataDataDefinition().setSystemName(newSystemName); + log.debug("Setting normalized name to be {}", newNormalizedName); + resource.getMetadataDataDefinition().setNormalizedName(newNormalizedName); + log.debug("Updating tag in metadata to be {}", newName); + resource.getMetadataDataDefinition().getTags().remove(oldName); + resource.getMetadataDataDefinition().getTags().add(newName); + + log.debug("Creating tag node with name {}", newName); + TagData tagData = new TagData(); + tagData.setName(newName); + Either createNode = titanGenericDao.createNode(tagData, TagData.class); + if (createNode.isRight()) { + log.error("Error while creating tag node {}, error: {}.", newName, createNode.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + + Either updateNode = titanGenericDao.updateNode(resource, + ResourceMetadataData.class); + if (updateNode.isRight()) { + log.error("DB error during while updating normative type {}, error: {}", + resource.getMetadataDataDefinition().getName(), updateNode.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("Normative type {} was successfully updated", resource.getMetadataDataDefinition().getName()); + return Either.left(true); + } + + return Either.left(false); + } + + private Either generateAndSetToscaResourceName(ResourceMetadataData resource, + String toscaResourceName) { + if (toscaResourceName == null) { + toscaResourceName = CommonBeUtils.generateToscaResourceName( + ((ResourceMetadataDataDefinition) resource.getMetadataDataDefinition()).getResourceType().name(), + resource.getMetadataDataDefinition().getSystemName()); + } + Either validateToscaResourceNameExists = resourceOperation + .validateToscaResourceNameExists(toscaResourceName); + if (validateToscaResourceNameExists.isRight()) { + StorageOperationStatus storageOperationStatus = validateToscaResourceNameExists.right().value(); + log.error("Couldn't validate toscaResourceName uniqueness - error: {}", storageOperationStatus); + return Either.right(storageOperationStatus); + } + if (validateToscaResourceNameExists.left().value()) { + log.debug("Setting tosca resource name to be {}", toscaResourceName); + ((ResourceMetadataDataDefinition) resource.getMetadataDataDefinition()) + .setToscaResourceName(toscaResourceName); + return Either.left(true); + } else { + // As agreed with Renana - cannot be fixed automatically + log.warn("toscaResourceName {} is not unique! Cannot set it. Continuing..."); + return Either.left(false); + } + } + + public boolean testRemoveHeatPlaceHolders(String appConfigDir) { + + if (!AllowMultipleHeats.removeAndUpdateHeatPlaceHolders(titanGenericDao, log, false)) { + log.error("Failed to update heat place holders"); + return false; + } + return true; + } + + private Either setVfToscaResourceName(ResourceMetadataData resource) { + String resourceName = resource.getMetadataDataDefinition().getName(); + String resourceType = ((ResourceMetadataDataDefinition) resource.getMetadataDataDefinition()).getResourceType() + .name(); + String toscaResourceName = CommonBeUtils.generateToscaResourceName(resourceType, + resource.getMetadataDataDefinition().getSystemName()); + log.debug("Setting tosca resource name {} to VF {}", toscaResourceName, resourceName); + ((ResourceMetadataDataDefinition) resource.getMetadataDataDefinition()).setToscaResourceName(toscaResourceName); + + Either updateNode = titanGenericDao.updateNode(resource, + ResourceMetadataData.class); + if (updateNode.isRight()) { + log.error("DB error during while updating VF tosca resource name {}, error: {}", + resource.getMetadataDataDefinition().getName(), updateNode.right().value()); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + log.debug("Tosca resource name of VF {} was successfully updated", + resource.getMetadataDataDefinition().getName()); + return Either.left(true); + } + + public boolean testAddGroupUuids(String appConfigDir) { + + if (!AddGroupUuid.addGroupUuids(titanGenericDao, log, false)) { + log.error("Failed to update group UUIDs"); + return false; + } + return true; + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/VfcNamingAlignment.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/VfcNamingAlignment.java new file mode 100644 index 0000000000..27b9351ebc --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1604/VfcNamingAlignment.java @@ -0,0 +1,185 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1604; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.TagData; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public class VfcNamingAlignment { + + private static Logger log = LoggerFactory.getLogger(VfcNamingAlignment.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + @Autowired + protected ResourceOperation resourceOperation; + + public boolean alignVfcNames1604(String appConfigDir) { + log.debug("Started alignVfcNames1604 procedure.."); + log.debug("Getting all resources with resourceType = VFC/CP/VL"); + boolean result = false; + try { + Map notProperties = new HashMap<>(); + notProperties.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + Either, TitanOperationStatus> allVfcResources = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, null, notProperties, ResourceMetadataData.class); + if (allVfcResources.isRight()) { + log.error("Couldn't get VFC resources from DB, error: {}", allVfcResources.right().value()); + result = false; + return result; + } + List vfcList = allVfcResources.left().value(); + if (vfcList == null) { + log.error("Couldn't get VFC/CP/VL resources from DB, no resources found"); + result = false; + return result; + } + log.debug("Found {} VFC/CP/VL resources", vfcList.size()); + for (ResourceMetadataData vfc : vfcList) { + log.debug("Checking resource {}", vfc.getMetadataDataDefinition().getName()); + boolean wasChanged = false; + + Either vfcEither = fixToscaNameEmpty(vfc); + if (vfcEither.isRight()) { + log.error("DB error during checkIsToscaNameEmpty - exiting..."); + result = false; + return result; + } + wasChanged = wasChanged | vfcEither.left().value(); + + vfcEither = fixVfcToscaNameHasVf(vfc); + if (vfcEither.isRight()) { + log.error("DB error during checkIsVfcToscaNameHasVf - exiting..."); + result = false; + return result; + } + wasChanged = wasChanged | vfcEither.left().value(); + + if (wasChanged) { + Either updateVfc = updateVfc(vfc); + if (updateVfc.isRight()) { + log.error("DB error during while updating resource {}, error: {} - exiting...", + vfc.getMetadataDataDefinition().getName(), updateVfc.right().value()); + result = false; + return result; + } + log.debug("Resource {} was successfully updated", vfc.getMetadataDataDefinition().getName()); + } + + } + result = true; + } finally { + if (!result) { + titanGenericDao.rollback(); + log.debug("**********************************************"); + log.debug("alignVfcNames1604 procedure FAILED!!"); + log.debug("**********************************************"); + } else { + titanGenericDao.commit(); + log.debug("**********************************************"); + log.debug("alignVfcNames1604 procedure ended successfully!"); + log.debug("**********************************************"); + } + } + + return result; + } + + private Either updateVfc(ResourceMetadataData vfc) { + return titanGenericDao.updateNode(vfc, ResourceMetadataData.class); + } + + private Either fixToscaNameEmpty(ResourceMetadataData vfc) { + String toscaResourceName = ((ResourceMetadataDataDefinition) vfc.getMetadataDataDefinition()) + .getToscaResourceName(); + if (toscaResourceName == null || toscaResourceName.trim().equals(Constants.EMPTY_STRING)) { + log.debug("Tosca resource name is empty - setting new tosca name..."); + Either generateAndSetToscaResourceName = generateAndSetToscaResourceName( + vfc, null); + if (generateAndSetToscaResourceName.isRight()) { + return Either.right(generateAndSetToscaResourceName.right().value()); + } + return Either.left(true); + } + return Either.left(false); + } + + private Either fixVfcToscaNameHasVf(ResourceMetadataData vfc) { + String toscaResourceName = ((ResourceMetadataDataDefinition) vfc.getMetadataDataDefinition()) + .getToscaResourceName(); + if (toscaResourceName.contains(".vf.")) { + log.debug("Tosca resource name {} is VF-style - setting new tosca name...", toscaResourceName); + Either generateAndSetToscaResourceName = generateAndSetToscaResourceName( + vfc, null); + if (generateAndSetToscaResourceName.isRight()) { + return Either.right(generateAndSetToscaResourceName.right().value()); + } + return Either.left(true); + } + return Either.left(false); + } + + + private Either generateAndSetToscaResourceName(ResourceMetadataData vfc, + String toscaResourceName) { + if (toscaResourceName == null) { + toscaResourceName = CommonBeUtils.generateToscaResourceName( + ((ResourceMetadataDataDefinition) vfc.getMetadataDataDefinition()).getResourceType().name(), + vfc.getMetadataDataDefinition().getSystemName()); + } + Either validateToscaResourceNameExists = resourceOperation + .validateToscaResourceNameExists(toscaResourceName); + if (validateToscaResourceNameExists.isRight()) { + StorageOperationStatus storageOperationStatus = validateToscaResourceNameExists.right().value(); + log.error("Couldn't validate toscaResourceName uniqueness - error: {}", storageOperationStatus); + return Either.right(storageOperationStatus); + } + if (validateToscaResourceNameExists.left().value()) { + log.debug("Setting tosca resource name to be {}", toscaResourceName); + ((ResourceMetadataDataDefinition) vfc.getMetadataDataDefinition()).setToscaResourceName(toscaResourceName); + return Either.left(true); + } else { + // As agreed with Renana - cannot be fixed automatically + log.warn("toscaResourceName {} is not unique! Cannot set it. Continuing..."); + return Either.left(false); + } + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1607/CsarMigration.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1607/CsarMigration.java new file mode 100644 index 0000000000..b141eecb87 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1607/CsarMigration.java @@ -0,0 +1,93 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1607; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; +import org.apache.tinkerpop.gremlin.structure.util.ElementHelper; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import com.thinkaurelius.titan.core.TitanVertex; + +import fj.data.Either; + +public class CsarMigration { + private static Logger log = LoggerFactory.getLogger(CsarMigration.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + + public boolean removeCsarResources() { + Map props = new HashMap<>(); + props.put(GraphPropertiesDictionary.RESOURCE_TYPE.getProperty(), ResourceTypeEnum.VF.name()); + + Either, TitanOperationStatus> byCriteria = titanGenericDao + .getByCriteria(NodeTypeEnum.Resource, props, ResourceMetadataData.class); + if (byCriteria.isRight()) { + log.debug("Failed to fetch VF resources by criteria ", byCriteria.right().value()); + return false; + } + List resources = byCriteria.left().value(); + + try { + for (ResourceMetadataData data : resources) { + if (data.getMetadataDataDefinition().getCsarUUID() != null) { + log.debug("VF {} with CSAR {}", data.getUniqueId(), data.getMetadataDataDefinition().getCsarUUID()); + Either vertexByProperty = titanGenericDao + .getVertexByProperty(GraphPropertiesDictionary.UNIQUE_ID.getProperty(), data.getUniqueId()); + if (vertexByProperty.isRight()) { + log.debug("Failed to fetch vertex with id {} . skip resource {} ", data.getUniqueId(), + data.getMetadataDataDefinition().getName()); + continue; + } + Vertex vertex = vertexByProperty.left().value(); + Iterator> properties = vertex + .properties(GraphPropertiesDictionary.CSAR_UUID.getProperty()); + while (properties.hasNext()) { + VertexProperty next = properties.next(); + next.remove(); + } + + } + } + titanGenericDao.commit(); + } catch (Exception e) { + log.debug("Failed to clean CSAR UUID. rollback"); + titanGenericDao.rollback(); + } + + return true; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/TitanFixUtils.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/TitanFixUtils.java new file mode 100644 index 0000000000..36ac98e578 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/TitanFixUtils.java @@ -0,0 +1,387 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1610; + +import com.google.gson.Gson; +import com.thinkaurelius.titan.core.TitanGraph; +import com.thinkaurelius.titan.core.TitanVertex; +import fj.data.Either; + +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.operations.impl.CacheMangerOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import java.util.*; + +/** + * Created by mlando on 8/17/2016. + */ +public class TitanFixUtils { + private static Logger log = LoggerFactory.getLogger(TitanFixUtils.class.getName()); + + @Autowired + protected TitanGenericDao titanGenericDao; + @Autowired + protected CacheMangerOperation cacheMangerOperation; + + public boolean fixIconsInNormatives() { + log.info("starting fix"); + String vlName = "VL"; + String elineName = "VL_ELINE"; + String elineFixedName = "VL ELINE"; + Either graphResult = titanGenericDao.getGraph(); + if (graphResult.isRight()) { + log.error("failed to get graph object."); + return false; + } + + boolean operationFailed = false; + Map vlVerticeProperties = null; + Map elineVerticeProperties = null; + + try { + TitanGraph titanGraph = graphResult.left().value(); + log.info("look up vl :{}", vlName); + + Iterable vertices = titanGraph.query() + .has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()) + .has(GraphPropertiesDictionary.NAME.getProperty(), vlName) + .has(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true).vertices(); + + if (vertices == null) { + log.error("failed to get vernice for resource name {}", vlName); + operationFailed = true; + return false; + } + + Iterator iterator = vertices.iterator(); + List vertexList = new ArrayList<>(); + + if (iterator == null) { + log.error("failed to get iterator over vertices object returned for resource id {}", vlName); + operationFailed = true; + return false; + } + + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertexList.add(vertex); + } + + if (!(vertexList.size() == 1)) { + log.error("failed to get 1 vertex for resource {} with highest true. instead got {}", vlName, + vertexList.size()); + operationFailed = true; + return false; + } + + TitanVertex vlVertex = vertexList.get(0); + + log.info("look up eline:{}", elineName); + + boolean vl_eline_found = true; + + vertices = titanGraph.query() + .has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()) + .has(GraphPropertiesDictionary.NAME.getProperty(), elineName) + .has(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true).vertices(); + + if (vertices == null) { + log.error("failed to get vertices object returned for resource {}", elineName); + operationFailed = true; + + vl_eline_found = false; + } + + if (vl_eline_found) { + iterator = vertices.iterator(); + vertexList = new ArrayList<>(); + if (iterator == null) { + log.error("failed to get iterator over vertices object returned for resource id {}", elineName); + operationFailed = true; + + vl_eline_found = false; + } + + if (vl_eline_found) { + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertexList.add(vertex); + } + + if (!(vertexList.size() == 1)) { + log.error("failed to get 1 vertex for resource {} with highest true. instead got {}", + elineName, vertexList.size()); + operationFailed = true; + + vl_eline_found = false; + } + } + } + + if (!vl_eline_found) { + log.info("look up eline:{}", elineFixedName); + vl_eline_found = true; + operationFailed = false; + + vertices = titanGraph.query() + .has(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Resource.getName()) + .has(GraphPropertiesDictionary.NAME.getProperty(), elineFixedName) + .has(GraphPropertiesDictionary.IS_HIGHEST_VERSION.getProperty(), true).vertices(); + + if (vertices == null) { + log.error("failed to get vertices object returned for resource {}", elineFixedName); + operationFailed = true; + + vl_eline_found = false; + } + + if (vl_eline_found) { + iterator = vertices.iterator(); + vertexList = new ArrayList<>(); + if (iterator == null) { + log.error("failed to get iterator over vertices object returned for resource id {}", + elineFixedName); + operationFailed = true; + + vl_eline_found = false; + } + + if (vl_eline_found) { + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertexList.add(vertex); + } + + if (!(vertexList.size() == 1)) { + log.error("failed to get 1 vertex for resource {} with highest true. instead got {}", + elineFixedName, vertexList.size()); + operationFailed = true; + + vl_eline_found = false; + } + } + } + } + + if (!vl_eline_found) { + return false; + } else { + TitanVertex elineVertex = vertexList.get(0); + + vlVerticeProperties = titanGenericDao.getProperties(vlVertex); + + log.info("VL Vertice Properties {}", vlVerticeProperties); + if ("network".equals(vlVerticeProperties.get(GraphPropertiesDictionary.ICON.getProperty()))) { + log.info("nothing to update in vl"); + } else { + log.info("updating property icon of vl"); + vlVertex.property(GraphPropertiesDictionary.ICON.getProperty(), "network"); + } + + elineVerticeProperties = titanGenericDao.getProperties(elineVertex); + + log.info("eline vertice Properties {}", elineVerticeProperties); + if ("network".equals(elineVerticeProperties.get(GraphPropertiesDictionary.ICON.getProperty()))) { + log.info("nothing to update in eline"); + } else { + log.info("updating property icon of eline"); + elineVertex.property(GraphPropertiesDictionary.ICON.getProperty(), "network"); + } + + if ("VL ELINE".equals(elineVerticeProperties.get(GraphPropertiesDictionary.NAME.getProperty()))) { + log.info("nothing to update in eline"); + } else { + log.info("updating property name and tag of eline"); + elineVertex.property(GraphPropertiesDictionary.NAME.getProperty(), elineFixedName); + List tags = new ArrayList<>(); + tags.add("VL ELINE"); + elineVertex.property(GraphPropertiesDictionary.TAGS.getProperty(), new Gson().toJson(tags)); + } + + log.info("print current properties state"); + + vlVerticeProperties = titanGenericDao.getProperties(vlVertex); + + log.info("vertice vl Properties {}", vlVerticeProperties); + elineVerticeProperties = titanGenericDao.getProperties(elineVertex); + + log.info("vertice eline Properties {}", elineVerticeProperties); + } + + try { + Thread.sleep(30 * 1000); + } catch (InterruptedException e) { + log.error("exception", e); + } + return true; + } finally { + if (operationFailed) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + long time = System.currentTimeMillis(); + if (vlVerticeProperties != null) { + cacheMangerOperation.updateComponentInCache( + (String) vlVerticeProperties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty()), time, + NodeTypeEnum.Resource); + } + if (elineVerticeProperties != null) { + cacheMangerOperation.updateComponentInCache( + (String) elineVerticeProperties.get(GraphPropertiesDictionary.UNIQUE_ID.getProperty()), + time, NodeTypeEnum.Resource); + } + } + } + } + + /** + * in 1610 we encounter an issue that if a capability property overrides a + * property of a derived capability then it was created with out a property + * type when it was first imported as part of the capability types. this + * will add property type to the properties missing it. + */ + public boolean fixCapabiltyPropertyTypes() { + + String propertyIdSecure = "tosca.capabilities.Endpoint.Admin.secure"; + String propertyIdNetworkName = "tosca.capabilities.Endpoint.Public.network_name"; + Either graphResult = titanGenericDao.getGraph(); + + if (graphResult.isRight()) { + log.error("failed to get graph object."); + return false; + } + + boolean operationFailed = false; + try { + TitanGraph titanGraph = graphResult.left().value(); + log.info("look up propertyIdSecure:{}", propertyIdSecure); + Iterable vertices = titanGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyIdSecure).vertices(); + if (vertices == null) { + log.error("failed to get vertices object returned for resource id {}", propertyIdSecure); + operationFailed = true; + return false; + } + Iterator iterator = vertices.iterator(); + List vertexList = new ArrayList<>(); + + if (iterator == null) { + log.error("failed to get iterator over vertices object returned for resource id " + propertyIdSecure); + operationFailed = true; + return false; + } + + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertexList.add(vertex); + } + + if (!(vertexList.size() == 1)) { + log.error("failed to get 1 vertex for resource id {} instead got {}", propertyIdSecure, + vertexList.size()); + operationFailed = true; + return false; + } + + TitanVertex propertyVerticeSecure = vertexList.get(0); + + log.info("look up propertyIdNetworkName:{}", propertyIdNetworkName); + vertices = titanGraph.query() + .has(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Property), propertyIdNetworkName).vertices(); + if (vertices == null) { + log.error("failed to get vertices object returned for resource id {}", propertyIdNetworkName); + operationFailed = true; + return false; + } + + iterator = vertices.iterator(); + vertexList = new ArrayList<>(); + + if (iterator == null) { + log.error("failed to get iterator over vertices object returned for resource id {}", + propertyIdNetworkName); + operationFailed = true; + return false; + } + + while (iterator.hasNext()) { + TitanVertex vertex = iterator.next(); + vertexList.add(vertex); + } + + if (!(vertexList.size() == 1)) { + log.error("failed to get 1 vertex for resource id {} instead got {}", propertyIdNetworkName, + vertexList.size()); + operationFailed = true; + return false; + } + + TitanVertex propertyVerticeNetworkName = vertexList.get(0); + + Map verticeNetworkNameProperties = titanGenericDao + .getProperties(propertyVerticeNetworkName); + + log.info("vertice NetworkName Properties {}", verticeNetworkNameProperties); + Object type = verticeNetworkNameProperties.get(GraphPropertiesDictionary.TYPE.getProperty()); + if (type == null || "".equals(type)) { + log.info("updating property Vertice Network Name"); + propertyVerticeNetworkName.property(GraphPropertiesDictionary.TYPE.getProperty(), "string"); + } + + Map verticeSecureProperties = titanGenericDao.getProperties(propertyVerticeSecure); + + log.info("vertice Secure Properties {}", verticeSecureProperties); + + type = verticeSecureProperties.get(GraphPropertiesDictionary.TYPE.getProperty()); + + if (type == null || "".equals(type)) { + log.info("updating property Vertice Secure"); + propertyVerticeSecure.property(GraphPropertiesDictionary.TYPE.getProperty(), "boolean"); + } + + log.info("print current properties state"); + + verticeNetworkNameProperties = titanGenericDao.getProperties(propertyVerticeNetworkName); + + log.info("vertice NetworkName Properties {}", verticeNetworkNameProperties); + + verticeSecureProperties = titanGenericDao.getProperties(propertyVerticeSecure); + + log.info("vertice Secure Properties {}", verticeSecureProperties); + + return true; + } finally { + if (operationFailed) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/ToscaArtifactsAlignment.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/ToscaArtifactsAlignment.java new file mode 100644 index 0000000000..347a5705b7 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/impl/migration/v1610/ToscaArtifactsAlignment.java @@ -0,0 +1,461 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.impl.migration.v1610; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.function.Supplier; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge; +import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.AbstractOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.ServiceMetadataData; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.StreamUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +/** + * This Class holds the logic to add Tosca Artifacts placeholder and payload.
+ * This addition is done for old version of Services and Resources (pre 1610) that weren't created with them.
+ * + * @author mshitrit
+ * + * + */ +public class ToscaArtifactsAlignment extends AbstractOperation { + @Autowired + private IArtifactOperation artifactOperation; + + @Autowired + private ServiceBusinessLogic serviceBusinessLogic; + + private static Logger log = LoggerFactory.getLogger(ToscaArtifactsAlignment.class.getName()); + + private static final String ERROR_PREFIX = "Tosca Artifact Alignment Error: "; + + // API that Fetches Resource + private final Function resourceFetcher = componentMD -> getComponent(componentMD, ComponentTypeEnum.RESOURCE); + // API that Fetches Service + private final Function serviceFetcher = componentMD -> getComponent(componentMD, ComponentTypeEnum.SERVICE); + // Class Getters + private final Supplier> resourceClassGetter = () -> ResourceMetadataData.class; + private final Supplier> serviceClassGetter = () -> ServiceMetadataData.class; + + /** + * This method holds the logic to add Tosca Artifacts placeholder and payload.
+ * + * @return true if succeed otherwise returns false + */ + public boolean alignToscaArtifacts() { + Wrapper errorWrapper = new Wrapper<>(); + List allResources = new ArrayList<>(); + List resourcesWithoutToscaPlaceHolder = new ArrayList<>(); + List allServices = new ArrayList<>(); + List servicesWithoutToscaPlaceHolder = new ArrayList<>(); + log.debug("alignToscaArtifacts Start"); + try { + + if (errorWrapper.isEmpty()) { + log.info("Fetching all resources"); + fillAllComponetOfSpecificType(allResources, NodeTypeEnum.Resource, resourceClassGetter, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Filter Resources Without Tosca Artifacts + log.info("filtering resources to add tosca placeholder"); + Either, TitanOperationStatus> eitherRelevantResources = getComponentsWithMissingToscaArtifacts(resourceClassGetter, NodeTypeEnum.Resource, allResources); + fillListOrWrapper(errorWrapper, resourcesWithoutToscaPlaceHolder, eitherRelevantResources); + } + + if (errorWrapper.isEmpty()) { + // Add PlaceHolders To Resources + log.info("adding tosca placeholders artifacts to resources"); + addToscaArtifactToComponents(resourcesWithoutToscaPlaceHolder, resourceFetcher, NodeTypeEnum.Resource, errorWrapper); + } + if (errorWrapper.isEmpty()) { + // Add payload to Resources + log.info("generating payload to tosca artifacts on resources"); + fillResourcesPayload(allResources, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + log.info("Fetching all services"); + fillAllComponetOfSpecificType(allServices, NodeTypeEnum.Service, serviceClassGetter, errorWrapper); + } + if (errorWrapper.isEmpty()) { + // Filter Services Without Tosca Artifacts + log.info("filtering services to add tosca placeholder"); + Either, TitanOperationStatus> eitherRelevantServices = getComponentsWithMissingToscaArtifacts(serviceClassGetter, NodeTypeEnum.Service, allServices); + fillListOrWrapper(errorWrapper, servicesWithoutToscaPlaceHolder, eitherRelevantServices); + } + + if (errorWrapper.isEmpty()) { + // Add PlaceHolders To Services + log.info("adding tosca placeholders artifacts to services"); + addToscaArtifactToComponents(servicesWithoutToscaPlaceHolder, serviceFetcher, NodeTypeEnum.Service, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + // Filter Services for Payload Add + // Add payload to Services + log.info("generating payload to tosca artifacts on services"); + fillToscaArtifactPayload(allServices, serviceFetcher, errorWrapper); + } + } finally { + titanGenericDao.commit(); + } + return errorWrapper.isEmpty(); + + } + + private void fillResourcesPayload(List allResources, Wrapper errorWrapper) { + if (errorWrapper.isEmpty()) { + // First Only Non VF (CP, VL & VFC) + List basicResources = allResources.stream().filter(e -> isBasicResource((ResourceMetadataDataDefinition) e.getMetadataDataDefinition())).collect(Collectors.toList()); + // Filter resources for Payload Add + // Add payload to resources + fillToscaArtifactPayload(basicResources, resourceFetcher, errorWrapper); + } + if (errorWrapper.isEmpty()) { + // VFs + List complexResource = allResources.stream().filter(e -> ((ResourceMetadataDataDefinition) e.getMetadataDataDefinition()).getResourceType() == ResourceTypeEnum.VF).collect(Collectors.toList()); + // Filter resources for Payload Add + // Add payload to resources + fillToscaArtifactPayload(complexResource, resourceFetcher, errorWrapper); + } + } + + private boolean isBasicResource(ResourceMetadataDataDefinition resourceMetadataDataDefinition) { + final ResourceTypeEnum resourceType = resourceMetadataDataDefinition.getResourceType(); + boolean isBasicResource = resourceType == ResourceTypeEnum.CP || resourceType == ResourceTypeEnum.VL || resourceType == ResourceTypeEnum.VFC; + return isBasicResource; + } + + private void fillAllComponetOfSpecificType(List components, NodeTypeEnum nodeType, Supplier> classGetter, Wrapper errorWrapper) { + + Map props = new HashMap(); + props.put(GraphPropertiesDictionary.IS_DELETED.getProperty(), true); + Either, TitanOperationStatus> eitherComponentMD = titanGenericDao.getByCriteria(nodeType, null, props, classGetter.get()); + if (eitherComponentMD.isLeft()) { + components.addAll(eitherComponentMD.left().value()); + } else { + final TitanOperationStatus errorType = eitherComponentMD.right().value(); + if (errorType != TitanOperationStatus.NOT_FOUND) { + log.error("{} When fetching all components of type:{} a titan error occured:{}", ERROR_PREFIX, nodeType.getName(), errorType.name()); + errorWrapper.setInnerElement(errorType); + } + } + + } + + private void addToscaArtifactToComponents(List relevantResources, Function componentConvertor, NodeTypeEnum nodeType, + Wrapper errorWrapper) { + + // This Stream contains all create tosca placeholder results + Stream addToscaToComponentsResultsStream = relevantResources.stream().map(e -> addToscaArtifacts(e, nodeType, componentConvertor)); + // Execute the stream, and collect error + Optional optionalError = addToscaToComponentsResultsStream.filter(e -> e != StorageOperationStatus.OK).findFirst(); + + // Handle error + if (optionalError.isPresent()) { + errorWrapper.setInnerElement(TitanOperationStatus.NOT_CREATED); + } + } + + private R getComponent(ComponentMetadataData md, ComponentTypeEnum componentTypeEnum) { + R result = null; + Either eitherComponent = serviceBusinessLogic.getComponent(md.getMetadataDataDefinition().getUniqueId(), componentTypeEnum); + if (eitherComponent.isRight()) { + log.error("{} When fetching component {} of type:{} with uniqueId:{}", ERROR_PREFIX, md.getMetadataDataDefinition().getName(), componentTypeEnum.getValue(), md.getMetadataDataDefinition().getUniqueId()); + } else { + result = eitherComponent.left().value(); + } + return result; + } + + private Either, ResponseFormat> populateToscaArtifactsWithLog(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) { + Either, ResponseFormat> ret; + try { + ret = serviceBusinessLogic.populateToscaArtifacts(component, user, isInCertificationRequest, inTransaction, shouldLock); + if (ret.isLeft()) { + log.debug("Added payload to tosca artifacts of component {} of type:{} with uniqueId:{}", component.getName(), component.getComponentType().getValue(), component.getUniqueId()); + } + return ret; + } catch (Exception e) { + log.error("{} Exception Occured When filling tosca artifact payload for component {} of type:{} with uniqueId:{}", ERROR_PREFIX, component.getName(), component.getComponentType().name(), component.getUniqueId(), e); + throw e; + } + } + + private void fillToscaArtifactPayload(List relevantComponents, Function componentCreator, Wrapper errorWrapper) { + + final User dummyUser = buildDummyUser(); + // Stream for all fill payload results + Stream, ResponseFormat>>> + // Filter elements that needs generation of tosca payload + fillToscaPayloadResultsStream = relevantComponents.stream().filter(e -> isGenerateToscaPayload(e)) + // Converts ComponentMetadataData to Component + .map(e -> componentCreator.apply(e)) + // For each component generate payload for tosca + // artifacts + .map(component -> { + return new ImmutablePair, ResponseFormat>>(component, populateToscaArtifactsWithLog(component, dummyUser, true, true, false)); + }); + + try { + // execute and the stream + Optional optionalError = fillToscaPayloadResultsStream. + // filter in error + filter(e -> e.getRight().isRight()) + // convert the result to error and execute the stream + .map(e -> e.getLeft()).findFirst(); + + // Check if error occurred + if (optionalError.isPresent()) { + Component component = optionalError.get(); + log.error("{} When filling tosca artifact payload for component {} of type:{} with uniqueId:{}", ERROR_PREFIX, component.getName(), component.getComponentType().name(), component.getUniqueId()); + + errorWrapper.setInnerElement(TitanOperationStatus.GENERAL_ERROR); + } + } catch (Exception e) { + log.error("{} When filling tosca artifact payload for components : {}", ERROR_PREFIX, e.getMessage(), e); + errorWrapper.setInnerElement(TitanOperationStatus.GENERAL_ERROR); + } + } + + private StorageOperationStatus addToscaArtifacts(ComponentMetadataData component, NodeTypeEnum nodeType, Function componentCreator) { + + StorageOperationStatus result = StorageOperationStatus.OK; + R componentDefinition = componentCreator.apply(component); + + // Fetch artifacts to be Added + Either, StorageOperationStatus> eitherToscaArtifacts = getToscaArtifactsToAdd(componentDefinition); + if (eitherToscaArtifacts.isRight()) { + result = eitherToscaArtifacts.right().value(); + } else { + List toscaArtifactsToAdd = eitherToscaArtifacts.left().value(); + if (!CollectionUtils.isEmpty(eitherToscaArtifacts.left().value())) { + final Stream>> createdToscaPlaceHolderStream = toscaArtifactsToAdd.stream() + // creates the artifact in the graph + .map(artifactDef -> new ImmutablePair>(artifactDef, + artifactOperation.addArifactToComponent(artifactDef, componentDefinition.getUniqueId(), nodeType, false, true))); + + // Execute the stream, and collect error + Optional> optionalError = createdToscaPlaceHolderStream.filter(e -> e.getRight().isRight()).map(e -> new ImmutablePair<>(e.getLeft(), e.getRight().right().value())) + .findFirst(); + + // In case error occurred + if (optionalError.isPresent()) { + ArtifactDefinition toscaArtifact = optionalError.get().getLeft(); + StorageOperationStatus storageError = optionalError.get().getRight(); + log.error("{} When adding tosca artifact of type {} to component {} of type:{} " + "with uniqueId:{} a storageError occurred:{}", ERROR_PREFIX, toscaArtifact.getArtifactType(), component.getMetadataDataDefinition().getName(), + nodeType.getName(), component.getMetadataDataDefinition().getUniqueId(), storageError.name()); + + result = storageError; + } else { + log.debug("Added tosca artifacts to component {} of type:{} with uniqueId:{}", component.getMetadataDataDefinition().getName(), nodeType.getName(), component.getMetadataDataDefinition().getUniqueId()); + } + + } + } + + return result; + } + + private Either, StorageOperationStatus> getToscaArtifactsToAdd(R componentDefinition) { + + Either, StorageOperationStatus> result; + List toscaArtifactsAlreadyExist = new ArrayList<>(); + if (!MapUtils.isEmpty(componentDefinition.getToscaArtifacts())) { + toscaArtifactsAlreadyExist.addAll(componentDefinition.getToscaArtifacts().values()); + } + + // Set Tosca Artifacts on component + serviceBusinessLogic.setToscaArtifactsPlaceHolders(componentDefinition, buildDummyUser()); + + List toscaArtifactsToAdd = new ArrayList<>(); + if (!MapUtils.isEmpty(componentDefinition.getToscaArtifacts())) { + final Collection allToscaArtifacts = componentDefinition.getToscaArtifacts().values(); + Set artifactTypesExist = toscaArtifactsAlreadyExist.stream().map(e -> e.getArtifactType()).collect(Collectors.toSet()); + toscaArtifactsToAdd = allToscaArtifacts.stream().filter(e -> !artifactTypesExist.contains(e.getArtifactType())).collect(Collectors.toList()); + result = Either.left(toscaArtifactsToAdd); + } else { + log.error("{} failed to add tosca artifacts in bussiness logic to component {} of type:{} with uniqueId:{}", ERROR_PREFIX, componentDefinition.getName(), componentDefinition.getComponentType().getValue(), + componentDefinition.getUniqueId()); + result = Either.right(StorageOperationStatus.ARTIFACT_NOT_FOUND); + } + return result; + } + + private User buildDummyUser() { + User user = new User(); + user.setUserId("migrationTask"); + return user; + } + + private boolean isGenerateToscaPayload(ComponentMetadataData component) { + final String state = component.getMetadataDataDefinition().getState(); + boolean componentLifeCycleStateIsValid = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN.name().equals(state) || LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name().equals(state); + + return !componentLifeCycleStateIsValid; + + } + + private void fillListOrWrapper(Wrapper wrapper, List listToFill, Either, TitanOperationStatus> either) { + if (either.isRight()) { + final TitanOperationStatus errorType = either.right().value(); + if (errorType != TitanOperationStatus.NOT_FOUND) { + wrapper.setInnerElement(errorType); + } + } else { + listToFill.addAll(either.left().value()); + } + } + + private Either, TitanOperationStatus> getComponentsWithMissingToscaArtifacts(Supplier> classGetter, NodeTypeEnum nodeType, List allComponents) { + + Either, TitanOperationStatus> result; + Stream, TitanOperationStatus>>> componentsWithToscaStream = + // Create a Stream of pairs : component and its Tosca Artifacts + allComponents.stream().map(e -> new ImmutablePair<>(e, getToscaArtifatcs(e, nodeType))); + + List, TitanOperationStatus>>> componentsWithToscaArtifacts = + // Collect the stream to list. + // in case getToscaArtifatcs failed, the first failure is + // added to the list + // (the collection stops after first failure) + StreamUtils.takeWhilePlusOneNoEval(componentsWithToscaStream, e -> e.getRight().isLeft()).collect(Collectors.toList()); + + // retrieve the failure optional (it may or may not exist) + Optional isErrorOccured = componentsWithToscaArtifacts.stream() + // convert to the right side of the pair of type Either + .map(e -> e.getRight()) + // Filter in only the errors + .filter(e -> e.isRight()). + // map the error from Either to TitanOperationStatus + map(e -> e.right().value()).findFirst(); + + // In case failure occurred + if (isErrorOccured.isPresent()) { + result = Either.right(isErrorOccured.get()); + // In case NO failure occurred + } else { + List filteredComponents = componentsWithToscaArtifacts.stream() + // Filter in only elements that does NOT have tosca + // artifacts + .filter(e -> isNotContainAllToscaArtifacts(e)) + // Convert back to Components List & collect + .map(e -> e.getLeft()).collect(Collectors.toList()); + + result = Either.left(filteredComponents); + } + + return result; + } + + private boolean isNotContainAllToscaArtifacts(ImmutablePair, TitanOperationStatus>> pair) { + + final List artifactList = pair.getRight().left().value(); + + Set filteredToscaList = artifactList.stream(). + // Convert to ArtifactDataDefinition + map(e -> e.getArtifactDataDefinition()). + // Filter in Only Tosca Artifacts + filter(e -> e.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA). + // Convert To ArtifactTypeEnum + map(e -> ArtifactTypeEnum.findType(e.getArtifactType())). + // Filter Out nulls in case of Type not found + filter(e -> e != null).collect(Collectors.toSet()); + + boolean toscaArifactContained = filteredToscaList.contains(ArtifactTypeEnum.TOSCA_CSAR) && filteredToscaList.contains(ArtifactTypeEnum.TOSCA_TEMPLATE); + return !toscaArifactContained; + } + + private Either, TitanOperationStatus> getToscaArtifatcs(T component, NodeTypeEnum nodeType) { + + Either, TitanOperationStatus> result; + // All The Artifacts of the Component + Either>, TitanOperationStatus> eitherComponentArtifacts = titanGenericDao.getChildrenNodes(UniqueIdBuilder.getKeyByNodeType(nodeType), component.getMetadataDataDefinition().getUniqueId(), + GraphEdgeLabels.ARTIFACT_REF, NodeTypeEnum.ArtifactRef, ArtifactData.class); + + if (eitherComponentArtifacts.isLeft()) { + // Convert Artifact Edge Pair to Artifact + List toscaArtifacts = eitherComponentArtifacts.left().value().stream() + // map ImmutablePair to + // ArtifactData + .map(e -> e.getLeft()) + // Filter in only Tosca Artifacts + .filter(artifact -> artifact.getArtifactDataDefinition().getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA) + // Collect + .collect(Collectors.toList()); + result = Either.left(toscaArtifacts); + } else if (eitherComponentArtifacts.right().value() == TitanOperationStatus.NOT_FOUND) { + result = Either.left(new ArrayList<>()); + } else { + final TitanOperationStatus titanError = eitherComponentArtifacts.right().value(); + log.error("{} When fetching artifacts for component {} of type:{} with uniqueId:{} a titanError occurred:{}", ERROR_PREFIX, component.getMetadataDataDefinition().getName(), nodeType.getName(), + component.getMetadataDataDefinition().getUniqueId(), titanError.name()); + + result = Either.right(titanError); + } + + return result; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/DataSchemaMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/DataSchemaMenu.java new file mode 100644 index 0000000000..e29cd7eb75 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/DataSchemaMenu.java @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.cassandra.schema.SdcSchemaBuilder; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DataSchemaMenu { + + private static Logger log = LoggerFactory.getLogger(DataSchemaMenu.class.getName()); + + public static void main(String[] args) throws Exception { + + String operation = args[0]; + + String appConfigDir = args[1]; + + if (args == null || args.length < 2) { + usageAndExit(); + } + + ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), + appConfigDir); + ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); + + try { + + switch (operation.toLowerCase()) { + case "create-cassandra-structures": + log.debug("Start create cassandra keyspace, tables and indexes"); + if (SdcSchemaBuilder.createSchema()) { + log.debug("create cassandra keyspace, tables and indexes successfull"); + System.exit(0); + } else { + log.debug("create cassandra keyspace, tables and indexes failed"); + System.exit(2); + } + case "create-titan-structures": + log.debug("Start create titan keyspace, tables and indexes"); + if (SdcSchemaBuilder.createSchema()) { + log.debug("create cassandra keyspace, tables and indexes successfull"); + System.exit(0); + } else { + log.debug("create cassandra keyspace, tables and indexes failed"); + System.exit(2); + } + case "clean-cassndra": + log.debug("Start clean keyspace, tables"); + if (SdcSchemaBuilder.deleteSchema()) { + log.debug(" successfull"); + System.exit(0); + } else { + log.debug(" failed"); + System.exit(2); + } + default: + usageAndExit(); + } + } catch (Throwable t) { + t.printStackTrace(); + log.debug("create cassandra keyspace, tables and indexes failed"); + System.exit(3); + } + } + + private static void usageAndExit() { + DataSchemeUsage(); + System.exit(1); + } + + private static void DataSchemeUsage() { + System.out.println("Usage: create-cassandra-structures "); + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/EsToCassandraDataMigrationMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/EsToCassandraDataMigrationMenu.java new file mode 100644 index 0000000000..17008b31a4 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/EsToCassandraDataMigrationMenu.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import org.openecomp.sdc.asdctool.impl.DataMigration; +import org.openecomp.sdc.asdctool.impl.EsToCassandraDataMigrationConfig; +import org.openecomp.sdc.asdctool.impl.migration.v1604.AppConfig; +import org.openecomp.sdc.asdctool.impl.migration.v1604.ServiceMigration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.cassandra.schema.SdcSchemaBuilder; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class EsToCassandraDataMigrationMenu { + + private static Logger log = LoggerFactory.getLogger(MigrationMenu.class.getName()); + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 2) { + usageAndExit(); + } + String operation = args[0]; + + String appConfigDir = args[1]; + System.setProperty("config.home", appConfigDir); + ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), + appConfigDir); + ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); + + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( + EsToCassandraDataMigrationConfig.class); + DataMigration dataMigration = null; + try { + switch (operation.toLowerCase()) { + case "es-to-cassndra-migration": + dataMigration = (DataMigration) context.getBean("DataMigrationBean"); + log.debug("Start migration from ES to C* "); + if (dataMigration.migrateDataESToCassndra(appConfigDir, true, true)) { + log.debug("migration from ES to C* was finished successfull"); + System.exit(0); + } else { + log.debug("migration from ES to C* failed"); + System.exit(2); + } + break; + case "es-to-cassndra-migration-export-only": + dataMigration = (DataMigration) context.getBean("DataMigrationBean"); + log.debug("Start migration export only from ES to C* "); + if (dataMigration.migrateDataESToCassndra(appConfigDir, true, false)) { + log.debug("migration export only from ES to C* was finished successfull"); + System.exit(0); + } else { + log.debug("migration export only from ES to C* failed"); + System.exit(2); + } + break; + case "es-to-cassndra-migration-import-only": + dataMigration = (DataMigration) context.getBean("DataMigrationBean"); + log.debug("Start migration import only from ES to C* "); + if (dataMigration.migrateDataESToCassndra(appConfigDir, false, true)) { + log.debug("migration import only from ES to C* was finished successfull"); + System.exit(0); + } else { + log.debug("migration import only from ES to C* failed"); + System.exit(2); + } + break; + default: + usageAndExit(); + } + } catch (Throwable t) { + t.printStackTrace(); + System.exit(3); + } + } + + private static void usageAndExit() { + MigrationUsage(); + System.exit(1); + } + + private static void MigrationUsage() { + System.out.println( + "Usage: es-to-cassndra-migration/es-to-cassndra-migration-import-only/es-to-cassndra-migration-export-only "); + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/ExportImportMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/ExportImportMenu.java new file mode 100644 index 0000000000..6b6f11c5a6 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/ExportImportMenu.java @@ -0,0 +1,169 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import org.openecomp.sdc.asdctool.impl.GraphMLConverter; +import org.openecomp.sdc.asdctool.impl.GraphMLDataAnalyzer; + +public class ExportImportMenu { + + private static void usageAndExit() { + exportUsage(); + importUsage(); + exportUsersUsage(); + + System.exit(1); + } + + private static void importUsage() { + System.out.println("Usage: import "); + } + + private static void exportUsage() { + System.out.println("Usage: export "); + } + + private static void dataReportUsage() { + System.out.println("Usage: get-data-report-from-graph-ml "); + } + + private static void exportUsersUsage() { + System.out.println("Usage: exportusers "); + } + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 1) { + usageAndExit(); + } + + String operation = args[0]; + GraphMLConverter graphMLConverter = new GraphMLConverter(); + switch (operation.toLowerCase()) { + + case "export": + boolean isValid = verifyParamsLength(args, 3); + if (false == isValid) { + exportUsage(); + System.exit(1); + } + + boolean result = graphMLConverter.exportGraph(args); + if (result == false) { + System.exit(2); + } + + break; + case "import": + isValid = verifyParamsLength(args, 3); + if (false == isValid) { + importUsage(); + System.exit(1); + } + result = graphMLConverter.importGraph(args); + if (result == false) { + System.exit(2); + } + break; + + case "exportusers": + isValid = verifyParamsLength(args, 3); + if (false == isValid) { + importUsage(); + System.exit(1); + } + result = graphMLConverter.exportUsers(args); + if (result == false) { + System.exit(2); + } + break; + + case "findproblem": + isValid = verifyParamsLength(args, 3); + if (false == isValid) { + importUsage(); + System.exit(1); + } + result = graphMLConverter.findErrorInJsonGraph(args); + if (result == false) { + System.exit(2); + } + break; + case "export-as-graph-ml": + isValid = verifyParamsLength(args, 3); + if (false == isValid) { + exportUsage(); + System.exit(1); + } + String mlFile = graphMLConverter.exportGraphMl(args); + if (mlFile == null) { + System.exit(2); + } + break; + case "export-as-graph-ml-with-data-report": + isValid = verifyParamsLength(args, 3); + if (false == isValid) { + exportUsage(); + System.exit(1); + } + mlFile = graphMLConverter.exportGraphMl(args); + if (mlFile == null) { + System.exit(2); + } + String[] dataArgs = new String[] { mlFile }; + mlFile = new GraphMLDataAnalyzer().analyzeGraphMLData(dataArgs); + if (mlFile == null) { + System.exit(2); + } + break; + case "get-data-report-from-graph-ml": + isValid = verifyParamsLength(args, 2); + if (false == isValid) { + dataReportUsage(); + System.exit(1); + } + dataArgs = new String[] { args[1] }; + mlFile = new GraphMLDataAnalyzer().analyzeGraphMLData(dataArgs); + if (mlFile == null) { + System.exit(2); + } + break; + default: + usageAndExit(); + } + + } + + private static boolean verifyParamsLength(String[] args, int i) { + if (args == null) { + if (i > 0) { + return false; + } + return true; + } + + if (args.length >= i) { + return true; + } + return false; + } + +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java new file mode 100644 index 0000000000..d7ed4600dd --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/MigrationMenu.java @@ -0,0 +1,251 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import java.util.Arrays; +import java.util.Optional; + +import org.openecomp.sdc.asdctool.impl.PopulateComponentCache; +import org.openecomp.sdc.asdctool.impl.migration.v1604.AppConfig; +import org.openecomp.sdc.asdctool.impl.migration.v1604.DerivedFromAlignment; +import org.openecomp.sdc.asdctool.impl.migration.v1604.GroupsAlignment; +import org.openecomp.sdc.asdctool.impl.migration.v1604.ServiceMigration; +import org.openecomp.sdc.asdctool.impl.migration.v1604.VfcNamingAlignment; +import org.openecomp.sdc.asdctool.impl.migration.v1607.CsarMigration; +import org.openecomp.sdc.asdctool.impl.migration.v1610.TitanFixUtils; +import org.openecomp.sdc.asdctool.impl.migration.v1610.ToscaArtifactsAlignment; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.impl.FSConfigurationSource; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.annotation.AnnotationConfigApplicationContext; + +public class MigrationMenu { + + private static Logger log = LoggerFactory.getLogger(MigrationMenu.class.getName()); + private static final String SERVICE_MIGARTION_BEAN = "serviceMigrationBean"; + + private static enum MigrationOperationEnum { + MIGRATION_1602_1604("migrate-1602-1604", SERVICE_MIGARTION_BEAN), + ALIGN_DERIVED_FROM_1604("align-derived-from-1604", "derivedFromAlignment"), + MIGRATE_1604_1607("migrate-1604-1607", SERVICE_MIGARTION_BEAN), + ALIGN_VFC_NAMES_1604("align-vfc-names-1604", "vfcNamingAlignmentBean"), + TEST_REMOVE_HEAT_PLACEHOLDERS("testremoveheatplaceholders", SERVICE_MIGARTION_BEAN), + TEST_ADD_GROUP_UUIDS("testaddgroupuuids", SERVICE_MIGARTION_BEAN), + ALIGN_GROUPS("align-groups", "groupsAlignment"), + CLEAN_CSAR("clean-csar", "csarMigration"), + POPULATE_COMPONENT_CACHE("populate-component-cache", "populateComponentCache"), + FIX_PROPERTIES("fix-properties", "titanFixUtils"), + ALIGN_TOSCA_ARTIFACTS("align-tosca-artifacts", "toscaArtifactsAlignment"), + FIX_ICONS("fix-icons", "titanFixUtils"); + + private String value, beanName; + + public static MigrationOperationEnum findByValue(String value) { + Optional optionalFound = Arrays.asList(MigrationOperationEnum.values()).stream().filter(e -> e.getValue().equalsIgnoreCase(value)).findAny(); + return optionalFound.isPresent() ? optionalFound.get() : null; + } + + MigrationOperationEnum(String value, String beanName) { + this.value = value; + this.beanName = beanName; + } + + public String getValue() { + return value; + } + + public String getBeanName() { + return beanName; + } + }; + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 2) { + usageAndExit(); + } + MigrationOperationEnum operationEnum = MigrationOperationEnum.findByValue(args[0]); + String appConfigDir = args[1]; + String dataInputFileDir = null; + if (operationEnum == MigrationOperationEnum.ALIGN_DERIVED_FROM_1604) { + dataInputFileDir = args[2]; + } + AnnotationConfigApplicationContext context = initContext(appConfigDir); + try { + ServiceMigration serviceMigration = (ServiceMigration) context.getBean(SERVICE_MIGARTION_BEAN); + switch (operationEnum) { + case MIGRATION_1602_1604: + log.debug("Start Titan migration from 1602 version to 1604"); + if (serviceMigration.migrate1602to1604(appConfigDir)) { + log.debug("Titan migration from 1602 version to 1604 was finished successfull"); + System.exit(0); + } else { + log.debug("Titan migration from 1602 version to 1604 was failed"); + System.exit(2); + } + case MIGRATE_1604_1607: + log.debug("Start Titan migration from 1604 version to 1607"); + if (serviceMigration.migrate1604to1607(appConfigDir)) { + log.debug("Titan migration from 1604 version to 1607 was finished successfull"); + System.exit(0); + } else { + log.debug("Titan migration from 1604 version to 1607 was failed"); + System.exit(2); + } + break; + case ALIGN_VFC_NAMES_1604: + VfcNamingAlignment vfcNamingAlignment = (VfcNamingAlignment) context.getBean(operationEnum.getBeanName()); + log.debug("Start VFC naming alignment on 1604"); + if (vfcNamingAlignment.alignVfcNames1604(appConfigDir)) { + log.debug("VFC naming alignment on 1604 was finished successfull"); + System.exit(0); + } else { + log.debug("VFC naming alignment on 1604 was failed"); + System.exit(2); + } + break; + case TEST_REMOVE_HEAT_PLACEHOLDERS: + boolean check = serviceMigration.testRemoveHeatPlaceHolders(appConfigDir); + if (check == true) { + System.exit(0); + } else { + System.exit(2); + } + break; + case TEST_ADD_GROUP_UUIDS: + check = serviceMigration.testAddGroupUuids(appConfigDir); + if (check == true) { + System.exit(0); + } else { + System.exit(2); + } + break; + case ALIGN_DERIVED_FROM_1604: + DerivedFromAlignment derivedFromAlignment = (DerivedFromAlignment) context.getBean(operationEnum.getBeanName()); + log.debug("Start derived from alignment on 1604"); + if (derivedFromAlignment.alignDerivedFrom1604(appConfigDir, dataInputFileDir)) { + log.debug("Derived from alignment on 1604 was finished successfull"); + System.exit(0); + } else { + log.debug("Derived from alignment on 1604 was failed"); + System.exit(2); + } + break; + case ALIGN_GROUPS: + GroupsAlignment groupsAlignment = (GroupsAlignment) context.getBean(operationEnum.getBeanName()); + log.debug("Start derived from alignment on 1604"); + if (groupsAlignment.alignGroups(appConfigDir)) { + log.debug("Groups alignment was finished successfull"); + System.exit(0); + } else { + log.debug("Groups alignment was failed"); + System.exit(2); + } + break; + case CLEAN_CSAR: + log.debug("Start remove CSAR resources"); + CsarMigration csarMigration = (CsarMigration) context.getBean(operationEnum.getBeanName()); + // TODO Show to Michael L fixed return value + if (csarMigration.removeCsarResources()) { + log.debug("Remove CSAR resources finished successfully"); + System.exit(0); + } else { + log.debug("Remove CSAR resources failed"); + System.exit(2); + } + break; + case POPULATE_COMPONENT_CACHE: + PopulateComponentCache populateComponentCache = (PopulateComponentCache) context.getBean(operationEnum.getBeanName()); + // TODO Show to Michael L No return value always returns 0 + populateComponentCache.populateCache(); + System.exit(0); + break; + case FIX_PROPERTIES: + log.debug("Start fix capability properties types"); + TitanFixUtils titanFixUtils = (TitanFixUtils) context.getBean(operationEnum.getBeanName()); + // TODO Show to Michael L fixed return value + if (titanFixUtils.fixCapabiltyPropertyTypes()) { + log.debug("Fix capability properties types finished successfully"); + System.exit(0); + } else { + log.debug("Fix capability properties types failed"); + System.exit(2); + } + break; + case FIX_ICONS: + log.debug("Start fix icons of vl and eline"); + titanFixUtils = (TitanFixUtils) context.getBean(operationEnum.getBeanName()); + // TODO Show to Michael L fixed return value + if (titanFixUtils.fixIconsInNormatives()) { + log.debug("Fix icons of vl and eline finished successfully"); + System.exit(0); + } else { + log.debug("Fix icons of vl and eline failed"); + System.exit(2); + } + break; + case ALIGN_TOSCA_ARTIFACTS: + log.debug("Start align tosca artifacts"); + ToscaArtifactsAlignment toscaArtifactsAlignment = (ToscaArtifactsAlignment) context.getBean(operationEnum.getBeanName()); + boolean isSuccessful = toscaArtifactsAlignment.alignToscaArtifacts(); + if (isSuccessful) { + log.debug("Tosca Artifacts alignment was finished successfull"); + System.exit(0); + } else { + log.debug("Tosca Artifacts alignment has failed"); + System.exit(2); + } + break; + default: + usageAndExit(); + } + } catch (Throwable t) { + t.printStackTrace(); + System.exit(3); + } finally { + context.close(); + } + } + + private static AnnotationConfigApplicationContext initContext(String appConfigDir) { + ConfigurationSource configurationSource = new FSConfigurationSource(ExternalConfiguration.getChangeListener(), appConfigDir); + ConfigurationManager configurationManager = new ConfigurationManager(configurationSource); + AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); + return context; + } + + private static void usageAndExit() { + MigrationUsage(); + System.exit(1); + } + + private static void MigrationUsage() { + System.out.println("Usage: migrate-1602-1604 "); + System.out.println("Usage: migrate-1604-1607 "); + System.out.println("Usage: align-vfc-names-1604 "); + System.out.println("Usage: align-derived-from-1604 "); + System.out.println("Usage: align-groups "); + System.out.println("Usage: fix-properties "); + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/RemoveUtils.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/RemoveUtils.java new file mode 100644 index 0000000000..ddece759c0 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/RemoveUtils.java @@ -0,0 +1,78 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import org.openecomp.sdc.asdctool.impl.ProductLogic; + +/** + * Created by mlando on 2/23/2016. + */ +public class RemoveUtils { + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 1) { + removeUsage(); + } + + String operation = args[0]; + + switch (operation.toLowerCase()) { + + case "remove-products": + + boolean isValid = verifyParamsLength(args, 5); + if (false == isValid) { + removeUsage(); + System.exit(1); + } + + ProductLogic productLogic = new ProductLogic(); + boolean result = productLogic.deleteAllProducts(args[1], args[2], args[3], args[4]); + + if (result == false) { + System.exit(2); + } + break; + default: + removeUsage(); + } + + } + + private static void removeUsage() { + System.out.println("Usage: remove-products "); + } + + private static boolean verifyParamsLength(String[] args, int i) { + if (args == null) { + if (i > 0) { + return false; + } + return true; + } + + if (args.length >= i) { + return true; + } + return false; + } +} diff --git a/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/UpdateIsVnfMenu.java b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/UpdateIsVnfMenu.java new file mode 100644 index 0000000000..e620510916 --- /dev/null +++ b/asdctool/src/main/java/org/openecomp/sdc/asdctool/main/UpdateIsVnfMenu.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.asdctool.main; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.asdctool.impl.UpdatePropertyOnVertex; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UpdateIsVnfMenu { + + private static Logger log = LoggerFactory.getLogger(UpdateIsVnfMenu.class.getName()); + + private static void usageAndExit() { + updateIsVnfTrueUsage(); + System.exit(1); + } + + private static void updateIsVnfTrueUsage() { + System.out.println( + "Usage: updateIsVnfTrue "); + } + + public static void main(String[] args) throws Exception { + + if (args == null || args.length < 1) { + usageAndExit(); + } + + UpdatePropertyOnVertex updatePropertyOnVertex = new UpdatePropertyOnVertex(); + String operation = args[0]; + + switch (operation.toLowerCase()) { + + case "updateisvnftrue": + boolean isValid = verifyParamsLength(args, 3); + if (false == isValid) { + updateIsVnfTrueUsage(); + System.exit(1); + } + + Map keyValueToSet = new HashMap<>(); + keyValueToSet.put(GraphPropertiesDictionary.IS_VNF.getProperty(), true); + + List> orCriteria = buildCriteriaFromSystemServiceNames(args[2]); + Integer updatePropertyOnServiceAtLeastCertified = updatePropertyOnVertex + .updatePropertyOnServiceAtLeastCertified(args[1], keyValueToSet, orCriteria); + + if (updatePropertyOnServiceAtLeastCertified == null) { + System.exit(2); + } else if (updatePropertyOnServiceAtLeastCertified.intValue() >= 0) { + log.debug("Number of updated services is {}", updatePropertyOnServiceAtLeastCertified.intValue()); + System.exit(0); + } + + break; + default: + usageAndExit(); + } + + } + + private static List> buildCriteriaFromSystemServiceNames(String systemList) { + + List> systemNames = new ArrayList<>(); + + String[] split = systemList.split(","); + if (split != null) { + for (String systemName : split) { + systemName = systemName.trim(); + + Map map = new HashMap(); + map.put(GraphPropertiesDictionary.SYSTEM_NAME.getProperty(), systemName); + map.put(GraphPropertiesDictionary.LABEL.getProperty(), NodeTypeEnum.Service.getName()); + + systemNames.add(map); + } + } + + return systemNames; + } + + private static boolean verifyParamsLength(String[] args, int i) { + if (args == null) { + if (i > 0) { + return false; + } + return true; + } + + if (args.length >= i) { + return true; + } + return false; + } + +} diff --git a/asdctool/src/main/resources/application-context.xml b/asdctool/src/main/resources/application-context.xml new file mode 100644 index 0000000000..cf5ae5a767 --- /dev/null +++ b/asdctool/src/main/resources/application-context.xml @@ -0,0 +1,11 @@ + + + + + + + diff --git a/asdctool/src/main/resources/config/categoryMigration.yaml b/asdctool/src/main/resources/config/categoryMigration.yaml new file mode 100644 index 0000000000..b62dd0a649 --- /dev/null +++ b/asdctool/src/main/resources/config/categoryMigration.yaml @@ -0,0 +1,113 @@ +services: + Mobility: + name: "Mobility" + oldName: "Mobility" + icons: ['mobility'] + Network_L1_3: + name: "Network L1-3" + oldName: "Network L1-3" + icons: ['network_l_1-3'] + Network_L4: + name: "Network L4+" + oldName: "Network L4" + icons: ['network_l_4'] + VoIP_Call_Control: + name: "VoIP Call Control" + oldName: "VoIP Call Control" + icons: ['call_controll'] +resources: + NetworkLayer23: + name: "Network L2-3" + oldName: "Network Layer 2-3" + subcategories: + Router: + name: "Router" + oldName: "Router" + icons: ['router','vRouter'] + Gateway: + name: "Gateway" + oldName: "Gateway" + icons: ['gateway'] + WAN_Connectors: + name: "WAN Connectors" + oldName: "WAN Connectors" + icons: ['network','connector','port'] + LAN_Connectors: + name: "LAN Connectors" + oldName: "LAN Connectors" + icons: ['network','connector','port'] + Infrastructure: + name: "Infrastructure" + icons: ['ucpe'] + NetworkLayer4: + name: "Network L4+" + oldName: "Network Layer 4+" + subcategories: + Common_Network_Resources: + name: "Common Network Resources" + oldName: "Common Network Resources" + icons: ['network'] + ApplicationLayer4: + name: "Application L4+" + oldName: "Application Layer 4+" + subcategories: + Border_Element: + name: "Border Element" + oldName: "Border Elements" + icons: ['borderElement'] + Application_Server: + name: "Application Server" + oldName: "Application Servers" + icons: ['applicationServer'] + Web_Server: + name: "Web Server" + oldName: "Web Server" + icons: ['applicationServer'] + Call_Control: + name: "Call Control" + oldName: "Call Control" + icons: ['call_controll'] + Media_Servers: + name: "Media Servers" + oldName: "Media Servers" + icons: ['applicationServer'] + Load_Balancer: + name: "Load Balancer" + oldName: "Load Balancer" + icons: ['loadBalancer'] + Database: + name: "Database" + oldName: "Database" + icons: ['database'] + Firewall: + name: "Firewall" + icons: ['firewall'] + Generic: + name: "Generic" + oldName: "Generic" + subcategories: + Infrastructure: + name: "Infrastructure" + oldName: "Infrastructure" + icons: ['connector'] + Abstract: + name: "Abstract" + oldName: "Abstract" + icons: ['objectStorage', 'compute'] + Network_Elements: + name: "Network Elements" + oldName: "Network Elements" + icons: ['network', 'connector'] + Database: + name: "Database" + oldName: "Database" + icons: ['database'] + NetworkConnectivity: + name: "Network Connectivity" + subcategories: + ConnectionPoints: + name: "Connection Points" + icons: ['cp'] + VirtualLinks: + name: "Virtual Links" + icons: ['vl'] \ No newline at end of file diff --git a/asdctool/src/main/resources/config/configuration.yaml b/asdctool/src/main/resources/config/configuration.yaml new file mode 100644 index 0000000000..294424fa9a --- /dev/null +++ b/asdctool/src/main/resources/config/configuration.yaml @@ -0,0 +1,376 @@ +identificationHeaderFields: + - HTTP_IV_USER + - HTTP_CSP_FIRSTNAME + - HTTP_CSP_LASTNAME + - HTTP_IV_REMOTE_ADDRESS + - HTTP_CSP_WSTYPE + + + +# catalog backend hostname +beFqdn: sdccatalog + +# catalog backend http port +beHttpPort: 8080 + +# catalog backend http context +beContext: /sdc/rest/config/get + +# catalog backend protocol +beProtocol: http + +# catalog backend ssl port +beSslPort: 8443 + +version: 1.0 +released: 2012-11-30 + +titanCfgFile: src/main/resources/config/titan.properties +titanInMemoryGraph: false +titanLockTimeout: 30 +titanReconnectIntervalInSeconds: 3 +titanHealthCheckReadTimeout: 1 +esReconnectIntervalInSeconds: 3 +uebHealthCheckReconnectIntervalInSeconds: 15 +uebHealthCheckReadTimeout: 4 + +# Protocols +protocols: + - http + - https + +# Users +users: + tom: passwd + bob: passwd + +neo4j: + host: neo4jhost + port: 7474 + user: neo4j + password: "12345" + + +#Application-specific settings of ES +elasticSearch: + # Mapping of index prefix to time-based frame. For example, if below is configured: + # + # - indexPrefix: auditingevents + # creationPeriod: minute + # + # then ES object of type which is mapped to "auditingevents-*" template, and created on 2015-12-23 13:24:54, will enter "auditingevents-2015-12-23-13-24" index. + # Another object created on 2015-12-23 13:25:54, will enter "auditingevents-2015-12-23-13-25" index. + # If creationPeriod: month, both of the above will enter "auditingevents-2015-12" index. + # + # PLEASE NOTE: the timestamps are created in UTC/GMT timezone! This is needed so that timestamps will be correctly presented in Kibana. + # + # Legal values for creationPeriod - year, month, day, hour, minute, none (meaning no time-based behaviour). + # + # If no creationPeriod is configured for indexPrefix, default behavour is creationPeriod: month. + + indicesTimeFrequency: + - indexPrefix: auditingevents + creationPeriod: month + - indexPrefix: monitoring_events + creationPeriod: month + +artifactTypes: + - CHEF + - PUPPET + - SHELL + - YANG + - YANG_XML + - HEAT + - BPEL + - DG_XML + - MURANO_PKG + - WORKFLOW + - NETWORK_CALL_FLOW + - TOSCA_TEMPLATE + - TOSCA_CSAR + - AAI_SERVICE_MODEL + - AAI_VF_MODEL + - AAI_VF_MODULE_MODEL + - AAI_VF_INSTANCE_MODEL + - OTHER + +licenseTypes: + - User + - Installation + - CPU + +#Deployment artifacts placeHolder +resourceTypes: &allResourceTypes + - VFC + - CP + - VL + - VF + +# validForResourceTypes usage +# validForResourceTypes: +# - VF +# - VL +deploymentResourceArtifacts: + heat: + displayName: "Base HEAT Template" + type: HEAT + validForResourceTypes: *allResourceTypes + heatVol: + displayName: "Volume HEAT Template" + type: HEAT_VOL + validForResourceTypes: *allResourceTypes + heatNet: + displayName: "Network HEAT Template" + type: HEAT_NET + validForResourceTypes: *allResourceTypes + +deploymentResourceInstanceArtifacts: + heatEnv: + displayName: "HEAT ENV" + type: HEAT_ENV + description: "Auto-generated HEAT Environment deployment artifact" + fileExtension: "env" + +#tosca artifacts placeholders +toscaArtifacts: + assetToscaTemplate: + artifactName: -template.yml + displayName: Tosca Template + type: TOSCA_TEMPLATE + description: TOSCA representation of the asset + assetToscaCsar: + artifactName: -csar.csar + displayName: Tosca Model + type: TOSCA_CSAR + description: TOSCA definition package of the asset + +#Informational artifacts placeHolder +excludeResourceCategory: + - Generic +informationalResourceArtifacts: + features: + displayName: Features + type: OTHER + capacity: + displayName: Capacity + type: OTHER + vendorTestResult: + displayName: Vendor Test Result + type: OTHER + testScripts: + displayName: Test Scripts + type: OTHER + cloudQuestionnaire: + displayName: Cloud Questionnaire (completed) + type: OTHER + HEATTemplateFromVendor: + displayName: HEAT Template from Vendor + type: HEAT + resourceSecurityTemplate: + displayName: Resource Security Template + type: OTHER + +excludeServiceCategory: + +informationalServiceArtifacts: + serviceArtifactPlan: + displayName: Service Artifact Plan + type: OTHER + summaryOfImpactsToECOMPElements: + displayName: Summary of impacts to ECOMP elements,OSSs, BSSs + type: OTHER + controlLoopFunctions: + displayName: Control Loop Functions + type: OTHER + dimensioningInfo: + displayName: Dimensioning Info + type: OTHER + affinityRules: + displayName: Affinity Rules + type: OTHER + operationalPolicies: + displayName: Operational Policies + type: OTHER + serviceSpecificPolicies: + displayName: Service-specific Policies + type: OTHER + engineeringRules: + displayName: Engineering Rules (ERD) + type: OTHER + distributionInstructions: + displayName: Distribution Instructions + type: OTHER + certificationTestResults: + displayName: TD Certification Test Results + type: OTHER + deploymentVotingRecord: + displayName: Deployment Voting Record + type: OTHER + serviceQuestionnaire: + displayName: Service Questionnaire + type: OTHER + serviceSecurityTemplate: + displayName: Service Security Template + type: OTHER + +serviceApiArtifacts: + configuration: + displayName: Configuration + type: OTHER + instantiation: + displayName: Instantiation + type: OTHER + monitoring: + displayName: Monitoring + type: OTHER + reporting: + displayName: Reporting + type: OTHER + logging: + displayName: Logging + type: OTHER + testing: + displayName: Testing + type: OTHER + + +additionalInformationMaxNumberOfKeys: 50 + +systemMonitoring: + enabled: false + isProxy: false + probeIntervalInSeconds: 15 + +defaultHeatArtifactTimeoutMinutes: 60 + +serviceDeploymentArtifacts: + YANG_XML: + acceptedTypes: + - xml + AAI_SERVICE_MODEL: + acceptedTypes: + - xml + AAI_VF_MODULE_MODEL: + acceptedTypes: + - xml + AAI_VF_INSTANCE_MODEL: + acceptedTypes: + - xml + OTHER: + acceptedTypes: + +resourceDeploymentArtifacts: + HEAT: + acceptedTypes: + - yaml + - yml + HEAT_VOL: + acceptedTypes: + - yaml + - yml + HEAT_NET: + acceptedTypes: + - yaml + - yml + YANG_XML: + acceptedTypes: + - xml + AAI_VF_MODEL: + acceptedTypes: + - xml + validForResourceTypes: + - VF + AAI_VF_MODULE_MODEL: + acceptedTypes: + - xml + validForResourceTypes: + - VF + OTHER: + acceptedTypes: + +resourceInstanceDeploymentArtifacts: + HEAT_ENV: + acceptedTypes: + - env + +resourceInformationalDeployedArtifacts: + + +requirementsToFulfillBeforeCert: + CP: + - tosca.capabilities.network.Bindable + +capabilitiesToConsumeBeforeCert: + +unLoggedUrls: + - /sdc2/rest/healthCheck + +cleanComponentsConfiguration: + cleanIntervalInMinutes: 1440 + componentsToClean: + - Resource + - Service + +artifactsIndex: resources +cassandraConfig: + cassandraHosts: ['localhost'] + localDataCenter: + reconnectTimeout : 30000 + authenticate: false + username: koko + password: bobo + ssl: false + truststorePath : /path/path + truststorePassword : 123123 + keySpaces: + - { name: sdcaudit, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + - { name: sdcartifact, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + - { name: sdccomponent, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + + +switchoverDetector: + gBeFqdn: + gFeFqdn: + beVip: 1.2.3.4 + feVip: 1.2.3.4 + beResolveAttempts: 3 + feResolveAttempts: 3 + enabled: false + interval: 60 + changePriorityUser: ecompasdc + changePriorityPassword: ecompasdc123 + publishNetworkUrl: + publishNetworkBody: '{"note":"publish network"}' + groups: + beSet: { changePriorityUrl: "http://localhost/", + changePriorityBody: '{"name":"AIO-BE.ecomp.idns.cip","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-BE.ecomp.idns.cip","no_ad_redirection":false,"v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_be","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_be"],"failover_policy":["FAILALL"]},"comment":"AIO BE G-fqdn","intended_app_proto":"DNS"}'} + feSet: { changePriorityUrl: "http://localhost/", + changePriorityBody: '{"comment":"AIO G-fqdn","name":"AIO-FE.ecomp.idns.cip","v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_fe","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_fe"],"failover_policy":["FAILALL"]},"no_ad_redirection":false,"intended_app_proto":"DNS","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-FE.ecomp.idns.cip.att.com"}'} + + +heatEnvArtifactHeader: + "" +heatEnvArtifactFooter: + "" + +applicationL1Cache: + datatypes: + enabled: false + firstRunDelay: 10 + pollIntervalInSec: 60 + +applicationL2Cache: + enabled: false + catalogL1Cache: + enabled: false + resourcesSizeInCache: 300 + servicesSizeInCache: 200 + productsSizeInCache: 100 + queue: + syncIntervalInSecondes: 60 + waitOnShutDownInMinutes: 30 + numberOfCacheWorkers: 4 + +toscaValidators: + stringMaxLength: 1024 +disableAudit: true \ No newline at end of file diff --git a/asdctool/src/main/resources/config/elasticsearch.yml b/asdctool/src/main/resources/config/elasticsearch.yml new file mode 100644 index 0000000000..e1808ad7cc --- /dev/null +++ b/asdctool/src/main/resources/config/elasticsearch.yml @@ -0,0 +1,392 @@ + +elasticSearch.local: true +elasticSearch.transportclient: false +cluster.name: elasticsearch_1_5_2222 + +discovery.zen.ping.multicast.enabled: false +discovery.zen.ping.unicast.enabled: true +discovery.zen.ping.unicast.hosts: 1.2.3.4 +transport.client.initial_nodes: + - 1.2.3.4:9300 + + +#plugin.types: "DeleteByQueryPlugin" + +##################### Elasticsearch Configuration Example ##################### + +# This file contains an overview of various configuration settings, +# targeted at operations staff. Application developers should +# consult the guide at . +# +# The installation procedure is covered at +# . +# +# Elasticsearch comes with reasonable defaults for most settings, +# so you can try it out without bothering with configuration. +# +# Most of the time, these defaults are just fine for running a production +# cluster. If you're fine-tuning your cluster, or wondering about the +# effect of certain configuration option, please _do ask_ on the +# mailing list or IRC channel [http://elasticsearch.org/community]. + +# Any element in the configuration can be replaced with environment variables +# by placing them in ${...} notation. For example: +# +# node.rack: ${RACK_ENV_VAR} + +# For information on supported formats and syntax for the config file, see +# + + +################################### Cluster ################################### + +# Cluster name identifies your cluster for auto-discovery. If you're running +# multiple clusters on the same network, make sure you're using unique names. +# +# cluster.name: elasticsearch + + +#################################### Node ##################################### + +# Node names are generated dynamically on startup, so you're relieved +# from configuring them manually. You can tie this node to a specific name: +# +# node.name: "Franz Kafka" + +# Every node can be configured to allow or deny being eligible as the master, +# and to allow or deny to store the data. +# +# Allow this node to be eligible as a master node (enabled by default): +# +# node.master: true +# +# Allow this node to store data (enabled by default): +# +# node.data: true + +# You can exploit these settings to design advanced cluster topologies. +# +# 1. You want this node to never become a master node, only to hold data. +# This will be the "workhorse" of your cluster. +# +# node.master: false +# node.data: true +# +# 2. You want this node to only serve as a master: to not store any data and +# to have free resources. This will be the "coordinator" of your cluster. +# +# node.master: true +# node.data: false +# +# 3. You want this node to be neither master nor data node, but +# to act as a "search load balancer" (fetching data from nodes, +# aggregating results, etc.) +# +# node.master: false +# node.data: false + +# Use the Cluster Health API [http://localhost:9200/_cluster/health], the +# Node Info API [http://localhost:9200/_nodes] or GUI tools +# such as , +# , +# and +# to inspect the cluster state. + +# A node can have generic attributes associated with it, which can later be used +# for customized shard allocation filtering, or allocation awareness. An attribute +# is a simple key value pair, similar to node.key: value, here is an example: +# +# node.rack: rack314 + +# By default, multiple nodes are allowed to start from the same installation location +# to disable it, set the following: +# node.max_local_storage_nodes: 1 + + +#################################### Index #################################### + +# You can set a number of options (such as shard/replica options, mapping +# or analyzer definitions, translog settings, ...) for indices globally, +# in this file. +# +# Note, that it makes more sense to configure index settings specifically for +# a certain index, either when creating it or by using the index templates API. +# +# See and +# +# for more information. + +# Set the number of shards (splits) of an index (5 by default): +# +# index.number_of_shards: 5 + +# Set the number of replicas (additional copies) of an index (1 by default): +# +# index.number_of_replicas: 1 + +# Note, that for development on a local machine, with small indices, it usually +# makes sense to "disable" the distributed features: +# +index.number_of_shards: 1 +index.number_of_replicas: 0 + +# These settings directly affect the performance of index and search operations +# in your cluster. Assuming you have enough machines to hold shards and +# replicas, the rule of thumb is: +# +# 1. Having more *shards* enhances the _indexing_ performance and allows to +# _distribute_ a big index across machines. +# 2. Having more *replicas* enhances the _search_ performance and improves the +# cluster _availability_. +# +# The "number_of_shards" is a one-time setting for an index. +# +# The "number_of_replicas" can be increased or decreased anytime, +# by using the Index Update Settings API. +# +# Elasticsearch takes care about load balancing, relocating, gathering the +# results from nodes, etc. Experiment with different settings to fine-tune +# your setup. + +# Use the Index Status API () to inspect +# the index status. + + +#################################### Paths #################################### +path.home: /src/test/resources +# Path to directory containing configuration (this file and logging.yml): +# +path.conf: /src/test/resources + +# Path to directory where to store index data allocated for this node. +# +path.data: target/esdata +# +# Can optionally include more than one location, causing data to be striped across +# the locations (a la RAID 0) on a file level, favouring locations with most free +# space on creation. For example: +# +# path.data: /path/to/data1,/path/to/data2 + +# Path to temporary files: +# +path.work: /target/eswork + +# Path to log files: +# +path.logs: /target/eslogs + +# Path to where plugins are installed: +# +# path.plugins: /path/to/plugins + + +#################################### Plugin ################################### + +# If a plugin listed here is not installed for current node, the node will not start. +# +# plugin.mandatory: mapper-attachments,lang-groovy + + +################################### Memory #################################### + +# Elasticsearch performs poorly when JVM starts swapping: you should ensure that +# it _never_ swaps. +# +# Set this property to true to lock the memory: +# +# bootstrap.mlockall: true + +# Make sure that the ES_MIN_MEM and ES_MAX_MEM environment variables are set +# to the same value, and that the machine has enough memory to allocate +# for Elasticsearch, leaving enough memory for the operating system itself. +# +# You should also make sure that the Elasticsearch process is allowed to lock +# the memory, eg. by using `ulimit -l unlimited`. + + +############################## Network And HTTP ############################### + +# Elasticsearch, by default, binds itself to the 0.0.0.0 address, and listens +# on port [9200-9300] for HTTP traffic and on port [9300-9400] for node-to-node +# communication. (the range means that if the port is busy, it will automatically +# try the next port). + +# Set the bind address specifically (IPv4 or IPv6): +# +# network.bind_host: 192.168.0.1 + +# Set the address other nodes will use to communicate with this node. If not +# set, it is automatically derived. It must point to an actual IP address. +# +# network.publish_host: 192.168.0.1 + +# Set both 'bind_host' and 'publish_host': +# +# network.host: 192.168.0.1 + +# Set a custom port for the node to node communication (9300 by default): +# +# transport.tcp.port: 9300 + +# Enable compression for all communication between nodes (disabled by default): +# +# transport.tcp.compress: true + +# Set a custom port to listen for HTTP traffic: +# +# http.port: 9200 + +# Set a custom allowed content length: +# +# http.max_content_length: 100mb + +# Disable HTTP completely: +# +# http.enabled: false + + +################################### Gateway ################################### + +# The gateway allows for persisting the cluster state between full cluster +# restarts. Every change to the state (such as adding an index) will be stored +# in the gateway, and when the cluster starts up for the first time, +# it will read its state from the gateway. + +# There are several types of gateway implementations. For more information, see +# . + +# The default gateway type is the "local" gateway (recommended): +# +# gateway.type: local + +# Settings below control how and when to start the initial recovery process on +# a full cluster restart (to reuse as much local data as possible when using shared +# gateway). + +# Allow recovery process after N nodes in a cluster are up: +# +gateway.recover_after_nodes: 1 + +# Set the timeout to initiate the recovery process, once the N nodes +# from previous setting are up (accepts time value): +# +# gateway.recover_after_time: 5m + +# Set how many nodes are expected in this cluster. Once these N nodes +# are up (and recover_after_nodes is met), begin recovery process immediately +# (without waiting for recover_after_time to expire): +# +gateway.expected_nodes: 1 + + +############################# Recovery Throttling ############################# + +# These settings allow to control the process of shards allocation between +# nodes during initial recovery, replica allocation, rebalancing, +# or when adding and removing nodes. + +# Set the number of concurrent recoveries happening on a node: +# +# 1. During the initial recovery +# +# cluster.routing.allocation.node_initial_primaries_recoveries: 4 +# +# 2. During adding/removing nodes, rebalancing, etc +# +# cluster.routing.allocation.node_concurrent_recoveries: 2 + +# Set to throttle throughput when recovering (eg. 100mb, by default 20mb): +# +# indices.recovery.max_bytes_per_sec: 20mb + +# Set to limit the number of open concurrent streams when +# recovering a shard from a peer: +# +# indices.recovery.concurrent_streams: 5 + + +################################## Discovery ################################## + +# Discovery infrastructure ensures nodes can be found within a cluster +# and master node is elected. Multicast discovery is the default. + +# Set to ensure a node sees N other master eligible nodes to be considered +# operational within the cluster. Its recommended to set it to a higher value +# than 1 when running more than 2 nodes in the cluster. +# +# discovery.zen.minimum_master_nodes: 1 + +# Set the time to wait for ping responses from other nodes when discovering. +# Set this option to a higher value on a slow or congested network +# to minimize discovery failures: +# +# discovery.zen.ping.timeout: 3s + +# For more information, see +# + +# Unicast discovery allows to explicitly control which nodes will be used +# to discover the cluster. It can be used when multicast is not present, +# or to restrict the cluster communication-wise. +# +# 1. Disable multicast discovery (enabled by default): +# +# discovery.zen.ping.multicast.enabled: false +# +# 2. Configure an initial list of master nodes in the cluster +# to perform discovery when new nodes (master or data) are started: +# +# discovery.zen.ping.unicast.hosts: ["host1", "host2:port"] + +# EC2 discovery allows to use AWS EC2 API in order to perform discovery. +# +# You have to install the cloud-aws plugin for enabling the EC2 discovery. +# +# For more information, see +# +# +# See +# for a step-by-step tutorial. + +# GCE discovery allows to use Google Compute Engine API in order to perform discovery. +# +# You have to install the cloud-gce plugin for enabling the GCE discovery. +# +# For more information, see . + +# Azure discovery allows to use Azure API in order to perform discovery. +# +# You have to install the cloud-azure plugin for enabling the Azure discovery. +# +# For more information, see . + +################################## Slow Log ################################## + +# Shard level query and fetch threshold logging. + +#index.search.slowlog.threshold.query.warn: 10s +#index.search.slowlog.threshold.query.info: 5s +#index.search.slowlog.threshold.query.debug: 2s +#index.search.slowlog.threshold.query.trace: 500ms + +#index.search.slowlog.threshold.fetch.warn: 1s +#index.search.slowlog.threshold.fetch.info: 800ms +#index.search.slowlog.threshold.fetch.debug: 500ms +#index.search.slowlog.threshold.fetch.trace: 200ms + +#index.indexing.slowlog.threshold.index.warn: 10s +#index.indexing.slowlog.threshold.index.info: 5s +#index.indexing.slowlog.threshold.index.debug: 2s +#index.indexing.slowlog.threshold.index.trace: 500ms + +################################## GC Logging ################################ + +#monitor.jvm.gc.young.warn: 1000ms +#monitor.jvm.gc.young.info: 700ms +#monitor.jvm.gc.young.debug: 400ms + +#monitor.jvm.gc.old.warn: 10s +#monitor.jvm.gc.old.info: 5s +#monitor.jvm.gc.old.debug: 2s + diff --git a/asdctool/src/main/resources/config/error-configuration.yaml b/asdctool/src/main/resources/config/error-configuration.yaml new file mode 100644 index 0000000000..5e5009e54f --- /dev/null +++ b/asdctool/src/main/resources/config/error-configuration.yaml @@ -0,0 +1,1671 @@ +# Errors +errors: + OK: { + code: 200, + message: "OK" + } + CREATED: { + code: 201, + message: "OK" + } + NO_CONTENT: { + code: 204, + message: "No Content" + } +#--------POL4050----------------------------- + NOT_ALLOWED: { + code: 405, + message: "Error: Method not allowed.", + messageId: "POL4050" + } +#--------POL5000----------------------------- + GENERAL_ERROR: { + code: 500, + message: "Error: Internal Server Error. Please try again later.", + messageId: "POL5000" + } +#---------POL5001------------------------------ + MISSING_X_ECOMP_INSTANCE_ID: { + code: 400 , + message: "Error: Missing 'X-ECOMP-InstanceID' HTTP header.", + messageId: "POL5001" + } +#---------POL5002------------------------------ + AUTH_REQUIRED: { + code: 401 , + message: "Error: Authentication is required to use the API.", + messageId: "POL5002" + } +#---------POL5003------------------------------ + AUTH_FAILED: { + code: 403 , + message: "Error: Not authorized to use the API.", + messageId: "POL5003" + } +#---------SVC4000----------------------------- + INVALID_CONTENT: { + code: 400, + message: "Error: Invalid content.", + messageId: "SVC4000" + }#---------SVC4000----------------------------- + INVALID_CONTENT: { + code: 400, + message: "Error: Invalid content.", + messageId: "SVC4000" + } +#---------SVC4002----------------------------- + MISSING_INFORMATION: { + code: 403, + message: "Error: Missing information.", + messageId: "SVC4002" + } +#---------SVC4003------------------------------ +# %1 - Users's USER_ID + USER_NOT_FOUND: { + code: 404, + message: "Error: User '%1' was not found.", + messageId: "SVC4003" + } +#---------SVC4004----------------------------- +# %1 - Users's email address + INVALID_EMAIL_ADDRESS: { + code: 400, + message: "Error: Invalid email address '%1'.", + messageId: "SVC4004" + } +#---------SVC4005------------------------------ +# %1 - role + INVALID_ROLE: { + code: 400, + message: "Error: Invalid role '%1'.", + messageId: "SVC4005" + } +#---------SVC4006------------------------------ +# %1 - Users's USER_ID + USER_ALREADY_EXIST: { + code: 409, + message: "Error: User with '%1' ID already exists.", + messageId: "SVC4006" + } +#---------SVC4007------------------------------ + DELETE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator can only be deleted by another administrator.", + messageId: "SVC4007" + } +#---------SVC4008----------------------------- +# %1 - Users's userId + INVALID_USER_ID: { + code: 400, + message: "Error: Invalid userId '%1'.", + messageId: "SVC4008" + } +#---------SVC4049------------------------------ +# %1 - service/resource + COMPONENT_MISSING_CONTACT: { + code: 400, + message: "Error: Invalid Content. Missing %1 contact id.", + messageId: "SVC4049" + } +#---------SVC4050----------------------------- +# %1 - Service/Resource/Additional parameter +# %2 - service/resource/label name + COMPONENT_NAME_ALREADY_EXIST: { + code: 409, + message: "Error: %1 with name '%2' already exists.", + messageId: "SVC4050" + } +#---------SVC4051------------------------------ +# %1 - resource/service + COMPONENT_MISSING_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Missing %1 category.", + messageId: "SVC4051" + } + +#---------SVC4052------------------------------ + COMPONENT_MISSING_TAGS: { + code: 400, + message: "Error: Invalid Content. At least one tag has to be specified.", + messageId: "SVC4052" + } + +#---------SVC4053------------------------------ +# %1 - service/resource + COMPONENT_MISSING_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. Missing %1 description.", + messageId: "SVC4053" + } +#---------SVC4054------------------------------ +# %1 - resource/service + COMPONENT_INVALID_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Invalid %1 category.", + messageId: "SVC4054" + } +#---------SVC4055------------------------------ + MISSING_VENDOR_NAME: { + code: 400, + message: "Error: Invalid Content. Missing vendor name.", + messageId: "SVC4055" + } +#---------SVC4056------------------------------ + MISSING_VENDOR_RELEASE: { + code: 400, + message: "Error: Invalid Content. Missing vendor release.", + messageId: "SVC4056" + } + +#---------SVC4057------------------------------ + MISSING_DERIVED_FROM_TEMPLATE: { + code: 400, + message: "Error: Invalid Content. Missing derived from template specification.", + messageId: "SVC4057" + } + +#---------SVC4058------------------------------ +# %1 - service/resource + COMPONENT_MISSING_ICON: { + code: 400, + message: "Error: Invalid Content. Missing %1 icon.", + messageId: "SVC4058" + } +#---------SVC4059------------------------------ +# %1 - service/resource + COMPONENT_INVALID_ICON: { + code: 400, + message: "Error: Invalid Content. Invalid %1 icon.", + messageId: "SVC4059" + } +#---------SVC4060------------------------------ + PARENT_RESOURCE_NOT_FOUND: { + code: 400, + message: "Error: Invalid Content. Derived from resource template was not found.", + messageId: "SVC4060" + } +#---------SVC4061------------------------------ + MULTIPLE_PARENT_RESOURCE_FOUND: { + code: 400, + message: "Error: Invalid Content. Multiple derived from resource template is not allowed.", + messageId: "SVC4061" + } + +#---------SVC4062------------------------------ +# %1 - service/resource + MISSING_COMPONENT_NAME: { + code: 400, + message: "Error: Invalid Content. Missing %1 name.", + messageId: "SVC4062" + } +#---------SVC4063------------------------------ + #%1  -  resource/service name + RESOURCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource was not found.", + messageId: "SVC4063" + } + +#---------SVC4064------------------------------ +# %1 - Service/Resource + COMPONENT_INVALID_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. %1 description contains non-english characters.", + messageId: "SVC4064" + } +#---------SVC4065------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name length + COMPONENT_DESCRIPTION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 description exceeds limit of %2 characters.", + messageId: "SVC4065" + } +#---------SVC4066------------------------------ +# %1 - max length + COMPONENT_TAGS_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Tags overall length exceeds limit of %1 characters.", + messageId: "SVC4066" + } +#---------SVC4067------------------------------ +# %1 - max length + VENDOR_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor name exceeds limit of %1 characters.", + messageId: "SVC4067" + } +#---------SVC4068------------------------------ +# %1 - max length + VENDOR_RELEASE_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor release exceeds limit of %1 characters.", + messageId: "SVC4068" + } + +#---------SVC4069------------------------------ +# %1 - Service/Resource/Product + COMPONENT_INVALID_CONTACT_ID: { + code: 400, + message: "Error: Invalid Content. %1 contact id should be in format 'mnnnnnn' or 'aannna' or 'aannnn', where m=m ,a=a-zA-Z and n=0-9", + messageId: "SVC4069" + } +#---------SVC4070------------------------------ +# %1 - Service/Resource + INVALID_COMPONENT_NAME: { + code: 400, + message: 'Error: Invalid Content. %1 name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4070" + } + +#---------SVC4071------------------------------ + INVALID_VENDOR_NAME: { + code: 400, + message: 'Error: Invalid Content. Vendor name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4071" + } +#---------SVC4072------------------------------ + INVALID_VENDOR_RELEASE: { + code: 400, + message: 'Error: Invalid Content. Vendor release is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4072" + } +#---------SVC4073------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name + COMPONENT_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 name exceeds limit of %2 characters.", + messageId: "SVC4073" + } +#---------SVC4080------------------------------ +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CHECKOUT_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for modification by %3 %4(%5).", + messageId: "SVC4080" + } +#---------SVC4081----------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CERT_IN_PROGRESS_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for certification by %3 %4(%5).", + messageId: "SVC4081" + } + +#-----------SVC4082--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_SENT_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is sent for certification by %3 %4(%5).", + messageId: "SVC4082" + } +#-----------SVC4083--------------------------- + COMPONENT_VERSION_ALREADY_EXIST: { + code: 409, + message: "Error: Version of this %1 was already promoted.", + messageId: "SVC4083" + } +#-----------SVC4084--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CHECKED_IN: { + code: 409, + message: "Error: The current version of '%1' %2 was already checked-in by %3 %4(%5).", + messageId: "SVC4084" + } +#-----------SVC4085--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_CHECKOUT_BY_ANOTHER_USER: { + code: 403, + message: "Error: %1 %2 has already been checked out by %3 %4(%5).", + messageId: "SVC4085" + } +#-----------SVC4086--------------------------- +# %1  - resource/service name +# %2  - resource/service + COMPONENT_IN_USE: { + code: 403, + message: "Error: Requested '%1' %2 is in use by another user.", + messageId: "SVC4086" + } +#-----------SVC4087--------------------------- +# %1 - component name +# %2 - resource/service/product + COMPONENT_HAS_NEWER_VERSION: { + code: 409, + message: "Error: Checking out of the requested version of the '%1' %2 is not allowed as a newer version exists.", + messageId: "SVC4087" + } +#-----------SVC4088--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CERTIFIED: { + code: 403, + message: "Error: Requested %1 %2 has already been certified by %3 %4(%5).", + messageId: "SVC4088" + } +#-----------SVC4089--------------------------- +# %1 - resource/service name +# %2 - resource/service + COMPONENT_NOT_READY_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification.", + messageId: "SVC4089" + } +#-----------SVC4100--------------------------- +#%1 - property name + PROPERTY_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' property was not found.", + messageId: "SVC4100" + } +#-----------SVC4101--------------------------- +#%1 - property name + PROPERTY_ALREADY_EXIST: { + code: 409, + message: "Error: Property with '%1' name already exists.", + messageId: "SVC4101" + } + +#-----------SVC4102--------------------------- +# %1 - capability type name + CAPABILITY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Capability Type with name '%1' already exists.", + messageId: "SVC4102" + } +#-----------SVC4114--------------------------- + AUTH_FAILED_INVALIDE_HEADER: { + code: 400, + message: "Error: Invalid Authorization header.", + messageId: "SVC4114" + } +#-----------SVC4115--------------------------- +# %1 - capability type name + MISSING_CAPABILITY_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Capability Type '%1'.", + messageId: "SVC4115" + } + RESOURCE_INSTANCE_BAD_REQUEST: { + code: 400, + message: "Error: Invalid Content.", + messageId: "SVC4116" + } +#-----------SVC4117--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_MATCH_NOT_FOUND: { + code: 404, + message: "Error: Match not found between resource instance '%1' and resource instance '%2' for requirement '%3'.", + messageId: "SVC4117" + } +#-----------SVC4118--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_ALREADY_EXIST: { + code: 409, + message: "Error: Resource instances '%1' and '%2' are already associated with requirement '%3'.", + messageId: "SVC4118" + } +#-----------SVC4119--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_RELATION_NOT_FOUND: { + code: 404, + message: "Error: No relation found between resource instances '%1' and '%2' for requirement '%3'.", + messageId: "SVC4119" + } +#-----------SVC4120--------------------------- +# %1 - User's USER_ID + USER_INACTIVE: { + code: 404, + message: "Error: User %1 was not found.", + messageId: "SVC4120" + } +#-----------SVC4121--------------------------- +# %1 - User's USER_ID + USER_HAS_ACTIVE_ELEMENTS: { + code: 403, + message: "Error: User with %1 ID can not be deleted since it has active elements(resources/services/artifacts).", + messageId: "SVC4121" + } +#-----------SVC4122--------------------------- +# %1 - artifact type + ARTIFACT_TYPE_NOT_SUPPORTED: { + code: 400, + message: "Error: Invalid artifact type '%1'.", + messageId: "SVC4122" + } +#-----------SVC4123--------------------------- + ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Artifact logical name cannot be changed.", + messageId: "SVC4123" + } +#-----------SVC4124--------------------------- + MISSING_ARTIFACT_TYPE: { + code: 400, + message: "Error: Missing artifact type.", + messageId: "SVC4124" + } +#-----------SVC4125--------------------------- +# %1-artifact name + ARTIFACT_EXIST: { + code: 400, + message: "Error: Artifact '%1' already exists.", + messageId: "SVC4125" + } +#---------SVC4126------------------------------ +# %1 - resource/service/product/... +# %2 - field (tag, vendor name...) + INVALID_FIELD_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 format.", + messageId: "SVC4126" + } +#-----------SVC4127--------------------------- + ARTIFACT_INVALID_MD5: { + code: 400, + message: "Error: Invalid artifact checksum.", + messageId: "SVC4127" + } +#-----------SVC4128--------------------------- + MISSING_ARTIFACT_NAME: { + code: 400, + message: "Error: Invalid content. Missing artifact name.", + messageId: "SVC4128" + } +#-----------SVC4129--------------------------- + MISSING_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. Missing PROJECT_CODE number.", + messageId: "SVC4129" + } +#-----------SVC4130--------------------------- + INVALID_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. PROJECT_CODE number must be numeric from 5 up to 10 digits.", + messageId: "SVC4130" + } +#-----------SVC4131--------------------------- +# %1-resource/service +# %2-srtifact/artifacts +# %3-semicolomn separated list of artifact + COMPONENT_MISSING_MANDATORY_ARTIFACTS: { + code: 403, + message: "Error: Missing mandatory informational %1 %2: [%3].", + messageId: "SVC4131" + } +#-----------SVC4132--------------------------- +# %1 - lifecycle type name + LIFECYCLE_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Lifecycle Type with name '%1' already exists.", + messageId: "SVC4132" + } +#-----------SVC4133--------------------------- +# %1 - service version +# %2 - service name + SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION: { + code: 403, + message: "Error: Version %1 of '%2' service is not available for distribution.", + messageId: "SVC4133" + } +#-----------SVC4134--------------------------- + MISSING_LIFECYCLE_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing interface life-cycle type.", + messageId: "SVC4134" + } +#---------SVC4135------------------------------ + SERVICE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service category cannot be changed once the service is certified.", + messageId: "SVC4135" + } +#---------SVC4136------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE: { + code: 500, + message: "Error: Requested distribution environment '%1' is not available.", + messageId: "SVC4136" + } +#---------SVC4137------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_FOUND: { + code: 400, + message: "Error: Requested distribution environment '%1' was not found.", + messageId: "SVC4137" + } +#---------SVC4138------------------------------ + DISTRIBUTION_ENVIRONMENT_INVALID: { + code: 400, + message: "Error: Invalid distribution environment.", + messageId: "SVC4138" + } +#---------SVC4139------------------------------ +# %1 - service name + DISTRIBUTION_ARTIFACT_NOT_FOUND: { + code: 409, + message: "Error: Service '%1' cannot be distributed due to missing deployment artifacts.", + messageId: "SVC4139" + } +#---------SVC4200------------------------------ +# %1 - Service/Resource +# %2 - max icon name length + COMPONENT_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 icon name exceeds limit of %2 characters.", + messageId: "SVC4200" + } +#---------SVC4300------------------------------ + RESTRICTED_ACCESS: { + code: 403, + message: "Error: Restricted access.", + messageId: "SVC4300" + } +#---------SVC4301------------------------------ + RESTRICTED_OPERATION: { + code: 409, + message: "Error: Restricted operation.", + messageId: "SVC4301" + } +#---------SVC4500------------------------------ + MISSING_BODY: { + code: 400 , + message: "Error: Missing request body.", + messageId: "SVC4500" + } +#---------SVC4501------------------------------ + MISSING_PUBLIC_KEY: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'apiPublicKey'." , + messageId: "SVC4501" + } +#---------SVC4502------------------------------ + DISTRIBUTION_ENV_DOES_NOT_EXIST: { + code: 400 , + message: "Error: Invalid Body : Missing mandatory parameter 'distrEnvName'." , + messageId: "SVC4502" + } +#-----------SVC4503--------------------------- +# %1 - service name + SERVICE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' service was not found.", + messageId: "SVC4503" + } + +#---------SVC4504------------------------------ +# %1 - Service/Resource +# %2 - service/resource version + COMPONENT_VERSION_NOT_FOUND: { + code: 404, + message: "Error: %1 version %2 was not found.", + messageId: "SVC4504" + } +#-----------SVC4505--------------------------- + #%1-artifact name + + ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Artifact '%1' was not found.", + messageId: "SVC4505" + } +#---------SVC4506------------------------------ + MISSING_ENV_NAME: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'distrEnvName'.", + messageId: "SVC4506" + } +#---------SVC4507------------------------------ + COMPONENT_INVALID_TAGS_NO_COMP_NAME: { + code: 400, + message: "Error: Invalid Content. One of the tags should be the component name.", + messageId: "SVC4507" + } + +#---------SVC4508------------------------------ + SERVICE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service name cannot be changed once the service is certified.", + messageId: "SVC4508" + } + +#---------SVC4509------------------------------ + SERVICE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the service is certified.", + messageId: "SVC4509" + } +#---------SVC4510------------------------------ +# %1 - icon name max length + SERVICE_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Icon name exceeds limit of %1 characters.", + messageId: "SVC4510" + } +#---------SVC4511------------------------------ + DISTRIBUTION_REQUESTED_NOT_FOUND: { + code: 404, + message: "Error: Requested distribution was not found.", + messageId: "SVC4511" + } +#---------SVC4512------------------------------ +# %1 - Distribution ID + DISTRIBUTION_REQUESTED_FAILED: { + code: 403, + message: "Error: Requested distribution '%1' failed.", + messageId: "SVC4512" + } +#---------SVC4513------------------------------ + RESOURCE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource category cannot be changed once the resource is certified.", + messageId: "SVC4513" + } +#---------SVC4514------------------------------ + RESOURCE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource name cannot be changed once the resource is certified.", + messageId: "SVC4514" + } +#---------SVC4515------------------------------ + RESOURCE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the resource is certified.", + messageId: "SVC4515" + } +#---------SVC4516------------------------------ + RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Vendor name cannot be changed once the resource is certified.", + messageId: "SVC4516" + } +#---------SVC4517------------------------------ + RESOURCE_DERIVED_FROM_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Derived from resource template cannot be changed once the resource is certified.", + messageId: "SVC4517" + } +#---------SVC4518------------------------------ +# %1 - max length + COMPONENT_SINGLE_TAG_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Single tag exceeds limit of %1 characters.", + messageId: "SVC4518" + } +#---------SVC4519------------------------------ + INVALID_DEFAULT_VALUE: { + code: 400, + message: "Error: mismatch in data-type occurred for property %1. data type is %2 and default value found is %3.", + messageId: "SVC4519" + } +#---------SVC4520------------------------------ +# %1 - service or resource + ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED: { + code: 409, + message: "Error: Maximal number of additional %1 parameters was reached.", + messageId: "SVC4520" + } +#---------SVC4521------------------------------ + ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED: { + code: 400, + message: "Error: Invalid Content. The Additional information label and value cannot be empty.", + messageId: "SVC4521" + } +#---------SVC4522------------------------------ +# %1 - label/value +# %2 - Maximal length of %1 + ADDITIONAL_INFORMATION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Additional information %1 exceeds limit of %2 characters.", + messageId: "SVC4522" + } +#---------SVC4523------------------------------ + ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information label is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4523" + } +#---------SVC4524------------------------------ + ADDITIONAL_INFORMATION_NOT_FOUND: { + code: 409, + message: "Error: Requested additional information was not found.", + messageId: "SVC4524" + } +#---------SVC4525------------------------------ + ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information contains non-english characters.', + messageId: "SVC4525" + } +#---------SVC4526------------------------------ + RESOURCE_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource instance was not found.", + messageId: "SVC4526" + } +#---------SVC4527------------------------------ + ASDC_VERSION_NOT_FOUND: { + code: 500, + message: 'Error: ASDC version cannot be displayed.', + messageId: "SVC4527" + } +#---------SVC4528------------------------------ +# %1-artifact url/artifact label/artifact description/VNF Service Indicator + MISSING_DATA: { + code: 400, + message: "Error: Invalid content. Missing %1.", + messageId: "SVC4528" + } +#---------SVC4529------------------------------ +# %1-artifact url/artifact label/artifact description/artifact name +# %2 - Maximal length of %1 + EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 exceeds limit of %2 characters.", + messageId: "SVC4529" + } +#---------SVC4530------------------------------ + ARTIFACT_INVALID_TIMEOUT: { + code: 400, + message: "Error: Invalid Content. Artifact Timeout should be set to valid positive non-zero number of minutes.", + messageId: "SVC4530" + } +#---------SVC4531------------------------------ + SERVICE_IS_VNF_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: VNF Indicator cannot be updated for certified service.", + messageId: "SVC4531" + } + #---------SVC4532------------------------------ + RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE: { + code: 404, + message: "Error: Requested '%1' resource instance was not found on the service '%2.", + messageId: "SVC4532" + } + #---------SVC4533------------------------------ + # %1 - "HEAT"/"HEAT_ENV"/"MURANO_PKG"/"YANG_XML" + WRONG_ARTIFACT_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for %1 artifact type.", + messageId: "SVC4533" + } + +#---------SVC4534------------------------------ +# %1 - "HEAT"/"HEAT_ENV" + INVALID_YAML: { + code: 400, + message: "Error: Uploaded YAML file for %1 artifact is invalid.", + messageId: "SVC4534" + } + +#---------SVC4535------------------------------ +# %1 - "HEAT" + INVALID_DEPLOYMENT_ARTIFACT_HEAT: { + code: 400, + message: "Error: Invalid %1 artifact.", + messageId: "SVC4535" + } +#---------SVC4536------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "HEAT"/"HEAT_ENV"/"MURANO_PKG" +# %4 - "HEAT"/"HEAT_ENV"/"MURANO_PKG + DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact of %3 type .Please delete or update an existing %4 artifact.", + messageId: "SVC4536" + } + +#---------SVC4537------------------------------ + MISSING_HEAT: { + code: 400, + message: "Error: Missing HEAT artifact. HEAT_ENV artifact cannot be uploaded without corresponding HEAT template.", + messageId: "SVC4537" + } +#---------SVC4538------------------------------ + MISMATCH_HEAT_VS_HEAT_ENV: { + code: 400, + message: "Error: Invalid artifact content. Parameter's set in HEAT_ENV '%1' artifact doesn't match the parameters in HEAT '%2' artifact.", + messageId: "SVC4538" + } +#---------SVC4539------------------------------ + INVALID_RESOURCE_PAYLOAD: { + code: 400, + message: "Error: Invalid resource payload.", + messageId: "SVC4539" + } +#---------SVC4540------------------------------ + INVALID_TOSCA_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for TOSCA template.", + messageId: "SVC4540" + } +#---------SVC4541------------------------------ + INVALID_YAML_FILE: { + code: 400, + message: "Error: Invalid YAML file.", + messageId: "SVC4541" + } +#---------SVC4542------------------------------ + INVALID_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Invalid TOSCA template.", + messageId: "SVC4542" + } +#---------SVC4543------------------------------ + NOT_RESOURCE_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Imported Service TOSCA template.", + messageId: "SVC4543" + } +#---------SVC4544------------------------------ + NOT_SINGLE_RESOURCE: { + code: 400, + message: "Error: Imported TOSCA template should contain one resource definition.", + messageId: "SVC4544" + } +#---------SVC4545------------------------------ + INVALID_RESOURCE_NAMESPACE: { + code: 400, + message: "Error: Invalid resource namespace.", + messageId: "SVC4545" + } +#---------SVC4546------------------------------ + RESOURCE_ALREADY_EXISTS: { + code: 400, + message: "Error: Imported resource already exists in ASDC Catalog.", + messageId: "SVC4546" + } +#---------SVC4549------------------------------ + INVALID_RESOURCE_CHECKSUM: { + code: 400, + message: "Error: Invalid resource checksum.", + messageId: "SVC4549" + } +#---------SVC4550------------------------------ + #%1  -  Consumer salt + INVALID_LENGTH: { + code: 400, + message: "Error: Invalid %1 length.", + messageId: "SVC4550" + } + #---------SVC4551------------------------------ + #%1  -  ECOMP User name + ECOMP_USER_NOT_FOUND: { + code: 404, + message: "Error: ECOMP User '%1' was not found.", + messageId: "SVC4551" + } +#---------SVC4552------------------------------ + CONSUMER_ALREADY_EXISTS: { + code: 409, + message: "Error: ECOMP User already exists.", + messageId: "SVC4552" + } +#---------SVC4553----------------------------- + #%1  -  Consumer name / Consumer password/ Consumer salt + INVALID_CONTENT_PARAM: { + code: 400, + message: "Error: %1 is invalid.", + messageId: "SVC4553" + } + #---------SVC4554------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Requested artifact doesn't belong to specified %1.", + messageId: "SVC4554" + } +#---------SVC4554------------------------------ +# %1 - "Service name" + SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND: { + code: 403, + message: "Error: Requested '%1' service is not ready for certification. Service has to have at least one deployment artifact.", + messageId: "SVC4554" + } +#---------SVC4555------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_LENGTH: { + code: 400, + message: "Error: Invalid %1 %2 name length.", + messageId: "SVC4555" + } +#---------SVC4556------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 name format.", + messageId: "SVC4556" + } +#---------SVC4557------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category name" + COMPONENT_CATEGORY_ALREADY_EXISTS: { + code: 409, + message: "Error: %1 category name '%2' already exists.", + messageId: "SVC4557" + } +#---------SVC4558------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + VALIDATED_RESOURCE_NOT_FOUND: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource.", + messageId: "SVC4558" + } +#---------SVC4559------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_ALREADY_VALIDATED_RESOURCE: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use already available validated resource version.", + messageId: "SVC4559" + } +#---------SVC4560------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_LIST_VALIDATED_RESOURCES: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use one of available validated resource versions.", + messageId: "SVC4560" + } +#---------SVC4561------------------------------ +# %1 - "resource"/"product" +# %2 - "category" +# %3 - "category name" + COMPONENT_CATEGORY_NOT_FOUND: { + code: 404, + message: "Error: Requested %1 %2 '%3' was not found.", + messageId: "SVC4561" + } +#---------SVC4562------------------------------ +# %1 - "Resource"/"Product" +# %2 - "sub-category name" +# %3 - "category name" + COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY: { + code: 409, + message: "Error: %1 sub-category '%2' already exists under '%3' category.", + messageId: "SVC4562" + } +#---------SVC4563------------------------------ +# %1 - "Product" +# %2 - "grouping name" +# %3 - "sub-category name" + COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY: { + code: 409, + message: "Error: %1 grouping '%2' already exists under '%3' sub-category.", + messageId: "SVC4563" + } +#---------SVC4564------------------------------ +# %1 - product name + PRODUCT_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' product was not found.", + messageId: "SVC4564" + } +#---------SVC4565------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") +# %3 - parameter name + INVALID_HEAT_PARAMETER_VALUE: { + code: 400, + message: "Error: Invalid %1 artifact. Invalid %2 value set for '%3' parameter.", + messageId: "SVC4565" + } +#---------SVC4566------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") + INVALID_HEAT_PARAMETER_TYPE: { + code: 400, + message: "Error: Invalid %1 artifact. Unsupported '%2' parameter type.", + messageId: "SVC4566" + } +#---------SVC4567------------------------------ +# %1 - "YANG_XML" + INVALID_XML: { + code: 400, + message: "Error: Uploaded XML file for %1 artifact is invalid.", + messageId: "SVC4567" + } +#---------SVC4567------------------------------ +# %1 - "User Name and UserId" +# %2 -"checked-out"/"in-certification" + CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: User cannot be deleted. User '%1' has %2 projects.", + messageId: "SVC4567" + } +#---------SVC4568------------------------------ +# %1 - "User Name and UserId" +# %2 -"checked-out"/"in-certification" + CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: Role cannot be changed. User '%1' has %2 projects.", + messageId: "SVC4568" + } +#---------SVC4570------------------------------ + UPDATE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator is not allowed to change his/her role.", + messageId: "SVC4570" + } +#---------SVC4571------------------------------ + SERVICE_CANNOT_CONTAIN_SUBCATEGORY: { + code: 400, + message: "Error: Sub category cannot be defined for service", + messageId: "SVC4571" + } +#---------SVC4572------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_TOO_MUCH_CATEGORIES: { + code: 400, + message: "Error: %1 must have only 1 category", + messageId: "SVC4572" + } +#---------SVC4574------------------------------ + RESOURCE_TOO_MUCH_SUBCATEGORIES: { + code: 400, + message: "Error: Resource must have only 1 sub category", + messageId: "SVC4574" + } +#---------SVC4575------------------------------ + COMPONENT_MISSING_SUBCATEGORY: { + code: 400, + message: "Error: Missing sub category", + messageId: "SVC4575" + } + #---------SVC4576------------------------------ +# %1 - "component type" + UNSUPPORTED_ERROR: { + code: 400, + message: "Error : Requested component type %1 is unsupported.", + messageId: "SVC4576" + } + #---------SVC4577------------------------------ +# %1 - "resource type" + RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES: { + code: 409, + message: "Error : Resource of type %1 cannot contain resource instances.", + messageId: "SVC4577" + } +#---------SVC4578------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "artifact name" + DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact named '%3'.", + messageId: "SVC4578" + } +#---------SVC4579------------------------------ +# %1 - "Category"/"Sub-Category"/"Group" +# %2 - category/sub-category/grouping name. + INVALID_GROUP_ASSOCIATION: { + code: 400, + message: "Error: Invalid group association. %1 '%2' was not found.", + messageId: "SVC4579" + } +#---------SVC4580------------------------------ + EMPTY_PRODUCT_CONTACTS_LIST: { + code: 400, + message: "Error: Invalid content. At least one Product Contact has to be specified.", + messageId: "SVC4580" + } +#---------SVC4581------------------------------ +# %1 - userId + INVALID_PRODUCT_CONTACT: { + code: 400, + message: "Error: Invalid content. User '%1' cannot be set as Product Contact.", + messageId: "SVC4581" + } +#---------SVC4582------------------------------ +# %1 - Product +# %2 - "abbreviated"/"full" + MISSING_ONE_OF_COMPONENT_NAMES: { + code: 400, + message: "Error: Invalid content. Missing %1 %2 name.", + messageId: "SVC4582" + } +#---------SVC4583------------------------------ +# %1 - "Icon" +# %2 - "resource"/"service"/"product" + COMPONENT_PARAMETER_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: %1 cannot be changed once the %2 is certified.", + messageId: "SVC4583" + } +#---------SVC4584------------------------------ +# %1 - service/VF name +# %2 - "service" /"VF" +# %3 - resource instance origin type +# %4 - resource instance name +# %5 - requirement/capability +# %6 - requirement/capability name +# %7 - "fulfilled" (for req)/"consumed (for cap)" + REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification. %3 '%4' has to have %5 '%6' %7.", + messageId: "SVC4584" + } +#---------SVC4585------------------------------ + INVALID_OCCURRENCES: { + code: 400, + message: "Error: Invalid occurrences format.", + messageId: "SVC4585" + } +#---------SVC4586------------------------------ +#---------SVC4586------------------------------ + INVALID_SERVICE_API_URL: { + code: 400, + message: 'Error: Invalid Service API URL. Please check whether your URL has a valid domain extension and does not contain the following characters - #?&@%+;,=$<>~^`\[]{}|"*!', + messageId: "SVC4586" + } +#---------SVC4587------------------------------ +# %1 - Data type name + DATA_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Data type %1 already exists.', + messageId: "SVC4587" + } +#---------SVC4588------------------------------ +# %1 - Data type name + DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM: { + code: 400, + message: 'Error: Invalid Data type %1. Data type must have either a valid derived from declaration or at least one valid property', + messageId: "SVC4588" + } +#---------SVC4589------------------------------ +# %1 - Data type name + DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY: { + code: 400, + message: "Error: Invalid Data type %1. 'properties' parameter cannot be empty if provided.", + messageId: "SVC4589" + } +#---------SVC4590------------------------------ +# %1 - Property type name +# %2 - Property name + INVALID_PROPERTY_TYPE: { + code: 400, + message: "Error: Invalid Property type %1 in property %2.", + messageId: "SVC4590" + } +#---------SVC4591------------------------------ +# %1 - Property inner type +# %2 - Property name + INVALID_PROPERTY_INNER_TYPE: { + code: 400, + message: "Error: Invalid property inner type %1, in property %2", + messageId: "SVC4591" + } +#---------SVC4592------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" + COMPONENT_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' %2 was not found.", + messageId: "SVC4592" + } +#---------SVC4593------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" +# %3 - "resource/"service"/"product" +# %4 - container name + COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER: { + code: 404, + message: "Error: Requested '%1' %2 was not found on the %3 '%4'.", + messageId: "SVC4593" + } +#---------SVC4594------------------------------ +#%1 - requirement / capability +#%2 - requirement name + IMPORT_DUPLICATE_REQ_CAP_NAME: { + code: 400, + message: "Error: Imported TOSCA template contains more than one %1 named '%2'.", + messageId: "SVC4594" + } +#---------SVC4595------------------------------ +#%1 - requirement / capability +#%2 - requirement name +#%3 - parent containing the requirement + IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED: { + code: 400, + message: "Error: Imported TOSCA template contains %1 '%2' that is already defined by derived template %3.", + messageId: "SVC4595" + } +#---------SVC4596------------------------------ +# %1 - Data type name + DATA_TYPE_DERIVED_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The ancestor data type %1 cannot be found in the system.", + messageId: "SVC4596" + } +#---------SVC4597------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties named %2 which are already defined in one of its ancestors.", + messageId: "SVC4597" + } +#---------SVC4598------------------------------ +# %1 - Data type name + DATA_TYPE_DUPLICATE_PROPERTY: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains duplicate property.", + messageId: "SVC4598" + } +#---------SVC4599------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties %2 which their type is this data type.", + messageId: "SVC4599" + } +#---------SVC4600------------------------------ +# %1 - Data type name + DATA_TYPE_CANNOT_HAVE_PROPERTIES: { + code: 400, + message: "Error: Invalid Content. The data type %1 cannot have properties since it is of type scalar", + messageId: "SVC4600" + } +#---------SVC4601------------------------------ + NOT_TOPOLOGY_TOSCA_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file %1 cannot be modeled to VF as it does not contain 'topology_template.", + messageId: "SVC4601" + } +#---------SVC4602-------------------------------- +# %1 - yaml file name +# %2 - node_template label +# %3 - node_template type + INVALID_NODE_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file '%1' contains node_template '%2' of type '%3' that does not represent existing VFC/CP/VL", + messageId: "SVC4602" + } +#---------SVC4603------------------------------ +# %1 - component type +# %2 - component name +# %3 - state + ILLEGAL_COMPONENT_STATE: { + code: 403, + message: "Error: Component instance of %1 can not be created because the component '%2' is in an illegal state %3.", + messageId: "SVC4603" + } +#---------SVC4604------------------------------ +# %1 - csar file name + CSAR_INVALID: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. 'TOSCA-Metadata/Tosca.meta' file must be provided.", + messageId: "SVC4604" + } +#---------SVC4605------------------------------ +# %1 - csar file name + CSAR_INVALID_FORMAT: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. Invalid 'TOSCA-Metadata/Tosca.meta' file format.", + messageId: "SVC4605" + } +#---------SVC4606------------------------------ +# %1 - property name +# %2 - property type +# %3 - property innerType +# %4 - default value is + INVALID_COMPLEX_DEFAULT_VALUE: { + code: 400, + message: "Error: Invalid default value of property %1. Data type is %2 with inner type %3 and default value found is %4.", + messageId: "SVC4606" + } +#---------SVC4607------------------------------ +# %1 - csar file name + CSAR_NOT_FOUND: { + code: 400, + message: "Error: TOSCA CSAR '%1' is not found.", + messageId: "SVC4607" + } +#---------SVC4608------------------------------ +# %1 - artifact name +# %2 - component type +# %3 - actual component type + MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE: { + code: 400, + message: "Error: Artifact %1 is only compatible with component of type %2, but component type is %3.", + messageId: "SVC4608" + } + +#---------SVC4609------------------------------ +# %1 - "INVALID_JSON" + INVALID_JSON: { + code: 400, + message: "Error: Uploaded JSON file for %1 artifact is invalid.", + messageId: "SVC4609" + } +#---------SVC4610------------------------------ +# %1 - csar file name +# %2 - missing file name + YAML_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error - TOSCA CSAR %1 is invalid. TOSCA-Metadata/Tosca.meta refers to file %2 that is not provided.", + messageId: "SVC4610" + } +#---------SVC4611------------------------------ +# %1 - group name + GROUP_MEMBER_EMPTY: { + code: 400, + message: "Error: Invalid Content. Group %1 member list was provided but does not have values", + messageId: "SVC4611" + } +#---------SVC4612------------------------------ +# %1 - group name + GROUP_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Group type %1 already exists.', + messageId: "SVC4612" + } +#---------SVC4613------------------------------ +# %1 - group name +# %2 - VF name(component name) +# %3 - actual component type [VF] + GROUP_ALREADY_EXIST: { + code: 409, + message: "Error: Group with name '%1' already exists in %2 %3.", + messageId: "SVC4613" + } +#---------SVC4614------------------------------ +# %1 - group type + GROUP_TYPE_IS_INVALID: { + code: 400, + message: "Error: Invalid content. Group type %1 does not exist", + messageId: "SVC4614" + } +#---------SVC4615------------------------------ +# %1 - group name + GROUP_MISSING_GROUP_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Group Type for group '%1'", + messageId: "SVC4615" + } +#---------SVC4616------------------------------ +# %1 - member name +# %2 - group name +# %3 - VF name +# %4 - component type [VF ] + GROUP_INVALID_COMPONENT_INSTANCE: { + code: 400, + message: "Error: member %1 listed in group %2 is not part of %3 %4.", + messageId: "SVC4616" + } +#---------SVC4617------------------------------ +# %1 - member name +# %2 - group name +# %3 - group type + GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE: { + code: 400, + message: "Error: member %1 listed in group %2 is not part of allowed members of group type %3.", + messageId: "SVC4617" + } +#---------SVC4618------------------------------ +# %1 - missing file name +# %2 - csar file name + ARTIFACT_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", + messageId: "SVC4618" + } +#---------SVC4619------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - existing artifact type + ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { + code: 400, + message: "Error: artifact %1 in type %2 already exists in type %3.", + messageId: "SVC4619" + } +#---------SVC4620------------------------------ + FAILED_RETRIVE_ARTIFACTS_TYPES: { + code: 400, + message: "Error: Failed to retrieve list of suported artifact types.", + messageId: "SVC4620" + } +#---------SVC4621------------------------------ +# %1 - artifact name +# %2 - master + ARTIFACT_ALRADY_EXIST_IN_MASTER_IN_CSAR: { + code: 400, + message: "Error: artifact %1 already exists in master %2 .", + messageId: "SVC4621" + } +#---------SVC4622------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - master name +# %4 - master type + ARTIFACT_NOT_VALID_IN_MASTER: { + code: 400, + message: "Error: artifact %1 in type %2 can not be exists under master %3 in type %4.", + messageId: "SVC4622" + } +#---------SVC4623------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - env name +# %4 - existing env + ARTIFACT_NOT_VALID_ENV: { + code: 400, + message: "Error: Artifact %1 in type %2 with env %3 already exists with another env %4", + messageId: "SVC4623" + } +#---------SVC4624------------------------------ +# %1 - groups names +# %2 - VF name +# %3 - component type [VF ] + GROUP_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The groups '%1' cannot be found under %2 %3.", + messageId: "SVC4624" + } +#---------SVC4625------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_ASSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already associated to group '%1'.", + messageId: "SVC4625" + } +#---------SVC4626------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_DISSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already dissociated from group '%1'.", + messageId: "SVC4626" + } +#---------SVC4627------------------------------ +# %1 - property name +# %2 - group name +# %3 - group type name + GROUP_PROPERTY_NOT_FOUND: { + code: 400, + message: "Error: property %1 listed in group %2 is not exist in group type %3.", + messageId: "SVC4627" + } +#---------SVC4628------------------------------ +# %1 - csarUUID +# %2 - VF name + VSP_ALREADY_EXISTS: { + code: 400, + message: "Error: The VSP with UUID %1 was already imported for VF %2. Please select another or update the existing VF.", + messageId: "SVC4628" + } +#---------SVC4629------------------------------ +# %1 - VF name + MISSING_CSAR_UUID: { + code: 400, + message: "Error: The Csar UUID or payload name is missing for VF %1.", + messageId: "SVC4629" + } +#---------SVC4630------------------------------ +# %1 - VF name +# %2 - new csarUUID +# %3 - old csarUUID + RESOURCE_LINKED_TO_DIFFERENT_VSP: { + code: 400, + message: "Error: Resource %1 cannot be updated using CsarUUID %2 since the resource is linked to a different VSP with csarUUID %3.", + messageId: "SVC4630" + } +#---------SVC4631------------------------------ +# %1 - policy name + POLICY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Policy type %1 already exists.", + messageId: "SVC4631" + } +#---------SVC4632------------------------------ +# %1 - target name +# %2 - policy type name + TARGETS_NON_VALID: { + code: 400, + message: "Error: target %1 listed in policy type %2 is not a group or resource.", + messageId: "SVC4632" + } +#---------SVC4633------------------------------ +# %1 - policy name + TARGETS_EMPTY: { + code: 400, + message: "Error: Invalid Content. Policy %1 target list was provided but does not have values", + messageId: "SVC4633" + } +#---------SVC4634------------------------------ + DATA_TYPE_CANNOT_BE_EMPTY: { + code: 500, + message: "Error: Data types are empty. Please import the data types.", + messageId: "SVC4634" + } +#---------SVC4635------------------------------ +# %1 - csar uuid + RESOURCE_FROM_CSAR_NOT_FOUND: { + code: 400, + message: "Error: resource from csar uuid %1 not found", + messageId: "SVC4635" + } +#---------SVC4636------------------------------ +# %1 - Data type name + DATA_TYPE_CANNOT_BE_UPDATED_BAD_REQUEST: { + code: 400, + message: 'Error: Data type %1 cannot be upgraded. The new data type does not contain old properties or the type of one of the properties has been changed.', + messageId: "SVC4636" + } +#-----------SVC4637--------------------------- +#%1 - attribute name + ATTRIBUTE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' attribute was not found.", + messageId: "SVC4637" + } +#-----------SVC4638--------------------------- +#%1 - attribute name + ATTRIBUTE_ALREADY_EXIST: { + code: 409, + message: "Error: Attribute with '%1' name already exists.", + messageId: "SVC4638" + } +#-----------SVC4639--------------------------- +#%1 - property name + PROPERTY_NAME_ALREADY_EXISTS: { + code: 409, + message: "Error: Property with '%1' name and different type already exists.", + messageId: "SVC4639" + } +#-----------SVC4640--------------------------- +#%1 - property name + INVALID_PROPERTY: { + code: 409, + message: "Error: Invalid property received.", + messageId: "SVC4640" + } +#---------SVC4641----------------------------- +#%1 - invalid filter +#%2 - valid filters + INVALID_FILTER_KEY: { + code: 400, + message: "Error: The filter %1 is not applicable. Please use one of the following filters: %2", + messageId: "SVC4641" + } +#---------SVC4642----------------------------- +#%1 - asset type +#%2 - filter + NO_ASSETS_FOUND: { + code: 404, + message: "No %1 were found to match criteria %2", + messageId: "SVC4642" + } +#---------SVC4643------------------------------ +# %1 - "Resource"/"Product" +# %2 - "sub-category name" +# %3 - "category name" + COMPONENT_SUB_CATEGORY_NOT_FOUND_FOR_CATEGORY: { + code: 404, + message: "Error: %1 sub-category '%2' not found under category '%3'.", + messageId: "SVC4643" + } +#---------SVC4644------------------------------ +# %1 - Format + CORRUPTED_FORMAT: { + code: 400, + message: "Error: %1 format is corrupted.", + messageId: "SVC4644" + } +#---------SVC4645------------------------------ +# %1 - "groupType" + INVALID_VF_MODULE_TYPE: { + code: 400, + message: "Error: Invalid group type '%1' (should be VfModule).", + messageId: "SVC4645" + } +#---------SVC4646------------------------------ +# %1 - "groupName" + INVALID_VF_MODULE_NAME: { + code: 400, + message: "Error: Invalid Content. VF Module name '%1' contains invalid characters", + messageId: "SVC4646" + } + +#---------SVC4647------------------------------ +# %1 - "modifiedName" + INVALID_VF_MODULE_NAME_MODIFICATION: { + code: 400, + message: "Error: Invalid VF Module name modification, can not modify '%1'", + messageId: "SVC4647" + } + diff --git a/asdctool/src/main/resources/config/logback.xml b/asdctool/src/main/resources/config/logback.xml new file mode 100644 index 0000000000..298587bd1d --- /dev/null +++ b/asdctool/src/main/resources/config/logback.xml @@ -0,0 +1,44 @@ + + + + + + + + ${HOME}/asdctool/logs/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log + + + + + + + + + + + + + + ${HOME}/asdctool/logs/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + + + + \ No newline at end of file diff --git a/asdctool/src/main/resources/config/titan.properties b/asdctool/src/main/resources/config/titan.properties new file mode 100644 index 0000000000..bfb0ebc542 --- /dev/null +++ b/asdctool/src/main/resources/config/titan.properties @@ -0,0 +1,3 @@ +storage.backend=cassandra +storage.hostname=localhost +storage.port=9160 diff --git a/asdctool/src/main/resources/es-resources/README.txt b/asdctool/src/main/resources/es-resources/README.txt new file mode 100644 index 0000000000..a7006efa80 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/README.txt @@ -0,0 +1,43 @@ +ASDC elasticsearch tool +======================== + +This tool purpose is to ease and allow updating elasticsearch indices. + +In order to use the scripts, you need to verify Python is installed and to install the elasticsearc-py library: + Verify pip is installed: $command -v pip + if not installed: + Download https://bootstrap.pypa.io/get-pip.py + $python get-pip.py (see instruction: https://pip.pypa.io/en/latest/installing/#installing-with-get-pip-py) + $pip install elasticsearch + + +Tool contains: + - index_ops.py + This script includes operations on elasticsearch index: + + create index: + $python index_ops.py -o create -a -n -f + + delete index: + $python index_ops.py -o delete -a -n + + copy index (assumes destination index already exists): + $python index_ops.py -o move -a -n -t + + + - file_utils.py + This script includes operations on files + + - audit_migration_1602.py + This script run full flow to migrate audit information from previous versions to ASDC 1602 + It has 2 inputs: + 1. config_properties.py - this file holds configuration (hostname, index name, index mapping file etc.) + 2. folder of fields mapping per elasticsearch type (map old field to new field) + The flow of this script is as follow: + * create temp index with correct index mapping + * scan the audit index to get all records + * manipulate fields data and insert it to temp index + * delete audit index + * create audit index with correct mapping + * copy from temp index to newly created audit index + * delete temp index \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/auditMappings.txt b/asdctool/src/main/resources/es-resources/auditMappings.txt new file mode 100644 index 0000000000..7de77cccbd --- /dev/null +++ b/asdctool/src/main/resources/es-resources/auditMappings.txt @@ -0,0 +1,169 @@ +{ "settings": {}, "mappings": +{ +"distributiondownloadevent": +{ "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "auditinggetuebclusterevent": +{ "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "distributionstatusevent": +{ "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, +"distributionengineevent": +{ "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ROLE": { "include_in_all": true, "type": "string" }, + "API_KEY": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "D_ENV": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CONSUMER_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }}, + "_all": { "enabled": true } }, + "useraccessevent": { + "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_NAME": { "include_in_all": true, "type": "string" }} , + "_all": { "enabled": true }}, + "resourceadminevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_NAME": { "include_in_all": true, "type": "string" }, + "PREV_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "PREV_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DPREV_STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DCURR_STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "COMMENT": { "include_in_all": true, "type": "string" }, + "ARTIFACT_NAME": { "include_in_all": true, "index": "not_analyzed", "type": "string" } }, + "_all": { "enabled": true }} , + "useradminevent": + { "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_NAME": { "include_in_all": true, "type": "string" }, + "USER_EMAIL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_ROLE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_AFTER_EMAIL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_BEFORE_ROLE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_AFTER_ROLE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_NAME": { "include_in_all": true, "type": "string" }, + "USER_BEFORE_NAME": { "include_in_all": true, "type": "string" }, + "USER_BEFORE_EMAIL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER_AFTER_NAME": { "include_in_all": true, "type": "string" } }, + "_all": { "enabled": true } }, +"distributionnotificationevent": + {"properties":{ + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_STATE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_NAME": { "include_in_all": true, "type": "string" }, + "MODIFIER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TOPIC_NAME":{ "include_in_all": true, "index": "not_analyzed", "type": "string" }}}, +"categoryevent": +{"properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CATEGORY_NAME": { "include_in_all": true, "type": "string" }, + "SUB_CATEGORY_NAME": { "include_in_all": true, "type": "string" }, + "GROUPING_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "authevent": { + "properties": { + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }, + "DESC": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "URL": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "USER": { "include_in_all": true, "type": "string" } , + "AUTH_STATUS": { "include_in_all": true, "index": "not_analyzed","type": "string" } , + "REALM": { "include_in_all": true, "index": "not_analyzed","type": "string" }} , + "_all": { "enabled": true }}, + "consumerevent": + {"properties":{ + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER": { "include_in_all": true, "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "ECOMP_USER": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }}, + "_all": { "enabled": true } }, + "distributiondeployevent": + { "properties": { + "ACTION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "CURR_VERSION": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "DESC": { "include_in_all": true, "type": "string" }, + "DID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "MODIFIER_NAME": { "include_in_all": true, "type": "string" }, + "MODIFIER_UID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "REQUEST_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "RESOURCE_NAME": { "include_in_all": true, "type": "string" }, + "RESOURCE_TYPE": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "SERVICE_INSTANCE_ID": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "STATUS": { "include_in_all": true, "index": "not_analyzed", "type": "string" }, + "TIMESTAMP": { "include_in_all": true, "ignore_malformed": false, "format": "yyyy-MM-dd HH:mm:ss.SSS", "precision_step": 4, "type": "date" }}}}} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/audit_migration_1602.py b/asdctool/src/main/resources/es-resources/audit_migration_1602.py new file mode 100644 index 0000000000..8b61ebfaf0 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/audit_migration_1602.py @@ -0,0 +1,132 @@ +import itertools +import string +import json +from datetime import datetime +from elasticsearch import Elasticsearch +import elasticsearch +import elasticsearch.helpers +from elasticsearch.client import IndicesClient +import sys, os +from index_ops import createIndex, deleteIndex, copyIndex +from config_properties import getGlobalVar +from file_utils import readFileToJson + +def updateFieldNames(client, queryFrom, fromIndex, destIndex, addUTC): + typesDir="types" + typeFields = {} + for filename in os.listdir(typesDir): + print filename + fieldNames=readFileToJson(typesDir+os.sep+filename) + + type=filename.split(".")[0] + typeFields[type] = fieldNames + + client.indices.refresh(index=fromIndex) + res = elasticsearch.helpers.scan(client, query=queryFrom, index=fromIndex) + + actions = [] + for i in res: + res_type = i['_type'] + fieldNames = typeFields.get(res_type) + if (fieldNames != None): + action={} + for field in i['_source']: + updatedName=fieldNames.get(field) + if (updatedName != None): + if (field == 'timestamp' and addUTC == True): + value+=" UTC" + value=i['_source'].get(field) + action[updatedName]=value + else: + action[field]=i['_source'].get(field) + i['_source']=action + + i['_index']=destIndex + i.pop('_id', None) + actions.append(i) + + bulk_res = elasticsearch.helpers.bulk(client, actions) + print "bulk response: ", bulk_res + + + +def updateAllrecordsWithUTC(client, queryFrom, fromIndex, destIndex): + + #scan indices + client.indices.refresh(index=fromIndex) + res = elasticsearch.helpers.scan(client, query=queryFrom, index=fromIndex) + + actions = [] + for i in res: + print i + i['_index']=destIndex + i['_source']['TIMESTAMP']+=" UTC" + actions.append(i) + + bulk_res = elasticsearch.helpers.bulk(client, actions) + print "bulk response: ", bulk_res + + +def printQueryResults(client, myQuery, indexName): + client.indices.refresh(index=indexName) + res = elasticsearch.helpers.scan(client, query=myQuery, index=indexName) + for i in res: + print i + +def main(): + print "start script for changing fields" + print "=================================" + + # initialize es + es = Elasticsearch([getGlobalVar('host')]) + + try: + mapping=readFileToJson(getGlobalVar('mappingFileName')) + res = createIndex(es, getGlobalVar('tempIndexName'), mapping) + if (res != 0): + print "script results in error" + sys.exit(1) + + print "scan audit index and manipulate data" + print "====================================" + + print "start time: ", datetime.now().time() + updateFieldNames(es, getGlobalVar('matchAllQuery'), getGlobalVar('origIndexName'), getGlobalVar('tempIndexName'), getGlobalVar('addUTC')) + + print "re-create original index" + print "=========================" + res = createIndex(es, getGlobalVar('origIndexName'), mapping) + if (res != 0): + print "script results in error" + sys.exit(1) + + print "copy data from temp index to original" + print "=======================================" + res = copyIndex(es, getGlobalVar('tempIndexName'), getGlobalVar('origIndexName')) + if (res != 0): + print "script results in error" + sys.exit(1) + + print "delete temp index" + print "==================" + res = deleteIndex(es, getGlobalVar('tempIndexName')) + if (res != 0): + print "script results in error" + sys.exit(1) + + + print "end time: ", datetime.now().time() + + except Exception, error: + print "An exception was thrown!" + print str(error) + return 2 + + +if __name__ == "__main__": + main() + + + + + diff --git a/asdctool/src/main/resources/es-resources/config_properties.py b/asdctool/src/main/resources/es-resources/config_properties.py new file mode 100644 index 0000000000..d0973001dc --- /dev/null +++ b/asdctool/src/main/resources/es-resources/config_properties.py @@ -0,0 +1,11 @@ +globalVars={ + "host": "127.0.0.1", + "origIndexName": "temp_audit", + "tempIndexName": "temp_audit2", + "addUTC": False, + "mappingFileName": "auditMappings.txt", + "matchAllQuery":{"query": {"match_all": {}}} +} + +def getGlobalVar(propertyName): + return globalVars.get(propertyName) \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/file_utils.py b/asdctool/src/main/resources/es-resources/file_utils.py new file mode 100644 index 0000000000..743902084e --- /dev/null +++ b/asdctool/src/main/resources/es-resources/file_utils.py @@ -0,0 +1,21 @@ +import itertools +import string +import json +from datetime import datetime +from elasticsearch import Elasticsearch +import elasticsearch +import elasticsearch.helpers +from elasticsearch.client import IndicesClient +import sys, os + +def readFileToJson(fileName): + print "read file ", fileName + fo=open(fileName) + try: + json_mapping=json.load(fo) + fo.close() + except ValueError: + print "error in reading file " , fileName + fo.close() + raise + return json_mapping diff --git a/asdctool/src/main/resources/es-resources/get-pip.py b/asdctool/src/main/resources/es-resources/get-pip.py new file mode 100644 index 0000000000..30a6cd7f4c --- /dev/null +++ b/asdctool/src/main/resources/es-resources/get-pip.py @@ -0,0 +1,17759 @@ +#!/usr/bin/env python +# +# Hi There! +# You may be wondering what this giant blob of binary data here is, you might +# even be worried that we're up to something nefarious (good for you for being +# paranoid!). This is a base85 encoding of a zip file, this zip file contains +# an entire copy of pip. +# +# Pip is a thing that installs packages, pip itself is a package that someone +# might want to install, especially if they're looking to run this get-pip.py +# script. Pip has a lot of code to deal with the security of installing +# packages, various edge cases on various platforms, and other such sort of +# "tribal knowledge" that has been encoded in its code base. Because of this +# we basically include an entire copy of pip inside this blob. We do this +# because the alternatives are attempt to implement a "minipip" that probably +# doesn't do things correctly and has weird edge cases, or compress pip itself +# down into a single file. +# +# If you're wondering how this is created, it is using an invoke task located +# in tasks/generate.py called "installer". It can be invoked by using +# ``invoke generate.installer``. + +import os.path +import pkgutil +import shutil +import sys +import struct +import tempfile + +# Useful for very coarse version differentiation. +PY2 = sys.version_info[0] == 2 +PY3 = sys.version_info[0] == 3 + +if PY3: + iterbytes = iter +else: + def iterbytes(buf): + return (ord(byte) for byte in buf) + +try: + from base64 import b85decode +except ImportError: + _b85alphabet = (b"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" + b"abcdefghijklmnopqrstuvwxyz!#$%&()*+-;<=>?@^_`{|}~") + + def b85decode(b): + _b85dec = [None] * 256 + for i, c in enumerate(iterbytes(_b85alphabet)): + _b85dec[c] = i + + padding = (-len(b)) % 5 + b = b + b'~' * padding + out = [] + packI = struct.Struct('!I').pack + for i in range(0, len(b), 5): + chunk = b[i:i + 5] + acc = 0 + try: + for c in iterbytes(chunk): + acc = acc * 85 + _b85dec[c] + except TypeError: + for j, c in enumerate(iterbytes(chunk)): + if _b85dec[c] is None: + raise ValueError( + 'bad base85 character at position %d' % (i + j) + ) + raise + try: + out.append(packI(acc)) + except struct.error: + raise ValueError('base85 overflow in hunk starting at byte %d' + % i) + + result = b''.join(out) + if padding: + result = result[:-padding] + return result + + +def bootstrap(tmpdir=None): + # Import pip so we can use it to install pip and maybe setuptools too + import pip + from pip.commands.install import InstallCommand + + # Wrapper to provide default certificate with the lowest priority + class CertInstallCommand(InstallCommand): + def parse_args(self, args): + # If cert isn't specified in config or environment, we provide our + # own certificate through defaults. + # This allows user to specify custom cert anywhere one likes: + # config, environment variable or argv. + if not self.parser.get_default_values().cert: + self.parser.defaults["cert"] = cert_path # calculated below + return super(CertInstallCommand, self).parse_args(args) + + pip.commands_dict["install"] = CertInstallCommand + + # We always want to install pip + packages = ["pip"] + + # Check if the user has requested us not to install setuptools + if "--no-setuptools" in sys.argv or os.environ.get("PIP_NO_SETUPTOOLS"): + args = [x for x in sys.argv[1:] if x != "--no-setuptools"] + else: + args = sys.argv[1:] + + # We want to see if setuptools is available before attempting to + # install it + try: + import setuptools # noqa + except ImportError: + packages += ["setuptools"] + + # Check if the user has requested us not to install wheel + if "--no-wheel" in args or os.environ.get("PIP_NO_WHEEL"): + args = [x for x in args if x != "--no-wheel"] + else: + # We want to see if wheel is available before attempting to install it. + try: + import wheel # noqa + except ImportError: + args += ["wheel"] + + delete_tmpdir = False + try: + # Create a temporary directory to act as a working directory if we were + # not given one. + if tmpdir is None: + tmpdir = tempfile.mkdtemp() + delete_tmpdir = True + + # We need to extract the SSL certificates from requests so that they + # can be passed to --cert + cert_path = os.path.join(tmpdir, "cacert.pem") + with open(cert_path, "wb") as cert: + cert.write(pkgutil.get_data("pip._vendor.requests", "cacert.pem")) + + # Execute the included pip and use it to install the latest pip and + # setuptools from PyPI + sys.exit(pip.main(["install", "--upgrade"] + packages + args)) + finally: + # Remove our temporary directory + if delete_tmpdir and tmpdir: + shutil.rmtree(tmpdir, ignore_errors=True) + + +def main(): + tmpdir = None + try: + # Create a temporary working directory + tmpdir = tempfile.mkdtemp() + + # Unpack the zipfile into the temporary directory + pip_zip = os.path.join(tmpdir, "pip.zip") + with open(pip_zip, "wb") as fp: + fp.write(b85decode(DATA.replace(b"\n", b""))) + + # Add the zipfile to sys.path so that we can import it + sys.path.insert(0, pip_zip) + + # Run the bootstrap + bootstrap(tmpdir=tmpdir) + finally: + # Clean up our temporary working directory + if tmpdir: + shutil.rmtree(tmpdir, ignore_errors=True) + + +DATA = b""" +P)h>@6aWAK2mtey7Dt5400EW_006Ei000jF003}la4%n9X>MtBUtcb8d7WBuZ`-yK|KFd2brwikWo_B +;u!rn<*pQ}JfvyeG_Vod&A;=bObCD&Dl#;mHzWcj7k|JfvSvC!;CGmK7Jl_3ycgo4LuUaL)T8i>3Uf! +{K-)yULvX<43rRlnDTFKLtiCtaEhGk1t6>Y;){XChN_eHhYh;m~eE7jfAO`S=_?el#mOCVI;OttT5C7 +)=ywWt&Ru;O(is#00muS(TqMUmmlODQWEvx{oC%gWq5U5T3R9Fw*YMK^!Ln^b5XJWq3>8Yz}7iHK>im +euCS+?>~vuSm3`xLY~iqKVm#%T+5yR>VxT%R4R=kjHG9ea7%&OvOsdBN9NTQurtUeqruxyzb{dn;XOOY|12T6iY~H_KCECyGp_mh|{!`wT`}HI6L3<7HmSMDpK +St{Rop+3GgiaFw*OD8%yHkxdIH3@+F@4yNJPdge#%1o0%AOeQBRQ%Y>g9WNWUt|VI**)9J!Ybv(nY@5 +~f9*N#>g<@;*z!l3_4crO=YisuGe#=WE4S2FUk%8apXYkt@aA)_NW#C*VOq8O5{SgW&n=Qv>v0at71& +`U(F0?blF0b@zrVNBjT!IpJ$Ox>%Kr;@T1iRXxviFs|W#B?Jm&G0=0sjo#TQn`XO=7*A4Bl~`xLY_MBV(C;pV+8Q)}jEnw2$Ew_O+6H8Z(F;zNzGXKJE(W2svM~tZgdrzPjKI52JH +(p6PUI;+$5hjl&ET-lEf>rn?L*V}?y&g>Ht5h#S5Tjlu}++`dPZOo;BX%$5ab%RN(7D_6MWs^qL%lPF +KR+VY}cY9&PtY(t3ZEdzx +gxNc>BxM>&y3-0XZP9TqOYDLRO`=8(tE8M3(fp0td~}$sFBHfK1YlZ?9jx3l@p03(#?apptr%_ra8NT;Gpe>Uj$jiH;T0$+=Y=A +b%+D +bP9#hMm;|(g*i-zR1>mQ3;Bx}M1K;T}9B0brb2Htsr&aC2D;~gS&Z47Y0c$a +tN%lw^rM3HVnK*5aOZ~P{K*RoOfqS=PQEQtErI^mr|*sEBf`3;kzy6-G+FH{s&w!U^Gj|gd@X;l{c`F +q*&0}afga7uE^_rAKtDx%fcF&oq-gdik`ta^(|@Hi^-&@$-je}ZxWxFnr~xa)cYy6G`n;}$I8M90Hy0 +J42cuHD3;TE49wA;YVdh%HDQ4aR-v8i^y^Fh5PXIdGMQw}Tc4p2Nn6@PKDt3co3CUAYOP7)g>clN&Wu +#I6ZQ`jMaLAWby;6g@qK#g6aOnnYj_v1juxEl%EjxVpN&eD^N>`SSJEV&a97K1x~DLdqcdov2y`5k$e +Y7QDj&eGq4N8RT|&U>!y?&c(G73_ci)59UDxs71?q=((B0>czl(XuXG+-9{l`fEf!!EKSp>18&+h8;XI19tvO-r(V7&{)XhR9Mm07?waf}%B5DOAw(hpG{yfNuh9zQdRIXEdeH|`vsONpTZ41gji!<_ +Nlydpv8upP5mBX%6Jnfbqhm<2Y4huhfVzX|tILQd@)_Ftai2)qfD!s>wm?ekl58K +j_1VK;6U%=!wahTPG%Q-4mvRU71IlT=3EjM>u%qr2^JOhf>D%qkfh1Ap}?*Jqpf&j`#0uwBKfYm1<}lrnp@c{LY4M8lD(EE$o<)jo?TU=h!E)V%G+?6m?G=W3zU2JGi~029`0QY2 +#I`WG`F~pMA8SA&^QRKHXqy+LyQh?{)Ix5|X})pWeTE`{tdK-L*c!?*R97i4#t9of=K!G0xov>+GhLT +0xJpV{6*r3X7y>3rF#0%XAA@nZwU1XkgDuNj04f!hUOYGSasjID$n&ca-^kF8jF!`_k}g0CrqTgJILl +>+84I=WrNLAs~QufOn4eQM|LQfMY#?E^b5XPxAvWwo5ZfoQ(lf(39JBB=m9O3%uqpE)& +iA;4Be27vWaR-bu!txHJ!{t;HoU-_y5e>a=E#%~#LWT$DUc(IO|-XN$tW5#pQpmWEhKFn70F!B%@CnN +@3JHYJ*fCapVfBUa3Qy8rN-d8l68-aJ8V>yb7o8CT%sggt +x4o~TCfWNT5FWUA*~Lt4*ub?(p&^cq}`lKvf;*f3QZ=@Po{jRLZ8{PP7!b!kwixs?9WGvuO}7(*s-Go +8=Dec<2ubP=;pgM|f`4=@AMn=_hA2^+El_k~H{cbc5a?{$A1Z!tq0^3uv^TbMLeL*11Y*+9er)`bBK2SZ=M4?u3-_$LG;@W9-o +4qJAxPkVE6}%u_qTE4|rr*Xu;+P*iNnYy))-jokL +_E<>#kOk1LOtA1C7r(LC=kGAv=D`)+6BERWm7u?l`aRevJBxVZcarjKM5jy1w=aH@VhRVRG2nVSaNQC +)ohKOSVD@$o?fBoL)DqVbP~c)7PWt1pz!-D+83TAe7W{EDhE$zy@j?2@P+p(fW8uD-)G!(RQ;Jo +xa*Q)S2yfc3lX+tL7NbPX@O5j4F#4!HT9nzQTr*?ebLnXr9oHuQDp|X_x}MtB6LPlNBO;hh9ZachS)9m2Y!fHTg19=I-g)>-5)UZy*_y +g#11e(nC2o%NFCruN3-zSHly^kvv&4T)DAYEvR0g_9P5B)m%Bk#ZkBv#&T8)v!gq=!%TaNnmBwC!^Py +mm5=^JNe<-@X_TBwIZv^)H;@Wb1=4di?Plpn;|NU2C%)Ny8rJE~ +SiK$#S29>XbnQuoOn|gWaxXKSuO9KQH000080P~d=N1nacs-_D70C_0@01^NI0B~t=FJfVHWn*t`ZDD +R?E^v9x8f$OcIP!ab1))V?Y2mutI~;HbVC=O?x@&Ce1bMW32ns^BXq#JE^pcbl-=hEhX86#PN?P1LP9 +GA9oEZ-1J*1;3dXp+fPQ`Yc78zOQsZwKtuaf1dX7FE>niot(QFOGDVoNApmAaISQo^@8AvH-CO5~+x) +P5fwx$#`A*SuK!PoeyqI#jP>r+2AT%zrbB-LRC|fTr5*F=hxSl*TBpCr}^cFId +z}!XVFIM&y{pUhi=-wrIHZq=UBdS_0fB{UPpRrddWe06}d$0( +`Tb4iv8G*~a(IH2B3*a!eY~Nu0IWUef;gWm6Vej?Hg|_il~h!^Nhguh +>NsD3!*n%xo@(DY_O|PVbBavXIZELyP{D;we!g`-EnQ)FHYM0LQqF3qH+05FtH?lK+17rQ{(n}tu4F; +mi2~#!xv1Zxo5wEfN{S}okk|x^b>PBq=spvtBs=QfU +wF(hRzIa5<~*)h?4%fJWCSHqVaF6_0=ZJnK^5N)P$FG01VWGvJK|4)7qyokLh3@)S|&_}e0j}B +jv9ynp(B6X~(B-NIt-=O=Cl&V(+{AokM((+3DF+{G+b3-@ +{gTdrsi)ySH+er}kWsc!P$Q2Iu!*!l?zcN#Sr&oJMA8yIp_*`235RBlSB;Q@ +xP&ar=DGQHX2OV3;rE;xYz`@r>MEQoS(xnzCY1AC@rx{du3!Za*=##HQUW2lsS+BWGc@bW%igq{-d#d +U62z7J~g(&M7XLpuNr{vX1Pmej36ZN#!N6a&jXKJ>N*6h!?2#)pK57e8^o2k*6s>r!?QFo;p +x?^Nj8WhG1)&UNoWNYvE5Rr4(#H$jT3noTz9J3Jj_lAF#G(kGq^Np+YyJQG=)^Ku7n-v4J!7m-9TTz`@Yo=B6$Nrrk!m)E7+#ID8u +uFC)~=5tqOmCo#zR^3M*@ne!aDF-OpY +_20|aqzi=ESTbWw&gsAlm)a13QM|8x@W`~l9f+~m?r@02b$T0+-{gMl^b#7rr+!7>uiA2tlYlz{RX>dUh5eTyh1s9_;fY?CH!9oJbKi-3NH3Fn;td4_+&4rZ5fMl+no3|O! +N>pq}eTh#CZBB?2B#=h?Q_#~#yWSx?!`vme9K7ruUZ+=lF=0L=-*3c$$2vw5?Rp2Y0n?ez-@V%5djQ+ +jDdV`D4;et1i!rPUf&n**t=?gx3@d8M^@FZSX5@5j!?3)$DAB;lbkEZy*^Bg9i&^L#pefdSW>6F+D0^ +*9tNx)e{$E$6qR>yaHd3Je1v^?N})S8)I3DmfQc#N)uXZm$_zO?6A-#75BEV$la`y!bV()3F}OsEMf_ +FO`b1z#JHXO{LPC~x0VwS`>MxF223uIT)d&gNHlx1*1EDE4X;BxUMmMWL^P&!_2~|2(_7y`is9Z)cZt +OO%Y-r!p;SVOw$M^k|IxlTH|!tw3uyfnB)+%!oOXMiN|`J{1ylo*&QvRsupxw?)F*a_IggP6Ex32|bg +gbhmv5HjKjchHT~ZNL$^IWNgf{^ZKsH5E(d&rk}+GUK9$Ei~y}z0~lrT?9xJI- +n5WzqdKDmto;6DguE5<~!YHN3T%X#Q@YfCv;F5Ta@c~bnb85fHhmYpjV8>NS)%)6pNjPVjBDo-3xVh5 +P#vl9jWj7lK+bh26xlEK>Q*uM~2J^-jSG9|5R>&VuyuDB?Nq^17*3>&+vM=W73{{EzxjuD3r+JV2;N| +e65SRk5|1qlxCfRy&>m57zOCQtV%&#|QJ`hVPP`u(v@@9NR +Sn&uf}^MRBL-Gr=TU1Tz0#vY-1v3Gfac!CMn-E6gQH3sW0Pk#`=-w%8@4B~G^wvZnGG47r!C&r~6BYl +?f>4_$G;7RW!)!k)R_pXiWaeoEtBgu(H{uf49zT7gXMQjE&2e4vSqE?%i=^!l~cfM_sXQoYC +UcXV_UjoQeinYmop8;;cqWtDC?7>uOZc2 +yZ?iY30BAybs3f=kQ>_;xxT0OI`ac`E3yG$4~XTNVl2G>s;tep#&GpV3B%JL7D#X+vp*A{`(=Hz*cb~ +V{Y5f`N*rYa(VC*Ow0_-TA;MnT^u0gWO`q|~o(F!7r~+OYk_m=~|IvM22V}0N@Eosa!#LPmyThORk-~ +5O*CY7vb2p)T$|x}O=TEA?$*sccz?( +cv!Sqf-)yg{nzrzjXU6BT`*jL7j2oH>F*5sZm}pZ5CPddo?t+zwx`eWe(NcK`ya#h@6oTgP7kRpSwEj +o9CFG;v+k=#FAyU@1BJFHlPZ1QY-O00;o{l@>?ZFvLBk3;+P(C;$Kv0001RX>c!MVRL10VRCb2axQRr +omy>g+_(|`?q5Ny5lBkc>LrJMG3rCpyxbWmF2SMc7snO25_gxiBnl+8>%F4?y)%4~NJ(ouX9Ui!G#t( +h=jEB9SF6?EsbWNQnv0fnR4OKkV!H2EtJTF;iiQ-$w%5I6ML~Ge38@L)C{g#C754kZg?p|}%6|lghS~ +6acq4~rnmy{Hq@CTS;!5|L*DA-~ek-M=78@bz3rp4UE-wzOt%S@Ke+>tGn(b(LD(sqK%WJlF42liduB8n;kbT>t1btgESsb|3J*`=LSQ{3KgRuez>LMGrH +A)Yr?YfFfwI(~J3(aK1TUr;2|IRKhE(&1CrD%&zvMqlsBqKLq&%6{(2V7IR`uCUHFU4w&4{tMAQPxx` +@|nhR`Qs>$8yCkkGaw4bv2MQu)Qe<{FnZj`*4o$W=AN<*C}c)UzhFXm|K2TN9S=u1T6) +ZBewVE2|vnJK^UPy7pT-vpZ?vVA+Azy^)tHPfcEV@&)lgK@iWWDdeI}kPN)(?tavddqd=fQ3%gLjTZH +*a!3`B-qJZO_+hrh4Q=v5W&`Pz7vwY~QW^P)yjkGGTS%!oedGNhThdF@2c`-%Cqzxm#2f#{)A|QCzu* +&ycMZAv2uUnEtH|tp{E9#z7b;1T|3`4A)-3Awj8<^|&imcBKxoj)JtQ|bB>8M)R7tGWu+wyJzw}Qex& +GEBv)y||cg*c=KA#D#kFA0VP4u3@Z?1@F>l6H9q-DpN!~YwmkBqgJiHR(rC0i&p+6xh?G%#uf3G!>cx +Ot;McanT-zasN%@=Ad!V0n{+Tw+BbRO%}}oFP6+Pb~T{$`P--BuX@ +lRH7WR7bBm>K*wOfu>S+0gHkWqu>BiPg*65BcxP| +qlCs;o3aiP0R{cg@Ld8HsMy+5bsd}5bd3iBmEGC%M!Crq830hkj$wWjrOtAXau56ATIF8`(_C$-`o2_VB +5OR#m+BGKe2c9MY=16Jf?%AaG#HsA3+?!HaoppZ=|rq67NVU>(N|y{G{1GnR>M@H0boJ^lt7w?<(!mv +!&lSJ-fH_}obsT1A=|4^=>(ch_SmV^ncuGS_pOaTK_VMi9qCW^>(va`c^9q^5Isnniv*_Bif&xgSEBL +nMzOeIn(al@BhO4IA6f_tMM^h-vFh5p+#Dc9BpY0eW(}fpB>J|t*z*jRn`X153oTFM;>W5OH1bYLMF1yatXLJ9SO(vaNro +ZgF^F;J4)FvZnS42PXgxBfo9aw`XE>cTtj0ufIed{a7qC|v|-k#DibxbLg&Kig?Amx%%X404m}*1G4w +F3=8{*CNRc~QTskt09}P}MWfd?A51eeN+K0#^Pzbv!2rlcNctB}_^P=~kfBkg(bMfi+A0Lz1!NOTZ91 +M$!9a?}Ni%=nKWiK(EqRntnMvlw^N7|muMC|IwD;9^*m@b?vp>0^m1t`R+3$eF5&j9Pk9%%FY{|G{nvukH$`lqbG5VzySwi#PqZa>^jMX +}R$eBN_!F=c$*nC-T+~Ord@A+>3LaCi8kli!#&femWKR^Q=7b)<^ja+l|A+InzNLL; +2R@wUOy6FsfkuaM*jeOViPyqVIf$^-YV2;qTZ#t71urZIo{kg&Obg%+|=1|OX!4u|DCwOh<%yZ42R6U +!<)g+Flk~|koGx`}2up{*$jhjlnh&9*bft}V+lj~qpEl-Py%#E8YH#@8vR*xOiW63%_Ej<51>W@+a=A +jB{;tjyjp%q=dgZ|6Vh_dVf{#T^x&8#tU0i36-p!)GSS2Ze!K(K`JO|j9z`x-!=VF5Q6Fe&DJl|>j6 +vki#26DB#=LOd8=xVH%lqC_uC!*622Ni77||L^|-wr}!Cvk0;(Xv#1SLD)3e)nY?ysF4HmnE0*(F7^x +-Ldq<|rl{t>vjV)ybyorKa2uxX|13KbTbJZ*ehzAWN7;)deo{bx`Gn*6G|NI!-hl%*J+jByepj8%7D>_pj#dxSre*hSbnx@Q4!gsCdp(yGnD25RXs@h`!i!!{b +pdE*-`*pt#A=6;4*=~*TRjXUAn8Iq!ViFB@e41}rzXrwH`UCi=5YFfX!9w?912hOXXwf7qp!PAm +xv}52h)(fqDf(6~Oe+TUxwq9OImZxwyBXEIq+5zR+q*=?CoVggalZp<2TSf>B2@{ +;u%YF{f?PvX;26T++~DQNTtIk<*LdTtigP@7w|7=0UjjvYz%h$0f^OZU5c;1>^2wA7`oIdS$BYEKu7J +7IurQCoJ`2*=PHkb0djYG0j2>tm5)X$FDqwT@LQ@!@%@S(&`RJKLM9o-WYEJO91g~ +yDzvMg=eT0Jr)pro0FuJLP>9N}p`EJX#|d8i2!+fCn$`~yf9_bz%)PsHKrCl7xa5$6ZF7kE+nGSEsap +iIlSRA$W|;qlPOcc0<=)iyxd)s$t1FT&E$cVwYGotX-(82<#M{G#tj*0!7WwRkNoI5@NCS!4&N$sHbH +w~~i-RWK;)F?a>JB~v`SHNC6H4(7w)(TSBO{gY_ae}fLKYD6A)h$SfK59o0Jy7(GE+46xvtiDR#(_$J +pgR~3)!$eJ#fJN`I3u0122aqg9ThVU%mqI-@s|R698ZntG$e|rN=-1FL3aP!1Wx;o4Jff$v1-xW-NEM +n1j){vL^&7$gNpNfBv@MW#3=^&()}fo_MIHZq50tA$JOs12DH)*ao{))TrHb(rx->|F;m(^(tM#ib-K +Jt?=75S>bgpHq6NA;{Q-f0|XQR000O8^OY7yRWz-g0}ucJZ8-n{5dZ)HaA|NaV{K$_aCB*JZgVbhdCe +RBZyUGucl{N_1;a^&bm=w}!;E^EYr9FXG%;eQE0zWa>O@JLPj}bjogHo1|GxJ@-jOF+a^e+0SC73RTOz!`IyF3}`MIRTsGbl-M)tvdtGo+>9z|ka|X(h?^3K5*e)2rcp%$;Cb# +52Va(Do|pGPH3(v%j9wMVXcU1Mmvy-jX}WBiwpM8>^rkB7M##A-^R`hbe;+a2vMsWvEOX<)fPN5H&a< +!~@#7}n5&y2#A%c +7~vd@7ckCe4~WU4w*jm2Q9!nWySgmbVMlPZwo6*M+RNQ$pnpw??J+Yo+o@zjcJp#7-d|t7OV7{FUtXpcuij0Csk5}I!MZ+;MkBB?v5~hbWeuccmg5!6fh1H7tJ +*_W9p=l@n&Ljbf`h}lel=GzU}eM355=&WJuiwn6?G1*CMH6M#xwKcS!cct}3ucs>-4Jh$R7N9JtyF6TR(WUj<&?*IwK$BGtX>LmY3Bn;r{t +cNj4cS5bU;h8tkh0)fctD^Y=I`0uxzce+mzx*o~QFx=Zlnshoft1VeHq_H)WxEE4a``&LLJ2a)Z=Ys- +77TM3q!q2qT_9L)a5A1OAJPPe3hl<0el8#y-{>YqyUnrD&@K#tVO4Koqa`7SQa}3DdMym20p);8?bKg +CGOdnk29$y$m5wU*! +5vM;l^wBXPi|u$L!H1ccDWjcCo@Pzfa640SATAmv_+i`)JqG}mLI;6ERt#<|iKlqbWVgAxQ~Bwi(B_}@|3=R`i+L7|kJc)$Qjmx}B$yMnO^(9xYz?^M*$g +4$snxk@PGfJt9jo3Demsq@*KnZW$0P=lG(-k4?nSyO7wXWa5in?BBX7$nKoA9cN2V#^aBS*UbxX(tPQ +RDAQ65pfwxV}!K}Wo%xbCnE#10;{D#{wQsERvXm&FE7ZE+`SjZuJ;nHHTl>hXb@EcL3b>0nBDVlo{8> +$Uo&)j%I$!ov?x9^(I*K+4J@-=bxMt~JO@iheOA^qOigW~l3!|jN~sZY8gUjfCa<}eYzFcAb9kl>Geo&dqHjT0bJk(a +9@ehLs6mg&Q6sdMGN!FkA&p8xjWH*hY1FP%n}Y}S!SM|1@Ps1zxjC2_Kjo(Su~tC%jxAK|3SbdyrdGl +%`@pS5nlX)*31Pj-nzp}^5>REF8u`4h6_KxVuokndi7A*}Bx3@`ic9oPLN68o$Q>-Q)k}@kbvuGyTCE8(a_d6P=^% +(7--_Va<}KnPa(!XDHviba8AZ_qxf}Q!&;P%r+rI8Q)KIg@5N0NavxnM28<`sy^oK2ol(UH}H_c2UjL +xOhD>`DBPXQIo)|RN}QjGd5d>CL}dnrX91PdBWNYaJtX%Sj!=%(<74T)zJ4tjvp~#xsWTuRl0ji0sep +;7rgnfab5&w$l8~6HSM47` +orTdp(d1-oYhCZ>n730zX23Cn2AL6?iILZJRaN>J^xoTq*I2F7tL`HOFY{{7o&>j*uhnPhJfReC~GqI +zVXlIb6@)K?mLE&CK#8Zh|};WV*84(x!@UTnuTDiv$n|40$R^_~<|xQ1-Mq9L-(kwHO3sxAsdjulN$0s`({NBJy!SfcW +e7)1C!HVVjhb_tfEvbOg5={>(Kj9jY6`h8nKl><2j+EG91Hh3T!_=|ow@qoR-Pkrr;YbPwcOtqBrBa7 +VjMsmnTSfr1&kb&@q7BZNAqJ@lhN&jQ=4PKf+bz;(mLS?8T+wuW=ga^B9)-U5DIbh`>++Q35FAGvfL$ +CFO8#4`1b-x3jxrrC+@Rb{qE)8|((G(-&6r*3VlVW(-o}6RgK|f3~;&ZowyHzld6S_KJrO}c-8Yo#vy +l0yD24kdsTJx_x>(%3%~6pk7Kwx3 +Ei2pw(36FM`Qh_DdFi;52;E3x3jk(+Zew~tf|@=7fzbOf_hW=Fd%#Jwz&qozBKT;+;_Y%%i`V6-Qv7& ++EvO=ybdk~2*^z1lAXr?cZ0k(r* +32mS4$;?@=+rLbxlZhrxLp%aA}%gLIOk_Kmlw$VQr>}0^ZPn*#?ScVIWF9!E7hc71Hc$k*B0-MIcoK- +A1@T-zaj*-tv`wDqZl+igs2h}Ww*2KgX-H07>IyVIA^AURu3AH=mHT1bJ}gf^U2=5aLK{Ot3IUK-P{I +A--y+Z;Z1`b9rEE#{oXk7NZZGsI!u^B1nnhrJBc(5BKo^Pl}35pm~bMb7>#1pjlu` +f`%uY2l~ZjXm6ls%P5TOiT>B`#JU6oLpHeC3j0&~AD}6=7HA;QcN@G!T4HmUaw;u=YZRp0i}VYPsy@r +hzV~+6dWoB|8oI&zTgSfYULC>0IBcoqp2OpQC=rWVMFqdiuOI^>eCCpZnM#Z2cTf67e38bs>F-&~I3# +A4YVLJ}M7r$N)XtY|EC;X1<+~4y*lXM}Vq-guxnd$}*~zd+&2UouFB=)Uea|h@OLn+(6ACnkQ=6)~=p +d4yig&G38fk>B6lu1FL%C7$a@2bZ=*fr4#m9I48B?R`4gQh|PHRd_q$pJ1>>1eolDm*0^Spzjp3Wn@yKrX*82 +^TKPL|$3F_Y+?i3_j(x7W?s$Xt(PelNEsZHxct>ad#s#c`Gw%xFPi*FL64wYKhiEAji$`FCJJJ32Ta| +Hi8OY0H0^I{F#QiHKj=pJ2TWJf?G?6Y(KPN7Ft#4I0P$;oYw6e$IBE1_P#(82+O++x}}_u7WSa*3f>^ +wPE%n)VAo;MGb@ffNiDQ$<47}tsi`#>#GL{8mT<&-h-l7FsR!9*0<*PHHA&K0^VrUBlRKYV~~%d|G9p +d2h<*Rs60aXT}O$}dC+Py(8a@6aWAK2mt +ey7DocJ&cxFq006*z000jF003}la4%$UcW!KNVPr0FdF?&@bK5qSzx%JiD&ry5%8b)?Z)V-`?xktE^< +A1|;`C$3^)a*vNvtVSOOUqJH21gP`v5=yq-3W%H#@U;noc8;z{A7C!}|ujXzH~{(?!>IjZ9NftT%Pji +tI|&W!K7-e;*v^=ksM@zRGo0lu6eXr819JnOc>_mHD}p?Iu(9?JugX%=fZhE{keuey)qPY_}U}+t&8m +rp($!-K@>;Mw)MGg@fB)Tid0T>&>Dl<-tMQY)=jZd`u%%3h_u(_1`mk{O!~8^zDmtaVp+6ojj0tbGd2 +788v?1G<9vv1FSc%DB0>Fx8E=Vz~8o=<}bBnS}L1lYsOWxkSgJ$QXv$tLWf+0-;Is$5oW3Qxm^U18dM4S>oz +%U?J3vH{G#%3zA&!}Cp1dBc_UJoDD=wgDQaup|=xS!d0)Y=|Izmz%k53||L46|fLc2$*chdFFMJ<=Li +{jfMGDrsPw81}yXT?Q8vGABe79neI>FJA&Z8@U58RqdmQS27Dvc2FNk8S8NB>Hr*V>mhJQm1_Xwel`7 +ieMt)t)+dch}$+BhNn|Ijf!yfYt`J}GerY`%T;Mp^Nwv#e$NB&_4`v%sMU<`W!FI?kNo2D<|H*MWLa> +KN}TbIpdp3chx81>-bAWdyyEcIdzo2JvnpW8w)Y}xA<#Hi9 +1=|VMzG~wsi}=Z8LjS&zz)_XR1aKGb{6=no!Jr}jXjhWD3hJ789rLWsVC?r6=}Ez&S2mLq@qU5`z?TU +u-()5xH?Y-Uzrzz+&s6_T(+~Z$C!1}%;x<|dCj7*-j;Bsz;DA!D0WT6HIHo5%4FVx3zncqDWAfpEHRy +t-coB|sdBKn`#p$Vtp1mfh(TRn!tCJxB^xHi>f+EX@jSV_$>kJH?K-dGw&DK)4s1`K{fKq~>DCLbTsp +F!kveM~^pFuZ3a}?ag$>*20CkQb4JK=m3!6wNh`K2zZ*cVj;jdPit*`P- ++?|NKizk=9q4R68iS=Y1Spi>*d~!MK5v5^M8mqYKcmq2-csjLTL9@;OF>C;Wi;R!P)f}m{YjB_(Ht}} +`Q;6WsiTwD*?ZOR$PPB~thC1=r`xhwBn%kn9Ohs1ZJ>u(3<9%^_8Hy}tkY0MfIu}0$;(H8MFEe{&$nc +D({xFG>Ehwa{E8BR&O#uA+57VC2haiT)wMhF2=(>kLfCV!g0cN)t)-EMPl;b+$n}fx-5K!q>dNJ_xNc>f{WXe>s1zS_#2B|x6GOH~(^;a^ +_0p7fk=<5{V@7kWa{iz-^;onI^4q-g`cOdYS>BZ5LOLwqyJs2P%>IHo@UTs_3H!coiL+fdbOcRYjoG9 +aTaq{F+d@5o_Z8nAP`o(7_mmU$mN533KQ@|end;zHp955+X*^MM++O7(vXKx{(9f&Lp>#mm#HM_TrXn +-0_MEtU@pfUb`>LK#{u5Ge;>tSG*0hG8Q5$r~TQw2aY;;z6nC<(w8$MHqyK7@fnsWX1;EwF>FI|$Il0 +P+WdHAmE}wM?x^?CR!TYoBBnJR}N~c!;oriD51Pi{o73Miu0MA}jHVnOKS22c7|J&nJ!DDNQC0edzZT +_mH<@Pumt`9QX*Uy1qs(Ucv0ZU;Ex}D@ +|c;p*VdVV2BbU195SC5BJ-*r=pMl71gE#S^B*Jbg01U5Qiezkv+b4E9+=$qW_I2ug&fh6A#~hckaXy2 +@fv_0}c(_IMT<-f?#)hv$%hgqcvZt4hGO63qn#`DKvw+DVFHHVS`G}(E>)?L0#6jqV5`;qQ}XO?rCJF +p(vU|B@<`!!9wdn{fA9~W%fu^u)Mahh99NH(7OJHnOqr{c5YWB)aqZ4TrfuuadH4}wDLw^jr-H +fZ)E>J-hZbBc&!Vg#Oqf_;G07sp==o4`(nSI~V=_-0+_#iAgM;N-isM*>cUj0t5JE?wj5%#b&h>y}*r +50sWBDdxEVoK1NpOAJ)d<9@!t#Ozu(erE}ZB#zC--7t?Q$eA5us6|Zzy{)WRe&`J_ND>|Msvy=S-~60_DKt}6#SsPXh70}@D%H8OW +@E*xk7UalUN0sJh1AR`$6-k4>0d?IX^)eJ!=1{ZUchGn-d$G)5O9EdwYr(Gh;Xz;Hi$xg^W#{eh$b!z +?f)2qOM_L*w+p$APr{Ma&fiot)zL^G^o+#ot$^%7h@n?oGnBFgsPm;7Lk=HT7K6M{xJC{v?8QVtgtqOxCZd;z(;eE&;@Pc0=w3-6g(g9sh}Ue9jlgmiN;d04DN1 +r8K$lyTPBmCl=2DfzaQ~0TjK4We6S;45>M4;`Z +PICwzwY-FAxomiIkbP3>@O$?36 +&lTz#_-Rf-%O#uYTvFhLs(|H-MF7e4xy=-gD=Xd%UMtoxX3^EZ=%TCtU-aFJ&NUqWlIyOg_Ww&CEWNf +U(IN*uDxKow8a;Blx +=5oJ&&4v8{^H4-9hJ;hQCE{?qu~$Q;E=SWkg+tF_3)O4z{~TZ|cuT1Xih}Eeg3m9-8iCCT3{R0!g|uYwTu)tsTHZ@#$|&f_kc9%|bixsrcjZ=PXHBN7ZW#w1b`N4hk=T7i5!_0W6StJsJR56~ImaDFb;8I2G +hV5eQYoB1EuU%UWc}b|~BeXbrD%>(fTZN)~l9mnAqzrx$?O<&a1@4y)D~vc$RuKMR)!D>>m`_#)d|^a +>Uk2<+U(i^YIEb(1q2ZyNNHQQ586vM~i#urY3md9Zvq3Jj7iGSq0N$H`}ZbSe#k6oN@(q?rFmwOFxv4 +{!+u3kaa-LbmWS*KuT(VE4Rsz>(IulJl(N6bb8`o2)D_`r{=ZkQ$(5jQHuHJK%Vn8R;FX?AdbxzR->Z +Ds_|ns0&qBzH8}#Ln4Eg2mhzSbd0<)!h)E%?*)(+#hthCphD?g7_TSEsf$4=vNWi39QvOG=+qCO%-K) +?vSF2PibaiXy50S(v%6I9%zlTu4IGPN5TP4j>}uN)$R4x20{LgOwA<16c8VUJoAt&Rxj5^?6AmO$D_l +{mjReq(ly$q2(|%_n4;3vZh~OvIGM+qsEWUs90$gI{K)aQ=#}p-~v6aGRsLo7oI=aC{Z>~`iz!qCpHS +HfPQYUHP0)ye4Wv>PV8#7b(6OMEZNq~4_(4$4B&L +X1iP)6&&kW=#yw!1aRP9|=V1^ca&axUlt2W^by +x;@A|gFr)Q8;kGSc}F5D%#WLB5tC4uA!)+&iZ1kVcnUIbmmNi|Gw~o-CWX+r&?%39ub*N>}^DrY%+Am +NFux*ss{Ye8Eru+O6)3koeIw@FkgGg99)_^%cEg`XEIV$M+AhdSn5X7MQ{cR~4Sj`ba;nYZ(my9g4U| +koeUvf(&OIlnQ5LyhAUYfs9TfN@+g19BYUFz!uq**<8la&p%^D{Nu>am)JGLB%cDGZXTA_-Mp`+lRPcT2cMIt6Mpa2ZMCh8RoYWEqH0LD6t-P6A#G2sYqUjOa$otbHqN9B5-1e1bZ)8Qm`cX +o>!ypRut)F}gp^FXs=;lnh-@l-5;@3P#~YwJUEuf{X7588#%Gm2(WVgfKQ0;}JUCjxUChnNnJ0enwp{ +$}#>Ec1DS2M4|6qHG~deZ2u#aTEPlj1uEFQog?-{3&iVXmU0^7}+af_s5^a7unITm(!nrv)xz?@gbU+ +a=2E#7Y!^t5<4aHS8hy(>0Q3b +*PLLc#3jAUY@+{yvmQvo#RYGU&sFN}WXq=(}WEVe43L5T4;wjQzPf}G5?@q62rj+EfSKdaaei7I}J)c +beR(BM|qpCKV2t!BX5S{GW>SxfrNV~&kiltM1F+*y~O=g723?HN;#a>LrzTYFa_!3s?U?G= +9Lj}$f4V2uMmH**1;({|hi~7ZzR$eS3;Jb3gCV+E`wav$>I8j2mZ5_d^fn;?#%8elhDTNh+nkOi54OG +DgZ@#w82>jD#^ltq!nYVaK`sS50L?`3fb!INP93LV>x98u6V^z$Js@~Q^n%QYFiDgj`lsUt(TR}iI_X +7`8CJ^~U-kI2a0g9BlrB-q>C&&gK56KptD9fdbs6uOnG+*9V-oQH`x&_bKfBmuUAQOOJO(q5+6mxkZ@`j;e1LBiNuuHiJ?QJ2hztkyuQkEM2-d@QYql6nL{=n$B_xt3LPJotX%TMhxlE +N_H0gXT4FCdyS8ThLsoWDClakkJRL01Xu-_n`$`Av0`?5%KN;{Juf-UZ`@&DwKcvh4O`n^9RKOx1|AaE5<$bE`F{nyuJ`P>ZbS8p)Z5dRUNf`88+~&@T2wg(nZbew9o +Jx#Zdb@jgEP$xBnuuzD4$yv|@rNz9HTr{|Q@NG5R6R8YS?!NyIfw0fuKURHtOs-4pzD4P# +E&*ny?IiyD=n#R6Q&5ZaqJe1UPPMIN8BX3+`YU0Q*QU{vtXcO#)U%vxhXOS_Rm^y+jyxbBq2;zm&}>| +w4o*>^mx8lUKi7pH$MC?uViTDyDE-@w4XaH`B7^oeY1HYS9q~wP%5gv_?8 +RQhfGh5V8{39@-DaVoM_R}&H9@}s$%U7%K1gH?7)>8DlP7R +B+fDF#(fl{52P&SP8~AekV3{(wgZf?)GACei4(5~uaxM_TS!^yp5zGOaIY3sjgae2yB*NwAD_wY!Aso +CTW9Ha&0-G-OfB198D;XrDV&Jquf=933|{yL&Xe-mdZPB2A=Yo;=p%7`GYFyAX4fX$LR5;Br2*9)-@6 +BdNhRow3*#;`5L)i^EAlH>0x4RHpffY$*_+_y!Dl9nwwE +*0_b|jp_JBD(S-pMGKG4VPQNZ%H+%vorMrq9!sZ9Z*Djb8U`T#sQP}y=#;cGpZ +X9}EXoym10_{w6B!j`R_ku%7FRWoY7;(@ji+tplMhHR|8*ojWXI@i9%F8JxL>W!V$9=SAah{`&k8i06A#TF4D+jqme3@#DIG30;5Zws^3^cVArXUQc&kZ?+u5=+pg!JU*Y9bK@G=%{ +AyPY}40?f>SKJhe=a0gW2ht#(XPcJb>rb*y;+j)9^CIAlmcRm>Y-sER;$_TuiZi2xb%CP79n>d^M%(8 +AT)x{bh8nb{s(ndPW82j&AXPSCOCm?vXqd&@9X?67_md%x)#G+ikSh^Nzm8f^^;-(d<5S{rwK)ZX}+; +A8EM{KBlP?0a>DWd;j$dO+!m1q{xbL6ChO}QzsJ!L4@b +8)7Mr8U<}c5%pvlY?kCo7QRdoC5fG(98_pT7z+NQar!+(wZ3&GNF)BbI$b9`=a&LwM4s@;9H)ONeYLF +5}A^^u|-kouu0%%p+uXgtt7`%Y$Cc=mS+YszcQ^ +>sQKsm}&nbw$amY#2Rp4kS|`Any$X4Nk*Qbku0exo$2-=7A*5i7zx}2VYk6LK~UR#h$S<$-R2h%wrE@ +eyOQS>cN{RGUOPuk!?Wt$K1yuuA=WTc46(oT00;24gy-Gt0+6$GZ0%KbaiskiPh`TguyT<1#xcXtIFeLi8%IyWMobr$T+0 +t$oNED`?oH7+!89bt$32pW29aJrfX3gcScq%~+%xcHyF!M7>lCcDzO9U?~=vv@Dq+sL!9;HMZpBR?Px +Bn$|lCN3ZUY49X(elxX>;I1G2o-^2&is?~hT~r1-J-meJef79-T^`S3{{_d!z=9v%tnZJw&Odb?>p1^ +UBdJ^t8QwfJuMww?yjt@6FFY +W1k5Bna+gi1y69aXiBA^hCaJy715)?q{XLrfBw-CJ~%@C+i%oMH~7YS{7qNUr8s5*G|%vDemVlDEkWu +`T-pC=3HOTK;ICZ7JxU;BZu3(|a!{ODwK?7o=BCxHuxBjDGVCQqKhfRcDR_*hLOt#TT{0ccoJ~-gJAp +jZb-6TcdgMsBf$$F+_)=8+<~U)td)-6qKha-3c#8*Okr!j{uOKA$c`sC7v*imiU9$1Yj}Sp7wN;r#&jUKQLrw^R%YBKmvP-be10 +Y0-&@=t4GFpy-3|I`k1(k3I=#Lwy#FZmssFKM2R|{%Dj=^}qIBz~MD>29vRKCvH1JQ_~-?*53k9d|aT +vBiI0sol$NFbyD^&2|Q7{`<}kNRh0OdV1IqO{ZQ%j;ZmnmN6V#PjKremTmi@lt36RoB9`xiKP*}pqCi +K^O*7`}U8fEmhuvCLXWD@yH}HpN=k&`V8`=x*2s5l7k39l~`7_l2VI(+g(jb{FT!Ss0M^x8$I_&|>O6^;UIk_^?VgTurC^b;lpN +8Xi1&c!bn$F_Q-6O+~k;BhT3wdPk9X8wb;n3@7Q@T|ZNAPFOvP-0NmN9Wrt>(4$cg*QcE=hkH6lIqH< +46m)5ByY*}023ImO5PeFU!*~RVQq6t!kgX4J>%>Mb>d3@R))W$kh0TAPZIyQ3>Bh%FX;nnu1U34<)l0 +z+k*a4yTxC8Oc?8n5dk?%LK}WG=#2c#k2vf*lpch`_jPJvhOE>oWnn`V-|DrA&Tp_{lktO9k4L5r^`o@_5S(I`?5pU6xBCsdoCIs|7qk+QFp5J3NEw)fqBmB27}v_%(Jt +h%$a#(tdK?B(O<{Vr>+#Ay(UM`ron8O%Aheuci(6GxazbZ^~y=UK?Y{Vsuhu>3?ro^{}Re!4k~^_q{! +4*T?$tMd1JfmHZKhocI|;jfl%0QheC&CDKdo;mje#`zpim6TP-PbQJOspY0S^S+3K;!& +_?zL?dliJY+ReT;@^EtDiBSVU2cQ{;*?_%*Q=J89W<~={Ei!P)h>@6aWAK2mtey7Dw4?P5ssZ008L(0 +00pH003}la4%(eV`Xr3X>V?GE^v9JludKfFc60C{uMjEv>cKjz>UxrIKX5&0~|9OYaQ<(OJ-LJOA(_D&%x83>*Dc<6i#Fktfy4^-E6)r#+7w`*gFLc1MsKX?g%d-XO3+D-3 +ORW%k>Vavn4h?m>n^jEJdNKayIPzeSefR=CBU{QW>8qiwI=M!RKoeA&Ak)S;Tz(iqp04~HO^t0pt!AA +ES_>MIQ?_)myk1W)a3#I+z`B)#=(i +TN&D(}Tf9G0qc5csBvqG|G?x$+BVg*JJBWk>5Wiw$Y`LP_A=8!Lq7G@FxoqRXXw=m>hR0phR +>WU|OI>F#rJPx&QzS0001RX>c!TZe(S6E^v9pegAvgHj?-6{wrAdvXUB!iM`vqJ>R;$Y?@sCylI*zPT +PB*tWQTvkj0Hesw5Rh`|WRk=Q9I<00_#?Cht@3T`H5n02mAg^9_T+VDP%!HF=@xq*CjwQH!K0lUMs!7 +n39}7V3kl2ZO=UvMM*pY_{AryGqSwNxs>ZRg+}bb-CU(Y9@al9qIS$^5!NlZp@$an_M8w%k^5#o4hP) +1ER<_YSHYrYh_C3jjEcmT-WABy|+J0`>V3$H~B_2`>nE{wq>1v*k;YjytvJ(g1S>5NiVkfHl4j!#iFc +IDw%G|_o_~J)q0&@n{I8hs#Zx>C-Qp6f8W1)rGD9|x^V#LH%=Gk<%T+GYUJB&v8YsCw*_ck))r5rqlB +J|VmV3X*?grIvu#yw2~+z?Qk2yuTjzgKGhlO))Y~;7@k8T&0X`-SLw%7qK_BFdm8ZK=ao|H=lNPOMi|(SMZMbsxRS4v +BWHw*^0ru)*}}B{-IL4Nn-_!`n!Z_63i=ZKi@)e)TXj<|R69>tI_#v9gCx$Eu-uB%Mkz`%&s<{IA{6m+xx7qw%hN( +;63${CpgMZBQ*De6lTx5PPFJC;XsWHVDCvS((L9flzvS_MuJ)9)N<))d(nSlCsKaWOXvSRO*Z{)NIclJ +-W`DbiIFc@=LY9{69~}N0-l@{`mUY?1$GE|8?>55*=hhI!Fg@Zallo~=-~HLeU2x0t-)7)NQ>2Q=*m^{BAU3PBEK +}sn~p-)peqm5U=j1gzS7lo585O{xk9G@!1i#v`|ah1o9$pX0uVP*2Iel6DToBG!aY^3=cr4QlcLeO?6 +4?j{fC;HY9fL6V*unckGuojqu>)r(a<9PVMRA$ZdM!wKVY|jol$u#Od@9oncgpcE2JS{2`93zdrt=`u +imL>xum5l>RgRdXO%eq(>G?h>(N5n%HVy|5jPO>g^vsjw}+qdh2%L%4VgiZe^**TT?~Tk3ux1+2(qYC +B!Gnv!qV`kd!`D^;w{v2Vm7Np9Ac92=?Z)^!Dox*w2F6uLG#XXX)%0L1#^A2k;~zA!=1FoCfkGi4U}2 +*Ez_&m|N&k@^>may`xS0VnedshPHgQI0`#2ZMMX!J7Wk}vnG$lw=4;8NH%@5%IjoF->@BV!8(%SDRukt7Np +&Rq6IxWQKX&0X)vkv0fqkn!$0ozPpM-~cMslHoP&ePpSbBj_1K@GGx-do}M&9iCr9(u7wx@(|!e!_iXPZCdzNQ7c&%jeB8O@6FJ%h46QeiHd%Nr{re@&b!UmJX6f$#q_2)xLd0@>~H}^={oj +{0+hJ#0s^vRADH?{LYsKJD^zfGgwbqP9oPEQgc{r8g-C6@K?#0)FJ{$queH+237&CnR`EJL%#CLDryt?!omua0DP +1$I_<`In)ofl=)`-m3s33E2`WC!pT|Aiu9fmUz}z+23hv;`=xMT5z2h&BjU#9u82_3EanG((zRrmbQl@-A&Vt;tE#{QE3lW7d516pBUwl)7`nlFz-mzblw7e)Z0KOR>{^A?8~ +xKMPSa>5=fKrbcS)rCLX_^a$5^-)&8cl}XFz1xrCIebT2G7^0toO(MC}64$L75*}G*fRgY|SwmU4B5G +};(7#-O7d*uaUT(b0ym@g+lLp)`CYYom`T5D~mzXJ<|Lr;>sgfF|Inqjm1B;N86UwM50@4Z$S|ii8$+ +OOiGxCD9pr`W{F@sUCw@$(>IkKs<5e6jT+P`7s<{$lHgVamwIT59T@~w?wJz@h}qf*V7x&GQZhj4Y5FF%p{uKX+bw4)mlJ=w?~(kFTl8N6;Zwj{PjB7l#AUO!g}(GHV+ZQf$RgY?Al7>g}MmB +b4{|xyH+F27K;v@YV9zbn`8Rl^Nauf{@EGznz~o7%H4VadL!BNW?f!0GlXpu5=2Mqy$6LvFxq& +C*fqu=v)9mefDNtK2uka%nu9w4!^(rvS$FTV^-je)i+y&2#i6^?RMY~^B?%QXHqwsrRHY)czwii)wW0 +%S-KQ$EzcD>UG^B4^hVp`YtifXcTV=I~gT~3hY#L-noZ&h~QiDo-A1sz6;u%XcS4#(7?KkEs@k{yi5| +wpR>@`|=uC>hbpR^4$`CM!%t)-zZD|lJ-0vXv~6WTeqG_)BhSfZ)>TDSduDV{vD!t#RXg-y-%AQ{2^K +nhYlW-JZBR!ADaZ!zsyC>haHUV*kinsqW_2oqEoN1NsEzAmH{0$4j{NS|Oekx{0Sz|L{W^W1@@Q}-sG)y74HTcwhU23ULw+l8PqkpWBMK +|THxS)n_~XJ)aYXr*jAySqMBN30iM*!O5~B{MY`d)DMVzJ$SlSBKE#39j!W7b;zQG()RnYGp-7!x~*` +~=qmn0B~HxnSo@m5LxSRS4q^Bg2r3#!E%1 +^F}id7+te6b%?4vXzAPJcmarPjf?%BsXqo`ExyBF3L?lt>^Oo(u2#rxmBF>Mz25PpLx3YqDf7b{i7Wt +B}&NfVFQzC=~AXxTfjAbO`S}fhNbi=YgHBUl=(@T=G9NU6RP6i>xZUb+oB5~dG^?TBgrA@~JdY)Xoyn +OTI#fxX(&VG9K8nGMxBB5=MAfMQGydt}hXmQSX+WgwbtdffTITl>ui(nk@a4vH_inOuRwL1GJDEii=5 +VaUZScLQ=4CRPx4uc1^k>ay9fI|0CBnJ9y!Y9(?qEFf%&_G1WmgSWWk_Wo8%NQ2$j3ZMp9o_b=fw40? +#N>c>roSi@hh)YfvvZJc36tu%?my;t`lHb`pb_MAC^Pm;5BvLLC6+Z}chm^25W{FjEHCrAA18YKk$7J +;vbtcFYUuwxMZ$6sW)%2Ai@R2|a26R`{*~DA7v&scl=ig!FAKw#Z~w0+>ns$tLOX(3_m_rQv!%b32sa +cXF+C?nw=0OFU>Jyxh>q9zS%oCM`G_FRm*}Z;=h{Kr*=_ui6_n9hoxiCZ9m<_FUU*#JHOm=Ik@e_k?8 +R~Nt)h))1J?yiZ$JvAgT2alVw+V}?rv77;J{jC)nZ;Q)S@R2Xac&sRix`>HJj&1EzdC`QmM8$?+M +K0Vi4V%+7aN0#2Su~{^TE_xWVx{gC${B)&Acc#@$fp=K7otIQ_@MXk +k1E)q_?36FuH`Tsd^f>uhC9pH1w~JCRwNRLaWC8r}&P|NGQr7q>-kAs}TBcl4T)CveLd`3!t>!fSkal +Vzo)T^(6Ihw%+nN3u-!Js=Pp+b036cErL{I>P*}|?j +T#z38G$9%Cb*Yjo^l7}5mYlubh +na7C(x)!$k|)7tn69DpePnO%Pbymweo*;t9eSg&7r$%%7ZJ9&zv&yC2ys^q0kMXT*GG=Ql%j< +Jqv^hu68*;QN56>?Y#1tgUm9#nEfkiSA)zmg&yTiaI#%?%PU7MB)54j=+Z&*vmxdH^FNJk((HHoWYXt +!o!cYASxvVqix2lZNU55yzL@iUAzrxnOK#>2o0H2Y|QlPHU+3$**~^5xVUv +?qa1%p&07@Ymll>y3SP%?ELano!)@$-)O%fXf^hScOzz#It;A;v1u}+C26>Nl%LjY_8$^oU3YJfcE03 +M-oL45!zH({uH)^$)9oN;=i*o)hh#d<$RGyrw2XqU{(Dh+oNumQq_1j)8t0fa#LN9j;3}gXgr8guTOpn>?sw|6#ioyumx#z-oPfZ@0avvPGXKe6WW)Et7)1RLn_ku%wRo5|+ +oaPb298_NeBy_2{oC_jk69dBivg<~J6moZQDh8kseox$g3iS>yl*^EQrDCbTXgO+32k>2TO?q_YqO!e +ZW%?DX9c45I<{ZzCIk>*5Q>(kf=A{*|+lGJ+6~6Bq;gcTku(c&la# +nTDbG4-ENgHAKpuCvPcP2A`^mJOl<{ +*ri5AorwRL><9uh@Y@G%x6qbr2NeBr2ON)>g7_aVB!DU2kvXM)+ +Et2zdl^>E`3p&ghX=Bi}D!>&YzY&ON2q0I6WFIe2Wl}V9S(PSfThusf5F5Mc>l|TY*MTvYjM9^p +m}shXT$z6ErgO8gN!`mfhtL;koyL(XN9-0K6&=O^*-7;}`*|&k}EK@LmLy6SAT;%!Rt%-He70T77mT{ +t{7Xxoehdl}p;;&xY|0h@FMrOpOEH?MH!F{h3DXRSPu;x1V1^vvWKPEl85c%OXd7hTe6(GsP*wTV?0< +x@1ICw`ZHI0g;)rzWU855?((ET6K?wGWO1C55SM8I2_hCXOLX3YMElYbr?<;?kPT*cescgU|CD_Dy#+ +K(e@8?cpw}KA5NFU19Tn+a83gDj<#Z~ZtLxdodYK#&lZ6cT>C`UD<5=;=Sh*R_kU@RV8{t^G{QuMUuj +3KW^J?05)ktOd&4j>aXpr|=*)4;dhZi##mva=E@;^9M^Z(c=fpS3Nq6GRFJeBCJ{&-OXEei3ye11$XF +L<#(nNt`I(QpJt2s<%{rV;d&t?iJVjb?lx*7)@*OwFSMz$|bbSE=k`jCR4Y4=kKNoM3aV#gnY-xu~Y+ +oz${4NHpzP()*_cr1i{TV9xqGq{hye0wgAk0Q|8(vHw=mD66=?5(ptR4zvS$W0zbS?j}qBR%vW9HJn{ +H_m{aNM^0Y(3^=-gncdMO|`dbG>tKOo|*AUAX>aU`>-XZR}0*>+UvGqIRYguQjz4EL?V^7vZ1j*_O_{ +ysM-qOXL}v-63c{w;sq|smQ +P0H6~juC=G(S4RDj=y&UtE!Q8@rk>pyZaW4l +VWW0b-NC6;C&9yLwC|!co?>`vi$gcW99}To5cGYFO +?jiRBqC)(PQmnYq2jZul*l`_oW7;Z1lx#4*R +i@-a*$y6pGLGh^}cC0~E#?p_p-# +N=30s8jwRU7F_M0H1`E1tt*8lK^^Aa=RU4v>rWZm&6j~P##2;QDXSh|lQn{lR49ZHMFFn|Uq3IE`^(ZMAg!ae8gN$RMa^Vl`p|7+fQdc0hG%36|`B)bBhV&2?m+M4udUAFZjh7u1#NG#o%=AJPhty(sK4C$R$ +uh~;$;n4q*M6*>X#|}kV~&zg^Sju54^e$yl=kvo$#zAv*k)k7gUUS&j>7t>!!aB+K!QliuI756e%!X) +%fs|}pKZw|E9UvV%#65C52xwIpM^aPJ?J*XKdeKU$Pt1$pOOMa{H4!Joloh;sHI8Se_t`=dfTnBt +4OZKm|*egwR}PwM-s6HF~0jf@ATBwK0CPAm33pKF@Wvww?>WqudEM@DDE-9;XPC+{~_2V_{5Qe4$v6z*HVY^5sJchf({1%s7JY1`-_-{i+#f4=KO5Nqea>@Sx=4wp~l)Xjbt(u7^ +2f};1B3<{xyL`KKE#pCk65jX~P9fB?*W;WKL=v5T`Vms!F*W+$!O(>3`sNXCI*J5{)JSJxa+aBwPK;M +)ntNQww=1Mm@LKJJoSJ03Ua53jZby$hl;*mj(Z>Vv@9s+!O$lA2h$|XTe7(1YgI@G6d9MfFmp$l#Yx? +gy>yy+2oylb!1WD@FM{ca0juVXJ8|&LMTbx9bg!LV*?@e3P3HCS7-Af$LfCO*tc>^&&kZ3DW7mOL+ws +s()4(ItmG!{wdIxkzFmcX4O4BuDv#1o%XJeUz?lO}}!K7xze4O_AA1PGpkbKYu6eJK_{VJaltE^o9`@ +6Z$!W+Y6|82emyJQJwSY0C)a0U)8y_&F!>Q2Mf7GVY&wpJ8=VQ_i;5_c*J-Un<2HHz12eHJonuqqirg +zrFfX`pw(N(|^DEX8bS1&Qa?_Ih|a_Zrp=v-6mubS3UB6z~_n!9g3;CvGEi*b}&io3y1gP2=zqsZne% +gd6BWEx!AF6->CTJLZE82GQ$rJ5Sh3^BGEm?Wq`flV4?$7z^23Iou#4@$Lw;NtG=#}fl16&B9@B6(pZ3hi5-g +gio-yH-HgPO7YqZ6h&2!O7Y)!w=E4pju%Ru6?0U1}*yAUvr5L&vDOEd{be0No)qX8=(gx})gKqCHe}r +%&HqWG3YV&7OOKhnrfqRmMFh;@#^2U-DvEvS1jL^b3AyY?%-3r-J;h^VHzc=gDKKa1Mywy<^P$@+Aw@>rGjcupQD5+_WSsFrZ<8<14`>uj3N}vmkScLcBE ++Kyds~&bK0)6E!*+oY)&lIJ_o2hXIJjpDp-IeTDJ%}7F?LPImh(UuYW|FOA!!Q>ZXzO(xv))hp()NOXIyjV#lFCsX +as7-8yBw}lbo>z#c6Jbf$@aFQtv~DPplfjfX@~lBB9Hx{(`_0_R6kWBw1lRus59?zlZjeBf}R!#QE=t9L3n{kO-Dy@c8W*)s2v$-d~7EbcpDtt@8aCO=jb(^zx6k6vpm1*)M% +rIFufIxonm73hQ3!oy4X(v9%xs)-*t^iSFSBSRNKjiXp$SG+uV#2V5d;ECy}^l#NoN*2^L$`l^;Hv*M6CkLrowa_bm^xobZcln97}YVNDf+Knr5zKKl^m}vW&z1{Q7HMCiLhL*v2SaoNwu`y4f9nL!MTGLzi-ox+SeE;GVd~L0(Pn+oE +jyd93G|N7$LlwJ&BluR!SQy2^euXb{ +8i=8S7lh`#9`XQ-K^+k93k~`D(8K;ld$xxvsvJ9L&OK(zI$mR4jJ#ni!!;zZC8SmfpzzM0=B`ybQ%2Y +V3bH^DqtaDZKaazvBY);6FqQvpu^zk~s*_FFmB0p-=(U#||^LI-6IX%^fhuZ7aO2R+h!+D4z^jGQ*2G +b#<&`i`K!k&;d+Xfz;#K_s;>%Ij6a{ ++?&`I&`YKGx|`8(hS0U?&;a*DL489OV{U^})JV6iF!4H}d6q1)S`Nn|*(;8TGsCwyv-Yir$zVFL(}yp +Pl56UAS&EN{w}=gF3k%A8>$n$lqAx2oe5rF!>1$jpQj1@&P>IBpWLR_h#4~;P@%4*C*M-83sgPBVgUe +PbTM)kVZJOq&c#u*sNTX|wFStO9_J)NV4G?Wd$7JBRjfUOwM^m=zkI+RW&D~S!;S?8DvQ=1r^|v=Y4$ +k|@`G2zwe2w#)Je9a|sWsA--}+#$x`EJx`3m)#fka>cUUx%v#vn!B4t2HRl@|`VOmzp*C;8=nwi%Jl& +FX2y0O11i-MVKe*cUOQse0Ub|?gZPTNCy~}&X{RqB~4E7xT8LLqNn4;0j0Qf6~7!uZ%3YQr( +2M)cAYJtpJH%NUO)Zr;-_Z^U5dH~24rhC)Nl@1`dlsuPP48hZq0pv*zPCS3t54;?mvrzr{5Zf>mZy)V +}#&bSaipgGjhLK-`D=&3-jDB&dEG&EPzfc(w_TXChoS;lZ~O%`kkg!Jl+O&uyjAt@q}6|_rO~`|D~G7 +8J&d71{)wrX>b{_e3xR1NWhRRQ0nZ_Bdj*fXgDV?9}m`dE9b%4=8;*DV(*?La#4_Mmy_g|ovQXEVe4> +$F;VTGI^&Dm=406tN9`?vd}-9M*XHkE!=zi#cQm4nQ+$;eR$Lksv(q2*fnz@%sgdrrUWXX5Wo_uTWG3AuDNJ`ZKhmNZV9b<SmT>2Qq`4QEC<(*1I&pbs(%A#fso) ++qiZvmkV<9CmLCpk7weA5GFAVJbfGdFO~|MvHhrmawXZBTztds-UIZCyF%foUIbnAlu%* +S=QY&~htx&Hb9e+C=`0W)O#ZdHJHh?-C-3+?&X35AOpfhtXjYa>ETw1~>M0+&MCgEIDrYtk+>Yup=Gc +XAIH{Z(dF(2{_ETUUsb+jz`uJ9kqf00zY^a>b=@N(QS7XQM`_8q5S3C;}VWbLV>+Fc?0;!nCL#Bieze +!3k|~H)kCA{=m@SF;K!zt^vF}_@*!jV)#*(6m?CS({+8igQ5Tg818FcKsE9rs9=6j`pZ2$phPWUaY@9 +EO?w%ynX8}3AySbJCdy?6Uz6r`_HS)jM_4iGTVunN4Y2nE?V0wa4aq3k{M5Q{&2zRF((S}L;+m~<5qN +O}A(>;fnvzXzcS{lLL&Um)Xjprz|#}E#(Zf+naw~u45;(U=bsL>#O^avFPoelGY^bnG?^vs%6ag#UoW +2*bn(#BP=QnEk+j|N@Zh1-m{3QiYu%X|l>iI|Gs<1?~0pNVs)Pc%nlU3X@qwI%do8>b3wet8G(wZ6sv +qfw2Dy{KMQYB?CY9_=`0rFEEL_?JbP)Q_^oSi!rQX<*vxpr<{|;yz9%CNVL^g@Z6dUu23=x3N8Vsxyb!Yg^k*XCN{GP(OPz;@2d)4eogXSTou+=NH +~RSE^T5boc@uR-P|hGMT;4a7k^{>-c7n286NUB_M4tu;;Iy>4F^LN2L>+tCOUPs%{Xo*ija>SL2dH{o +0J36#<}_7xYOISs3tAux<02}S06OS&TEvh;rNaEKy$S=9YGG+Lj7)Reu5KZ`)goWh}D3}8z1~9gyoB{lXtHxK({TUygk6?bf_&>= +2@xlztEJVTI6KA +Z&){$A34F9=ymExMNXvpL9boW?Gvl{;oNp3-`E?N8=9+gvX)9mS9gA3S()`eDfM7bD;6JvJsl?at;2v +aak_3Gp4%JcDh7wRTBct`zl9+YTNxIqG2hEcx-}Q$m>>SEy;&p0gPxzc^1WiluQ$c}|Ky(GzMALhDdj +kXG5;nG!gBd;F(fgn#>oU&z@w%um0-$Gch0R@ychmDPsGGsL~qA+#eim`PawK9XNk+4^oc7E#o;-xWO +k!wU%#`&wdn*Gspm`o+=+6S6->Rso%xQ&D2VBo~)xUzW{<$z9{*Hx49M=qe1V6=S6{h58jb^F>c**3G +ZbnLqUO<<~&WA9@gT^J^gH>z=;+8i@J22QjOxUiB_Rd<<7_S9vpT>JZ2*wC&J~S+7B-ZN}6$7l3q=4| +Vbmv5SD)3Tyj~6>_Vce+E-*JBb8mj)rVYt4wAJSlQYGl$sg&{WNFz?d?=u6p3}J2g`Th!-jlx!OD>TN +w6oqVELAS`vBGGysM?tD~I#jGu}NxK<0B~+O=>W%zZCi9%zKacnFFl3D +cZF2wai{C{w2ez-T=$rMMASW|@8_ep|MQ!xFUP}vG&(>!mO?K;K4{LwzII0#kAHQ>?wJB2fs`j^gv`F +ek+n64BNFyb{zm_tp8gL1`R(udKc`>)EB^D<$?4xVi?7D#2(Dft)yl)M_{)2-VOe4?7Ic>mj=q27?kG +>=alHq6HjDA$|6koZ`KazeqlsBSb=AJ*9*cl8FTOD^dS|OW8xk=t+TSKc4s7wh`Aq8%_RNSln~h~-BB +{>#F48t$L%iOSh>b(uB|=s^!xu*RkLN^erFu`ur|r!g1r9`Tcwu9rv6=4 +r=7D~F8G6#DD~L^;GfBxQkxblT#mm81m|-KHud{r^kubYP*3+=INx@<#?4mIVTEPX2JB*Ef^47VM`EJ +IHd8$7C7##?Qp_E0PF9b2@ao5J}UUKigkB2SZub&g=;uKmezRefh&1XF>N3L# +}sd#}H>T_hKzL`yD}l%Pr;RyWF4t?gj2$#-G3c-cY^ddk*wHkt*dRE+=lI}Sb`YTD!+l +Qd(=srZmt2R+Av2x=OZdQ22dX?S~NRSr*T-(`8MQaQYHxiLiO}-lACe&7iL=z5}c#Ch0+K=2dBN$)j- +=$)%57-V#(>LV6=u=nDDsQ85O}DYb94D3CI2G@QiSCHvBu6(1&zIwxjn)`q*7u`tDLDr +R49FBPX4_7Z7di#pWi5lxeA48ipo2koUCzF6t>;%w&^22z{JNb&3&Fa{ARPms-opPU+)%b#IF7c))ejdzI_E;@;u=JMu42?=sq!->mj2L +RJNsbv75jS?w;6|Ci-3@6P$+UUVFR-Wz+Q@p>dI^=Hvb2}cE+!f)H +VdKY;;&#HxlX9~L@s^qq4zrx~*GgW?t)o5;K_nOt`-Z->ccP|Lbh~orLC;RRl*Sp5Ab(N{mqYKP94(4 +^PVUJ$S{jd7(&YiC^5}QB~UcI*_wc5lc^tiGIID?C7aW$eqPMswlW@fZq9|}B89K4D41GF5ZADm@I7M +w%PpV+Yoq>t^9IYL^Me?d3_oVX|*&XEOcW=YS=;Wcl&pgTJ0c5@QLL8SFvt+d<_??AVM!apQ}tmaz;o +c>IwML8vyQ^~`I2zhLO^Gql8b-Z|-4a)H8B@K{Nbm!)bVe*RafJ@{K6auUF6j{^QI90YtY3$$X7HIeU +S-RDV^R&Cp-|3)8jQ-MGZ|v@S@)8@KIaS}1rn%Z!cD<+B7X8GrH)1bxkEI+nms9yiM`uvFkp4;~2ACY +R=KIere7zf_Zh70LRA{^4ZZ%#F-8U(3Q|(B`=QbUMX)C$3>3%Za^>`w&OBvFIRArU}eqWb-g)oPfV?X ++TP)h>@6aWAK2mtey7Dr3@xpO=U008tE000mG003}la4&3cV_|e@Z*FrgaCyC0U2o&K6@B-wU_B4Ar; +d!p0)0pk6xoSqC)msf##zi3=|DqEbj*z`YDp@NyV(8hJ@=B5B`29}i=ugnO!8jdd+rAhIUbL%OfJ1Pl +@q&-vP$ffD2=%jYhy)js2 +j^8R@OXu33ruUWB(r?=S(bLy;;0nWIrtaz7*n +xsLU@i?osQSq+v`e^y%{5#rsdo!}P!eS=WWOuyFK3ygC=(HC0h6(IGl|b)J3q?u=3VaugiUuXq=swz^0tLjkM}unl;9sR +PM;HH)g9=R_%nT#QWt>kCc!B1|}UD@tJ~g?!DU9UU(yDu~$O&0^~OcF!DT?m7t77YG9#Nzck8uWILud +@}6W$Bo)+|wWy7AdIe!qDJM7`?xoeHag>PI&86aU9ko`*i?yx_T8!OPh4F;SN0Bza(T*&8N3+g!<`il +zo05&*VMyI8+ZiPw0_mov*^T7jj9x(5I|Ju1c42nNZ>!|?lM(niP&=e{|uGnoTk&QQn@+zkc6;O +n7+t%e?G)_U?Q-6<*DGV@}l=@CV5L+b#R*B7vJplFjMitNKYE`5h{FGbHWI7EXMN3qneK5AvjL7& +k1XeVzF7Wms(}HUjv|mvr=KqEZijGI`)0_kie&<3iQzwkf6R0Xg6%57X(46;8R@&+EF>q0GgFwt&-Et +=tI3^f7yNjt-MuTzu|=eS*Jil{G#P$R#^@zuQgyMoT3j!(x91;!faKf7a(Vv!0&+=`{9|-YAgncF +hyQgcb5#g#(yKi+BML6EjGF=>2&fvHqlHVXZv3dXG#!oJS9#2VTIP51mX*3D&y{oQrUdY@Lt+zN7PaN +b7vvJsccn&!Dv>;em^4)hInFbyw&p&nCS#}R2-c52Tz<%g-o3uOTD&`d%kIIZlc4N`1W$?x;y(2cJ^? +VO2C=g^3bL>)+e&)}3~7f+w|aUS`T|ZP`u~Xp7z%VvC|Nz&NOM2%|xp0I +!bE|XGb+90<_uN_dmt{zZjM^i6cZgYxSAbcq*K}l|&9p1&P^Ou@u@ +>}6)YecZOZzDs+1sP-BNI*WpVUpFmx0vPyP}_E_(|*PU84)a9^Z;Sr_;3FWn>8)`6@tRduQ{Q=a0hCB +|UC;?fwA4^L7O1pnEdy +4B;An$Q8KM`{jbt{-EiFxP&RF-$5L9#@bYyd2#9Nue6Y-PybFX6i9V%jpbgGrbp=cFuGxtnr0@4 +n=6m0+o5CIZ%0&wolyx#kbspczP&C@h8vs0uit)ywKeD|Ck+}lVY9q2}cf)s-qAC0&dv_G+1cdMdY$bwHCAd0@j|Q`T^6SC)HR$)pdum2KY=xw9g%SJx3*VM +(2qD@FtOLY{tcUHi|Ih%k8BPSEE15<=uG4m7kCmbvN{P1N_8vqedbVCh}RL~2hE|cLo}Ka#iIJBj)cz +Q$2-irxg+z!M88@6NBI12u%Y4q2AuT&g-+YWjm?=07|KP_yT`&uE?02xs*tugw5YX(9_ptpGj~zhdFi +O#v9{mmS9(P)e|}|d-JDg?4$MNSF~2euI+#jv6JeQqt#-<`Y0tqarH9z|=JYS0#TkHw89OQ!z8-ebyE +*+P&d--jmAajiCrTt4x|qaP(?i*H?;!)Q17SWwGenAf<2Fj%EnckpT4`Vs^Zs+>7u~y1=5YDi(%r#%K +DTGgCC->e&cp_7{fsVnGePeW;d5{rb$=Ro;>uM7(WhCa>_1qwuV-w)@VYU4x}vX^hg{&>>QzH`%#cMv +9;p5L+o+9SYs(=5xZ7Hpv6s@`63D-f9rs24Jw6pTD{}#D=TgT6+3CjjU2?3d$iVoD +HHEB~9FmH0CEtW+A6@51+y#+jvw6JcNG%ZgLm(*L8P4WOdq +)SAfYJm%u)CTjf>GqAe%%mSxKbuVIfj1Y72D+zCjF#GBfTSUsH?5lHgibvef@nnW=ev(i($}uy{|eO- +UiB!k|mGG0sbRm*N)=GL3F02g~BEM5nQRww{E6HZ$n^5Kf(TgreogDLZr){9}08(nHmr +>DkLp319i?Eo7ool@g8f@(%3>h~%nJ^e$rPeQSl=uc#ZVXg{P>R6y+!Bhyqcr<(zRzG0w*FJ-xtd-sy +;5_0WTnmCo6vIqpdC7$Js<3ZZ%yXUvT_Erb?Y_&wP|$&9lK7e{?tMWk<465{q2&`PoC5S06aVU>ttrWm +Bl+XqZlk&FQzFhwBdKMgKn0)zv!GNW3=Csc|~AH25`+evQBG7yXgG$0yIDYrwJI> +CHE%N2X5)?=20|XQR000O8^OY7y?@^De^#uR`OA!D75dZ)HaA|NaaAj~bGBtEzXLBxad97G& +Z`(Ey{;pra*$70TvgX8D+8Hy3uIRRWS%bFN3S@>#%e2ExqBN39Vif)FyQ4&zvfQ94W*~{om%HbldsRl +G(QjOG#SAA*uE~9={vr3m+>oo+SLFQc2lA>cDrUq=IQ3lTI#S+EX$(hrfd$E%ignRCbdB17rb4BpI+Fa!yr9lV?#%|6cEZ!$KGZL +9pf*UA0TWVhu-A +Ava~%%EnK%Ls$$_!E_?3Y>h7m||z(7iHue(nSBsT#JgtP3%kxX>OGqDjEsnQDh==6L{0=qD;m|}&ypy$4Dqaee(t +r*wL4JVe?>(OjBipgkpHd@AAynuehpOE)>PACxMpxlc*Co8B_TGs^vE**O7ub01ECeBRzcW>H)TrY#x +Pk**xNKu1q5VsX~TsBotaWvPUWQ18MzTpbI$6Y!)ONh`G=04859jnW&7VH)bS`0&Rx<4}}?^-Ju*jHg +?C~JTxBwTHanv}mClT-Zh(%c7|unOao4pN6&;BliNiZE;1ii)XxP~Mt7wi4 +PSx~u8d6D906G&D8W#(eXb-Z4ePcW=Ob5ZJbWv_=1oE%;cgxvlz_;CD{Or_<->on+TU5`3VePt(t%1f +z=?%A=UPt)&qK|EoC_4FI7J1Lxdk5&NKh>J`hZvW}Se1rsg4p3bLBG#kqsdFF0b&@M4uBk;kp<7b8hX +>Mrb_b2!hIFIUjvk?#IQdmuz{KgfosizpR+GPl%9?Ariga^L1dK0!@Q}0fL4-3p0LiAji@CSn-p_`(D +nM|#SE(q)?7dR3K45N-hS(>)+cr?McHfZ)$u4l_(hgmZP)i&(gG47JRU>UUL$>}t?mLb7p_JWxB*%1?#nVRKkYp1=KY*krTnnnWw-eGR@#amboP6H5MI>Z +GH#q7le_JOL(4t;%8N$0B#GvN@>V=CGv_arUWBTv+WrhKD1FlzRd+CU3P|8_liF2otz~H1T&F*O_n5i;d>e{CJn6OTSG9tnpqoo#lC=vjuPzB))gm`;Y|5ae +?<^@ep)}3hW6rV#JqP)Ms@g|jH`|!{5{=!6;~1pji3Z;zi`bmwuGK@?hkgiJVk^uQ^Twjzp~tR-WJ+) +t($*yyj+MOD+|EJm5CZ0TEq$oD+O?WJosHV2P4qR7q4`?lzqiXVS=IQW_-`#>3bSTxQo| +(-gZKv9sf`{*d7K{)WXR+$jCvhPU|X6V_9J*3-okL%b2SplapuibsrAI+%-YxJoFB-bcJ92zQ52bO=E +cG6-4Em^Ilb=yXWMZPZ1H~qB5VEqKkFOgU +e!Db{sT};0|XQR000O8^OY7y+pKr?eEt4x@6aWAK2mt +ey7DuA+%h!}7008QB000aC003}la4&agWo2wGaCyBwX>;7hvETJ8Cd;T6u$CYtA1}q2R(wziE0(1a<= +82T55_KLmk6=I1_xK`#Q**EH3yDe(aw7hRT6Q`^z`)f^mO<1^iC#|M_27;Q&x>ymX*qix=HdpD^@BgQ +Z;Y0JjI9RR;$VOR_lDC=2?+cJGDs`cgad)wRO@&k0tuwTNC7DUYB{>=$M}$J(Bl} +a=poN4Gr2i^}V^(RaKPcVc8aorY!T?ytqy3+dP|_$Glvv08jH+*6uFaB+adPthBkSZ`&rb?Lw~`d%v@ +_8@=8v0Yme=O{xN#sULAq=Si(U`^5CJt@1iq>UjRyC%Raaspdj@on$#6QPsLKMPJjCK-pxQD8AQ4T2@ +h=y*Fj9nhKh_d}XNxGH%KkkeI2qz`?r9a@PzJN{^$y +(3U_eIV8p!th~ke7?310c=n28me5_2O1z<=2<5<8Lm$y?A>Ozx?veUoYOoFD}2m`0mS>7Z!{~SZ_Xg_ +GyyMP3%oGS7DYzEE9C6*wH&waNbv;uW@B`jTvudW+$(@d==atR@w|hWgk!+Cp(ztHYvTbGrrCK+Y +)?u%uNVvwdm=&omni$>=2L}5J{1(-VD%&&`$t!w%33yb4I<}{GE5NTV+X{LxI^@y1yw?`yqAZr#Y9lQ +2h-O`^-#6-9O{48?K7I7)Zx?T_E?<2YfBov^>o4D4e)a7Id<>q>)M*Gcuv@@u=Vn$!E8Toc?}9kSQI2 +CQw#bvZRy4?8Coq6PIsb=VG~pSM45ss!KumbA%B3PCY7!AVxs9Z#Bb@hCBh^co`&p4SaU9e-U(UEbj} +?oF7&_NfWiE|KLtj@qX|zhX8LkyQvL()d7RlNHJ5z4~tEwy;L=8og)aX^{HhHGLB)a1$zmHzfx3Bq=; +-0IfRC%_}8Vd+75_cI4&s-y~0II2?K^$oqX<_b>0#R&{hT#xd1XFPX!nK9r4eaMoWlPsX1;p0syRy(d +aNRBe%Y0=&9k!tRS{T7{W7O=|uw6#Q}oS3H*EMGjLMu6i`;xIHzZ7s}%^B`z+OdYXk^d}%j95fB; +Yo9Bkg#A%V`X1Y1TLEk0?$(WTcbVUNMK&1g+A-h5kpf3XDPVZ)JJWb7iv~?r!Dt#& +2Nu@a{Mywhu%Cs=q{C95?ob42~E7HGmYI9HN6ESpfYtVOT^DzL~_u;`tuYno<&bd1ad1!Dv6hRVXAPz +hAeX!a{04saOBGHTL(_P;neWE+c;%?9`&n4C|df0S7fTz3J_9Hg5tw1^@-&(-8eDp_!$8HWo}&4|+Qk +?2qJqP|U@J^O?h5QdUTo7FyDk;Q6Q9`d9TShZfXRo3iKfNWqY<0^qt3P64O*$lY6Vb}@0LXE0|uP|?* +@n!?x0+uFiE#Puca2TczBlVYZ3w&PDprzSz33Igo1ww`jRUd$x^BU;BBV!6U>>{GR04-IaDCFTpiUGf +$8x=a@o(Dp`h;`Q>45M59KFwCTZh~-xiwpQ5$g%Xp-q$4zIegqyI7f*K$(De3BnX;v1Kqp_wNm)btGg +v}y)`1IY6~P3)&l*nQxafNLocqlOO`viZ`WtfZf4TY>t|=5xQ9>9K64MBo!#7+eq9zdE&wvcQLk4<-K +DACS#m%Lr4^hg%x&WnGMs>;^#TMW^cQq5=ojNDi>%QDh(o<)kPWPQGE*NJo_#b}%Lgm)!L|3y%u1YTP +7L;!eT3wfB*}NE5Y4@;W}F@b4ogF)vSqSpK3Ku;!~VjHq$rCFECiM`=Uq)ZB4Z4{1Rauq)(`7mz#@Z* +hrHud!{r*N+2o?s)Ip!X-DX3B_k``@33Y<E)-eNtf0Kd2Y+0$A-FAhrmw@tU>D99AT#5FkV@&(@x +Lb#+lysPfdxqaz@zBQmcM&w%cti|<}teD`*y?93`d%!u&&WmyfO6k(8cCFcOQp{fJWBX4SIb&QeTmhLK>qLu)vx-SoeyPq*~mb=w@-aDM +u2soCTd`W8%0NG_@d{d87%$?z}Zn4$cMBQVoEGy;00~h6f28WRjUz{`&Oh`sq#R3n(`izD17od<%3Bs +5TX7B04>PTeVifuQUo)DglaezADeByb?}fDFkVHS7$%#^QY?b&(*V2r|yfUA7Eu*d0nia1tL3PPfDO& +s|vjh5Oiqlgj;VRvmfaTLxRtz^hgUatkQ)bIIZT>5GTgc5tXn+qbfoxFR)05-qZsg<8obgk=CA^;~m! +wI|Xi|c7yaD`*yfpUW3v4XL6oT)svyK$ysZ+kzKX%F^p181*YgCDV|QlsH&SP+XU0|X=m62u4e~9#ub +T1;%QOe2dsLn0iIi1>Rla)vJVWsEPR;bJR9VA6rofvpAesiDZUCl)=zzew_0cRuR(T2^9Y33ytxO#)V{(JApQ=tI~^xCN_(-oyM3!fP41Kx!jh2hU%Bj@^X$^o6^f1K>w5|opeV@`1y$le5BO7#q%cAy9chRaUTM&$h2e8BWxsP8@L$M6hSzQf2 +GeQ>l>W9BvTzoqXiMM*%vgLMmUpe(?SOhPb4>VUrhc%LXoE2D4*Vv5-j`ML=AIl(|;R>!N;|<~E^Q`y +GbDmiTW^xP~QMKDZ$5Brf^{Z=iIHxBJ$Doi0`d`1yaE%Zd`WB7vOdL$c2;Y@0DlVWHfT0XVHSLg~NF_ +94#zSo@)U~Rb{WAh@t&>8$UgTC=Cp!gX$3KWA$YjzZ)#Z1WB--nU96w2eTR;t&&xlS_8q*)?4hvaxPDS)4*?vvWytyTKEjA>1mzw}#n95~Qm$`OI!K%&N13JPt=-7#Cu=qi# +2&Pg&7V+9&lpL%yTQmXGBzMH7n*{eb#nD7uL2QyrIc0q7v>x*JMY+kex9P+yt?U-0plYC_-)ssX2vJEL0 +C{HX#oOZ#%y#C{?^tp)yA66a@?B_w8E>@%hr0RBd!M$Ii4hRk2C$XIGWWc$$z*q^*4kJsev8-EMfWvx +JGs?_d@uzBCE3oHf|OpBvM9{`t{VQbv!ZUD=}3Y*mz +%o(`987ZqVtLuA8%nUDN^3p3~c*=D*CBiyn&?ev1tH*Z$~_W+e{Sae$S>bfmLXnu`s8r0QdrZ&SBdAP +l9idr4b<8;thZ$lrkltx +X&tepk6=D^Z-`ski;o4pEUGp6+P6buF#jU_}PeQ81;4J)e}=j7gf>Mm*9j@^U`cZpc%z%0VikV|s?>E +J#`w^vqTC;E~S-Nf7uD=MV7GTD;jfccxjf$lFv;iEwVS9lz7ERJU`KelwY2tafjc{7%s7@j9Z$@)Q2Q +Mkk0Vb`#}8DcRLKG%53aPZf7t01u2;AqQ_ea+#>!>Q?jstuUVy24GP=LZ@#=8xyHIA{#_+p_X&dOQWW6;JK1K)8plU~%AHJ^S`qRe*{w+q}s(uq +e6y`x{l$akEV7n-Ow@91eJINxD2vz#&>k>go<`khZ`bIn)oZ*cgwoj39>M+hDn;mwUNFRismsfSXg`u&__U72-xtVX;D +L^mZ{coBsjP;GF=|39-{;EwE;-%W!p3>CPP@X748E;`xGC5fjlFiWO1#jA~5lqCHxxiM$m0|qF@xN!F +6=C0JAk|nhI99nVPf+Y_ex212p>X=`f%SLJKir1IrOT5JKT7H7=L5zfCLy9d+K^8Am{oKLbm676_Fdf +#tb^$GQc`CJPMjbOQyievDuJbx-deMlig<_*iFkO<}9&YX2%B#=2${cp>%Ez*g4j4QP<`2MUVzCvbr`XBICjKTKTVza=p!dNN?Yjn}=6xdum+!3s0DWJkfcA +89(1=`tSnS%M=gK@%7q4gV5BEN3!e6{TmW=@rEhsXL!R>5ZUl1SporKC5l?HZkyW!Y(Z{$gfF=~*fhe +5-A)sQ^fvM+;wuFsA?xpAgKz8{*y{Q)qao<0cZ1fV5-sr4ZgYkj!9N5D%mt39e6J5mer`*v>Nz-88t$ +KGM@Jur%}1DQy$GN7&wAFRslaHJ^*xOF0UMGfn}MGJ%NhwjeCo^1tbxUZ*&|%)_B9f96>k%ETD6 +L+7dg69_eqr{xZy!8BuLF|>@)A5B>B3uF{6bxIu^yx&C7I0ida2{`#fvr?cz>1QCY1ReK`cdT{!vp(- +W@)78~~D1yeAr!mz)c1LC~}!Jk?@DMEFd)mjN~*7|jAdqfIn;sq)X)rnt=_%k1Iz?RqjF6pnb^#-Kaj +$?k=o5>c`d)5Y%MPv7qaD_-P99#<4TUbfUtqJTzvV$N8H5udztg?$c+$~!CM(jU1`AyY6KCx?AjLRLP +8aH5F1T>q+9e`D23$D>;u3?e>S7$O#fO>7NCuh8PfuRix_WSOx#e~ncknwE`*6k7siqmEiP0&-*tA^* +kdgWb-U%crY_4|a8b-h>qp!fQ8jvmJ&b^Ot>;)sMZ)i%rHKj52@vtv7R0_<_Xoe%BloyURK)ey>Mcq) +cZ-H-^5<8_i1aV#GMWQ*%iEzwlqm78)L>;`TT9+Wn2j_RqV+4lC=?sLY +xosaBs_7!hk+&*k4Z=KQ^yGNS@d5R1^n8D=Nu_`N9}zaeeAv|c$z8QEF$$4g|%y-KnEU*mN_s*N>K^| +%Wbn*GZ1=8ryCU8Pt>W>gh5E~L+x#Gptd8>67`V{ApFQb7a=%OAcc<;#S4Muzpct*MLW@!U=^y(B!$> +6Ww}cBIq2vM-L+lWfq;?{Z(*4PrkWdIb-TFrhTF%0gV)*Cr&7BX8FeDuD*YBfhSm +By?%T7>bt9-euAnnG-ZM3TLc)XImlFe_=nH^hzE;bnd$8;y+-w%hNhQ;CeM?+k+M=mfxLT#hs6N@AEU +q1zyMWu##}$fmquJTONWkHnMU`vHf)MpAu;;n>{mAwf%#!)7+#_up`UDHJh_bqn~IkQl%4~uc!PkIEh +}8`!YMtV&o>t@zWn~%w_X?Cdg|C*;{g2Xi9DnCVP>4jE2DDdJ5WN;Kc`DpFO>qc_@d!8Rv(z_3@sz9?*^{3LK_$EfyCar*rZX2Vvl +qGR&cIfUa4<-1&|LjB+sni521>yi0?3(YrK!&MMwr=&W5^n?d%1x^!-!Uf)UBi^r^c_|q@aXVj7E|63 +gEgBI2uY3)Deht6z0$QdK8|L?O%r`Myr(m{inrbC1ea*z)oIDVHhD={NkNFyB8Yxp2*S(mI+2`n}!Bm +eyUWmlUJD}c0Wr&ky@!|(v99;z?Y>Dhj|_xyfl5aP9Ly$07)ZNiym8bBeMHc)_n#s$@ +RjYy3YxPR4MY3>g%O6+Gjc`z()sFRPq*y1KkWVH*ckD7qqQ49yjFw@8P~L7srDQQgTccH95!z^5k}4} +*h(G(7;*okQ*{t&g>j?g5re7`KLoa!?!rMatEMPF1P<(QTfHi`I1~(YYG<*tU9ksIatjHq~{usD%ZY?f?QCK{ +v;H7B>ned~Vrp1UN$3kO=HVL9Rkv^0_J4<(8S>tmTZf| +h7jh6zfW#Ki(zF0bd)+tEAVCPWw`t11Q?q19&x&=r1fR2aFE_zX}9=bfYIYwTzCfU`A_ntq(;iLn<$A +5FKG_c`&XOU(^gR-W?DZ(zV%yz@9bD~Akk}UAN5_-GnNP{{t5MiQr*`;${ndSy)Z7I(bQr0^M(U(~P> +kv;uv(eyi6;gj2g%?AHy5lqv?U5wGs!0_`7;O+teF;m{2yJZYKgkIy>^|Gqb5r|>dHK$a +v&RAp-^dd6QyvIYrAg{rslXGj8UeZpQ^BW{RwnO*E6rFJEPr!j7dz$CYrCW;bgCCEP0T6ql-NLfHx%(Vg=R9#^>C|=nYzDMQP0pX^j9rjh+cW>5!B;0|?KKY2=_|6lIB_eyc&Bf| +uBrnRUDX_eP{>P9xp!PqMY#|8V3wpgeB6yJuqK1CAwkXiLJbqK!TVp0(zNam!s9wL`EmMuLpp&O`AHX4 +NvHm6Q>=>)dG1ywfy%#6Zq6bh|UXbWBUDYJy?$pqvkTIPIE02XLKvxONi +PjpVFj{zRq1+W=#AYMt!nnnEo*hgD=3iVoDEgBZbcMR#^D6 +Y39J!o^&-wejf?_@XtuDzLAre{$UC;k4F=3@LV>kp2_=UCKRX8a1 +MYzXr?kng`IP3c!%!d=&<dLepb3l8(K#{z#Hj0eiLpV-io~SnK3?qSBTmF=Jg|^0$?Qvv~D`hXkfP{q(fgr@q4AV-4R9B255@ +rA-j#5C(k)C{BauR);AtUJ*VVsD_hePlNEKThSxZmtwUv$qI$4dr3VUIDJso0er775< +Z)NZDJ=Cmg7*=p>NWnf_MY$57AzWUkK!;bacK{%y{X=QkBBVzqCLjDZ&6l)CFt2r0yd)~jn6WFD<%{} +G*$9?)(XkcY!`d-^DMZ5YjfiS>LY0NUno9B|F@ei&X;p;>grP^{xkiAHdXe27amT{+qjuf3NO66%}I_ +J=%RCJkdK+DXx?T;t)L~Ny1%2`K8w=qhvT-aU%p}jE=Sb*`Jc_;4iIX*Q-9_)I +Sx$h5M0@V=@sS%Chv>&5uV}xONR|c!H9%$tqn@`T^1v?2Z7gP?_p|U+(S=KrR3y7eP7&+@^pW+(ajd4 +uX?a?*v-L&YT05s8kOmVEd4QNtvfz{T>Y_UTq3N%m_L-G#1sxCyOL7_-@U8ey(>@`#6K{UJy@nD9?$@ +=(=e379}(daZ``4(8})=1_FzOVczRoh7v8i*K?<;mE1Xj@AW`XI>JndIb6rmDoSmP3;~i}3^OTI1smQ +z|!{CPGiMpP8O_Oe%n%Xz&U56-7MnvU)anMVQA2C>gkIr3y2MyWWu>O{bmxJD}B$6%5Y=(%!!B8cjF5iu>8FGlKzy3m_flnieuFiL8mP4pLd?zEOXHlD)aO+l!`ddesS@41dB8$}&>m8maW{kj{hfcVj7EkYlxiO6HznFMsg2OjH +}dcy>^UIFq2ctqZll*KZq`C?qz|D7U!r?;p$IBiq@5Gj9mbo%BYB7 +3HEYO0`WW!XF!HHzW)zO~0a0Cxsq4M{TaXX$gcH{nX3*b2;yA0xwUhMZKiY2kY%iJ8ik%CYRVh1P_{& +cugKOG0kt5Ob)~12@G&>{-zQF5l!|!zqC7sg%>AcPQA6$t(AMJHvOu +jlCT49QRca({b6D4nw7b3P24o$9~>}5@K+&&_)TX|!rYM-;eJM_pAU*vySiQQPZ{we+KesjE?nQt{Iw +6Sk(Pg>AaX{K8s;4D>kcz3u*Ml+uW5;wmj>fQme;{F<^9XsbqXe5jj5bsf8(f54o_KgnIQ)8yPwrNaQh>+aL*}li1OLe12B$Fhf_b;n{Sd1gbeyNgnA00mVI +3&sbm1qC*=ILM{W$-Y(tOzGk+E?p3OU9_vXk59SUU8LWn_FkgKr5qyA6Cpv^S*Y5S2#pedhlxy6>k^n +*EHvUGnUf!ek_mrsn*eX#0nt)Xj^S*=6PTE7eVmnC;V0@jrr-L{{c`-0|XQR000O8^OY7ynY3ELV*~& +I%n1Mh7XSbNaA|NaUv_0~WN&gWUtei%X>?y-E^v8`R>6+jHW0n*D+uLKyLIHGKw4md92(e*E)eukw8$ +Y?2$VFkSW}`(Qr5ab{=IKV$!o{nqB^W4&TwY<=Dp#jX`1w^&+-Fxm9auOQR63msct7K>hVrpsmKXa3p +fjJL~jW`UUWniyT#=sdJEGDXIksJ0!vEHnv;u +#=1F^bvl^&{xvK3FREfI)!bbwx$(B@4O}1W=V?Ug{3^N2R~TKbHwb8^+FcT=)qGSzmsHI-)U3K@5W`l +^v(R~jxI@FiH#Y%m_VRLg;!M!-dHEbMwN|drshyd5Y +LfAI3Cw8ppE?a0CrSX7nrIIh%jH&8|(>?`HqNCeoO&}vU2b?PadLdt_wI)do}^vP!X;m_YTAGaIvUfi +P|;^TcdqTE^z+OLE*W{-Zw@+xJi#5s?FB2wUhs2pv~#zu=e^fn?eQYae1P%3BVstekwu46`E3!n_pVi +mzqk@wX0o~>}7ThtxHSt1UI#zmMeK;(u#_*Cc3czw~00KkR{CA&bMdjiiSN@Una<(dE)wtB{llog02J +~c!-s^F?~@RzD$K&JL`amlA&x7&~T=HYjsI58#zyZCo8e*?QtwzL2bfm5C@mr0-!)e7g4!nG1jZb2wpED@GKBZm63i-gxyF}obEjh0Nru563ui2NkU(* +aYx6%U_w&eLrob64*UT=>v2tWBG*F0Zb#9Rg4g2Ia>v$mYyFs1bSH_Nb}o=WPycnATu)*5>=?sEbECn +!Hm=BX*4FRFUPQO}Lfp&w713+a%kAz8usVs~a;ua#eoHvGon-WaztEAh!T?l*zibHKEe<#ALsdQ8|6{ +R(i+Fg;=H| +`&W*Cz+<3Fcq^OsTG;*@qJ((gHAx?GAMPJ5GYtB#Xq!uO(!=QA+7(DNcKW!Vrw^VT52w??Beaa(z1;4 +Xk0SL=;$^}AaJsBh1JT^aa(yRioTAIQCI$p))$<>_U)m$;{PFI%$dpN;?Ua6Of(R`9!a+V65p4)~Tg> +g%o9!Fp}5gfV!lta%p0@GnqH0|XQR000O8^OY7yhqJe*GdlnPD>nfE7ytkOaA|NaUv_0~WN&gWX>eg= +WO8M5b1ras?R|T98@aLP|N0ad={h8BiXthRmKDoc$FUQgGx5xwagyEjIy_CXDRoSCbGn;)WV83PZ&l& +_=w?%rJ)Yd*z46#2P$(1%g+ih5!vTApt#9+>;<9AJe*YQ!W0qYkV|Jd-dV2?qeVfeUw20@d%-HuozGa +(q9_K8AT4|Xl(@mM>?A1jc$E!FkdwYBP`}?ohA}Y!*TO!fxm`I<0e>FOSKgMhorOA4;jLIZSp~y6k@> +`aq?EBmDGE0HN`^%)zKNM^uTA$@{RK`c^>{EQCh{QyhMd_Ro^=LlN489Uy6lK1dm3w=W$yJ;e&;_7!##)13zc(1Q +_CR8zxAR2k)55f{wZSzV#wGrD`FUsGMN +=re;zLsWg;>uGy2Qq3WVE+zjb)?_{n1!ixeB%idTer3 +=-DF41!6Kq(vE}v$#FI>iUY+u`2O4+W4OrFW5I%v9%8P2Hvjw>HQM{3_WXdiE%myDMd+k{Sq$ll4htND +AEmFKJVl2(RzP7|ixK}&KO6%ouMZrNa1%L$iDOQ_2MR;3B3e`8$++B1t;c?tcv&e9hCnSa8GFzh{J*O +ze~lbK}kO;VHrQ>19M6W@F!Mq9vTg)It`Kq=$g0anz4(VJzPv}||mfy0qTnbL$qGiv=>JK1PJ+c16dk +|r3)qm0*Q1AB_$ckHDw7YP}4s6hX^zD!_UPe8|@wr=<~iI;PhXk}zi&WH@OKU)G>HhG_w(ek?-7XBo? +_;YfTr0s0_k9a1n@MKafv$CM25M(FD@K5n_4f;sqg;lSh&*f#zGWa8B)T=xxVExFT7`X!lL(?g$PbSL +}DB?0cnZ!R$CgS_Q#VoqYk~v>mNz^6sH^~HpY#PrZa2jAN*gT61)Rapgvy8QJ8F~qv +|(a(#MqG~HYjy*2kqvi#yGDT+-z==Vp%j#dlet6jv)MVEK0(_jwl8THe+vVQ#224)-#1^n6*E%7p@-Q +cCbOR^hs%mvpeyNEjhQkZf?&EyY<;6D9ZR`+j7W?goV8uGhGg}mOOi9~ks*I-X;WF|^rRg=++>WnxpJn9k$R{7Iz4Pz?I{Nm_yFb4F6EuH3#D9;~zhRM77V8z?1^hKyZn&e?)_)Zp +p?wN{%jj!p4!0Au(?BaFHWEGBHwd!t;&K%gpYB683|znawh=o4^~!qx`YXs~TZuqcv +A6vBbuxFyCVAL$EY#?Y7Q@$r0>Ul_AQv~kK_36jF!K;NNDB%m?bdB)x(WUXnFmF33h*}E;+)!l;KWyN +N_UMBJUw~}PR6#*6jSf(F8J|42`WVtlxOp)ibNWgY;DNV(eZhDKF7;ToN=*JJ#Wuq&vQYtA18~cGwse +h7OWL-2?MpZp-r>Lyh?Z=`sk7+*zyd<=8#9ROoBLU!l#|HPJ&Ym1F`mfqw7+P#Fs)m_6PJCa{_Efg(t +D7+gY0p>J+W7Odh7OGO;sxz4-z$2HgFg+e>EC*k(*jLXJX){gC>IJ4rBdT8J?pWSP2dmU2Ha*F;t##A +NNif$xS>@s1vcz3WI2vt8w0^pKs! +y-!cg9wps=mdHFdF!#mD{91Hc&9SwsJ#_m?3$G*!Y5g`xU`moEaC>d-e3RprVAKPrlyRcS#W*hQ(TfN +7$65`xpTA|wIi%1)-pMNg>qE^{+DL**|#ur~~Lh&ZRUo=~IPtv^loo0x-R2@{D9JSk49S$n}HD?F4B#wC6WyLB7l%CZ*kKe@*fPaaISoO&qA{f> +vWLcWub5}3#*&WYQ?N+vHs`Z$3ZC;RC>w$eS{h#fw^uZ;%PeCsDK26)KDI3i^rKFzy*RO2M@C&9&b3v +}3}|-QcUPbb%k0|KG*7?w<=hT;Wx=&;w6BzAd{?CzjK8GTjPI>Az;AO#?>3Ty@s}UUu^P%r0SjR{$<` +>jXgLwvYkx##FfwCQ!`zGWl|H;-!6hq=<9R%n(m~4X%se?$jrE9hyLBXF!Q=h(bBDcT!|mIn{qIs(Y_ +c?FK!gFqtE9x>0Sw=xeBa!c7-NIqNpUQabS}dQB4Vt(2Q7@ZPzsi`BK~O;V@Mq|uE=t12s*lfPRuA|0 +g^s=WvO3Km%-Ekv1L+_dt_7+j)AQFzcA2jIu@*iw#YFlqa;O_07qq!VD&7GDZtg390D9-}u# +4$bSO{iVo#5ay|KHoM(9WP_)y{YKkr-{zDJwYb?)ontsQDz&d=Fk#VWzH|b~d8tyPJBqjRcF> +U0%}Ua!Y$KS2_MV<6J$G^fJY!91J6>QJ7tC-1)d;m@zWJ^$ZtCV%_W`TI9Ne*fzA8%64axuw-S9}S-Z ++bsCwV0dzLJTQAzQSP{ZbUbWzK8Dnr#D8jxL{0oq*cy^?&ziuTfEd7r^(*&QlyZVeG(zRoD3kqdkN!3 +8C~dOsDY<#Z41>L>k(8i>v|l@WjfhcU8F}S9o^zvyrQLF5xY}SCD7IwZC6;CIO# +2aB1hTtwO%ngEZgT%oLG3-#BPG?$7%X%w?8vP7F>RgA5BM}R9je{AmSg2qpRF+_Vy(_zxU)`*#~PMTW +8!nCa~Y~N_G^vpT7Jrc$@?b#lxEiy77|nyk84_tfhKQs0*m4VeE3Cj1M7-*IdGey3yDP^MIwHXjs<%K(QIeX>{IemnW@-J2h6b20^m`lQ{b=kjpwXBZAy>(rT{^84O8Ter1#6dTxG@)Gc8PyW*=L0MGToio{F?;=Jol$W%#5@cCA@K0lVZi?z +3WYv$nQQgwgB=HUXXj3>~e(XTIJ^P(r?Wwp~Qi4$aL;>=K%L9(kFvm$Q4Crip`QZlgo +0K6`zvz8oz?Zz+nSTHMtR+JQRf5Vxp+QBjnrcwiM_UE;mKn^cpZ|fc1s<;!E>@{V4L_;#*qPInAz9h} +IUtv79itrr>D1Uqf3F-=x@Hmf)o~&9i7e!*xN{c*zNQKlu41$m5&TuLZFqC>kp4y{7d6cJQ`H7K!?yF{RFXJ +8u}RiqY*g(FAKbqTaMz4)f&&cOC?pG*l-=OXo6jRLk#C_))g1Q%*TmXK~cOg_c8m`ZJ)Jn@)5gI}QIN +f}L-{M-X2!?T;q>o`{DIa~?cD54BPnWxci%mxV(b)5t7TY2=&jprtvN0^jJN8s~hv50B&!%xUzy5O-D +Dw%fht74JpdDJX-BJortYp-}d2J|0qp7khr3_NpR2UNRERxxJLT*p@!3g?;sm!6)gg!IRWa-HvF#5`qqeW{I*z)E)Mw6^3yizrb7?PpMyoE_c^zK}mr#~!u;1x999b0TIwll@;z@dl)q7F +Cj#>?y8TR{w)A{t|^t53^&HwMDH|@=lHTu^OnjH()Oj(AN$sL2r!4m4=4$`W?y?pBtbg!U1#57ZyQ>^ +1zvPj}NCcn0EY2vlJ#>I)sJ6%B7ygD$ujAx%H!$L}wUn7V-%K_{0psdE}hxTM@Y1ryVWW+k9nip!-f$WzQC** +OPZRNi7)05~Sg5n5&?!BS+22{){sI;S-QzlW@lsq~Ty|Vu{O`d<+ZGjJ5nwkRVfE^y#i{$ElBrCfwx9 +vv6JUy(pv$lRHWuF&**ifW`~>q0*PD{3bFRSmSi-cz(<%7RZ!o>72#!z*lVb^`C!*+CT_OyZ#7=WVe` +w4t3#w0>8%o(a{*4T!BJWRe)`kEZn98FwG4fc$tRNq78;mR&@@+(0)~Nessi6t +m5;y1jY&@n@wNn=h9UatsFo35e|jO3I;n`;>MSOiN+nSGvcj)8T9O*;K;kJsn1qxW@H{CLI?1D6)lsw +N(H1@DgJ?uZonhTsw<15Gi20sT_Nu_pmv0|+YIq{u^F&Ut;1%m1&J^j3bsl!;pR88wb;NZKKQSr-sBH&UZ4N@)wh#Bod5Cs{f|AoBECi!y=+$vC4OjXRw +%1o&#;WQ6(h-kN~-FKh-Os|&K)=rB53z9qNBNZ5wbY<@Aod#-&v5&iN*gJa9|>-Uq^T+i>#QK5W?_cc@0Xlf|YWUZ3?m-u$=${bx7+r1#00 +Rd|m8dK+~X9Qc4tUUj$2aqBOnPfGaAz(58k!U*6%ooRg+X?-aKqzLH>^HSzR(4!@P>HwC+v~`iWQv%@8@3=rV7(x3{>RX7#bOmtR7j*UbZL|azkG?%%KdP8IT{Y4ds}g?TL#L5b*wE1dP>;`4zNiWct2p9^Kp3s +1o4RyTDkvNowdtalJteu?!IyW?I}b>07u5?|ImGAUlb<~ijF__ny7INLc^F_5Z`V~CG0@NUqr5{3Xj6 +s1;c*7qde79`VkoQ0yES{l(XrMwsiZd9%c!`lq>DecFXNlGUEd_&p2UR-wXNCB1BUln79}(8YA6qWo2 +`cSg@@0vDjLY3f&pvUOSI+pk1co~XVL63=2@6uiM9dxqepX1-APRm;b1qsiFDD4D*}glf5agnkX4l4)tHJA)2aD ++RJ6s<#8>zp_~#6i%&NBgbliyren}}x+5QLIUi}z+c&nWMFMii;OFa=(Id+Kzgw@s3PHzKYBHr?sBgI +bV3MkHsK_(0#GpX|O}8rF>Ku&84TrU}el*RWEdZl|x@54Fu06QinKDnoYZ1gAjytP?&R6T~`bjIg(+} +Y6nxC)F@omnXo5-!0bbhFIj=c==Fo96ZwCgup#4l=Fq8cyk3N`NdefN}=yTtn4r7M!N3ZYg~G0hovu| +o;A@TJx9&cp6ixBH8gR+jzUXW23h($}gShyxZaucO<7EpYTuNf5&TR(}D_UMkpE{BGR4`!q9^M7KVVq +b0@nlM-CLlsBb(5~H!*%*_ssx%0#~_y=AYqm7!ud12}fy7}-;z1sQfqA{B2z+uK}#Ykdg91l*!z~Fcx +Skm%VI@}zMf^$=qs^r}-5f#v*v&~(Y-1|W;Y5Bm39SmQL5$DYFP& +SCVW{+ld>1?Y6baM?E>OyhYZ*{dEN&59|El7ovj;puy3jaCfjHvCt3Kx#KUdw-<_PTn(itNcIzb?0Da +nZuT9y+OF9X+CIi?tZ57+vk`k(IsA>dvYDuYDRa5C^Wn9Ga_n+?+Vu;#n(xI%lh0Cweh0IWmEo6t)`w +iUbRPpL4oWtyaILo69ef0RGb&*;3ZP-6w${X(r=L}DQ`1$q1@Zk^GD$508Ur}ODr}1TUm1G-OXl8j<6 +c(nW61wWFxiA|y0g`l{TqScvkR}Yu0OUg`Nff%9%@Te%C8&`M?w2d-OL*H|(7NN1dtKIm)`U9TjlLqcIoH(g6SbSJfd_Z_5KJ}j4Eg}NWq-XD|ZW1E +h3OJRa3#KAI!NQ{>go3G{baFI&Ze8*g7Z4i=%t*8j%fJW;&NlE3TG`Xf2`yz#O)Stdew72q&&S3BtaJN= +_kKKjEn7bVY&RW}=hqfLG4s1|5tl2Z2+&7oI-h2B^)dPV$9S6C-WQxQs1-8V_mFw1oqkB2cnrOIsg}c +&NLAb~NHaV>!rTg?N!K^IXShk_&&{D@%k(ECC2GYD{lAG)XJH8QMjWKh${u(A<%FOQ!CoZQzjy8ubkE-G4-A|iKBOGxYD6~Qc$@a6z^`zq1)}NsGE0OVmfB!xHz17t3vCo_F6Le?J)iq1$B@lwD?`Oybwky_%!tsd@2P)3 +?A~aKAYFwOF-kW}k*Q)C=NE~V=q`&F$f{O@#<_PHpRJx+pP}Q>P^i`MS?BAhF$ii9uP4QiObQTJhZmn +k3(WCTow;su1fO<89co&hgDrA}MJu@nXoM*#*mU#W9qN7?XB!CK!^?;+j(>#|q>bYr-3_t95*4pwJ&) +V*D40y23?`G3@nO)N&b?SAf;o(~F)ZuWjmE6l6$PL^sH9qCq(!tP~-VPn2>Mt8q*R{nLeJ9z;LNN%06 +8X=Ev`8YjhD34jt-bNy2fq!1`9yd-TIjTliR<;zI0%%t`1nGppdtujOW}F!0|WaSGD5<8AZCOjL^z>I +QTFf`g(V?+;|e2`$JHqO%TbQG*UP7XzKVhK{A_@ir>;fR?F<9*{=I(*Nyj(u|HyEW&p3=nAY5ypg{10 +^4VN?-S(Vw9Nig*D?^Tty69h!PJsv8If84DHO5odYl7hsL?{tMH8X3_EI@9|Hf|O>P+}V`Z-KRoP`L{ +BomBQt=FOo3p!vPWT(m|5qBiB4dt!JVol2OB#Ul2xa;ndgTLu$4xGXAhoxD3CeGLMS{-7@&zxnLqZJO +R`iIcs16TWsZfLQQ?>Y!{}ardr&`;A8|?IOus*(p>9O-(+~ctrL|1c|kMz4e&aGAEe4It{+%sp5*GXC# +YrT}pWzsGt)tpPDE`cu}XbB_;v9E9qbY*#H`bG7tRJHzAuTk5VPJczRbqT4!*gXP +EEM!2~gCQG0$v_^xw#~e2R}Iq~z5``*Se@YV8x}~FGNDI!bM}dnB`x(!b-r9uOjd}Qjmu#ODlRTc8Cz +0GcxdX1IKPVdTCVEjjh(H=4@^V0gz4L5_)2boc4QFr?y2MF$2ev`ynW4v$Ip)0u=k9Z5O5?-w%(4Qd! +`72iNay0!K&wN(d7x}FE|0WeHj%|S?2PjwdDw|6?k$5K5nf*Ze=)mH+*1j2`fm=}jEu`i={UBDvc-BCFMj71ZO?1oq6)@{a2 +?5;!CR_ZO@pj4yTKVmul?AKX!9x??*^O;@aw+d5CKqB5=(nm#GuQA{LS3bBd$?lt5G5}xe~Mrm}Itgl +9g1o9d!5A*mUDG<#CkNCu|WAE2H3SRbXH>rzSbt1o5X45TdS}XC*beYT^P~hm~e_^4kJU}h68i8$6h3 +eaUavPQIBqE-Pf|CvxsAVutViv^Tt??paOlq<==uT639Y>uEIeZbekfGh(ui^OEyDG|#8mR +ItZ)wWg}Q-E66-=3qhmb=2nJDFglizZWNXHs%B3m*Ncx^kXEX0|tX6kb_Z&?uYOok;FVAA}W2!dLPC> +exScNC`j~`I`(HH`r?4S`Dp|5ZYhBNhfhIS_5W~g9}mUDwhK0BiA|=4mj%*8_V_Vy_Sez3Z{Gd!{hu_ +{rvoR54+rMiKk*5Kvfb(rhR36)<7X$&WeUduN4}uwH@>=B(j5|Uu_IO3Zbgruqk_B^o25D^6^wCMECR +R`G|W~%K%ctM$r1iBgg-_n_(vc97{Ygh=kVQN2;cQT3Z@*$(KDl?g6a3_EeB#NqDOy`GY}Z>43AiU)rA>m^wcvMxcz&+hO!J;`X!s;b?!S ++A^{&s~hvDZ%}eVtI$`TU@pMntikl+q(&M#RNM|ZgdbC7p_27`IQ=*Hz7SW;*9fCdGfkrlCLVZemal^ +KJ^bNn)L2v_kA}ER{?0>!+<{wRMI1YSo+vcuq8a)$kqZ5~O<~p>L6qtlfBwAox>(qDPrQs7dI=uIGc;WgK8y^?nqd4PTzvv{>GZ_SiQwFU}l& +=Yg*R?ohgj5ic{$qq)XM$Ovae5iedGt-~p*4;ROe_0vFiEihP?3ZlY`hOI|4_RX;2-w-96o^7N<)5{0}3&9 +iaqF+6u%LDC>fxFG~ZKugUqa2^;DmRNo&t;Jmu^KNsH14Fs{Arc%&{dRznI{+MVCx4zxZ>4!o#V^vX3 +Xx!{JpPOF3t1|3T$h@x17s9^Gg%lJ}HT?*n(aX)9|KK(m=duKDHU~! +c?j?K1uXo7)edvG0L;hC36&@>v1KlPrjzqg1Mz8+z!E$Ed9f!{06AZ>SL+~A$0D7?qi+3D8R5KRfvV7 +=G{!(Yz12~tJ&!fEON!PG-KAa|{(mgWn-1Ssr25d%7(suJlQcR5UMsAJ~U5T{s)qtl!Yz3T%9%e?{z| +pjI?QK$gbE!RTee?TPmrXmMSwTJa7pjpG{)&WK(de~KkRf0HBQ +$n*~{e53Vd3p#r6I8`h}#0I&x_%CX=S!Jq-X7Ppi>*3&IuqF!Coggmo+x901jkgd(uMN^`g!;)rJdpN +gKfgLDK}vYwnwv7rke}trlrO74ynQ|BA3tTsy{DDaoU^O85MGGLP=ODpry!b26JgWBEYX(pkRi9cUWn +R?zSW|rSS72-RXikU5fWuogxB1Qi)gP0V7{jYP(+DnVO>ROvfeE5@JPjP^+qtRdg`-HiZsw#1iF&xz4}0Z+Ozamyo~l4c)G}Y3D&Y@lHAhI-QEar*sGUf~5TIc +sLvkhfklMJngvgl?)a>azP1N89AtF1DEKkHao$4lvSm74g{Ppj8}RCu>gPG+Sd)=EEdTup~$BU2jhFt +xPel;Gg;aR5X!4j+k%7wFU)(|(#yKgh4D#)8q7ZvFyggj8}&#)67gpkJpvW{^Oe7vXXjBzRc~Z-KD{z +c7ZH^UKaVnO>u*hf0%!-H5%b0I3O0r-`DBgxu<|rECLz8MEw1U=*Vhe7e5W8@-YMj(K72n`Qj&&z9am +Mt9#T-sHsM~!VIW#ZErP!mH5!IW{*uZ^8YKZ9Hu3KbXtBz_dci~4b~UIL4SdCez0)L(^4s9;e|?r7!d +JT*@tKlM4Elsl`Gs?M!v0(HEFL#~$I9Os+4(#54nEyoRGt|bq6l1yp6a%|q5AKhR#Gn}n6+&wD$F7i7 +k7e^6Wvi)dw)R*$BJAy&G>lmY|uQ#xKg!LD-Cq(7nct5^cgwa+a;qeBpQ-2no}6o)w22O@;YP&-0|^o +|BkvLX*E!duPO^r)6!CSK74jpDF8Jhro~`vRL&(1r|J31y+Nb5Kq}m^Hn~nAx6<*^jCOk!jrp#YyyRs +grRXKts}Q)%X>S0{8i7l?p)OKZ!p^<qN%VorUISZoKf +^5JXGS4+9c+I->dQ}{N+^eUT6%B6kQVqx0M17lWfiRohtRjQ>ZP&^+Bce+)o%4l9yczNq-mFHIth$rF +VHlr}n|7I@~>ri_n`pwJ#e8i9!(s>pgQu%ByJ3RYFj-s%N?L1tDvj*u23YomEE_s5+Up)x!akQ571zb +Z{W!_GFml-31ebShj-Q`0l;u!XNM>AbvW#NqzKUgt&;x7UGrgBO`ns!68vbpW;FwS(JH1hj?Q9IHO0& +dm$lsk5|+@sv^a^B=j9;guQy^2wOFqjb+6nER6>9#eK%|Z!vp3&mQyBVkZ+*qhQOuJz?PB@VFxy8b<8 +80We3>;D-f-Gbd>`8>rgnGt@@>@18BQpU#l>$wmwiF-!TB8d_-U-JG8Otc-Vajz;FU`DyzJ(^PaK-GhR`Rw5`lr|HQ#O32^ThGL2kbRT8 +Z6ePh(!`IKHY3!Ny~h6KJlfw<|AZT`fVExX@5 +M>FHMq8yYw;)4&R+%ojG0vLFStcIr=R^A6?x3eFURkDoo<*hsSjDw2GUyhu-{+g1YXh8;x%;qpw_XfE +4!2zX!>Dw+_LeL3G|*cE;fMbxSPay_U?iKU%fqtnt(0khwJz%Exm-bC}V +y?dL&=hkOB7&^2k$9o#+gcDG(|nxQkCZVwdzI=0@)G0)Hj6nj#E(l4dErip~~2 +O#TD@lMzJH)Jpm`Ap6-PquiyS%g)43-Cx+|`k9_NM9;cP>nYS#S2F?%XDoNjOXW +9M|O;RHx=<9EBa$MasX!IW)+`G0UXJ3p-b=q^zpmL%^C&4@D_|ZQ2sEmQ^cw;>i>ps5O6SVac?NCBB9 +&Z79ngtY+ktU4kPDX{1AHC1f)#}SJe1T;AzHh&cv_2^b$Eg!&hg54@=;aNg4*dh)die@Ec-o{qT@Al& +|bj&Ca6s6L|2^>f6tICNHi^g^uQTiElQLW9`8@YOnp~h@7RgVh$a5TFp;$X8EJMeU9CAl9-%^G#6n|+ +?1c-{0YqzoGOjAHE_l5uG6K#AlCF_m-$ik2&$B*I}T@Z?{8mvJ@j77R(t$HgE8{=zW@F44z}DlN2M!rJmN7dOGN#mew{p>>nfhgX1m5Mt!XSRb}je2Y)$`ii+E;UKW$5W@am*P9 +O=xvD{L>u*#lw1ftIHdAQt|Z4Q{kxEf4idb;mzAi6?%plvYh;#(EdqEt7I&sut8J +P7sH_>_>r*qiM-q2xiTe1G~B^!)!C*8k!3!f&HRb8V}jTVAdw*=5Mh2$yu;Y8`;b59p(c^3&SR0>f;V +(|#}rjU!v{^{wyy45O>VYm}yPy%(Fi=YpX;|ExDB!Z2a>W?mmP=7L$mOt}^4JxL@OQUM-U3i!gqQ~w< +_~08521DRt-EX4&At_*+8|8B;IT%d3eFzh9k$`*HIz4Uiqa_4i71xKS;4{W?Y7YxNWid}?bW~5*<0F= +D=)4J~8uMv5g?g;`lz`gIb$$E-)Mg&vfLstdUj2e&m-r7yK(`G^`|%24YWa*!K87Qsy3tC|dfma-Ayq +{LRg_S$jx)-#Y-o`A5Z1(KD@M{SY{@Y(2bv@?xlCj-yMPSI#Fbb6VCDK&9GpzEtN3UdFEa52q}4}BY? +(D8Mz60O=~G&ZR>NVCucI-Xz9>;mf<$VR_2~>xlk5oM&p4J(7`iX%?w@-*`QkE` +T>notsb5+{|#Sx_ZSLcSx4FofPX{!ZR*>#EqTn0RH9YyXP_6Ol~l{arUVQq5DCy!d)eQDTOO^mV(igD)l061ZpxwbT +(wBslpUV*I{*q*s`(66-#{T +dLo16bUyyBwyACvKBIt24yG@We!raddbsb`*B|%0=R?k?ctzs38cvcmd{kT=na}Wcb3IZ_<(Kgc#!V* +kfA~bvzzQVRl*n3-Bpo9K517Xg?oboZyziCH(I-h;d@i#LHCxDAoo~bPEpv94FYgCvqG=g!ho+fVkud +eMe{L5lRmClvP-ApAq*>2dhoYx8TrerLo|u(6nLqDzM)`i41CHm%b8gH-kIa*^X*Aw4?iiyM;yZttkN +h))@uw`G%5zFZZ!BxJ^i9Zm<*8KsV9FC`a9##hoYRKMP}R&fCJBw7h6c>V=93`Xx#lS{p3JCniwNA? +IeN*vu})L&uvbZ@x4VC}%LWu-N|TKF0x)LgMb)I?wQu2%nr%1ak?}V?J!?hG`qvH_8I{WNEIkv@PYWZ +cip~C{-b3!N^SJ*=D+oDTFhTuWuS}g?nZA8G&BJx74qzO6w}_N2NZZ4#Z$W@fG2??dvFh5~-3w@V`)# +Pb&6r0nU;2su;?TrEupWOLZ|kRJiH*)uQpY>j7@~!>u9FS26eAxau$GoW~^|7%rj;80d^h)tpW!n`!dJ^n@6G^(Mt@xlR9~0kN1rwJ;T_R@Bj0G-q7AWlp%z_ +WC*2j?T`4H~zX{bRwkn`vS`eRt+9ebswV!ygGoCo$qexZk6ERxpucY(+Zy`3v?GM#M>_hyaLmoJ5qX? +w#a10g`6I7GI=L+nNh+BCVikcf~V1ohAcy~&CaP*Pu&2e{JXr_aaq=2JafDQ-1YRB;G7tLhSI+vKLAYC_yo4D(lcO)*^jF1Hjb? +^wX~lpfWND2Dio%s!}{2`RohBRpy@oEcPpV@Y#eyH4y(jvAI_-YH?7%DlA9yzF5N-op(WUtQ10#fZ4r +|5RiZ;gm)PwXovulE~2OuYeXzliF$K1Ec`~^^p*ozo;-W5XW3ssRgD*u<@4%+t9{~Vg3|{b+@#4*8w| +A03}iOrW{SpD6%CID&yPRDa2`J$@P}o`cN|m{V$(tW1%e~*`oQz&0!RMY?vj@GxJ&x$>)7hE%j?+MZ& +JxLzYNUd9mUW98Cr^APz|ehHJYq23qPa;M!<#uU3kH!eLr7#ksRJ(k5X6i?79}ARz+hJ$JQ=Sb;MHnr +g$OYcu3iM{Bl7BP-N;I_=oTk)D;D~rcfo{5|J6RkcQD6JXp!%)ij=C{FN7lwzfacCF`Pi+hjywt3O*N +gjodyaC=1JvDM8YGS6bZ)dt~4x!7Grk_$OrZCQ+;385osQK4=B=@E#vnf#xRh5WH%A3lx8z`|{?XpTo +6doX;oL9_0Eg-5V*2#e&V%of>ZOGJ}YbzEj6J)#Zg$$PW*peMRKW9@bD$D=@5>_z~eYbt`vu12- +59^~eqHG;=I^C;g5)gN&f01xqf2OkWz7T()~hSaNwP^3bs4TY6Z5O1`BtUpp#!Ls2U!{K7%W>qg5Os= +Lc#7dcdnQ2@VuH>nxZ`IiYvZj95fkmUcCkmSY){|ZTNllc{ryc&{R9gJ-ajQZ +44z8jG!52>7`BM4#A4hW+Q)RA)xtt|sAy#LU9r$zb~G|N^y5JRwUrfVl+z*$f5w +~^*@Vn#3G!E+(-JIh3rt{(>hLZBnq#cL%i^@ym@I_8iMbQ;EG=n9^n5IBg}K;@##e4EH2*Kjl8-U +HA{%PdPZgtkWrscgwVzI%d>N#$Wc#4Cu0LBy}4S`=~o`Ln}_Z%;--L$+IXPvf9fHBzivn`(nspA}8~D +?|t14ea|qh~3Rc#*4)LHwODwviTM4yC!ZJ3U}Gu|$AYKLKay8{_(QhA%Lp*F?aaW +Scc3Hh+l{l@WSXVDou@9Z(&23AGTG!4MA^|apLnBiOHclA@mt%$_Dx+#|Dw_<~e6_9S>#CY>wsHHmU(wIECtC#c_6-$y?hdGzRq9XJnVztF);X7pJFm^c-v0+sO9KQH +000080P~d=M_?WYjb;G=00jd802lxO0B~t=FJE?LZe(wAFLGrqc4cm4Z*nehd3933Zo)7Oz4t3Tc1Sw +WO6-WlXY7Pf6u>PWA+3^tK-$O8Nz+nkEQi!_-gBOxOP9WL0XkpM5c$Ux_SBDIYr6e}I9&soqBx;L*f6 +#3bvV^}@8egF=Oa0*FDR92$e>bXSrkWX;OcdYvRoIyt9N9BTztjc8XQ(Pw8zfX{R6fKgWCQKiQS@1cv +e^Aoq}BDY6&z}YdQyw1+r0;As<+Sj570mTv^sk_;*J(p_WW8Cm=Nwf_yBLnX_6+QF5bpm*5a5OoF_Fr +#p}b&4FzVLUdvYwhNr<_2JB2CnP^~wTA3jz7Qq23L7Fu0|!SY2dS?wn!#H^)(35jU`iEu&-BX0Og1*$ +gV>dmTcaCnSsZa4Hz_`9Y}<-#(}`KP|8!cgQA)*FDcEd4C>8Z6B?c;A8?-V`PP_J2!rKNupH=hkFhWP +zcC|~z(tO1ep68v;XkHM8K4*;4u1xXx_w8R$O9KQH000080P~d=M3eO1u0Q4pR02crN0B~t=FJE +?LZe(wAFLGsca(QWPXD)Dgy;}coyL%VrFzp3PI?DU@)f&6nHDR;`zgz$Rbr+Dj32fTq?m=m2&LWhzDBR1Yj|mlj+ +4Bxw@N@zg^s2-OUl?{nh;sH$UH#_ZPRf7uWY!mv`jmmb|^Wes^_$b#o0*-;;~$U&-IEuHVfG18V^v_E +ZYg0L0{INtS4{-7)5fkQPQHS+ba?JO +&qz`*ng2Ygmg>EfF=-+XoY=d(9}o3Ir8ti&!jPN;a0b8>u~eBRE^Cj>s +z=~VxH$Kpaz1;VFQ9;4=kclDSIjUr&is?^3^6_8ioY1PrM_19oVs3eax;|UlrSM*6Q<0;8l9%v0_WC=FZYh +s#Zm=b2zusS0TjXAnXi9}_u^PAG8{@tmtD3M9+Y`9M%2RZ%XliySt9 +E#=C5^^--Al@V2nZAum8)n>)SLGpxUbT>wY45O4kv1BiWsYlU<=a!)DD1F+y7>bQxm~CL52$EhX8^oD +yANB%5iH2FM9a*%gGR3h>3mep-7#C0HZB*ou**>AN9HfN30XU9|htc1GeNQ3e$9#k3aKBp)5q#nh38G +cd&La%9Fd7LNDCA#bT^gH)?G^EK!j2J*anjMIcZ!9>!i@Wo^;{3I3rqv1(X2rSsT=p9bioTy9ga0T1n +VaEA=0P5aMsK?XuUJ^K!<7Ki0hdiau^aFg(W(^NvyU8wfkI4PayBk6iXcE@YqU(0VWD;31=+Jl}q($vabb>V{MuIdSKDOig(;g2ND5ATa +c32_qg?XZPvQQ7x6cwnEtR2*w`+pQ(19-r3(H`6e1uW2#cOWdQVH&@Tug>UZl~7V^3GIRw=o}ikU62O +7;h8=gqaCX(K-0Z?ZC%ep%4o;|T3x~HW%Gy_W>S-GHs2F*umu8A)Te_1#(4I8+$nVD)4i0LCK +8o>lXK1lttajwG#ZbGFNuLEwpSw@}n&LUS*QB-LIeUbf{-t`i7`>5x&+E3}7@W>PcPtxjUv*fNfjwPP2h9a)u;(w+o-a!$ +4ZG}&IsaI*uz^Cgz&K`x$(V^8dFHALiIsM)hcrT_wK@mc;3^r6KL99(EpB9TwBy0P7L8}{i3^<{iqJl +jM?{LxlE2g%LK@p?z+DPdWv470!B(^usmlxTfkICHc3Gk|{*9drYF_U`7=ebGa!P#%_Kfuj8y@z}B%W +23!{tQ~=F{r)98)@#25!YjYZ}%KwM=UeG;AIVL@87j;4T)u} +da1qu>sC4~&w-`)qOw-Xbx~!ByRtcS+Dma7bTE7^t!vtFO=Z^$^bMdF|7SVcaW%bY_(-#geK`HtMeeY +D8HFFUdvSQKfm%7j;hh38=m0-t-%r4>_n62Kr9I0VakDlNQ138B(a#kSVIvyYc6#KI@p{xD +#;0Q0uv?@g^KF0$(561=z~;^+OXg%%Df69ts-$_rujAzJTG4zD+j;<7t*ewiD5 +UhrNq`Xx8>ct+|PqGF>%$BW_xX;sjFU+H7`VqRkpCDajG@3VTvi4N0n(F^%rjd_Jdrg?eRP% +r$VJ}F6PCxcgzBl^8B<*oF-RzZbO0~+-Z0~@92iC_&}yW-5F6;W>Xg-m*E*{-Yw`C9xphQN7+#y`t2X +FQ*LD9@#Bn9?2M$Rka1J5Z6N@Wc6SfMp_1k?3XqXR+l9Nn!QAh6?ftO~jJ2fca`(D;KOn}yT?j&wX+1 +&e9YoxusHMT`-IA+$rFX64H>$m^0zR;?()v|fm;$5XZ?s(sz1lrEUlg*1-gyxCnNNus|WNuDxD~4V(w +I%eb(xl#=0>}H(dG?2XF+t2{RTBOb3Z|C_o%=s5KF+OZfF8toJUh^mbSFO(L{@kTR*E`2E#E%F2sP@o +c7;4Azb$^B6Rqv}zw+Nsf1idaW?sEB_G5lJ4L=n;589us)YOq$1+HqdXDHVf;}={E-w#RAahkdB^o`d +pdr8?ACp)y9@`Nb>C~6q;=9gl196sU$mHFgKyY*ob1wIy~&v6jo9g{*RQ^V|9)Wa +c=U(64FHR0JQZ;?_y(YFdAbdR2!Ko=*oLQkxnt|pjWX_!*(&9n#Vh7*+;q*yEQ_J59ZLwG#mmeMB4o` +4=8_$d1K4Z>ghaf`9^I4^XRZ*j7q~!?`LUO8d6c;s_P7c{7^9VKI2$e$#&AU4_}mSF9m4D5S_#!fE*Cc1&jl^9kXrh2P^#LG`J*RhJo0OnI9nWWu8H$z)Futhy +`Q$PnZwELu3tT;0)1-OAZMN`$qApLARW+{1`+>z5c=l)g(4<7_uc-l7p^6&TeH?De@pP(1XAYSrVtzX??V|Wa7h= +EpFc5eVWXtY_?#x^P6917t;$ioGhR`9J5ceyAL-X?-)SLC)ansvzzy9a{W8|`|SE+%%;EH&Zmn7yO{& +A+12gkYznor>+{Qx7qjbM*gL?yzPV$Uv#Z%1kiEO1E)}uabb;iqrt|X;P@KG*UC!=)9|NiPv%71g`~G +ImChT@Hznh(ZyqwJ0?Z^4;&0-2HTma$g+4cK5^fSGhUf=c^cbT_{NQLGq%yd5z3LpKtw9U2)TW$Bpe1MseEo)!&ImJMDAzO +tysUs<2=r;Ms46{=eXk(=&x?Q)l)^swP-^4ntee^bTf)_oGeKly-%g12(DbOo1H?aW!o9Sh@VJ!;|6A +|~bJ+2`1F2bZG;*Lf7+`qjcYjz@O9B8HRD&0w;&Hh7;j6X?>d;UDgUI~+;=@$Vboxo7C-&y`h<(RiOAbq+NTRds1pH+T&T<)Y^u8MxTr0{iURfjp_8(`ue7kc5UOL& +R?2@FzezRh7;0DL|=kpah6cD_AV1X&R +?hly5*l-+_QCm3u|h6qBU&8yF_Z!u5RzLIMjN#~6bHB@qZ^CVo9yz~Do=7_?K2b` +TURYzL{3<-@NgF8zuFt9%}ED{{BIq&|~AN4AZX)Nz5u)lJqicLgqoDqv1Cpqv$*I-0m6=?;vkBcme<; +xjgW0e+-bIG64}cNbiEX{jEAQZFEs%9LV^nZYjpVWo|AFhu+@@z%UV1G-?0iGc}`QXXb#XGp?_T@MNyRy5r5(5&5IN+a)rpWSj2=Ns}Qm_&*_aP2^fx)YiG=i-mf&}M +PqmuG%{7?Y-D6$}dWy7wSQ>Zxy4Um4xF~-m^j!CBCx)$q50NW56O{Ek;F@IMOXZcrBoyxh~Gl?)KAw< +#}U6qspA-uozkfQOWwqE~r!oVXiDj9Z*JrBk`s?!A7MqW;KZjloZ?eV~?F1fG`YWpjwY=ZcGWTW_ +y~-sHV0!dxfyDU{F%HJ&OC_hB>w?LYAYgnJ6{%yX<8wQAc&IskUmZYPRL_CJVH_9d5WZ$p)=GlPm{Yx +HDB$x~&_`&ix>5t|mB2T%A7;6$ZrMaEV>P^_LplUjY!Wq=Ugg2}`&qklk-lMIBcgkN8p-9FdVsLHL+2 +iCu6Q0yblz&j3A51KPX>(#9Gjk=HL(Lo1B+nYM;%K=vjtum<}f>y!0GvE3Mpj*qrS?77z_9c6p{c8O4 +J)aC4Skq00>=58R(2SK$kf`3hK(1NMEY7Rq_R$C+hE!Id{m|C1b6f +hN!lx{Prz-%vb+e5OL3mmX6?KF$VOxNMRVmx3T^Gh8vEG4+;K@cC612^Spcl96D(bN1*k~n|-2zg`F_ +6M_`F48y=G7@%1(6RV5j~7uxP+Z=rY&}f=LuWr9OGc3hGBSd-emtE&vn8OR@Ok!>6F?H(Gh`!ds7)ui +^;+ulu(_XaHj@Ug}IO7$4E7!6ZzM_jfutR(wH>5n_)9Ll~)57}B8474&&Mm3`o}w)Zh6WvcrAt}>0?6*smt)niDyaK +A-?fBusT;s1U)mToTSGDksp}BTgStd<#;_A@>ZVAIPz6z*KN32-^k8p|2I0cMkWA}Xjs3zi2U&?(r2| +y~gCYEKM8=#4B8c#G&*K&ug%O3;Hl>m*{NEOWHGMe&I#S9-1XJ2<+gO#E)WlM;oIp5<>)pHSo*B@N2L +I-gMwaHF_JKUJL~vhEHSJIoN#!r`?-PJ=uFg%t0dHbDl?7>nKTK0Rk`)Q}m~`2Kykdc@yyF}Ddj?!`b +hO|9VC;NN2Gt-pt|(&Dj#;C?4J{V}H$y2A6c1E-oiNR=)k|O*sfjpGJr%;!Xpo#hSLBMKZZL3)1@NqW1=W$QvCxu2&oaIhX7F7uvRFr!jcXTJCoNdP-pk{{ONg>34;Hr2GIvK<&71y3&mk +7m}q_Tn()badCrDuQ1^IH^(f^?|68KaE_L4nTkUiu3)?V2}1G0Q~7D;oxaAm*ej-&l;pz1llEWb&gSC +#2l*0h=%pzXcepzyjwyp<($g5vfPf4>{6~|p6ndFZiDleTW1~R2)Bl7{DmJItJ=UFKi_V5PPR!o7zhH +_%2j|i5}PbbU@?jB1OA7bN(QkI21_hpvt2gtp&+C%@Un(1I#9QvgEyEmg^Lwb-oZ*<)Yt_`Cy{b4KHO +bh-WDZ7Pr4^YG9L!egXXw0a@o>`$+vD0I@Es<*FZSJSIzHGv +_<s;sqLldHh>5+uDSxs!U*D-P^ZS5L_!jNltA4!gT>Ryr>LX(u`Zjyb(dfR%qOygyomBC7_s +2DSA+h{#)!!+@Xutip=1wt13LKlTEYRlYjSC{kK^Kzk6gnE{`#~@Nst)ngh>dU~qPu4gEP*2+EJCo&U +guDZ(Zn2j)Dyv6w@+M{bnOt!gVw>mN5@RSQ2+uK#UPc3a;zHi?F!*TR)x*P;dfi|kZ!(-!4^$dDF&qu +r`Jz_M*l=Xr;iCh6dA1Ktj%g4_oY>IWwZ11(wJv-rc2J>z_?Zob*mHUcKxyuNi#2!85N2n`qf2K06fe +OIk3j|)*qNm6`bgwI;vhN_)r5a8u0U}giJM0+={b*%?z=ddDO~R1XigI5;`z9FbY!Or@z`!t*!ALx?( +#2ai>NPeTjZs>SQsN`(X>o`tb@G&(@I+oQY(p_}r4K6Z)^X9W*?EvmMV_ +WJ4Ss@l7Tw5+q`I@pWZzB2amHRxFV_N;Py!opEA1XY1(dkksTYWeP6a49_eS_`g>H7g4)RUN+Iew<%U +s{!n3Z!Bw|;`zm~xaY9<07JctUtTBFYqRLwt49wzX~CmuCGE#k +MAPDTZ&&}fM16ajqvL+^-}!BO9WlDS#{aqNZTJgme2nN>y_brS{N~F%6+opNO8nud6$qfbkh@Wy +9D@zPYkl>7#x%N-w|fx^uAD5gV%% +Eg3JNotVrVM>z#aRdi8)-)*c?wf;9C_?-p%ReRQZJ;Cf*!_yz)yV+r7^wJ*W#4rEL8E>q}`)uFZ^(T_ +9+iM+=eIv9MuIcVMMv4^U(_Zx(QZ(4*VwBIDk+e2T?DvUc$Rl_J74!4atBH`j)K8JJAjjj%T>tW$Ql` +AP6r*$QMzvA_9`fS}ZC%Iewns*BKYG8FHy2fpzX5r`Ns-%3J38xLl;9Sy2i-7&a25Ko`NAf8&p4#X^%Jc%pK{b1z6I}mm`Plpny&MXq?c}Y?| +k^cFFFiytogvN~*Y8diTGDX)V{gW@x)b(!tK2WDgS8+J9uLpT^wfe%m8)3?gExxl*Dy3Gh*1ORNq8tU +0Q+?12*m7;Dy*WRp7TFD@2WfUxc^5{%q+RK?d>>`co7s)mYS53#-f&jE%yB+H`>mjAXVx$RY31IA=#J +U9>5zTPXw>5o%ENrm)4`WQ9DL{+vy3=&+IQ3Zr3-_)rNA=uJo+X$cuFS`a{mfJ>96uO2`spuGkS;iH+&k4R%FvspP +uW0C|252>G5^wRsu)&~HJw3_*+|A34e$qu*0D?;JU0y8CA}l6FMImeAo#v#vtu{fSvcu<2J8$mGPuWO +snBwIL-Ag|%^6X;6`}*}+ccJMzLO8qtj+ss-nq&YLJud(bDEfT=gE*nM(3?14^ +5ejAa2_>n}W$$-q=A!$fEFZlOw8v(v&WKmZFBgVsxuL_r!SOQm9>SCj#SUZg5~!^p%^9-$jUjuJ6+2Z +pC;MKire9aB1x9y9=`;TV3U8&3n(a7%a7jjCYU%nUulJ>Lln-!1;j{bQR`0Xn`-Km=jLCfG)KC-&nju +r>+-J(snQfP`wp4+D|y$Cpqh{zJeYaagA8q|Ts*1JV#%hX%A9L^r%_H!+CoZUkxu_^Q)6cv1?$7fg%+ +`l886Uphf0`i^P`*YY<%+2q$63{LrIN +oA1&h4bi#c!EnrV4mVr%LknX2XQ}sOhpC#*Gdb((OsHG*EDkE(9FqSpM=X9d)UaMUfBIK}I%BWRO~49sf}LWPIxA>jJt>2oWd-9=dv3NOv(yq7zSAeRa)nIL<;pCd#oNm=U6 +@RZNiSrd{EOv;M;h4P!Jz559B^j(e1$+|~RYWZmuhf&gk{+YWW#?SS-p$R&tx3%Yd&7VqGqp}KI1Csz%uiLI@137=6 +;`H84Wqg9^MKd?@-7t89`chg-IosAUUyWJNft9a52MW!c{^IRjd|nGPty;zFoi@IuJVxx1sUQ_yFw~ +?}3td@Nn;z|;J^AysBiXAS$(5UV8?dC(?JdU`$|AEYBp(-2j9Rqk)Q)c~Rod0TM{Niy_rYJ>bS>n{h* +xR`YDsw{XhRAktBzgi%NXv_of$Ot_4cxUI(snJ1OCK4$4Htc&rE +oo$AI=0pXO*&IsmRO?(3hb5e83T@908`A$ye!$W?c_!xVAhQi$I6yQDy9-_P;*W+a!VeofY30a7mmsb +=7h1Q3e^l6Q$WfyE^}{VlH~H#);3dQ1S?IkT>`6AB{PDh63;KGY#GTx$dnX?GYM|5^tPh{gA2g=sLe(s;e;3k%v +q`6+;5mx%F4Z*~mU$BIIg0RS-OxoCQHBRroA)Y;T~On_4~3SQSasA&ujJpfNkfi<+qm<9kXXQ3&88b5 +bwUQKyO4yUG+L{e0etm;2$@pw+EZiyhL+gxOr2@qMu4+6LL$&Vuv%2K2``mgF;K2EFcHC6 +&jpWQR$;485*N+&A!t!#ax=h8RW7m`s2I+Ns(_7AXT0+hg%NL5$BtY!&(wl@`1)%up5U^37td9gi%os +4#X5i||5$=bewteoLqL)mF6gTs9|_)>04?+QP{og9d3Rb`ATF15Cr+h`AGL>yuS(f{KPuyt$J9-Ph5s +j*ClB^l!8+ppS-D;RG@snwPUp^Kv6%gGjUNtK)NkVFiI1PWX+ipUdoj72E)2QrPB8~@{pQlDa!$~}+E +{lt0{kjE?5`9!Jz1iz+fLvbDLoZSMifciHyM(Je +yL1ZsI$t)xS2~rH=={Sw-hKX@o{$+_}oS90pGfH@39w34W(!m^vQV9w}<=zwn6xTBXwt0eep(pIf$O! +p`#{&Id<_bSdsDZ8|v2eF!Q0oIkib@RY}xl8*dOkI*#RqLg%i=q?43m2x|OMTR2K2<&z1l05lH<@D8M +{Nf-T(*-6In_z1tcK{Y31W{t+|U;nN=Q&QoVu8e7;A^F^k<+(IUkZ#GU&p-9gqp9C8VqQa94bw`~6H8U#g~s$C%VTFhoxrVxdW+N_L_;I*~DI{V|WWX!2Lwh^uh&=bl+ +$o*N-i2waiRfcvbuC#w7nf%R_%Ab4&rxRz>kqUTCW#TwZ|_H92cJr13TwO(J&`B_m%#2b)uBF!y|z#-&`%`C%>$2--sChv#bPH!3JWk)r`>+gSfO&EksNW}w$m?T%`7iMpM{E_`U= +ajw1pHMJ>Bg0@vogIRpD3SxYCLEtt8#Vo+ZnKLd@{Ztc>TT%YP=5JMGp%@IKch*alK8*6X+RINe8bek +fnb$jts;18Nn($lHi+oaSiWOY@sczK{H?InOt=xy+Mx4^$eRNpiUQ;#-twu#GLy9W(jAXfl5OtW%vyj +VBov{LPUE-#kTkjMc*_CQ6)^clM2(En{78wY=)OoiTnX_j@Rg5Jec&lS5k(Intn8Q_p9}GpO(H3lpZ-8@4XK`+1{xUWYtdazeA-*QPCp{{xx?%m@^40=U(jd?Mq#h5=$5j +@6aWAK2mtey7Dsmm +g2n;?001-s001HY003}la4%nWWo~3|axY(PVRCC_a%^d0FJE72ZfSI1UoLQYjZiyo!!Qipa|!|->;Qo +dP#|N6E}gmyicPmdB~hSgCqdD>SGEbg_;7SGF17phYc4i6;nHQHzr +^mqC?f~>{;3PaNV}TeKONBvT>S_+4i`!o4vW7pg|wy3b#`jMtJ8D8~DVLZ4%qTnL;BuR +1)JH;6>PE(U{a7RdF0h3Ykj6Hn#hUswS1zJ#|{cvCJN0S7c3JuV3;X;Qv7j>B9lDv0qS20|XQR000O8 +^OY7yE)(3O#svTXiw^(*ApigXaA|NaUv_0~WN&gWUu|J>Yh`k5X<{#JVRCC_a&ssU13evtqA4;+3F72vZQE=wm_B%j6^wHWKtt(JI2!gzB`hVB}YZSOh8~tyf@xG_waH6&z?MkLX| +=;j$vi1XRqi>G?`3JrRBQO+``-WTX^x^OW<-Xw316MEi9S7d_4`8a0an#YEHRlcF)78K(NA~(wu{_8Y?`7THJAnkFxLMDJTu`M#vXOF_k-t@|g};RN~P7Zvj( +m8v9m|~zTl08QztXmT4`@WRJ#JtVDdLxvx(oK=Ky|l*5D|63AfD9d0?r^Rn4bxv$8z?WXygB{!#~d1lB62b86k%M-G_PG?K8e<`fZGB^FMVShwk1wj;E8y)$gmPW +WJgb@ND?I}Ix0d{%qTWW2^(Q=`w>1qQor*<0*0L*1ETpk^?yGh0VSvrR)cKqwKhsU?)FiI(BXZBuIWb +=Mqxwh<8bQR;P+ND6g^kSGML$0&TGJrTn;kzIf~E|fd^?D`N7!4!6&=pTa%<|*En$&lLQLx;OHc;@Kd +Ha#$50OrH~x*IK4*vb=yc0)C41}(zXCH&^wR*LN)F}2*UpMdG!(&wYp(7)?T>wVtShqZT0$wc6{(@6c +sfy22L*Df4mizyK`YXXXmQq?=_Q#(#v)5PQm2}Z(;L1F}$wuO2M4E)b@ImcCv1RE`n}-0F*^eR0B(H3 +|n9yI>nQ-vx|@O*C_1*_yu{5Y3v1h`B|y@qVek!i~WoZ61L6>bZ&K~Sm{@nR(n=I0MZ22aP2B@2A-Y< +S0^&)U36;RyD&&{Us0a_<8^(N_{*; +G?{*WUF)<&LWh@0tG<&l%%i91|Ys5)0wg%qE{Q;7eH({y(kc-W7?I(wAey~O7o+P+wVH^@Oq7C`h-^E +HwOHYID-fE5M8e2{y|H#ylssJ94CChj7c(B$UMvu5>*XQK2TGqRV4bz$#E&qjoh*Q)Rw*E;FW+aF8CbMlhExxa4@@=03F~nfA%2Rrdjf>7@wc?CiZ>QI_%o?-@Eu`~*>VdD@xcW~*3x_%~Hh*#dKpT@%+_dDPAhB$f}B=`1WqJH;E8I43uf2yM6_`ST6NiUokU5h +va<9)3KB7t7_cwyq6u>p;8Ix?KKi3zpa4Y30l?7=kszhZ5-Vbzq#G^U^Y{d3S9+=}BkMFx)_A*qwVLG +tsydcU$?w9prtjo<#!7vwX4ilhx99jgPiK(d$hY2S+1>XMq}d8rEbFOL7_wuiXu_E3J%r$cnQM(O?sN +=AJ5%cKXL)0RFNMEW04O9KQH000080P~d=N1Xbo@2&s<04@Ol03-ka0B~t=FJE?LZe(wAFJob2Xk}w> +Zgg^QY%gD5X>MtBUtcb8d2NqD4uUWcMfW|$q#JgPE?k;uhzk=v1DVtT8lclmi^SVo1QHi)|9gM(M{8Z +8ZK-6RgnMv9U`cTIiKIqLMyV%u1TFz#{6OMOsf7oybJwoj$)%RZ1U>r(JPs5?z7UPlTC1wUF=MGJI74 +w0XW@Yo*%uknfUaK%WpZ)sg>7e8ni;=IVvZK!V2(#~DwO&SFq2>iB-^V0XI2AW7}CCRUC=77fAsrqj@ +1`XO9KQH000080P~d=NAZw!T=@h50AvsV03!eZ0B~t=FJE?LZe(wAFJob2Xk}w>Zgg^QY%gJCVQ_S1a +xQRromWw7pLUavTVx<)DYseXFiQ) +zHc-Z=SFGEj%{69rKDM{j#`~rBbvN;g}PEY*YI}>#+sa0ys@AS6W-~U{r>Au{#oaim#Vf}NeQ|)dgSE +^9>e3_j-K`=pG0Y$S@-fNBwRFanixgO1211bNEF}y_m%B85d74>s*276 +MKVLN8PW`C}~e%r6NZ2jr!x2OHn`mfE(xm0juMImZoiy|{1k6Y&A-u

*gBKZLf+9z?4Mea0brp5|G&_HNytRDT`|t-ESw(p(?}eU=q>BpmaLQbn=;1;=_jz +;rK_8p8c}_v2g)H|#sGbBh@|@mHV?TU>-a?fLW2N?d+Q)nb~@!0QBvJ#mXIVT}+6fZE513E@&B-L91 +W&V(5}j-$*C7%l)@n^cjrU-3p@u{7qE$bg;~j=^ESv6>Q5B_O;WqW*=MaO-0H{vl>$=J$T<@wmmraIQ +PLW<;J@O*%qXv1t?-GSOwZkI@y8X~(GB%%NR{xdv9@8ILTtCzlF5d|olRgW9N2j3?Y1WsEq;sQn)lmN +Y9B7E(}6JeHSG0>E#>H3AwlQ2&kycx2F<1F-wMyC1O8XxJ>&Rf7cHoo85<8cIihn&uoK@Nt8a=e)E*2 +DH1Zf>KpjMl3AyylX0N`M6cdzRnUwiwH9*-c-C)0eRt96CI`>@9qP_SiT^a1bjbdLGqMLoM`=%&19(* +vu@a9IHRcJ3~k1%=`5a4wijD>o+LmHfB-;pb&Xf`eRpapj+03*&Go51gL&?HV>awCr2!oH$1@ClA$U1 +()_*DZ9z_R1s8a$f3gvPFKQ0-I3_D{FGrj?0MNE5!>J3U3M><~Z=1QY-O00;o{l@>=5s>bjv0RR9N0{{Ra0001RX>c!Jc4cm4Z*nhVVPj}zV{dMB +a&K%eV_{=xWiD`eol(7RgD?=@{S+rABBeY)qzwI8B1KV$?#Q)|;Kta@0zaAc5+DQi~`n1mhkWYrIK{2uQ` +!#y0M}@d@L$Tx`Zypbpq6vq^S*FJL*9GxY2>mr&QMw2)ccRr>h|E>G(#E}mWzaK-zS@xjkF}mqdOk>W +-r$T)gpDljT}W<>|5*&EbjQrP(7L)|IZ8-UCS@bFHEr+D6Y%y;Wv6yrDcvj3e6Yh9$Md~fGhD0P)h>@ +6aWAK2mtey7DvLpK6;V>001`u001HY003}la4%nWWo~3|axY_HV`yb#Z*FvQZ)`7PZ*6d4bS`jtl}^1 +5fSaW=wc^&)Jt{am +?61Ib))@W{_2_R3Wlq0}oJ30|XQR000O8^OY7y%Rm<*LJR-^j3)p9CIA2caA|NaUv_0~WN&gWV_{=xW +n*t{baHQOFJo_RbaHQOY-MsTaCy}kYi}F5@wi&d?pS(ln^YGp*umbGGy7VHjInG(M +@LK~e9hJYzcgn>o>l<`7TIamJO$WjcJsxFx*xh&Gg$U-ysal@4sIX7Z%{uo%OjohU3TOd)ZG;F1fYBJ +L(5il>f7MGP4m6k@{idQl-jzF66436XA@WTZzxQ|*W$qV^M0Qle+)L=09_5CHA!C}&@E;q6ei5h-NlB +-YWhc6DUpN-GQFOtJUc*oa2kKyg=6FnvWz(==skfiu`I0k~bSlUC*8zmF?H$ERQ_<`tt!DY=j!%Z74s +}(cAw-PIH&sK1ziph$-+-yJ=@}B+3>Lq*s=7OF6_4~7QKveLTXgFLcCX6>`je2{Sz>a1;VIVsNFH6N& +rKrppPS$0`b3%Vts%|zKV1S*pP)nW(W@@GdsB7shkLh*Y6geY3=L~GKs!iHC42pd|mz6a0d7?$JoLK1D&vh +l-^IRCd(zB1Mft6quia;DI_(N=GQZtK)I|j3Ig6Tq9(jMNvb-~*G04jO`(yc)PZNmB+Nv#y1-@H9uql +&6lWs((o!dlC6V)z+8SvyCg`t|)=lw+m@_!^j;=1akD!~=OY0uZBKdjAcx!XKy%G{Y<B-)%Pv_Km +k?lH-)CZDWL+i0cUAGg_(Io3WAFf%;3^7uFN*q3`mM)+5}0Gxv}pf{OGMH~^6F9H9E# +UdDyIgHhe8jw+PGv30iqWXK1LjfjV=o0as`&2f-wmAml5_ +^dXkaLAliTas})+7&F$u}J|d>3j;T>>fg=hsQx_{om=PS$U7PHX> +*91Qx`o?E2}Eo#bh(dL0pmK=P#>6NG#QPzG3F?%Iad_+t~%fGXPOOU)2n;TVz=JUY*KLu8$C{uqn-R9aG#&qjFz9oPcRQOyreJ +8XI*~BeP^-QgRX<+bLXheIo#VG=Xh@^ai373%G%UWTH#rwVd7qDJXqEG&xF3kIRZY->+zWOUa0Gjhjw_b@e# +%z?3L|WmU4`Xq)cR4^nR>g$JpKs9FsmD5^NeMH-Ej>kHr*U#Nu2kMCP+J`dI|LUy3#c(gwei=k_57`Fh$8eQ=zh&aRX3}3q*=Z3nrKTE@C%-6uZBsa(R3wD5_CK6Xy#%qvYV)+yMw-i--_1wY$@1J!pOoC +1+atW>Cy4TBjD-FQsfe>qIgKzZxG4rYGh*T5r6|M8mu+zMzs!s?oO5;635~&vjUCqp>$Oe`V#1bpoAF +`6MRvKAp`AN>Hi|2ET|xPq!AwE`t#_OQAegB3!A!zlqiK+rnOofu1#4Ss%7?$7!rY6k&?4*l +2VU(8x}8B3P?UPk*+n+e?UK@cy2`cvMi>2>Z(st?tWt2kbXI9ReZ-*6WkjgQAFtLaf9s7{EecN1XS_U +`%k`2>|2*{0?f>4iH8X+~9GJ@E3WMr4%{U6MUhn??7_cey8|fQ~=XCXQ5N4&#N-&XUWi+C%zW2qKxu# +6s#MC#n2ogA&`ccm>f-rg(+><2?8JAy?S@fK7t?P@zEmXh-A)!McP6M}`iLcalY~Fy5Q~{0 +Y$B-E))(Q>meUfkJNFHR_#ALbOb_NsN0j-8f@`NDXn_fk7irhr+N7MkMYx5+_7G-bFz!XFu+*pgs0%k +Lh~?y{Z&wdrUAoG&r0eY&)|Bn!7{yUC)siJ8#*pGj~bOIax$`kGa@9i`_HS7G%JI9xG%ijkf`a`j1pR +-9tex**@i74fmAWl??X$?C+R}UMp3rCz3rHba|E4l;EDuEuhS8CXAR2WWJuwnBGx8GvuEeS5CN4$F +`!)mX(|Q(nyq!4=j)Q2cf@_~oqlXhw{6RO1ByseGmse-Gtx>Ea^GHOq$@>rP?adS1gTuw3mO@G1xGPXovjxc)t5hz`6?@(}Ure&SWr4;$sZ +S|AGnts6K-repklJx-bzE1HGtzP#$_o=+A`AJCe6Sk=HhyI{AZgpS!D-_C2z7=h6P68m6DpdW@Re*

&Te{plpUXi=mOn!27HqxQ$!DxWreA~BGzO>dtegc6BYDC4WRp(02-W5Lv9j8D-^DkQ|?YC{IS%%Y&uNoD!sE?y{S&R34qU%RuenkNb;~rf^wI!GDg7K +mUyEBTG0H#f?uo1<|CmvtWI@S;w1qhs8(9(zoyH*b7rNxCs>TQ?}kVjF_`3fapelsU;(@CY1Fc6VA)NY0@di9&ME@A1EJmqme!SqC_P_dlbt2c$9*X#rCUi +Y)wXVN1Zr?GY}>S*HCoj3!J7=H4LvkSz0;tdICEb_@ZGQxFg)*)+ThVp^y5ZSM1T4-HivWBl^mByq(f +;Ah%T?Bgt*hrzrIa%I%Q)7NhsSUe)0HwQyaVh2Cs}ajg`*(x}4t8W%qFh`5#np=pNEEylNcy2n-MB;5 +y!y1M^6abvmCY^Y5QGyliSmTs-`4k!MnN6%3cG-Clvg%v1^uuH^iM(?6DkwGZXL|i)9-EB)_=VW%6h? +ByJEo#s&{Wun?rGDY#ETG1#UO!dCsVR`Uvwn`bL{qZ_?E@5$=vINosy0UWV{qLGFyD3s(M4!QySIGr) +i_r2`@(TI(?-Lz{uHyfdp|5;gC+B}!|IPK_cd1MO3wH?=kndCj2CF?5rO`KAqu`W6p#161 +pnWyZ>#-wS=s7=QS0!L>A3$)`$-E=O`}H~D;6a;GGloox`nrS*x(&OH2j +Ry{C!q5IViuai@O(8R%ShHt?hcR`T7btwaV^VEnPn*HxqViZ)Nc*j;sM$8d2(G`!W=*_9 +k5Hx{jcKj-BRy5W)+G=HZBLReacR$7HvXx4PSVKwl3bnV5b*R)tTGMfg2Y{R@%2$5Ir<$6HNk4|ecxP +)h>@6aWAK2mtey7Dqt>BlV#J004Lh001Wd003}la4%nWWo~3|axY_HV`yb#Z*FvQZ)`7SX>4V8a$#_A +WpXZXd7W0lZsRr(z56Q$$ssn7%0-U>a!9vbpqHk=7T7~k2oyE4xTZ*fq+B)fZB>l)Nm*Mdef(@Je+{bdIc$CPjdj|+YzVK1hll+6r9&j0#t>4$53V +LfO;2Muom!(?IvGSIX5tSHm(&_}punmome~x=_ +^(Io?4vY45qzH>{2A(j5s5DvB^*0fS^(erUFI;ZKgi>vq1vT0S2KA4)!8EGlQ|3>+wI^Oh|+pBF=Z*R +UG2TKvC_7%3dL&_5k0O<&G@s6}&!hW6l&&cg%3kCrPWcHZ?e-o(siR)&2x6W}d|)eEw2%LuF~4NoBc> +Y@27O{yfQX?UTIZVNsS)fL?E%-tN|q(Xv+{tbd;5eVw3}`460g;6%Zxju)vPp%v4IIt(fp&fPeuP^kl +>L)Jo4;~n%1VBT(lzlPw$XjRy<_8i?)f-_A7!|aimynven%4;xj3l!rT=^dlj0agw0)3) +h+umAPpZSrUb1IkQx)%9$$$6Om^QT7*mGZAyK7+3#zwW6@&{y(@e;?0?$BlR$Tx_k4yyV?@?SQHaDAG67dQ>U-Adhxd9!=&>>Y8Y9A`f}Y~igGF7qD?z)6=PyNG`G +ZkCPDn)|fs;XO=`x!(MTEF-)BpW%_dGJPAOSV-Eal}5|qD0JQx%Tap&<^6@;>KePFWBB)Q5Yvb)ilSK +S`dQh?vzD@LuQRH;^eUn(w5(N9b2Cv?4oBd3YXV!OI0YDYD`$3d8K${~+%;`?U-}$%+a~wV7nyDW+eK +!WB~Ryex5zw+2w5>|GH`i_q{ghyGe$!ztZMSmG@Oh~lT1~1U%rD@U?^Xe6iP57MT$ +j-*3XLOq|?a+&k@NnWnrZ#lgNI}xX7_eu_7Z>Vj;=VZLGdoW&NaWIZgLGG9FUG6z+6ZZ_i)HZ_Za}iM +l;JLcJ9A)~NR{>YXim=ZoGa^w;^S+v#*tk|A>^tFD@pwycs=X*{*J?G(4;*fxR@vkrYVK53G7=0112CE}EG7B_OL9gkL8YQez}H_% +qOI29g4-Py1uZs#BrF?&BU$o7y7lN^x7+piAL}?Uy2gyAXnJ$w^idtM{!kGxEE7T3`n}o`NOH0z-Uv> +=R#N4pP%`ZJw=0ly-Vv3k6#SZ|Bt?pIgc;*I=Sm_*uLzn>XI^=$RJn*E5M?r?L}eitn`owME53AP;09Z$G_Tl2)E5LJy_s~^E!m5-Y$ +)Qm`w-c$j*ROw)ZVH<1Ap)%0VeGK1Q=FppzD_u!klqn0xH_@|0^l0)%*gp9`=B2{^!twnI9!%&e?MNf +QY^4>U6f0t&?QV_Mi5=IX~$1ZDz +m_9K)*m}rfYE5r+9eC(_nE0uH`fvxj{^d`-Gd;)dP!;|pDC;?FeG)cvD>tk3jmb}1gM(X{C<-Ru%Y{q +XOPRUWqA#hD}YOA9$TL`5o5h~aRA|aBLTocCOZJ6_Klrd}qBE|UPQcxW%+FO+Y963qA-D5lX?TgXiinV5 +!*9wDkT-`b#rPf5wf8yGGJ6m1(vI5&x<94PQB +%E_7)BKGV&W+vYl!c+|9I%Hy-c;qfUr=FDbvYTvQ*-6CAC(+=;lwKp=(p-S~WNUx=B&VG1w32>6KjA5 +b=8W%|=1Z+BEywPjS@l7xp8S$}k-3U6`F#(Nlq0x$~(aIp(+k!|LGn&;$OYbG8MSUVf5z>7DhlC-TJ) +cb4yTdz7{JuPl`_a`mL}w3>w@uz+x&v}Eut_B{1D!kl)<@!Slbg4W?FJ9B*Fhg!KRSDz{{c`-0|XQR0 +00O8^OY7y3?_n=#|HoaEf@d*B>(^baA|NaUv_0~WN&gWV_{=xWn*t{baHQOFLPybX<=+>dSxzfd7W5o +Z`?K#{_bBfC*!bMpH7#TqPQB^4{e&><$xx|#b`em#+s5wUdCEc6{+=Yi~RS_kkpELv7PH8i1k7~oEgq +M^H6f%sMbIxG=BZnnRItj^;e&?s{8BTDw&;~m95%CBb#)4z`9Uv+TyPrYNJza+AcR;iyHilH-!4G)>v +z4Baw1$t^N +>Rz*u#Hvr33EeG7K_&@x_v{Fu__brJH{7%$TL+OH}6%AetBntd%NACD6rMAS=!LJAC~%I>$4MrEG;ld +4U9cN^UuE7oK~Sc5=HD?%~fr%Hk%(rr7-~H-#NVhaP{^QzWL^_peftH>pPHUg5iEUr1{xDa(D-Ys#gYf;(#E40&U=k28@EHRR>(0ElmpF2`zI`RY!^;mWtpyO$#oLzs*IyL-w +szRa(jlA6n5g*rsm?Artxi5A^I8_v|)V#IVlpDbOHlz_R4(AtNb@Z0!z#VabiUs3;CsyJgF7mlg!QW3 +*hhc_)o_OL06QJ1(Nol7@rJ%i7%(+FtwJ13SIe-5!gCUo3)<eRap=44nklS=L?39|@vY||sD*cX2@ZE=)jSSMV5Ju2|-$%2fetL8{ +d1K!)1ie|HH^xrp6MT8moPx`4Hh_Qel;ZB!$&B_6L_SNCDVN|rfdj{ETGXjDxYzM~;*zD>2-C5lClvQ +&Vd#OdrK-cR{?Wor+yx8KM$F44sU3tZH%D077n64f{* +DaeXb*Z72R+eeGUoKJrDP!=i@P*(lCidz}3^?*DFR^-K4syq={F_YP_4g{cb2PHio;LMahrc_zN4&W+ +6X9->%)*8*7|xL8tV(Lle8}#I}lc7{a%9r)~Ux4&ukWN1e#E06bFpQ{zQqC12A8^U;4ket7>_pyze;h +4sVxa$stzm9gdmQlEmuJfM9&g)7f$DR8#e4^a}OpOmcQ>v7MF@_h3u8fPBsGOMR($Mu{SSi+^Q{V$e1 +o0d@28qo@)TD^&B@dTpFhn6sHRM?U^&r +jebZgq +<~$wEa=D>=971(h8s&AKU<=%I8;BVvYdeX0dd2Q1hU +U&P9#;VTrn?zHFGIux!W+flrjg9a1-(TL$j|M>=NKI#we8CJH@>BXkl@g6CV+$41#Q0@m8)CLCr@|^fMJzd7QOMQoOt`yn24>r-G +npd%CtF0(^Z!3D1(?4nk?TL`X3W=2XLEiMBliRu?PRVh&t->^FJ8M^S4ICN&tQl)jPzpyI?J(&wY~?b +L&LUo_E}$Vi;K9HJ+E6CAbs3)}16eA^aX*GNbfte+#YxAjo`Y{jTs_NhBH&4rdC9sqgEPEQ7HkoeF%Y +GdEs#j?cKSLf?^$j7^XEj>GwQ7Hu8z$UHOIPR$497| +-3-rop%x)dIlKf{?GU?99P0_3JvzcqN1~b6*DV=JNqx(4aMSnyO;C)71`()y@P?^wVGSEQq^ +WS|Q~j5^8snw%#J;qVqK%GCJ>)xf8Hb$jY|2NemVaRztX8MQg2yh0tjw-8J@mk3BJVWofl0l};&g{KC +!Y1;>g7$7(&-PGSAWGtdqHH&!XcQ_PIxj}GG@7Z>w1o60x)HODjii)YmhoyURuR`AjDbjk{zO}|ovr>Q5GTsU4mWvc(EFpUb +E@N7)_xyci2J$u@GHV*&)X>+{x7o0c0u#ElyP)h>@6aWAK2mtey7DtPF#X`IQ008m<001KZ003}la4% +nWWo~3|axY_HV`yb#Z*FvQZ)`7ja$#_AWpXZXd3BIK4}%~O#dkgho0u5gO&A(Gck12{JS&NcIgX{Dz7 +hYRMp-!We)sNi4ceaPs#YTba?_6%iC0RuP}zadc8^(NO#ti1$B6Z*5`b4k3bBe2UG%P7aNTQ!Sw +sA-9LZ~Z_bX^FZ=1QY-O00;o{l@>>y9aj9y0001S0RR9i0001RX>c! +Jc4cm4Z*nhVVPj}zV{dMBa&K%eV_{=xWpgiIUukY>bYEXCaCv=@F>eAf42Adninm=^_yI_rDk`xQ39) +plqQobx-X)Raqww#W#J(r^FTk&x)UwJ&q6*bFm +!R06uZW^B2nha5S1O_{pR`BbzS3M`{Q6W2IloU-C%&(x-d=zePoaL8(hf&3cZM +dfT*5Lj_$i^OS8fLh+Wi$iObFsoK1;gW66x-t)o-}V&poF6XH{?Dg4RP_25$>wbS0Z>Z=1QY-O00;o{ +l@>?Arw0F91pold4FCWw0001RX>c!Jc4cm4Z*nhVVPj}zV{dMBa&K%eV_{=xWpgiPX>4U*V_{=xWiD` +eomXvd+cpsX?q9*VA1Y^t5_DS!7znT=O@IPv45Znzq9_DfIz@~nQXuI#9{S^VM^X}HC)+T6u_)gA^W2 +dZO{=tJ6*pBaRukcu%1kDuRt;-Kn`TcS3#HRqqqY9WUCJdi9>>iks^^R@1w9G2zr +0K<0!Z6aBGou(;V!|>ZgM?EeOU_PN^9RFDv0~{myT4uDTz{Da2kz6w?d91W`|cN)e_mX(t*C2Oa#1r; +qAzf+7_T+(V#nZF7;Bv8t@jnIc|8}+k%aA$Q#0w1jA`dx-*n!|pnEHXCCdtS*9%tQ|{pF4-eVn6+pbuW*k7r<5?*-X0OHFY`EEVj9sE +N%v1(6H^#V&x0||a|}YsLRg_BBGRID>H)h2bVJ7bGB_$ZIFW76Guq-ZSOO}6_q77FD-0AVqSQCj#)?| +}g;rQU)toU?sZCwP{pzEjFgw1Z7%~N#)@XmaIRsj6cYh*^?^nm_qeOoBjh$FQ(h~BTq;%Mt^1IcIndpn0W{Nz?~Vpii%OZ769pLkXXrsFU|6C-dH0|DbLs@GA-seKP!(5iX}Uim;{E%!TDXU +>v;}ge6uWY>3_@<`^=l##@U~7%p-42d_8aS|^!aa7m)Xm67#5i&i}VwJSpOT0mn@k?!gK@fjHy2Yndu +$jqSy!X)h>L6QD_EE1qXf$+As9iXHA@Ot1P?1#7U_9)6>G4X-^W-PZNZ?J%>=y?S)M?1;$?4U2g#U?c +sfA{X^9JV9P1iU +_^ksbeh23WAl+SV+Nj~|4sHY>d4G{-o>G$wuQ4!3aaITprjz#PB-sW(G;0SydSvyjv<-sx$%wyuUavJ +)@=b@9u$8T*la^~-NBOp%t`Dt%PKmm!T>^vD^EYK1HgwOYe2Diwv%MMm|c-I%9Tug;Ud?<9N0jzS_D4 +;Sgt!c3Gu#RK*CJIO;ijqW=B2;3M=t@ipGH{4oSWi-e0?FF2af^kBkx*8x;8 +NtZk>$equAKI)F4VE^Hy_GovfYhS0mcJgkhScek^Z;<|Sizfij?S|K`c}FtN<_i~WvgY!cj|aeuxX^> +3cuimX0UCeR`QMz1r_(|4!!5|Si2t*&(RF53M)778e}W(U(UV8#)^s|(^;B?NDr|+Poa=Gg{Qd +Si_1U;7Q7G_dM}Kb#`kpI4bmrYJCWQIz{j2f+iZYCgV)F@i%Zgg^QY%gPBV`yb_FLGsMX>(s=VPj}zE^v8uQ%!H%F +buu>S8%!1PE#-Ih8zm?w98J#FkojvvFKW@ECmwNHvfL4qxfT6bg*dhy~hvJZ45mq)gI{>Q7N$fAw&XW +-)yqM7ey-oqY26OIEM3kQ4|JSpg`KGgiY`!m1L@i0{E;}tDh(8f`|Kh2TkY?n)Kc}OD7Hu5ZgkhlO~E +x+rZ62=_c#QiO2UQ;md +Zt-c|7VY;ebo(<#9(G&X(LO^0RJzhFaL?4Th7QObHtN|gy+yW!TopYMRj#LC&^;fh(ece$;m?8&&9eMcck{=y{xXMz>jm1< +#)|G)tG#2)SzS1f5$ZGX3%m(jYAy=;*7(a_ygSmBeWr&A=W>Gb`GdRNsz#L(9)0I>x4D@P6+Rox>2Li +N8+F5(`BpWh#HfHJC!ABWp!=dSBmC+{=4WI$0oUX|9HlK08mQ<1QY-O00;o{l@>=YN2j8v0002t0000 +W0001RX>c!Jc4cm4Z*nhVZ)|UJVQpbAUtei%X>?y-E^v8Gj6Dm&KoCUx`xOfoY2p#R+CpPQMQkEihC? +@I@p2pXP9^`|_ytzOJl@O*a_)MeOA}$s-p0mySX+q>dzfYuqhV1l!HjcfZvny434Op60wU}-d9g1GsL +7#LwQviXJVmmO2AA57CBloOaK=x{JHN8^fqvSGWw>3~(=~-M_HHQoO#;iG8~H)rOn;O4fDU|oA*HJ7j +uMD{Rly9BOdD+yrJhhr0|XQR000O8^OY7ym!pF1Gy?zt00{s98~^|SaA|NaUv_0~WN&gWV{dG4a$#*@ +FJW$TX)bViwUyCw+Bg)3@BI{K$c14_i4ATu%?=mFxCtqN4v@)qb~_%`96+s+8A)uy+pi=$7>7}3bFsb +vOP~IuqvK!F1w{Go!0CD;;Vx%HZU}>0!exdB=z4yy1B3Yxdher*>;*zbQ)B|$AP`|ZisH#Uh84}QDgf%kcM52IjG9N*@A)KTVIi&egb;=xeoH9w-TJ>Z(H(iQvDI=NaICI2n*hsm%zPv=%d7 +{7Q4wsa4a=yOQtxFv@L6MRjCOW7|!HLvleQ^KwdcD6~XF88wTHjq~5RZ$Nccn%;OI(?35}7ADKhe~!* +0lrb;VAc(~JnUG$v@I*VD{@{KQn2S{*n^D5Ek-ngX*`yI6IJ^|Q)3FtSCU43@Nr +e#-SjSHN;7I+6pD*> +{>r0@%f0Ef*1(_~iBWxUn!|CJXEz&_H{XCsLhO^;Y)KR4#gwdC`NQag5>vUc!pZk6r4!@TljQo#A*?c +z5+eYC%^%W9H)n03w-@5U%bJf_c(HgG)m4Qp!W=MDPc!*zx3JkapZ{o=!JOv*Nh`xoBSBj4YJ +l>8LaUEQh>CWRt9ei>Oxq!t6)yYRV!irFy9pDMG48(r7%elm58-DDi*{3_TLm^**+@LBSVN1f79TQ|c +y18ALS|#zHCj2L_0;*O;w*h_yOs$TJZUu^38KOY%bdHC(jHN(OfwESbDe$2Jx>l9qV+BmDj+0;23@{+ ++FPi}Zn*jow0Ro!=0-FH>n*jow0Ro!=0-FJX|JMM%XLEq>*(~6DHV^oo%>=$@bAj*KY~Xt~ANXF~2y= +PJUXFs99$f}7J;Txcv6@BVlj-a}9G5-as_;oT))%wqIQnQ&Z`HkeJaC}pXxp7b)7x@PD(AH5ZaKx>^} +>sbtmXU*P)h>@6aWAK2mtey7DxVZxGdud001r|001KZ003}la4%nWWo~3|axY_VY;SU5ZDB8AZgXjLZ ++B^KGcqo4d97M)Z`(K${+?gK+kB9mQ;fWPI3PWva2#)&ZJGi}id-)Z1VyG}ZDmqRQcZn(``>Sdq$G-x +72n<&D595{hcm-xhC{0RWX6k)$eve<{K8qHRtY2T6QOdtAty)2r(<${dqGYQXL(XeO7bkFOwx!*O3Bs +bY<_(^C(A6SXOU7y`|u5GESJxhz}y*G`u=b(r@PKR&8>4sQ*~Cmy9VY)|K +Xc#_r%Y!iyQtxzJah!s$sR4mXQD-`m@(U?$|6Gca^%Uy)1_#+810wnyOCNZPT&5$G@I5=7%9R%#PUC1 +|o98F@ifDHvHLGEqv{cM%CPyx#;PlCT9aPsiq&22ArrO7Ik)-;1Ous0jJfuQXK_HwXg#7hg(}SO^lzG +F_2G!u^7mY7~(qRT+E6M+s2^!dxVRGDQl(e{9H-3z9$x5DE>$6eqkC8f(VccPb!KBx6z~ECnLCW@EtOIAfWL<51Fk34q$oMMTm{*Sd>w1RHfn|5!N`Sxd+-Y*x1tgzO05V>)^N#}4o>YQJZD6$Xf<#ZLKEh3t%BB#;|j9@a`XaAqP5kfJ}71LWH?HnLi(rWWSY9lytH=qJ|Yy2$AoB8 +tSR=e;6=p8W_T2oMYYB4PeA$QOuVR*>oS?IlT9i2(9ZLkLNKD=E-G8a`p%(V$54AMy>zT9iuJ$posZj +fJ#+pbF$UQ@qMU$m3AHwkM+1JIt-;54M;X`ux +uj%1GA4iaoh9*E@C3sG5t=;4j?-yli{n6;3Zf9H29}#_w;BQCa*B?iJtB?))C&=eSJA1p43jCV!^%^3 +vw`+1tup&h!-1a&tVXmp9YVvcEOWI1FyDrT`#>E<q)V$^0-Hvyahp0aJl1MAv1GmCu!KRFT=i-TdZb0JKFI%D!iUv;Md_nd9Y36EemqKml$Rr`l)zs +$&eUWIa}QLZx-}-z}z^t12-)n=wUgdg`of8C~i0nq9r@HQdhCIL)~P77qAhN=mgFTRo3z%~1Br^>mS? +0K6o+CrSB&Y9hBQju{0ONT3Gr+6$tVjkWt2N_+%$J$4?4BX>ktk}CmBcI#Z~>LO)YXAex`42g%OzQ2U5POL%))6%*%)b(Oc!mOnkQ%^mP= +S!^zsFzMZa;FffAXNrOrTJj4O=*Ho4#t28pczzR-&0Do_S;J$o;6djayzxn4Ypn6TO7oq+hksK= +M_MlP@h8Hq+(5Qagm_5U2W%?HRAWyL;TfE_V{LgJHLykS662wv>0P;O$;MPWE2hPp5I))dw=IBO4GMj +owyYk#JITpH~?_{>E`3~Y7oGP{8hqrn3(Y!cuQZs-1;-J*0m#zu2w~FNbvB-OT6L+qL!UA^k7 +&tE*4<+X2k`VedcBhn)XBAJYCfeK)_pn{EfN0z(+HFVle#;M*bX`}dc30}en0zYI?vBtS=fNaG4gtw| +Bj|M3cKB3*S~MFWxyV!`_zku+fjv9!dFXofw5a7JWDJY>@=LHj)45z7*55YEc%h=@!ZghPQHu{0}Rn} +;uhV0a$VsZCG%kYuOYr1jgi$_8I+NAY6waEh*tWDPYR&DAyzqK}L?QU)I0ETOm#_(#B2 +QW~Zw69mqa@v_0*<5O6`c&SDShXwj*A*HucbLN37o3)K9)0 +5xcdihl)F5_0*;wV)lal;WxOrg$j2&uBzJBcKd6aSZ`lzc0B+ULvvf5aM_csN{B+!->YW!kM3dER-t8 +H%9Yc?S2os7dCvfKd#n#|E61Cs!`*rhAU64?-w%Uz5RvdG8o6!)0`7}ihC93C<~-UF7`+-9um5*_=|; +YHLf!q&J*w!<;&b*Lw~Zib&xySQDSMcuH+~7*=u-t}|2uGcSnc0n^JneSr-;>Yq1kcPP|iuAZ){o$sg +G}u>POn%No%HJE>n*`c#6JG6rP9My`6LTI9|fe6QUqOFHYJql?ZTyGCWt)5Mx;+EbQebMjy7X8H*7qG +!ZaHM+T`!t+E;qGr|Ki#IxXKA;VEyymlX~@sIunht4T8zIDms=rml39JjrUz~|)e_+qCNe$WbMApW>R +HaEt#f?^EQM>$AA_Kc^j`Z#vibTzsaPrxob_>Rrf&|L(K(i2 +JVSK%-6*?B0OXGX8OCzdv{~7whA-Nk`*BV?A!w1C?6+;izBELN{{9XZ?cqkZ)odoccs|(mtT=PF`h9c +!2s5IXEy#-g@5Ri5J?cC!->fG?uBLH7mg_{1*3`F`Xek3=WZJjQ)=UV6D+__N&#U;4;%+><&rtBzayc ++G_%KO-3cIRIDw3$`F$)TMQ92PZYE#EkjscbbQk6lPM^bMMTcw?}ERuh|J&$xDRs*Npk@=*g3bfeney +gkiQ30umcjD9I{bFf^&PPZ)SJ{Xh(R1_J)W0?vDrS%VTe>Y@CwCuccHW4m1>_?kb24O>ZZ+rLQrcJ^v +4VjqR@VN`9tQ9-+ePTkHTHdn$W-fv&-;j>fOtE(h>4tfeDPBHn`j`TXj&RmWW}etPp$H@o*?fjq@65W!Dm%tiAsLP)h>@6aWAK2mtey7Dw)4%f<=<002D(001HY003}la4%nWWo~3|axY_VY;SU5ZDB8I +ZfSIBVQgu0WiD`ejZ{r<+b|5h`&SUyp*D~jTXP%W!(hM|`h+hH97wWebMieymovi$o|@|Wy%O$`L +G`0@BiKI;u^OmiZ+uN{0dTDV$h_#((DJi*P|ck3KJ-hG1g^+t)-A}INU+Tsc? +ML4ur$M(hVnjvPn{rIY2J7mChWcUf)3P{lKPs^V6G>Br!~5XI*Jp2ZhhfyTj-}qRGLBBsr338Z4j9ih +SpZ9m`#5G_vQjP!^d%i4_o9bUUF`n!QhepNM1{QOxovvd@)Tx>U5z1XmGYSMX%?A0$`Yaxos9BiZ!to +?>xNEpn+)OIDzb3w98?UPFt4Mw(0|7+-fs7Id9kxjmg4i3;>)H7ok?oAOXh`&Ww~N}n-)JdPP +wg3tIC}}rqLY|`VK|Mo;fxcLJXm6N%tW0|XQR000O8^OY7yv#FkMF9iSq0TciL9RL6TaA|NaU +v_0~WN&gWV{dG4a$#*@FL!BfGcqo4dCgaCZ=*&K{_bC~N^~_`3Chd2sQKVHPUFgFN5-e*bUGmnL!ia1 +wY$XeRsHXsWic!^kh4yeiXtn_JoC!T?CdES()E_bFOeXB(9{!=my!pMi3GOf^8Dh;Cb!NVxjGvrUdDk +Wu@5N+i*Nuk84pKOXGFp{0lU{bB_X3LvWe5B$H9(z&f;$Nc|mT-*~Nu?8O`VU%Vn=8*!H?d@QGJz$^` +Mnb`3nIae6nIm~HA%Seb)2AJ&2x10h(v%mj=Wqs$`X9G +AbC*L8bSnnF%-Kn!WhX#xv)6Qu@(B;INnc;usdtMaD3*zUxOGI`KFgPZy(kF +P9w7X7fALy>s1mbBbd6iN`rYrp|0Ka-HFPG@81%pYQKSb9X$wpBbh0A{zOeoSg8SOyX3k^=WEHHd0H3 +8^(|X+(olrOQL*?lVIb--{Hhkewo$*dzdj!*(2q#h-umi+?09ah$(}6YQl1cpEaNx9q4=-OeXGpG+Z? +J@X33NSJ_HQwfOt3{4aozxGtu|bqx+lsHI9i3^0Ew=^GyctMkw7lMlqG$;wBnv{l;dFIMgK`2bw<>uJ +;k_ZY1zv;?<7c6qfIbiGfSKq&TUw^Rta+NaLt2x$-G;9F?19P;Ynn5xR%-$6Jcc<`_jLA3(5r2QAL6q +2h;TW22%*dBXPji*<0Sx9%XimJFxpW +Nea1HCf1o4;<@Ab0@$D-whr{W>W+-CH~~AmbT1Qnx!2+K67O>I$ZU0$c{}($Wj|l+|8>TW@0&%8>*Q1 +SG?0)%v*0@^nLG}i#k{4@m4Z%3qkP0m<$ssT)#iF#KLrd$)wTz<(>B16TEPBMM&x$UK3)x6JHT7Had1 +=EsFsgtcit6#el4-p?&9-hjEIg6&@8b$^L^kl+>Uu)-(QqvOYN$LG-g)%ip5A$t591eZ55|QJS6fX<1 +B2o4RT}WsM6i!PJKY?{;UfcN(X;tT-+>Jrtiz^YV7A-WPIFFs$86saY#f26*%UEW`fX=FfV;U*8)mXD +xx@ju}iTyECuW@&I}}2Mn!ubU@LF<%U}mK8OSz|MdoS$|d?8Z5&k`UVXc&mK;NJ{>SyPYr&3$Hr7TN +@DCM8(@86L9Ye@p?b|jSnfXps0DJ!eP)h>@6aWAK2mtey7Dtq_Cm|~Z003kb0018V003}la4%nWWo~3 +|axY_VY;SU5ZDB8WX>N37a&0bfdF@wQkJ>mCe&<&l326sfCW4u6w_1rx3`3{Wox%zjweu8(#6VhOBgZ +Mjsy}{xOJaw>K)18nhvfwy`}o}aozG4k`gFZz@nXs010?}p1_a&*jAOKgi+1PIgR99kT%PxFkR}Ll93 +qmS79^*4x +-wp&i;aiN{K!>C8$KD+{KN0j}yA5@S;uUc8$XjYO3&O7pMpF{$l*YF=@23?z--w+veGX4-_OC>hZpNe +g;kDWP#&v7VSeuJvriiVIT$I%a&B6C$5_8{gBnZzZ7!X7=Da;_(ZJ$i{e(p*tVMJ*OiY* +sNC;wd9m6!6k=1uvlUI-e=obn|V&w*aSTr_Lr#wFtimP`b+|yM|tW`xag`E3~rQGAoS?!k)q2cPPzRf +NB;YGo*sX*n~`pFdZSrxD8=d|^pZ)UV6CF(#9bb#;B8j6jpv?S!@K(i<8i +KGCi6RBDlVOz=No#jNwDd%>Y64ok0~)V(5hCt+4?aTjoIu)n|{g?%KkKab7OV5LZN!I2slP`lR!u*i( +>J{K?ww+x!dQnAVE>f+9HhZFDaT|7DE2XPARD3(>-GwA5fKxu;U}tRO$}ExLf!VED%PP +5$&#ixf)JyC>G!w7)8rsqNk5ys-0Az85`C%{ZuD?Cdb@u6T2Rs8B%Yp%&RHqx=iTWy;e5-xIY9J!m0tPS3cVZB0&mW@kv#BG71#=>h>rc?zwe}KsohQ8^|rC!kt&;Q +WZz%KpYwX{n2QA-4K1%ZXOduwMT?4pBF#dXP&nOh7cwyDy*ebL_aF_Mbo_z +Q!BWs^?$9-k33^VlmiB)FRhP}|Cu&#ozs1JSNHz{3o}WT{C(z9vnth58o`~f~iRd3iqbv14IaLJZe3I +~(=bx`?Y|+8aH=)wiTD89cP)h>@6aWAK2mtey7Ds~_d-q)d002b-0018V003}la4%nWWo~3|axY|Qb9 +8KJVlQ7`X>MtBUtcb8d4*BIZo)7Oz2_?|aiE<>1!#w<5|?#MLqaf7wrdqyx6Rfjm1{Qm`?;k|+?GRPz +dS!bCnK2LO(1odu|)_+&L@u@qDE>2k!#Lmiju*Le3(yX^NDN^@L{YzL##hd69{c>QnW2*zz(=Xcsq0H +EW|G7A591^?r1a3MlcDGKubT%WDZAmk`;tlqvcL3Muhb$T5jTHz$XT6Gl;gE{ciR2zTfWR4iug;b>oP +kaz!D=l}eItq*hua2`ped4d%gYtW;X*wuNWYa%B$7Q;JPz!~2W;P=TyQSV}RSFKJG$zDmQ;X>+WqS8- +DzDeTK()!!_M9EC7~hICQu5Ui8!@CF>q7t4Z6XQ4-UGOVGd=FdM#G@JrJgjGC#cdyQN`m_+L^=s2 +SHT{pzVg>5iZhK;CHMEGpHxksn!H#|;YPb&q*TVs(v4;t!-iXW4a#+kt#v{Q^)+0|XQR000O8^OY7yx +xzwfPbvTa)SdtU9RL6TaA|NaUv_0~WN&gWWNCABY-wUIV{dJ6VRSBVdF_2$d)qj&;Cp@rjyyS{9GQuo +nZ9^Oy_0sFY44=toY?8^J&s3BiMU6)C+Nb(wCoh6BQd2)38>g+hI-`66_V{vr)>i +o^gw{Oo+-<;u((C)#!EEZxqoi}w;Cex`%7t5lA=2umbHFYxO?++fx--}9pDiigoT2=6Tj{k>uNm&7Y( +=?wK7f&w5pT*NdA$G*FjII~ap~wqB85%th@JC~x0si^*$*CGyeWw-`eVNv)Wm1WWxQeQTe;U){I(c8y +LwMHYDG)zt0dpq_^+lQ`=h!f+#2h|TFKR0rOs7{(n$>9zG=MhpOJz1WD)M=H{W>ZuBz=Xnhwn@J-VPg +1ucFy4bx`!VY3ej>QFT4rf2AJbVgnd9+BFl)gXJ;sBbDar!j~*LhK#-N0DKWm%MCLFgbcM-K>2oXmOLpc)-&$RHhQ1>~%wd< +IX(id#k#VmI)y3X>ck1w&dx!;x+Q6Kl#`P6og~Fqy-2IB*Gbpegev`LzMzp}7~!1PJ@~%}Y6n@6OL(^ +T%FVP@8X~DxE!R>YMLiIc16L`8ukq`=X4$zuwgU%<5--d6UFxnapbSV?Q7i&3KAaNXn5(f}6SqW?Y#+ +yAuNEzM3l3zA8Fi?MPA*Xdx){RvmyR_akxY-#+QG=rtl3$z8s +Fk-rhIDZZI5+q1h$`U>fjsR$N6{i;=kiS~Sy&@U&&WRjcN&=G@98oE3{DXs=-S_aNLI{RRK|!%!{+{9 +8oz>;{_ZZXx}`^EZ*9pAXfNqHp1KSv1RFe=H6~!|pwrW08*L6>yJ{SM^ualYCMTyqm +eF#l#ipyoeOkMtrTeuqtdr2v%)tiLtc6JG+BK_|{!IPb(dm{hbfW#cKJ(^k*AP@Gv_bjvC|ieB(8x4OmPR%Jc~!KdnNj1iWNx9FL(dB#q?us-9j^!y#MHFDWlkyJ2A#t?=H0Mo)^j{Q?b=-k4Dar*HCq1q}`!Gi +-!azufXQFCK5Tq3Xg=HCCWodPj#15Qgk)^Yhh!zEmb9VL;#W;@Nsr45f^oqRFwlxi>~!MDufVypF9q +R7k>{g9~rAI$qXz*5OG+)_i23-4BzK_d*H-^<%PT5lEaYu97$g2sj +0h0AS#=J;_rS)?4*pj?GdSxXfueM_Kw001+3c|7bDwlN-G5q?$#`Bv2$CnWV20mwu-xTK6eBiYOME^| +@xbbcDwu39mzOe}BLGDWijfvCJX}qs!sDU5rLh9zY9Q>oAIAA|k7JRGvz(AoxzNbI_#1(lWa5ykPx_% +S#)G!z~cRP9_r2$_`op-)BQqS;KeXFhmbJKu9D0=|6{PkiwI{zB+w#eDv(>xD$jxVZ7!#fG~gfZ4_g<{e_B002Ypi3f(Cu2#A~7>BcBcAM1Uby9<#EfGL48fiu&*>}~ +zyI_KFK^=Ux{}tun)aq&{*JLOiz>j&6p+=3z;LCzz^ctB63#O8fQB8v{0!|a-Xb#d+-8C_|X2|%&U?# +;pO0x#2EKYM+&H$_eaX^IUO-^gwp?QU)q8AjJ^mB~|QoykrWbRrAEf}!Q1ANf4YjGSqd=oiXF4U6)3t +s1MfHt}!J|Iy1hN)195=k+LBqasE3Chv&oAc@E>+_S-SI=G|Ao}6W@qfHMd2{@H(2AgRBOR}-0<|)s> +7XzKL(q`FfX;lD)vus22y|fR3S`-BvKos!BnvJt=E6W~CN0 +0UNpORjph_hiYHW7^SSpvlZy-1b7mo8YjyNa+{(MiTKqS(nNp;Dpw95B!xve>p9X59xFGwHkqAzwcY^9p`qS7xhEmN*u&RQsqPG9H|uxw)$b!ZTwIKZQO=NkL|}IS_bF=kM$%*qfy5*GL +Z+O{~p*sEH~h+Fn|zit^d%64J;vGPg#H;i$OpuH>kBd=-CSj;`Jm0y?URJooVuTfVR_)-mMLjGYWvPZ +?yzx1Fa!uNWdLP{IUCn;9d0%3c|}a$olg$agF&KSZ6cUfz~pqlSPx&DImp*x*}5{qcLTuy+A1sFa^&P@;0xQg+f>T +tfjmc|*i@?ySpsh*(HbzlIBv56Tx*t4^78WLM4S(flgz_`aGXnO~2%Y(b;%7w4ZpGeh1z$BR&>aPCAK +j&8k&~SmAYOwJVKxI}4WfedFH;C1a`qH}I-szTpGj02c;bi#o~A(Uh$A#}>_A468aOXCMns;K3{nVFu +r8R*B$}BK@Uu8hIU-TUlcD~M;C^QM;TW6@ElMzH5t>@@BlzXTePw`BO)&F^Suh$G=)uS^@X%fq{Afy# +f_cvJG4iGW0)Rv$N#3VbT|w&+$&ntQ?e8@-*cPXvz@!!6i%_hvD*OlRv(a&HhT1V<*tEXyow;zSY(+m=ZN3-d0K(q;giHNZ`Xb`7pjC>K7iW@W +l;B{H4s2}4^BOcwE|27uZZZqHv>FPos +*D~5LL1qStw%J00gu(Y8W)ngZngpdNA;Ln;p7~I=V%1hp!2&=viVcjnE~s6h8n0{n01v&O~7zrg?>7- +IHK-%S426DEO~9nd*i%(b96(q&3@N9&WHCO9lEM8MvTe8AD_AkQkvc2M0B7i;#Mw?ZiS +QN?^^4n@BFSPIN%cy4-{r;zChLNFZg*X)Tzc`f)_g15#UZ8$SA?g*4;H4&Yr{PrLq^+g>~(_}y_@K;9 +%#E>n<7@++|_8Xy_EluQc@yDO2Uw~3ZCq)!42f~K9cSyZzGRLy*zzLz-zV9u<;oHvlWD#R}snviWMNQ +Hnc*-IVL+Qeu>-6X+Sw*o=6L)zZ8l*6p>;Y6!I`~_3d0j(y7pSU_z7mU|nye{SO*D#9XK(_4K8bk>QO +QcA7QB?luhIiWb9(vJ|L}(!C!O@^KmF=lFduAf6)mlRB%gQp@ETDZ}f(2w#74C)7M7_Lk>x{+>lSZDN?@K1W +xU}!cW=R#`$@H1a=_zhVhGJyr#BKR^-yQm7+F`&`H$}U$0)ThNN8EN=>gka7)LFWqmmj!(XDiXz1_vz +X%Vjr!khb`E&w)52NjFK`CHH3s-3lkJN*fLv1xGm;8JRANndcHLP}+8F)vu%{$Q_)kv5vQ9=LOk!D4f +@!p!ww;U;0S}qiH%$OJyk`yq?DdG88_qX#D71vU-nN#27Bi`;%kNBIK$+McPijxgFjH!f)ayTJYgC|Q +icU9FWiTq3|2eh4L2au)3)vPjP2_NH#=zt7S)@L>I-u9vFW}rq2R2#exHEb!UCLAC}PM*}RNL3BMrmV +nA^$VnGWTzLsP;^DxdPu6&)u76_o!sU$Ayzc2{T1@^8GX!lU~wIJ3JNRU<57>CztQ4-QZ&H-Fkil*kB$+U!^W&fZp126&>7#9_oMB(Ca|KL&wgle07FvW;^Z(t=dsN+NosK$JNe1>04`@~P +6msjp&KNliQE*N0aDBs)1LDQ<(`|7JdecgUj52+~QoeA0*U&Gn60qr@E0K*;>jlo^xp$OKp)e*s|!!&H{n530GCMy<9-&2hZX2JlzJco1z&+vdy +uG?#PtO;;rxy6aaIS|e#%e^NDUpz&E&!ImhU=a*YK=mrscy&v43{m5>qSHt~BXPC@fAl>UBM@P6zlJI +j7`QbJ2^eGG+~DI~l%-qsQ +Fo;8Dcsu%4t;>%fL}Xof+bvTrFybPS7Z4b_UQ+YFw9{_{4y5H5}S;;ylgcDa%jbsIFdocEoe3Y$^dZb +MLEA9H+80FrlT%qS(?0lv5TlYTcUj9bJ>iC6}pEb0`qY23E_nv!jy}+K$4iKv^k3BYS{hDXU_DLZDkw +fLKmtTsWa`${XsOpfZU3mJeX@^gSYke~Sts4%G4kq!(#LmAF1~bT^^Xc`J!>C#$;;VGlO^@R3q@AO5Z +UI1ITGD}YC14XK-!V{KsQ0_@;q>s4NS(z-q&3JmD@z#yPED=GW-N}{!3h{Ww;>bOf17?uHS7Ef~Qkg4 +Rz1q!a0p)aXT4<}`I|0=nO?ou$Pz{o{9tE}7sW{E(V*G@^MB!tPxO-vj#`E6d@x2uLrl{>aa&%m2yUj +t8z$f5Y~aiGLRM+|G7bUzXCZyPyE=dBX;mS+*mI9Kv-T50xG9{nb!$N{%wOiRq6CgQRzuCiny4=WG7{ +rXw62BN_p2JLdlpIYyse+MNs+9Md6Ot{be)xxG9av(8rjF#!bQw!4xSD}=fXf({|dD%GSYH}F*|KjPP +y`kjVQyYJ&aHy-l5TCn`u?W#;yGbi +os2B}*#0xAFDe^n4z5lL}~tgwET?pLkHIPyy*zgmU<0Z7LGb%<(_ePy-a2e5aJGv^O +6pEPVJvK6WBvyxw_mwsBy0JkdH0gVw6GH=-9T+JTX{Oc2SGG1rB4#&Umgup +nw;BsQh}Wh6(Ugss84z16h{SvdMFqdZm5YPAe)O<3qE)?H~0=)u +tj06?UT_v*!9~bCr6g7CJ(GskC)g)C1oMbM9ii;v{GQ7cKg6yMRUW)>>&#M{@ySTTI;$pS|47FGbgEO +CNfpC+xP@){{3Ln7R0L*GR9D`fv@$Z;361>eCZ5%o)(cEoSDl)M3o3W~3eT!$houDK2Ra?1=ThNsVKx +1(A$ASS=BTzRmIkR*P3yHwq;sqW8V=mmO=lyKjeY#7Ndm~+e2|2nGCZjz;1(z~3V698e>Tu>M#O6`WS +t#%tm(5j{&M31pGqNtah!L>mfn&kvFzJK~3{makAurBC5YV>dlc!f<4%onwW0XpkS`r)|((+^qDAQ~O +4Y0~KVud3UIc*SplJgZf5nA&5GOd$Jk*VSYU7TbI+a{_(Dwdd7&~>Zi188Ux0|Vosn`LkdiIEIln{on +eQaWV@m}_acTA`jM*FuuduBVmrw?lkRL|F_4H~S9Mb3E3fA>@(5ltdQm&}0fWe9$pJ=6Bk^M^q?tP}K +oV2RVN6;p1i7ZbwAfeYAq%L2Qz!q6#iV$|a6W5NP_Kn)GeB{4H6ri%)vg0Rk%l4;rokf;Lx@go}mbG` +dQ>*H-AOF9^y7jB#l_-@(No74=YBJK1>16{*sbM51?t6!ucoH2o;hS#=LivWTUnB@)2Kt!kFML)~1FY +NB&z5$1;Hn6xrF+r-5}Lrv7Nnu1$8?%=}2X^lSqMv&I(t6B?~oZc*N$4xgCx?qFekzHu=2tu_^m}Ol?z6z9xuxwgV*?|mZJzI+>0`ztNi|gHv9LVI +Wtb;uK@B~DQWM(?mhWcahVgKVu$LSqu<@x*0-5B&U@uUG3V9|=$!Vvv_pi~viGCYWiSzanm-1XG+43C +uk(;8G(f=i``D^D89xZMCzKtpd{0LBflU#Ky0k#M**E0!xCJ%_K7`xY@iqsCr>L^6lx*ctseBoJPQ#y +dvyild7qU9;dtQ>p;Tr&bmKNJtogm)^=Qf-%rW(Os^{W5N&id;qQK>?X~mvw!HaTK(;C>FM)dqWroT@ +(CU+tz9?tMG}*4DMThDOkFz7Wmj2wtS0^Wvyv;zRIRk%Ut?y9+-%JXiC>*Jx*Sn_F}_UyzkT +(0cl2+?-wOru^udmtb=f?053>clSshYHAeVFF6qFiD=15bm1<)uCCh+4@IIqb>I);C;v!lc +saK+4JLZyVFG1S)P8i`8^HfIZkuqbp>f>J3Z2`XNp3$9%zr{CooHmp*Pp%eW$psc&)wT^2K+^SlkInM +uh4ub?UMz#uLlDrLw1tw8RGXSj2BlVCa`W+#YZY*Ovu`EelQUWDZIkU@TB#=~P3TaB&ogcBXm$_3fp{ +=%*}rw<6-y$G)qHamQqUhka>l~S%#yzPQ=+dz4lSjls4X2|Atewxn)k(6%zG_L{Y2iEvR~A-3(zoJl62K2 +?+`6r>;2vv&c+)n@t_$Gc&0=JNJO=elXi*Un$Fo!urmDbzqt|pyxJ>Y3&5PG>j(-@7SI0k{kHz1P|Mz +9MJ_FUBYlt^wqNJos31iZSLY$@7d4$(LBZ3Zh9p|>oX+Dw!tiy{Ru^6wRONR7~HJ}iS1^g5{SFWifH; +hLIzO1!GMK|SDT9=67`V^MD;elLU-k`*>v1AJeC#?h)2Tc~WeeK&G0d3cMKzdE +@NKkrMYf2|r$IUvtC9HgWb%zD;*0chva;Ea2Vps-${{DY{+tu24$I} ++*iHO5fsI;r>8wrQ=VU(y`yX+HNCOPa{-_Y9o#jUa@ar;Y5}tJ^I&jA3U2Y)WW^1GgqIbA1ErIeRh_7 +IG`y=siT;%B2|u?(K1Ajy40#h%_$vlEGw24p}a}Efp?;Y|bb)+1s-h746;hC^mXVD@esy6kEaqC}MBE +p7y>yD_1J6o?(<)GY3+el)Xb;v^%QumO`a49o0<=xNm5FXpP)a2y3z6)*6@5W@O5B6xYuQB~HO}9UW% +Qh^HG^Ah%{aEHLcHnz1F>`^N6)3QfD;6KBiIWb%+?6OXt-FIpDMxasGjh^9iK=@8HxzWGd#Y-#~KMz|JCA1f69h*=;CEIbZMYcn-b +tLb~QaO(UtfG*2&k29=zlBJf+6f-UT(LC5BuSw089R9rI?+wn*TK`zLX=C5+U$%7o~V)Sp{OEdLIb(R +eMfwcWxV(@oKhE+-6!xHmKayfV#(VAeByXOg=_XvCaz_hh@f*isAa`u;^T$tNq9MS-9GJ3EjeE9zs{D +F12**g(XC;ba5K;LZDw2oB*({b$YL7}eGYs?!A^lYQ6tQXc1^9R +fbC04SF%7OJiwF|PHq1Abu) +W{bhp*Kb|ecrFPBCbkm`TLf|cgR+wQ_EfW9ZUFb$1#M35TF$Zn~leW7;>vJi>?>3na*~-Uq`>Hm7-?2 +?c}YZw6U0)<@9}X*L`&IW$8&XN%LYsJhZ=dliGMBW9lAwnD(7`Nat+_Al-ERc?VTvhX+lphgQD}1re# +azd5n8Hpn)IeF$2POtM{mq^tbKy*2UJ^Vm8I@^;*_Q%{z<%rLb9$`9EtZ+I9YAG{>y{i+UOUCQUlTFR@tKcx!SLvNKGqk0WIw?dcWq(*Vjmz|6l9tr +Bp(F`zMrJk#moYZ?%0n4tatT^GVRBVgMI9T0Wm@)9pNmb%_Q)lpdf8IvnW2VrsK4AkU+}w*xTMN{OO> +eSBA!8)fK7l&a%ZrjONm3ZuMQK@aeT@~Je8r%?zALH{e$#YA*&@>gUnc+M1W4sS&_=>Kz=Zi(uWe575V29#i +iN1&dSCW*D+cTD2taGG~YvXHNRA`3FMxOJ-FH{?f$|T13iOJ#g8z!o;geUj5hx{X>M2B(Xfu&|D +g-sxl_2T~FY-Xot#NZbz(bt@1RUr$O00LPTG<-(-8S>k=md=M-xCDyTogBM-Fa9o%|uSSd1+ruikiLK +tPW(=ubU{xk+bPdpWhe)>KfNw`WqBG<9ta-9#P9cj&S_wnzTNO_9ZFcRZTaU@zP0x9wqSbl6p&t* +5I%tz(s%hrSZL!C>&rJe6<4KIbUWz3-vIQA0kV +AxXKeA;)R(uTQ@zXuOC(|;@4_tM=%b60sIq5)d +AHOiYdD^0bn8h)zQrdr_t*4qEts}}$4m7B)zCwu$rcy6`*XYhJkHvJdp!4?aY;0Lucin~PV`9Eci5~S +a6k^XUZ~#M)1F}2mJiBfB1Kyz +t735=f^+w_qs58y}NXVJNfI$ngQcS)_h1vr^=MjrS%`|>=&4ip*W=fRlA`rgTvYUnwr4>o+cm7WYUj` +SftlCU}vMeR^eCF8ZLhO61}jDa}HU0)%q{=3++&1wmqG3CMuXt`HANRD%NonmM-sWLO9Jaal<{?qpyR +d4%GUwFn~o-WOs=~z^!dD#UKCPaBCe!;|m9A$yD-o8=WVR2^qTaSjD_HmULBNxOO;s4R0mi=QRwS$_2 +{nP52$;Xxg4^an?lLJ;)hN$uPVWDei9Yn6LB3LHtUJu)zBiLwrFuw)Zw$d-0aSN?p<m%xPk$j=!$Rk# +BW|1VqZT +n9JGXFL-@e_m4=ry&;)Aiv`VsMuDFbcS54N5z>Tj*`HvjNFe;^`+BOZz>>CFjwgU6ob)d~TX5aRYo)^ +iP_e=7OFT<`?Qq^esr3xrZk-WwYbo8`<>;z_&6Sq=Z}fw6lc;~qdg6L?;^b_#PJ!` +3sG0bzJ*?lfs-P?eG*+9IKrTJV7WmF{%L#V#Lv<~^kCGl$>P>P#Z-&rZN-5&Y0D +vh9{N>X>t;zb-7uCmO&El)rpZ89_gUlItD9W_E&kktmW!J5@OAXbPx_6Lk^tQ_;PJdAAfC&$lrR7(=) +Ljl;$F}pDmRlDBZJlOmy=t!*mv4|!g#&Cyu|j~%Xh%Z4%4dTPulux +~CHVgrP)h>@6aWAK2mtey7DvvPfCGLm004Br0018V003}la4%nWWo~3|axY|Qb98KJVlQN2bYWs)b7d +}YdF_4ubK|&?=uqGCE4>)^2KMLe{l@|`6_vTB +a*kGzkB(oAKt%tcY!aV+`*G4 +Pu`xtO}_l6Z<1oQF2zbz9RqxnR;`Rw>Q?$vcA3sB&eUYuDPz;;$fY4H|j;Z)!+VFtobk5*@^1oi=xH0&L8GtjRP7djcD +slGZ(EaIj>g$RF%Kz8fg6G8~O20G%eIpU#~?sZRaqT~h8NRyQ?EtSZN~|hsq&SW!n{spS +H}lQ_%tG4OvMAjZpX=e0~2O`KEL?$JNPad`tvXNu^Am4989NqS;B0eCYLFqu_U{`3}RJ^cWELgEk&bV*Xl1ZL!WdY4TZ6;tT?`HyekynBD4F%0F?^>zU +OkL9Q*Key1}!Sgq-UY)&u5iJRHu>!oRq6aTtUc9Gr7f>imU%tM0fA;}f=jGTx;j}{GtfHV7Geqfps0#&I?Y;9E@g9e8GK$si +6SqHRzM?3fy7YF#RNGQ@T#Iss=8SLeQcAu63Mb|5&`{7{HdQrfn&Q9904HYZ~y7O#xX=*UyBMj6|7kJ +_APKMaiE7YFGb!AjpaEONV*$|!!bbYIz(d8A+n0DO$r`v0>kXYj!sXw!BN=n_?LmM=Zgh(d`vUe)BUr +>BFUX8#a`>-nBJZMU&&Wg@`Sb+zYa7PA6v1cvW)zy2A*1(QJpxnuU}v48XsU__#-Sw=mKoRSo2NUWmM +%>01LeQFq!}r)dg&59lPvNtAW$enBg?w&x|kEy!VW}zA5Dgr$C +zrKz6L5E1I&53fo)SgwTOIO8d+rqi(bA>KfkZL +5h((;D8Kh>WB@fYC7RHbx#$a7blr@0cx+z3ENnS2#>f5!L7t2B{qWe*zF^5b5ATEN2Ei9cN(D%&- ++U;(N)}Z6QC`;H0>RVzR$i^BNV^c{i#9Nk+JI^qldjY`UUy!GOU7-j=lP=|=UW!+Pz`1p4T=F0_(kO! +pKTOrYv4cxvi +YMNXr(KHVS2&+~wuQUP11HZa@ +n*sz35J_OA*H|)H7NtO*LK7pZyP~Npl(;7rwxQ#v$Um(qK#s#}zju>c7S)1;RXyGbznVhjDVEP@^KdE +wx@5g5Qz6O)6$+3doDbLzSENR=G!5V)Uv3iUH~ldw+9^WH3lJ>!Z3H(-zyxVMSu@cCbK4?8uId`xn5a +$&-tR6I9|gtiUN;kiZ&8IHdwVSbMc6BD8PxIwM2PmjfElqR?NPiDrQ1yv6IY7qntV1M +e?)-O^7EtUJ0juf&%YQA>w_&hVE&Wrz8@}3S&LyQ}xIG!$S6ON=!7UBFccmaAS=SSe7DBW!>!&O$QHw +Nk=_2`dcHnmYa)*Tt<$)=d;$bdw0B;=gfj>Q6UHMBs3Vnx?XQel!>+4k|0Vo3>MwGo4iBz4?tkl@qG& +Vr35UJR;|5OD_TxrmXhKV>_MO%IfMfAp<9K~NuVbI#=Q;BZlktqk@MXTgu68^_Y)b`RtE;a&?09c +#yO9@a`cGjoi8yNm3q;L?ziB5tqb6QXW?8Q0~0HPZIMpO$7;HF+^V#QwJs)X(}sB&iWvK^C&1f)wguJ +zC^sz*my@QCQ)NR~cINR<&F>$OCXz>MJ&b_N7MQof7E2o%6~5yr7-=lL4S05PmUTbzgqK;0%+SLtzjb +p=ut0G(@?jaZlY+@dpF5m!V@YUFlpcHmmezt@j>^vDb@DtftNd3fL$}C!KRx{u- +W|B|zh^fX23NdEXXgomUNVUkDg=<$J__M7X4%&ZXWJV7nquBsUsBsIdjzOAR!vHrc(G+tVJ%kBp5TKQ +zM4%suSW5#11z*Viw`32FjZflWaEJ;|3}upBtaCIx_jUyy5QI^ET<6%+cVZdkeMLsH^C +g~2J-espfMPcq|mtnovm08AqyU^iDO=fs?}pAEYn9HlNwV#GFjnkPqYPLOIWuGV0~53UUAawN0uSE0y +3DzaROv-_?A>C;R8!%m(F7TFiL)(*y5hqw@?GzTXlNd)OW>#?5GKygup;}6GGEO+q0L+v750HOFFrVa +&1`1O;9poLch|sk=9sKanZxv0tv0`l`3(odkjT(^Z~jZ5XOF;=`)@LJ16VbpJ-ELNyV`#hC3KT^yCz8 ++X{QYyA;X%WK!7GzQ2D3f<#!mr%~F~b~GGoJVw^ibb_m*hqk}h6r58rk89UPWV1-?JsRnjn`$o0lv_p +ZRC-x7Fe*?Tf!VN(M)t(2PF8gzc(by1A{r-hS@Ez2E+H1m$aq86_g2BUxeto_^7#lyDczQeW5@>|P|qHhiAorw+#`i|6yUju)yp)d&t?%o2MF`5vhq09XyJ +0N9MvrWTt$}Oq2&?RA26&;(|XM*hX48QCIABFJ{+h4c%L3Ef4XZ>qvxOXw1BVpI!03Dr8DZzmb6E#TH +q*|PD5mgH&xslZ5xrN-p0h7g?&~1smgVK>avxh!_fP^AENzi=KhCc}?^y}^U+v6|4`WpDgUUKK4AZ61 +BG%&v*tE0nmBwNw`3^Chc*K9-5H}Gt8|3tpd(x+{bJ#9y6@-)d@UCGrSr40IKoJ?|*h^(?44~l({jVv +uHAb~=z+1i@6r_C7t4^8iBMhQCTSaTh28cKj3D^)8*^2do<+@a*KMxd&AIO_G3d$mRn4muKwxpidgsB +u)yPOq(4mg7c-`8_@nk;#8trmvoU(?HNV@n6|-rlX9;-Xq97s#}hzgBmrP*=-)%h!WJ=JO0wcWZy9Z@ +2q3bTwC!;Q;(aKq)91CK}3AcKFk(yD12?!v{p9L-yj>IZ4R#Oawb$)KV{$Jp2&&nOzjA*Ab(Fa78t;aN$z1dzcrm#WZ*7!zPwhWEcgE}( +>-2p3Y1Txl%RJYtn2UhW9?4!y)Qau@a1=<{E~1NnrD2MYBVq#Z#f63btsVRIFpsyrytI4`KweZD2ZX0 +>V2{SeP4(Ilb|1mGtTMcNV(%Rlj0Q`*_E2e7?E7dCVDwN#y@KW3W(B=N2Q7QPVZog%9FR{QPPvf*Mow^e;ljy5yF#F{g}V+5F305h}=5*VC$?p~5FJA()E;T(CrLkUH+wkMJN3`nl)Qjo3Ck$n_) +aVcM2X@53Qwe$fJ@>KsctmkA%@+43CwkWPe8|cCGNj!87OecTh_lM|XR< +L(dvJ^SG9k+&V-TKm@*amQDpW}n5(cA*jp}y3Rgy!}P7F${8i|M8*+u)Sn>U_)og!Jj(l(UE?Ik~w4k +RekcQjQcNaPLC2tM-#0-hEFKLoQCc3B`7n(eq+@As2%+I6Ajip9x8Sf+cv5W@>hU26`z%lnG$YZh(RGc$g@guB~@yG9Nn>JL(&XlGTTY5OD~!9A;%3MpZ` +MH86M5*nMIEKcVqws+htWtqqpH6q{QDs_EdC7>i*Zb}fo%63F5s)icKFYt{;7po9TnFPq@Q)FtQ(!h{H +{$*rU)rT?Z1uRSUxdpzn8ePG7r01DjQ^_%#J+MC|`*75)?Y~FM{hsCUH3(a5i0p0@9!x)t3B^V+BG>T +9h{vk8kJ3w1Be0BFRx#HehCXq+Spz^?zj|VZT-b-nk3aq>_vGVMy%4M=R^$jL@gmijxp?sXiWogP^0PMYG4>V +l6pw6QOy+!np9?4vAg#(wp?KI>W3>o96f)xD3|zk<@CsqHazL_>zP;r1b1IjO6d9$Fx!zNuh4TQyiu`LXV6px;^e;ksK#uB3K +&Ncl3+ZupRoYBbet*Ek_uy%{xa-<>|4OF&*q41m)U46DJA3B(QtQqO7+F?bKDl^-Xc +>el#X-Dg16w4_#jZLM^TP`v? +T$-vc2;Eherg!ShB|OwIc2uG*wsl +k27QXW!7oBZ8%g7<2@K_iQOS0(4z#P!YVt`w@6qnFSBNGnvioBLn&m=j2$PpH~NAfYW<&SW6m9{te=j +qi|FEB3h#TQ>;A^GdeKkzU34}Sal8})6q_*(ko4ukvp^Doe2mHnU;I|I73j=6Zz@u&Xvg=P?n16AvEh +YO%u41MraG^g^c!VP;Bj0ggCi1D1Q!S$Et7*H-cFL(gne9OcW}ju2T)w* +MTb$mL$Rvt<-$jT3|6_rfB+2QA-t7`h{6Dp4Mo5$>k>`zM2G2V>g(OE&h5!W2ASb0pWf1lCwR^8TURc +O36Pud(72RMShrFlCqiiq3r)Angg8UpuqEZZ^COI9FMIS2{pYc)oO2&=Fq&QG=%fbdEuI8pm!24$9;l +J;qY#~V?zJ#IEt!gh=n)(x&-T+_WmSt@yAuVCiIadA|AL^>mi(m|Myj>g;(iK(*EEN1_V|G@+W)2_)8 +5e^LKm<$8E^W%{zrb)&$n$M9)QtLp_D|bn$6G9U@xjvdCG*KrLFX(Vbz~W)@Uf_^(Ai-mrWSMI~?ybJ +jWWXsYh*echhcT-|P{>KfIFyl(%u^|gAxh=y4YRWh*}4WFA`rKaw0ccaqshFiQA)}hJ92V_8yNqHc-R +dDVRD^u7*OenmyZ)IEse&4G)Sv%w=E)6$ww?ef#oZhZ<7)yFp-`qi6mmt+H1+ts<(X{8rwH!x7kbEjG +{P2>nYG!-oYPiK5~svy|yGJ!#n0AfZN-FC(z8(_Q~$^P3zokj(!$HW&$PLtJEDvpXM<5n2r_NbItbH%D2m?loSe(&p~txq0u_48{VVX;TZJRj8*A^ +5`7dpsmG|#076d9nE1-_>Gu8lC{$4GC7H_iWa#kMF$SuwGjnBJM6v^_#FIU3=zGXi4$1VAkWYp*Jo3> +x3KBS9R;q_Z5lX6uC`wIr_0y#0EG82b9BC2s-gWa?OZ%+zJ*qW)oOS}3j@qNw^Daf5}g)?YUt3lXXzNhv? +Ai>>(^AxQAnGEO6Kcv2+C7mp5$k-QIC2|k*$iFbyLu3?jt=L_c%b{n) +-8{9MzdVObX-MqsutqKGP|8qt#gdkx1;DBPcA_|aUgte@-hS_+m-x^gEw!*mIp^pSOeU~O;)yp+4!mA +9C@?pF?!2=(If)Qb{d|Y(u0$mFVs}9MMqi>mCJ2QU#O0dgy_2NXkVQ%qq`Zlrl77NLwyf_*nYrmGVvIvPY3gFFZp&`%%j>N*aif0kR+>0KN;m8Q? +#?PiexJ9;G-_rO~wXJpA2Q0OfwNJ1pY$oA>7@Y*;^g`;z@QZg7{?!WLzSwU)TW_F-?VOSClhL{u0%$T +f7M(jC&UyeL!c)?)SBWU4a*!lsO{Ggjsm)%FfukYwaeG|p+6Ip7S&r49*919Xx_7SDl0g5A=kN)-Bc6 +fmWkq*wYPIZa}DjEe<&Ev3zBkLvg!vs3eQdg@JP@6@Q+7Sp0ZBpC(%Lu`#nAVOujO`0=M>C(Qo(!z2( +M}4m^at2w-RF|aHJh*4Nah%Gt9(4#%epGmhl_&sxFE(~+hO4X0=v-2MlX??{{g*{0!p*jIBmP4W(a!Q +r(;iZ|K5wjXdh#yEcf|LR7>ZbK1xBR}t<84YY^uTZn6$~XKIRapI;b*7l`Tev4;EPd6mNS4mg5{{_n3{?iA8!pF0;fuG#3Y@S4#o9QPb +!Nk(M4$9JjHXwXSelw>+`Lir0M)GMC9!dtO^Gc;lnGtPN|=gPhsSJ|&&f=|mPCE5+-gH(tAsk8%hTfFb|O&rgp$?{Yfw5yO%+WYd_t8ulmRxMX~U3foYi~Dx-PpSDg(-acXOXy@yL +PQM!i~j1+F_h-Z(s*lXdC&Cpg-5p#C7#43PwU>bjq#Rvj3N4_88EYviM*HQl#q*Y^}u%x%e8CM)@b2l +-A7KZ%8wyKhbKM(uzna#t;()THZmF`=D+>rCQe&aeti^E3~c9R+3w`u%(qfF0it*p}Na&Y3D?{4D2wQ +s-rxMBnu;*(54{wO$`e}wG)aIH__$^MX7U|?z;lrPUsqyV^l{0XV)7FkQz;rmz4txBRso<%wbD8ivIB;+f&bf+cJXBQ2vf?@7d@fLp97|hIDem&BbIvvjJMt +o5nCzK+t&8JP>z>B3qtE`fW=Z0)?MUyh_H{DWI`&w-1!)wq7x7h26Jk16QRF=-x)bpIRi`Q4U)9TukQ +7ilPz;CpCB4mDrbAvP1t%?~?;$Xv52ag>&BNiovCT(jKC`H7C;^&%^N4@x2wytz2(^nrUILsC`ZfadZ +NU5<}fHGax+HS);NX$<_KH8R}o3l;3wgWpG54kvCs>j#+BNyU;HN;+#A7u?utId+daarLafa%HfzLlh +MgR*udYp#XpGz%HSZ|*6J<&^5ru0}98)2G>tkm^tRt> +gBSK5f`7id|-Nl@5O5&)sf6%!pFB!x^)0a6gdu8ge#3C>=Wz3>+rUd{qCWX|WyFJX?RLjz%XY^nYm89 +a6;UfM1aXYtY@-vPl>=Ly00x45l)6M^DHo(;**@54<1bDE-tN~Y^~@`+y4t2a>iw;p#$4%n9`19%% +FF`!gJk4&BZD+h)hrbYp*X3(r*+dlgD_(bLGuBzEAb2l*Gp2(tV>R)NZ&0d(bFI+j#5QoTQttMCEs-2 +`sCR&&{$yDbhq-PZmyq!j4T?orawbD7=u~LLrzpUQPJ51MEyX#d7o9#P$aMTJ|RQ9qlHW~t-CMN`cOe +b1WsN2`N*Iltp@Q~)K~>s7fZ`+hwyttg0}K|$xVO8E_lk+Zka|195r!u_4Yr$JI0$CU^q%jqQed)7e( +_KQpN$AOuEsLgPuVl#9(;96sA@LzJVvKu;7HuD@ag$71YZ1)*FHpi8&&RBP`r7TiQ6O#>t(x7+RIeuk +v1V{=Uk}+xLjHeGJ0n?Yr|XhO{<%_k$lxY%T9chcW4k3ib$P(q;R?nYf2Bv^t^saufIS6k0(hfn~<(k +72v&r7ifY=P-FKbPy|AerIBddCPGizNh%F>9WsX_l?b=VY-+#F*>?q6g3oKMURLX(s3smTTv}YWx)#0 +GAI+DovEpv5)?00CqA10*|*NB?4Kw|NPlAmh%US5G|dj2BZPf)qPSm2spKeX++2=(46JgonTtgXn%61 +M`0|TqXTe9AUpTMSuP}7dXJz7~DAuTPQ-0UmaC+%mZ8ShHUDOYiI{YOdCkc!`$h?=d^PDoT?{{|{0*a +p_#nXt#vv>T3=>YfZ36*uT8Ir%GMQnJsw4ba`cZI0r29 +b*v6_O^r*~4Dm^>h=-R~g7S9nND6+jHJB$?b_GMIAjo=Y5ODX!oKoOyw8b3TX0JHj+^y1n*>58_s`e2 +f2&%a``28yz$96jDjz@4DE}2LDt7{m_1lbG}BmM#Z(=Whc%Anvd4EzHWy>kJ$_poV}vh&bfM<7=ZPd5Mkl?^w`8q$r^?vXWw9x(MM^!;ggNMliZ>S8UpdLsHx7Aep<<6J5WD$+s_ +me02`Oap!Fs*N>qnYx(aU^A}xe_(;%w9o;dR`1DVxmWu2_9!E#HYyEi*IR{1L91~f0d`;v>F1 +{TE|633_J_AkmEb-puy<=rZ(#-YP_oz=~JQS7G<28B{dDZ%O&u#y@Rt7##Lm{6~#!+0)L1iGwZcODv7 +aOI8Sz7RpnE8lC@edj?|Gz${|MPrMhbKE@ +h+))qoAQ6-5reHbF+L|=Z0CzEGS_~u5we1{Ai^6HbB=GqAnRdX2k`!T`A&9;sjCt#WmR +n;)jFq#obgi*Ij>wLHVq?>-UR-odgTVOuB9;mNZemti>sHxs%2>=M%uKu-YTC)z5AYwmeYZ`IMXGRRfs!G3 +R<;h+}-0sH@}T>~P@=s%=mKqc;p5l`7c;56>ja8S$Jy>+q3_{^1x`fj}MntXi|zg6*_av*eX(@U@KIX%x9uRxm_lmW +Ah{wpzkuranVY*DQ$jGYNJ?OlO9T7lq1E}75xODbeUpswTiwDdQ4Gk8{qhuJXm>Cj3&uh+16v?FLZmg +ST2isL09WEIYP?IvEJtdyx6+EySjS7y~KXxqA>^yRl`&nvh$S62;!z>Hr|`tsoe=72t{cxbc +bBn0UtP(HI7E|zPxeQL3}{*yq66 +o=jB4ED^aIZ%aP}>1*kitT(j#3(`xaxdygK~Mu`bPe5jUJn%S=Y(vq?;6JCdOJEpq?6{mPZN&SWt7kz +M3S`S8$EwS^c?nr;<6(H^e&7VqV2znCDiqWll>Jl}&H8c2NzVuUMQ+2a{P@}=GJ53aHopnRzCp*;h!g +3f&4`jPYSFiy6T)kKoy<6Pvu>+R@)rp0}?J@OJ8X?RD}%26nBLkpK0GK_-;g%9p2KsjgzAxf#SoI +CB-;pQ7~5>HFNPIqRA6tmgT*$Gy%W;Sw&LZ=vXP(m5n`4ofx3{No#WQAvf1|*O-&{=u^5V^VHTRl9kOm-S3@uxc@#Sb~vkJ721dWlQq~)v4jlG19dC-#PNM#x +l$#gl3bXv&l5|ZF!@*K;W(Dd59VTPE)@&rxX*uHd*f_`A{uda^E;#Qy;zRBJ8xneLD0vH*QA@ +JGM+E>rSrm*;M{@q#Pt_AQ8i2_bmQdTXo+bco6-!uxIgYX32=&*`NaInq1a~a4<)goxOjh*xf9@!rMF`<7iS@OcaKm3FtI)j^t%^=M!ZsGQ>o_^~?v^PIhJ{LBPjGP0(D7I-Ha +BA$AqvVf%w3cpL@nn~%{uZzcU4hYjnml=7Rd~{0es(>t%bH^^7gQ{mX5yzsl?;=OgDymp#!DPZcpS;%=k6T0UuZub6cY!56bbk0&G-zqXlR#4|!CLB&TPjYff|ZMy%nM_AIFA`11YaeEHH{K$1I9a +q$N@8?E$vHa^SrS(O0)v7yok53Coq-kqvBXN*%SC{o^RNO%y++q;O0fcmw34BYYFq +D0UgfvwW6<7^_?*n^^;V%=b2B$@a~|r?6res%?jFSm3C`s$C04k!;uQg-ux;Tk +@A>3A8o?`&ZuoeKDVh%+`!}9T$1i!I1axyLCiTZ{K6->F9=A^{iTYnal?};SZWN~uPA|0#Eh*ek(J(8Airl2vGl5Eh8?uaUKqS +4NML!*LR`XS+Rk__AVigPx9~n^!-=x7Inu4$wT`a{1#GjZu>oGPJvEs*~x|NilYwR?<;FN5Xz(=iyP;m +e<(9|r8HFlLtgb@*}@ac8b*Ily)ME_<%u&Dh!mS+5>7zfc}cu^mg>IY)j7@bt`#;hQub=@m+p<++^L-0&?z!PnRbXLw`ym%jG-jD%r}7EI{~WIwW!F|sBcr|9iEKY?U6PkN +dd_+BT+Y>_&$}q?|RA`Rs +&dwNuRLX)l>WKQTc6(p`(qbq2qOf(B5}9i(huG`tMU7$w5le7-N7WVTQ9z`i{q}}p3=^p`RVhbV0!2>>ZY5 +2_H;P)L$5w1I@=;x6x_qjoAut{r>?_O9KQH000080P~d=N8$#~TnQBb0Ps-&02}}S0B~t=FJE?LZe(w +AFJx(RbZlv2FKKRMWq2-ddF?#?bK5qSzx%JiC6^)9%1oTzcJ{RAo5{NF)-!49vEAL<$z~*qge24y$pb +*k+ME5~_q_*z1ixf8$=q~1^NoSlAg%90`#`Fh4Gy*m9pJ~?@Q@|;~1n +AyCUayO8&I)x`MVM&V=HiBrp-B<2>QfN!?%u+>W;hW(IWN?8lq8tXR>s2#JVYtyo@wI+Q#SE5TDUXKc +3uy+kT7p$3Ji0(FlD(L&rK7!yc={{x&B%iHZxBj#WWR$^UAvJl~K>&WdCTJkuNeA10-y3` +AdoEUsj{HbaqYhi>==j9A$|hzs??8|nvt%^*Yuk+YD*F_>Dh3_Q}~C1a#^S7pOM)@TzTU_mT-9(HP?hc#+)ClQ_%5_rPM%B$&Sf5(gj9Or=Go&k>O +k12=v_UoIu}oecH`Awgu$*{fkp2}ncpVWq%p2_k*pdu#p054WDL=w2ujo-F|DIY(nB6Ht)t7UYCvd&C +(0iEGkbv@&SB6|$Tp2g52_NegBP3z%C?j4UK?6J +d~P{C{8LJXAE@yJ~B?JEXpd2HCJr00Bb7ILoOCm_~ncP{Hnn%7BHD?yI4>_1U+Pi_u9|}fY@+_w=o`O ++jGR$6O{%{#IJ5f%84>RB#R9jlBh9zt_PskykDWlB+;DMVZekPd*}#&4ObL7gn@e&jMz@Ut$WsOOGNV +<(gQSA6i0NiAg|@Mb<=_ljUlhaOT`cTc=5W0)`!I_Vt*|vwyhL~wa{1rlYH4=zFzoZ;>*F3uTTrohN8 +A>6tyjfASU%9gE#9~2t7pRocCe9#Mc@Qb+iUZk?xZRr>d&6dwe9RW#+h>b9Qb#l)-UqNCZyAq)H!(wMj0ZQ!O&bx +hyxJ}SVRY}#@z-dBsx1$IakTM6_}b}Xrhw#yR;q-!fWu9~#RJTkd<>bd3f^GgwiSwyF=<6_L}?P#k2D +}Pfho8KSLwY&>tDauMJf{QzkMIfFxKNcqz`+2kNe*H!aK`|%f +F}TT#bsY1aCjqGS+N%2o9Ky4Mh#jlBoBlG+5!S-U$&n_U0|lU0cX3y;Dj_HX2YwU$TFtESD+`{W5zGa +QI!BUobyCC6)d1oS!o9z@bqWf!^qInP7pK;p~NL*QYM}x)C}=-F{}%_jmS8=lU2vQE0hmHf>LD!61Ec +{iPSMXq2pXhzC~Dv%u*w%qB8i5h?0_{>ip(rR)qZIzJpgD~t;67ja>;IJ#cbjkaD#l36$&x0#S? +wK66?H`+dwuCWUxTsB^9Tzk@Elt^1ge%r}*Gd#pK4Q5Assz7^^*gl7u6XH6|?jLhNuee8yq~39*$Jd~ +58kK|SruEzQXE7G&-yv3E*9Z{070!2p1o6b=ie%8iV{Dmh1B00rY2s<}!j9>Am`-B_)7mIS?#9dVnfl +Zb=U0pCDzKL~KLp{g!KmWmL;PUA?>m?CGUz>(Mhc(5Qf4#c_A0Fx+J_3-22IwWOSj~E?0hGW9|?RmQ +zGz6jD6L5<7qehK?4?|-o;4t9fnty0j)mrk1xFGBL_;jEyW1Vcw+#2b%bAAib(d$0tksGp%z+X?%U1yQULFZAu8mO?<0Y))}r2EkZv3u$g4XpOT|3|NC^c{6L{9?<%MJQT(47S#p +>DKfHticLin{AYkr`&rq6L8WX`hA+ +M_qxrRozd*_avAIU~Kw?_u=!GCiVH?PdKyH#4U+p;C#(PLx$;x+%8%f5&f0>eMug2dUbbJBzi_EPne|r`|pTWCW`gxCjeKdIFrv(qUQ%g}F{Ocb0BUwv8MIP-WBr##rV +=~yP6&jisyI8blb!H4=3%AY_YaYwU+!)>TNC$KC3U}zZ&@LYtbsiO5-a?n(V#oj2*wGC+vX0qAhvT3= +DQt|Fs>rZ;%}|d8FfFtrj;s*bQNY$mg{U*Kz+&9JSd+BY0bMtD`uMDA@NyjUv@7WiUIaCW +zTLh^y)0W|p3H!I+>fBiQ6TvpQT@2(&jZNmb{KkS~unZ6vo7l>vUxTqsX{-vw4Mm*#cEuH_`WA)^Nrz +45*&u4z9k*wk2MX(aXt?*b4hWBmN`jCdXQh55BtiWo$C6`XdzxJVzld_CXA%uv2aMu~QT2832?+nfX4 +Q#=85HkY6JK)VL_Kj+6BFuSI^AD8HkKJ8sB!9(D@RzYxV9TH``-cQgY1QQZ$GHuJu)>{OuAo`>ue*QznuO=YTib4IA%%B#g}Az +|t>E;_yS9h`i4C$Jk*~{Gps;I{y7&QHA62hT4KNBWgLWLwGsXMRyD>)-GJnQkqaSEAdytx80=YC>kXD +`jN6^A#BInHPB=gsf(%;Qfu{J9#c9UoX55v0GB--#t)5Pb}CVu_9ulrri^QU^JQB{&qbkc0M5;S80K` +?f?Q%DMcZ8|Av&zG{T&$?}#*@u_zwhLw7^snzbZ5rx8qvl69>-TAa$-n>GOZ}VqBT86hcpnC6$v{nmL +lwDc!^6pkjzW;IwHe+BhkHLR9K=g#H6|Z5wr+`oHnGj?NPP%zH|peojJq)>?V-%}<4A6`h$6Hn8}CE4;<6zK5g97KmS9FxkWJ(Bk-LuxLp!9Bm$QWfM8OFeLFCQ)LL-ow15=Y#rmv4;|CMNje2IE0T +`t)a6YKU*)#BiUc$`7q3g9iYzYm*pJE2Fnqu~cbk0NwEVw)jGH{}JlSc->Zjw`Nvz1#aS{6&t +gTmB@6>|LL*z|mckaOcKeP1)IzF`${%$1hJju`pqeF*T+sEp~Z#WulT9&<+A2lSP}9-Y!buu?ML)MR9 ++~^0QO{jO~o=aj<5d +s3}dVft#>+N~LiASem`Blnfkqe$-oB@rDQ?`hXlWJ&vNkLQkHzEJ?_f-Y-spL`RVzE#n%33q%JG +9I+QEo_;~2_9CT?$EqKYzhEKaVTs}!V>1IXLNRj=2n;Jl5EOPr{@jK|!5+RnZ{%QTwXp>PcSo6SeRhm +xA}{J-b1M|#Mv(y?=&1vXqtZDd>kB*u4@9(QfoiAfjQ+8Jx|buOncd_FpXt(ITgGu7v(AWGHs2&f@M~ +;eC#S91-N2_VwppLCK%Zldc9W1&E+%wSPjJgB{Qw)rHsP5obps?s@u)?bW^E=MKoZ;D*rt==Sj`@)Rq +f5x?p$*B>}^}PT;KYf*ie^A52*iPlOq87%^P6m>qYp%9q(gC;TH}IUIoF2fclg)AzeJyEdb1?Qd%(bwr1b9_oFh^#w!>$B9oqhDrDH3*WoQxka%u|&W +TE8b7IWdEdeQ@GU8kgEFC7O>f0d=Of3Ws?I@(62KvDeZAfZyYpy?luTk8ok?fn%wfxkwsGt0cx{=Z7C39O{5>-dT1TNepWGTOhx9(n<$YG +qo1qq4jvv7KDta}%&|QOw?4&!>#of38c&T7=@=s7p0|XQR000O8^OY7ypI>kZFERiCtHb~R9{>OVaA| +NaUv_0~WN&gWWNCABY-wUIY;R*>bZ>HVE^vA6eQTH7Hj?P~{uNC3cu6H{+U`7dMw52d<2W1NlZV%KW^ ++%wqozbk&1s2LNXl(xod1671rPv1O6_Fs=ALtT61PMFg#u8h7Yc=w;Pk`OU|yzqv77|kW^wvwd~MRYKGH9-|;Q6k(E{ou0xoB>aDhs|U +w?&#XIlO}pSrsJEUeQ$fY}=IZZCPd6Ix8B4^)kzXZ=OAQ`rXT?ar3qbk|GVBeE;367tj9o!>jLKyu_D +K?&v6AZ_26(mcQhiqeWG&gS-sn-QRXiRzLe*75PV97V7h=TrQ!b>T6l6Pn)vN-)@rTTD_>Uqo&$Tjsk +e(RdZcs369fI_I93an&26|e_B;#Wfe@f>-BD`iw8+<)Ri*7tn%3rV;-w|U*>fKub&ch7%usFUakQ%RV +dn4tACVvF%ICvCaLO-K5dKk^BH!eNY?O8eL92JW5TiX{JhP!Q1a((*bdjP!10GGNM6C@heaqz>7Z|KuV1_KBwnE^y| +%!ra;yvEkI=g{?Wuug8WX$r5U{yJ+CgrVwxE8pd3sJYT3Jx}J>SvuWR(Cw<(;b_7TPv=#Z0=eeN3dRK +}e_LhKdX?1I-fq>KRo+Y&`6}ZXS!NAF{0EH26dP7hE9g9o5iSHT94>`0rZ9-pH(6CvmtSTTe12Y)Z+B +{pksGG*zX2Do +x}f8{NV`x{3#q`$!DXZuU~!p%@i5L)9+qQU;XdrPo3tP>}_-Zx>>K@B^#KCIkBPpZ=>sG^u>AwO@I0H +tH(cl^J@C+yDy*q2$jR@rrAvH-`@}ui_2;WA2)e;bd+Wb8p>p~B7#zMM!l|aS)PAa7TJhd!SV6&5z}< +Dt%?9D1!kpyDg`%1d0Pat9q_pz2j2KLrb-i->|~8gc@n$=jtYw)C>O+B%~BP?o&=AB6@bPP*bKw$HWp +iWGTjinA16dtXR4|)#Sh8+JN?bsN%TB2oi2WP=7Qjli&bn(Cj=2UEjp+tSe)kh{oR +V)^wIR_>d+JH5#qB}$|m&mxMi!CrSco~hxfeTu|Unh0aG*u+sgz>7f%_^B^Q-0$P9X?Vvwo67ZLjGp5 +Rh{)hp@9Y5xuPy5wB+F%@uB4F*Fpv#Mes*d*J|h?(t`QoWB0|syD!cZH>8D7R#7=ay`aPRh&ORbq~aB +qu7gup)*yqCXCw{3&MeOFu)ez7RxlkP6G3gkp8=sLjGLs2m%rdrppUa(&eUi63o15$S7m0uggk#UFa) +Yy2VS;ZQo-zPMt^UwS5g5K=hZd^oyx7UNf+T*M)kxHXiWmW1DQvX8&v7r>wJD4ke*TpyK)=cCLonSB& +?HWejSsv1P+z}hY?tBk`-_`0EO#~ivb@=mPuaJ4Y5UPqt$VO+q}7EUb-y`RM{C2b4+6MorZ%F%2(VLE +D=yx7{@8W1_qa?NmC3R8c&LOh7gjrw_D(fz%(~IV4mY3ndR_LHNPH7zq=hKa7I(Y^O%!^9Bk8l!jp423u7?@7;0(94@tRUtu=b?6z +tugeCpfqoUhQjkp@Boy{FbXlW3OL%sr`b^F6Te2Bu?Oj}2J28TB0KC_rtK?ZTi+Xc+)EDuRD(VfMB)_6^uJ7Km*`r +Ovr!T1Kv3I2swPK3kaPQ#3*`ItN7v#*_>g=71>75OH4Xl_o(05Kcd=QL3c0CNaLi(5l6mp}?`mq*SFp +BXOETalJz}jF^BbPvZh&Rgt07X@!%uPGPCdK~t@GPHD9nYs;AKn2JT_5^aq;x1I<{t}evT)~oG$W9D6 +*W;Hd@&s<->Q-*OgHBC$dw2P>kIBpTGk{%xN75asOW&Q?~U8zKtGrR;*fNKQg4ovW7L;jUFphzQ^(`* +7q-}D8v`jXHB2uA&mxdE%uGjc4fh!TJZaEWYZBzdhWK!_&YC7M)}{yny*`!)x|Y?cwxA;;H%Q~{-;n} +mpL0z^{10IiAS%WckPf`W!5St(78qS%=)O85WY}hb&5ooW;O +RmDaR$TvI-itpluN;gh(SUza7&$i^8%czO*dt2JjY|n +#N)wY#`c|B#1-?;`EgL+e=0vwrYyU>p+Z%>#7-|`kl)AL12)%EA +3H#`9%!L%oijM0N?%1+p3OWXESJ4aaPhZY7SkDmD1|DsOf{1oYF2Jt{FGp4Om43kN`2B(~Bc4-{*_8FE} +84{f5XA1V&gE_5vAu#Yousk4p~1i(Fl(p?{giPA&2mi+huBiyabzVtZFKpl@lkaGb$Opu}9tJn^`hc> +uDmk0PwY_Km52ieCetsM+mD(!}b+RPXbs*jr{TW?sSL0~}Ksy;4d#SR&sS_4QN;-!>VeN@4Eu8n06eu +lvJP;?qO&z;u`C=w*uH|U-LZ-8bkwkeUqidb?LuI9bMo-cvJB1FD +%ogdvj}k41MHM#HnMe67}*@wpQWk*K0HEDpQisN+ttA_cIS8;9Lvxiw>;%o4c#$K!7+@&@n2g7bj*$v +1FU~qh;nd0$duj>S@$|~e1_&v=;_0+@v6K<`%hl0ukIS7vgq@qQUeRrl6?617tcw{b~9Oyz@)>|5O-< +9Y3R}`dV5M3cn=^{51I^=I2I3i2Cqw>WB3b_zEYMfnNM>d#`QUzIQvvo)VyshDhqUGv!UFZrqV}|@Th*hB=cd>8vs>i>Iy8tX! +M3}}t@z8^|!0B&Ducd$XQztwjwh~SP1A*c4vJ!L^we3G#OR*GPO-sY!da#V4N*hfQMJ_i`lzZpB6NiC +>;b^o68P@kt+Yz9>1lqpZ+xSHoOHp*KM{h39CYPfTN!~ZeP>}5t~wY`36W%YRSM_#6&H7l=m*j?9bSTx#_?`f>t(GIRqxM$_t{0i`+vf +b@ce6;QFXmlco4q2`RsM1aUVs-Uy*~7ts5b*bf>b$dLKEv$CQfL7T(i`-yt1LLUTU-)D5lrS~3pqzE^ +*smjCVUis+RrPfbh|bW;!9M=;7x~dC93r=T|S-mzDG;@v9q#4Cvp +uHArsPhOHRcp~BrM4JAYj6~cyj^g=>#lHlx=_F03-RMbYKwqiulm=-lV*MleQL0Pq1j)(*9k%4W74CC +e3kIz2+Y|L(qZ@>I>kLRKjk%BmINJ@R303;N0>-1AsW5Z|^&;vVD;hIAdwSuEOU<*mlu@psDba|UiDS +flM-Jp%DVi75vQAb-~(ZT8dfhxm%2wKKelTEzHi)5vKByupF!6P>t$%ad3sa=Fztqw0 +Q;CBzlLR&A5B@zO`ePF?xIQW|-1v|riZ2iug30_tTKLAE?oi!3f5w$~@HPL7kCuwS1(=4RxEd@yPpPc2c +@AbgXm%WU=-pK++@{tvgwW6pognGIuD@MIQTp`!#^M3*N;b`i-s{86ZE59U7@{sbv4F4xbhZ%Ka~P{q +i?YFro@dQ9{w~AzHgmpcLs$U3I(}_U2mHa|2v^g&&id!^LVAV98o!fKB4Tnx?&wOsJHX$ZoAgZ&ee{% +>c<^KTSeNw6W1OYpDk`y^=wDd{;zu~f<5I)z*dz-LH8<@i{4gr(1H^%(P39km`3|aqG#nrRK?zQY}-N +#qZtuI_v%qNRshE+hq6e%jp8 +Oo~cI^9m!H#rADnCvVZ1YkW%sljytjGm0_8$D{V-?(@EFMfnw_Y1|^GGy8WtBp;teY1q2V7Mj*Mp0HC +6~Sfqu#1&iCN&+q;i6+)hv&jl;A3~k5lijc+hd3nJ}RCH#-mfM)hnsMh3PU@k7nd*HFotzZ83JD<*PV +*+f<2X1#<=Y8FfuE|{tHlI)pXLDn{B=a%9nHzsSM9(^nuW9jP_Yt%+2KqSreAnb^YSSvU#E +V$OqCv5^Cxfrg-3%P*C&r`DQnwh5=@Sp^e>)2Q8DH6*9j_rWkg?L1WO(K`0Y2RP^}GobRx-vXA~|CN^ +e;)3iG5uzNA86XkFD5YY?n+Ty`~Da$u~Jwal-`mLe{VV$%*!_rx5NI{o2?H?W+oZG}Suj$JL!I!?u*z +%wr*>Fa!0I2O4?-1GJs@2Cz}t$es`0EJ1-U9o4HX}FM$|dTf97C?9~f{@nsd!P +K3+=;{9iA>|L(5R5bK3?fK_2snygwRAX7jF!b?~bJ5ajTx +rB%>wgvkhG186T(FVRcy@)ars2hYM9fx>tnb%4aqeJf@PRt|gJnDZKLD3)ZO*X%dww8k%ExhnwCq3+w +lh$C4(IbB!6HK7rfifs?ka9ct9kUbK-lzq{XI|(}m;8mD@(0`dfuZ+ATB0mqjZ`71Q(R`WNl!csaMpwKbeB>po +QQnAS@_w>5-Rt<9CgIDJ2tZ#%l5-S@Kk1F$#&#&JtWH8>zysdb%U)z~16S_W8^2Hb(IuR$O68hM(a&k +gb(_Czsm$qLu-E=W!LO+Dq^7N%5D3s63Ji?j<+K6Oj^2)=YFUY9&n9cf9s+^dz)Jp2~5q`V7}8x`J*( +v4oe&wh>%%%S9d(l>&v*PXcV-EAv#96N;%(op@i9Gd79IsjFC4nT5v@P}BtyI-SA?5jmZh};zn(?V<`QhmJT_|tP;7tf`!guoGV|elCb +^W@4m!sG9N24!}umuMep6ak+;Rz257QC=v9Yp}mi`6F`tUh(I`pkp`C_xuFGgI&m|GeZsKQe(&DUF4l +;|VH!j;{d+qdOPj@#Pm0v~~RG@}rRpv_C@u=hNyx%IEhKwh148C~{P=X~nceE~k{(ZD?j6n4|nfQ)J+ +rzEYyikO$Wwqwif;-&*q_EDL-N<4qzBbtr7zZ9(GJqlYqfQ#?psOe=Rf!i%4h(_bE({^d{q_R;wMZcU%rZH%K43$^jqo)X4I9xpJV3rvea%TBnF+CFBo#n7%O +>>O%A!j4#Ve;8gO-{vo8=9iD@i?4tD`zL1MPt7l%g^n4?ONouKwn1dD=9iBh9d*!s(3v+WElC)=^J*{ +*y@tWKokgo;Jxded13`H2-o3N8=#T(&I8rPB!D!SQmqbbu?;k+Ft&AK0ozb?X&*lFgD?YGMbWyYE7C@%Tq#3(h3D+PG=L!+8X~S{PPt`9o!KF?e<*qwniza?dUVcvu`0{P-CXR738^KRaZUL$W=08`M~az_D2R;mR`QHVZjrisQcy +iae_{<0$?2%C2y|L$MQ1)rM;)w;5n{~X#SAk`ECPP5>DkOh1%wSmJuF2!s6Bje=N;FfT~_a^|6RP}R! +KF6=V~PYdp>Cib?*dDW_~3p0lzM{}=w-DK<;e>2=9L0v<3Jm_vtlD&PoMhJrioGR7Q30 +ppv~6mY#8?59dy9KV23y@^cmVB|&m$u-w#`(_|8Bf~6oy +4C2KWm_0Bflu2OQg$=E-7F7cnFituOO)GF-f*i~X&L4*ft7tn1W6KpOpAv4Q>djFpbP>aFDGXA-@v5D3=5y#32+kj%K15o&SpS!?3CgI0Xo +bYE<*rEEDu(65aqGK?}$E0kFOzIt7Llzl$gg-F**QsWVXQ*E8gu?`6JQ{ROdg*2RtAkB{Po-f(QF6p6`UFzKLKTeGRq0La2_=*Y +*RU1*1~A((m&?t{%$hP1leYqyG7-t+^~}aR1N%v7f+q+SdlQ*G(wm2OQ9n@OHd^e1g$A-j|-|X@fe_* +r^TCX6H#(xZs)x~HhiG7!#7PTYp3h?-2>#%CS$RCdaD6C35aw7>r@|~+&|n>z>UVWx;Z)B0@x{^FVTmNUIM_1u7#+skne=f;Ifnx9p<_ZT4^CXwTDHzE9xOUz=K8D(e5G-4ivM(@_iysY1ze(^f}X! +Lq!dtivnF&4Ok+uoE`Ut%g{_C5r3h=tRTDoCgL=#;W}zVL!EGYodIP!20Q!T=ZL9LxiqaAhyDD!WS2r +dO%Ac|&mkI4=05)*>w^X)3>ctwpwmxN&2W2IW^oYy5e<^N1KBqC}}nJ1TlFZVFZx= +u3bkNTM=)$nAK9(96kSSH(M5an6$*-JQ-7_NmKG4s|~!uSqt@WCyf_1^;?Iz164ort+E*BKH3or;lV< +Q|I|8~{EN)xv8UO7yMM?k(W^T?e#>`w(Ru2+HL^XzrrEMAXMwA);^s2tFLSv6+~!zN8IlN-826}R~E23=)w +*lnD%LTHYoDSvMYU6Y|m@&sT*V@yy~=NKccG8^W_={j4Npn= +Ittw5nEgrn4aP6e7w`+8UfEKR7QLr-Z&EJ-&g(J%Y`3y`%vYX;&^ny;paxzx!xl};|NYxrzks(=&8?D ++JDIwV5J(cP`{<0I5cXb2f8#mdCZW`DYd9yz$z+His)}f0HueKN&AwB{;gT+N;0MwenIOyv1Y3Te{H#>N2#p8~F8*OtDq=GoUBe?y&(U7u=lx +GkiS9$hFfXHM{WFE^p{PUu}2bt4trn?eh)E*mK!F35PQ-IK4wF;R<)$P9KKi^Iw3-nkB|Io%?8ZN#U*>%BP9DAJ>i)& +~-eQ0XQAh_l)+Wa>NJeH>Rk-56**69(=MlFN6{C`;`;yYl@ow1PAKM(*dM@b5r=Z-m^VJtYs8w{#_Ac +^k83#%-^L8y?S+vvZEVldI-q=!kZX!xfd+LWMn&$DP)iSwN~C2s(ym-6 +7)a)FP1@p^kwn?uOCl1C;pyAq<1Gmz&*F^2?`yC(@XSWyy;5P|R+TS;$8~T^ff$^Uu0_ON6>^UcsBU; +2q?yJa2w_u|ZvcZ7E0x>jHG5QQK80dl4rpJmGMEEHC;LAv!SlZ?paI7a83m?4#YrQl4K +P0;H%qC5{d(k`_EGm_qxWTZRZss;rhgMtfNCeLW@6nY4$2Dq$5eFwKf&|!MH*`NfJIc8Te +t!yQP3V2HiBP0SvI>Z`V{n4b=0lq!ZDI?#_?555%6YF%Zl}-bsFXf8&;)9Cb-qIk%hgtew4^NHCGV)d +S@(#$L`f@k?&9`LgM^A|sJT8vsSigrQ7(aHZbYxpCk7ZKN +q0klm5WodZ$w#$}ujtHIBf>;!1!SFIFULzYyT7OCR>~Y@uK%ikx`8J(A{Z1hpp6zpddbcL&@K8#-D|L +gErE+i>Hz?_4z!BS+U%HzO_oUsdndRs-kmM&oXGOMvYU!4OVcPZJ0nx6I&X1ks)@DW%$&%h?E;)cdN= +MJTsYc%Ca)R(VUhRar%BANzZ^t9vqx$i3S!GK)jv+`~?M;b=P5&luiR<50B +;w0(|~?g=Dkhz~IC(b-aARHAAqYCGy;;~3(qpb(R7jPDmw!t*Rpu`8ZEG6<^;Umbji%p17%w|hs8N&F +M~*5!M;O}j9z6kdBR_qrVY>Zxzw=>dV=g?d)CU;EaZEVwS2@AoZIws}5UNB0RQbh5_tS +csIt?`1gS|tJ)@g8@!zJ9KWw?;b@^rOP%e^=I`~4;~SCOF`b5TylXyU$<4>WR4 +Ox*57r8C@(~5pPg=zCwCg5yYO|d*Xh9nLRU8|2Esq^4uvtND5e_y>FXT$bg#k?=oasbo6F!GQ0rjP{d +Wko!1`dNY0qT#j*_AQ8mFGr>kL`X4%hH(UiWsuI_UiH&&1?W5TL5S9GgN>_#{RK=7hSbtOpudaq9383 +q26^4PKp|@y3-pT7|c9P`FgyO|{3c618tyGZJy|m2p!%-%IW8JN1B)Bf^~VOJBJo!PQp3f<-S7b??p@ +RK@;;Alx&#d#cg?{hHyD+MN5Fdk5p(6+octLgG#8 +fJ1oqy)%T)c|x9_Uz-NO}jDY*q^VD);iKj5O4gS%lqwg=cjfFSMjLe4a4C7pW8w?OkMCsr3ut`wk +F}}rW3i!`o70&+ihZF-Z12vW#o^ +B2G?=I2kJ2cMjM7To7gpFD_*W0GO*s7e9@#`sh!HmH5Q8!vTjGwRr>63={IE}x|0Du=CtwViDS +I;$C2cHx3=`#g)J4TPn0gtnkBnN?;UEkU1QiKNt)UorPiI-GX{^-)Cum;$-`)lV)mC%iV9Zf+I%kk2? +B4gOBK$63pQywzKN9XP?j^d`J8GmA`0Yf;eK~~gsN`>x^Lw!Ak{G|7Po#tfjXtLg +$@RS!^0dP7_Wn!L=F7276RD?lSEzyJLv|;Ic>Rw5v*ed(Ek7D^0uNpa}%X3hib=j&zYzR^!MB7qrAv( +muWq^*__w6O4Zj+IjL$~zUr)pzG#UluS_*({W)#J77XphDnoUIsYFXF_Z(&hEhg?hW$P+rNubE_Ve@q +`W)qOOrNr)v!HhdGo>%_tEPasXf6d|67^vK#^H9R3={+4h@>rYb+SWP!|QDl}8o`zb?T)@$$7NswcL7 +uBp5$io~$IfzmWlkxyssWZ}{JvRlLcr<-Yn7wjF(p)R{)T`?d#6HBU&~c9ENsVVDYmBLE@;Bz~dH#@i +S)?vwXgU3Yo8mYI<~r8gTbE3z`7?|2`tLG|-qSqn;yHINDOH@e>&d#qB5<2vW8LS$r4s(iMhKSbuis; +LkogP4fKg&qw!z2;6)Z1s$Lv+17c;O2`*yP)H%+$QG%QRB5N7ymr-L)56a*~R`3Ks|;jR3Hlz5LqNZw +eHCS(hs_|fTJd84tG9ESQz>((rd{uc19)XK5;M3>ROJscT}@+%7YP`gyBGklHr)s^bc)fM1SV?+&#hw +j>{jlSSAyt<;ELp529b(aq)*vt#sk>fnFFiWzzuf`XLv?F$?nGS@|2cUbXL8f@3NZ +c?-Q%|itb9g=UzkzfvIO9c|xy&57Py16KDfW!2Pk+2TSA#YQyq`tuymqvcUjSKxB^<Vo%#KgOFR}cYetIMpYHF>1rk3iM;v +1)Y-?5~iHtzLiSN)JK=UAo46p*z$fmkXM7#)>fWlrJK(dopWv{UXS#|jr8HRoK*Snc0}Rmt2cMcd<< +tM^mHn7~(}iZzzFqJLZ^SZgM5Wm0p<{=dy-Vk@N5)=Oh@o@zrv9<#D;XG6)n(Z*;KG)fFwX5zQdW$9_ +bJa;E69p0;tpLs%Je(K-(?KXO?&rxFCo-W^N(6Z!98?ToJ0JKFJ7`U4$vt2s9{gJKmz*T1?7w?z#t*X +Z{R0aK+LmtThNb?25_$=pXYc(mK^O#`+(#A7R3yP%*617 +jIc5Km}YM#7_4hzZ^VCE(!*TX?hPrdPpQlMd>$QqoSd7ylE$h$se*MUjiFv2g +-u1>UQ*0Ow&T2?$fuAuQKOVhG<)Ob{nV{va-7M%dV=f6+(mHk$Of6Qr$6s#R}sat40U*~)&n4o*}cW? +sj-lef2W4=oq+Aw737A~H9Zjo%G;`_%JIQ^+*&FvhAMMN7Od||qa_YcLF|AnfdS$7oN4Dt5Az)##zWO +}f*NtrqM_r*B!~?tDV2zZx?}IPK#X?Ax-4H;P^c4to&hskrTi-@@vf<}_ma%rhN61~!~i0Dv-`*dKH* +&gRe=JQ4!yivSTysL+}Xw&5*=56|}ZvG2cELjcf;|B4iH%8v@@kS4A68Q)!W*Pw@Mp +>`N(mPZBRvOVaA|NaUv_0~WN&gWWNCABY-wUIZDDR{W@U49E^v9x8{2Z*Huha#fyA33=}JtKzU; +VhGG52o^)$9Kw!7_2>{TEVl2}s&OOTc|(~sYC4geCo$Z_H}Q$55IE(hm+1G2*=yAu}4ILQ`!tSaY|f8 +xk!XSBl(Wxgqr#j<4nVZdH~|KjBY{`rA@*py3|u?smb*SrwyovgB$mx;_m*mWTUdw+a*bb4_VmUkuNS +aw%AvsFKM!n +{@)piWliAT-ByvQ_OhJ``jeBR)61i`)Az@xN1fF>;qDv%&Hhyu{Bf1RmwyCiBl`pYTmVv|h-7Q2@ +#X9{5tYH-h`|SBaL|$RtV+@naR<#3cX=ucs|_^2QKeXsF2T=I6htS%;(4BKaP2KG5?Lt*JcR|BLd{q& +K^$v@0XqR0AZHO6(U(}v*>sv@NjaVRN~Ckp9InLvsmz2y)~>hTk704b0eb=XfOe{qXA!`y7wqM{;46Z +&$1Z^a{02%|00U&PLA*4Df`Q?PA{;yhkqK$%KB!`dniBGv!oR-#oylTF1GG*SxDZq%TE~761Z_}YV_* +*etO5KTu2&*&F9cQ8BH3rih4!SKQKIw%P4bTZmwl*aX%ex6565P>W-xLepb~%EOnrxPfhnT|#10ZV;f +LaegV?7}7N<|2kbAfQSRvD@Y|ukKph>7kr{?IGhPg{736iUg^LfRc+WZcte-;b1-2@Y6XR0Qo^{LbHZc2@Mal(Z{vH +sI_ViI)p3H>C%oibXroSDJ^N#@;8}e1Z_;4Ixw|%9Nfwz2E7NDq%`9r;GbfX3Hz-=N014&PCyf4IR*j +q?1pV*^`r-hw$jn~&9~SDy@f0AyqbR{ES=)d-kM}?=n7)**Rz}m{nIN`pJLNMA#S@Xd?a7+k;i2@mAY$m{`rx4$7Yk;WN!* +&H!BaH|b1yq!3oq&IGJWz*ZT-jBn+I9?`11=~;R`lE;t#0#c3dC<5rm1_m){aRJVxMaBPdN;Pq~^;xh +$cu(0Ta~lTl~^a2#D95sYzAf#Dvw3HP6t()&4u4s%>%XT$ELjnT<`Z)x;@TfH!V!t$$eNq8q`3#w_m0 +6-NorxNRIdr3qs(s}{azU?42O;hFLfP+LFdEM`v}f7-VgkOd@yV>Wg4Nabl#cF)ESBqfk|nLS!pGv<4 +6u=m^>Sl%L1?{fSb#Dq>ws%Y+2$iew~(8o`M5IJeuEtP~SOgC2R`;zc!m2I)dv)d!tnFVjw>_#BoXxB1msRFR +iAAy;P~4nY5(M;A#ws#+$39tkM|W5!F;65~zO$0}#`dOae6%LkHfJSb)jN!Rhh4ql?Qh +$$%8XYp);j>9Z`$eDC@5SVo`{R5pgPSUj(xJy)_SB7widWw}as;9PLGu^MDNxb30<+P6+9*ZggUQ)XkO|5)R$e#wx5P56Ap#i*)jQ;ah$Ado@>>#`1 +7c8omKVrS@+bt@0EJ9aLB;0+!Qe|K0PG|+UO}a|;wckFA&W`06wwWq)vj|k(DwJ4mt;{|#lqX`xns)~ +up`U1zFRiAkY=2LH8sn9^B1)*TFPSovZ%IYgC=CId65CKzL!b2zG2kEzykPL;nh-f#6hX3LlxxUkD*E +*YW2YYyPvFnIbc{ru=+>rY@r$w$XhJ&)6K-N)8;MSFpSQ}`#Od#QaR)45>KAJkMNuEE+c^&l2~8} +)4S=x?l_LwtP@tcUY{QSf=$;rG3ohP}p`g-)WImd0MC@-q4t3fS_x_a>_iiV`#r +}DFAEcjx@_kbkG|8Je#lF_tVLu3NxA#cNu82Dv{Ie1fEM7+Z6ty3ZHFq1x(VwI=7 +6jRLO+O;XiwtDw=#qUuGshLS2wS0g$_RRd~wxx^Y7S0;#OZT$bht+@o#gh@FQvfz8=p$}QoIp5C~hh;pB4tF-Y;}6j=w*Cf88`jY;YMjiQ{L@srTuoP+t$>5jg +Y%=A(c-h8yG?$JV8E9KsITpV8|DoCGS63M?)wQ~HAHa_r#LvT1GCRcn%Ao6G-x+^lk3oAqk7yz80z@@ +(H|o7N($ZuU-SpkVq^ZRzPmPsZI&aZ6=iv6p>6`cU^l=R-6UcRARHVy_H&FJ9MQU%qBx81}r%0G~d(m +$`(V?sicJ0Jx%g{9^C=dN{Ta;|7#-NZCHak{|v=mVne>e+6S|t?6+EcyJv&j)^btXX5>K)n?X{{XbKI +I8zW~!Ee8EjOF!KCbcbU3#Zxv`XONw@?~tdWcNfx+O2zC4~j2Nu=B{B_bp8PInBn5bzX7UFK +`n&LuWyO&{6lr0qV@rg*a;)Jdoc)|7cN0}^sIi&G5eNP9(eV +V96sN=b!73>BMyy0u>X#Qd<(YRSjbC2LxJn@t@OC{4v)&ueBA3Z*qCklfp0 +a2OsY3)Of-H3X_|!}}7i@}Q?u5PDiS7`>*?UZ-TrIIZhV=c2-EtHyjp_#Hj7K+iQ4Q?v*~Rl;k}Q^M^ +&_pKeF)}+N9^pvVa4$r8wDt0>VuXbX68H5C?NIG?K!L3nnGB;l7)K@jv^(jpYDeF=Bd8-)r+6brKB-@ +zk?jdf#)+`;9!Vo)NovM=BPkpHj|}ouqxqz?a-mMlQya31EI%nx^+2m +^QcX+*nK*lD-J{<;+mw`!CwMJbu7zl%0T`^tF4k=tlSL-+-AjT@rn^}sI)qt+szo$zAduc!%2A&UJW` +K_sTN;qb}KMBI1y6Ty5Eehjs%EqtK8 +d*H&^zTj~Va-WK{!1SVSLu04}FQTPS&l>vCw{yKe{I0|D5rx+cX*B1AtZqgA*M_Wfy1RQ=$a12UHuk; ++I{JD>mPdu9!0P8_HhSv?y_$Uwb(=ARf?d!@`%p?yTC-X#m7l<#B2)7zZTcaH;sXqW^HpM9Y7!2 +P+;Il*~!bQkP914vebn@cx1ibG|-&xZ%guKi#jOd2rn@6Uv2wR=$;i~tqwXo(Ca~qF*bnpBhp!f6pm0 +n-|!m39peV@9=tNs0oe`!y|;II^FI!TioC%>}!0BS?++|lP(DQ}ugkV}KXDE+|K4xTsnvhGH47j`2ag +*!KvX6<06dm&(pH5@`mM;;%x-}vIaZ^yz+_o`@`8qf%yUmSu!Pd7?7Tun%B+5P{ZFCVZ8PFFa +b>}&5ucJrY>=g~p=2miVFfe27Jp;yrx$?A>Fw{S|e`pJU=QSsqm#sjCP!Z3CzwHH>=LM~{m3hYsBEa; +pAFm()CYVV=7KU!d>Rz2&x4E>+%Z*ct^+@zOZ-Vsc+xVd$xP9E4V4>N99bC7-D3O~-jLz#@L!cg|mh; +t>H{>vIZ-JBdu=;-<`;M7czOX~H)vwY2imp|-iy)g*f_@A6z7MsvjPM{E1XIV-**GIMPx+$D2t76Q-f +J77%}lS_?b{2I;J8gkjxB%rAXkT*+iuQyw|l+XP%2$#!{FfFCi6K)drTRc{J>O~VeRK3(CeZAatW+3V +=1(8n3AerUN%0-*AJI4pQy`9T0c*sEpDvE{ysAOi%Z2@4v@D*zmtB4jvZyEV?&|A@v8?n|;R5J3D=$eXZ4tua*l2G8+XvrTsE#Pe<8QZ +f)Bdr_8$S>FLuRh#d75Z5d+EnEI#}Bu^UjO*p?Z;nla1-EWCnqPLs8m2~4J42&YaY224H6=IDtAmOvg +a!)&THCiI=W$`Vr$-joV+2Qu0D}(zWuHMI*;Zz&n6O-&0EeYeFR@F%lc3{$foF4i!(VD$y +ZqWM2rY(#I2!gV(~p2HadsJwhyl>i{l0Q^lFe$eF=#`z3GI;%<3yKVY7c7P12ZFQQDiGLlMGbNW!T1% +V92LmC05Ppl`dx1nScP1YR*`Jhe!TBx?>I?qV9A +aCb)Zvtg9p~{Bt(Zxa)xC%|=bSqsZAyqAN_m<}l!5I@3EFdAmbqf}dSR+7d)Aj9M8jO2z{l4Le69hW)0!&=zJ$v|%zA(&1Q6YOQcH5 +ZCaPsCzUHi25OjhfSlnwNcHsH0#rW4-2!=gvTZp_O$rlAI98t&!zk*8j*OwSbiB7HKFQYsK^tMSo@{!Z9C!&DyLT>8CAUZ83aTv@^LvNh<~9#Xc>&XIs{+0lD7383cyc>`Y=_=7I2cR< +fo2A+I9}_wyc|uSpUFsvP_eDF#YfzOR9CQ50Ff4PB#?4N+UFW8I{htoIM-u>j=& +8?w9kVe{8P7L5pwf20oN|d&G^%5+Md*_3+u6?mU)CE~{umgnLOA+lFB*e4#uWh{;Tb7D-^5@T<+UL&@ +0&FN!6^9x`4+zAhgqE0A4ZOvb&zRhj4!iu=M^P{%c=UM(Bhtn+hinhuu*RbavM&)7@bps0)CUrGnTN> +kft-JdptU?q(TyiBar!B+X?T@hy|Q%Y5dwQ&u~w6t0~Dj@E3^_Il7vvGl2JWMSXQ`Xoxn?qwJ4yQLyy +E4>kHz#-hkMLkh5x0mS$2aOIV@iu)zK+^8v?)bRe3~j3FmNM|%V)5*T{Ru~S0lCSklOvfM#o|D}(V*V +usPS!~=|eYGWx$}3TqDT7Xpc~U_`(PY<%C$fb_6A_lbAsChz8gxm43Iab6FTKMmv_J^%8P_ +RBkD|bwf1T{kUK!Tf59*@Qmj#o>)dV;BF8=mQHwV1)tG+YX$IFSm^%YKRVk#eE}|U@45m89z(*Ov;!O +Mk@Vlm(#y>I;(qV@N&K*JgvtrK?Ft;eUYX^DrCAK2=YaHoFsMp)&{j{w!hupj;=iqL~Yq@tpW#Oh=%i1?FLmIX>|?^8<#vqA)Py&cmM +^-|kb)ER4B`9B*xcSKFMu~&b(jNX;-bZ$6t6uRoJTF9Yn_Gz^){+l%bLm@Q=9M#+ug*tTNq1VNp9g7? +ufwv-%DoCsY`Ph@}Qt&NMRzgCFY084zKUc-~hpC?sU2~q?$l?*F2HZPP^f*dV)6}(!)wx;L*9w;c)Rc +P)h>@6aWAK2mtey7DxD)XW1vz`5@*Hz>ZZL8Kuvy#S+yUqW80QfCZnsKsy?e(2syRj +t_1VIo4KmgiilP424ud=+n+GDHsa`IpJWNUkCn?0|V_jP`C-Lm-ki0wYz*=48KoV~qoud9-sRF~~tT6 +6ZYT9sMa=2ba`PA8nRSBKAMM<=ss`=MoNnX%_@j!usczkGN4=J*63Lc6U;j~*Q^mIYt%vZcqkv5H9{nvTZK-*beS9RQ_%4lzk!4E9p0TA)WR +bKPVutDCih3Jhd+y(r+DldzC-mZn*wtTT{SzEynX~uvV?`mKNi`{ZwWDW2vEC%j_xrDq*i)m=&cV*4z +)m54Qjc4Bo3a&%qU3pVhccmFqQNCO)E_fXr=CHg?i#%ITIRi8;RvgKei>?H9n=MxtFdcUA_E2n1q-&L +}fVGnZ_8sh&eRdY9VWTmN-hTa6a(MLeO)@)r{^rHu(O1sHx5u-Wv*Y903&kDLISw-`h4f*o238R_JxT +%SHNjpC_foUvL58s-l2#F+TJuX@BNs>lP1&ESCBIx1#XY;rK}cM{`dp{w70;kKtSJZvR+V#(49kA~>^ +C_5Mo1Na!U4?v-8F|D+K)b>073>3NM0Qt&8WfQcks04v_}E)IQpSv;^&9IN29G|_t{SJ@^JR*#R;^FH +Ss2rACO*0up{ta>(SdHZBe*I<1Oa?L?^2S?Cg7N^@2C^I;Uk0H2j+1-&J+iV9P&M3qDzbxWYdURv=<) +^V@{vS^&bUe9p^;!!)*%U++Box#uBiKQWE|DYJu?&v8HHu)V3@3)p}~m1dK7$FK13Hy2G+@Rm0LAaCp +HHqSVraV!K=qv`ef;P`9c93q$nq^DO0kM2+%yl9MPzxg*?lh-L6Q}BPW5aut{!CE!1?}m#wK?xaN$-n +Y>tJw@eGYYBp!A8z}(V=Z)_4LW7T8`uadZ^tQ=@*gxC-kN@Yn|5H3ifb +-k5eU!oO(U)wFC~oH@gLpntgYAd;kivt1#426p^m|L-S;RAN~_RiqHP?==_V(qrXS+TLiyFBWQ#w +bH*>3G7ol19W7w`v3w$Rz5G&Zjr*jrJdO4=8NmQp)g`lLPOo_3_1X#aGW6){wHxZCsTA(D8^qAij$YM +i-thIRwIYQg)&*}`MX^{Y@J1zm0cb3z+b0LA`GnlN=(>Lu8#U|8Z4?2AhJ`IZ`)>^Z6LmvSCcuxb`fY~hFtqT +0k~=dhjL9esWD=G!CKSw~gLM=nBO__TRxVS?jM(7X?@JC)9`^$AZDef@8*l1;_pY*~qYORK~n>=Ov16xpDhpXzrm|cspLWbL=*|p*Fjb-~jam85)($)6?T!5_iDmKT(TF?PrB>w8sKQl4y&rP<$^8Ch^ +Sb)@i*|=Fy&KPet01mDsI9rj=?h%&R@i(h_en%i7ut8DG(jvbgqa>r1@51`8}93vACZ$Hd!Im}Gm#IJ +2K8!rs~o8f?+RSZR9!JJxz{;P|$jXj@2oZm(t}tYiL(R?^#TT7_)Fs6m@3@!AGWr4HPsFdg^$+zh5AR~F@7(9CpO+l{(2wkPXR%^{f86AfiWcE@g3 +Ey%RAw_Vuk)gxue#l1b4WpAQECXLBG-{>_fM|PXDbkd65`Uv6ygwcz`=Le@V+hO9_t-j~Rw1$EI$s4o`KU*dCJ}=TR@)2NBYq2it`})H;3l_SM +WLnLRqX8D_6$uV+W6C+ZN0Es2Ql-yI!3fAhiyVcb%#->Jvpg+N{(o}7pakm>@5kMZHl!&kGDgO?p=LU +i_*gUO%M$={w%emgz?!uSmE#*S{@;NaHgFg_S7jd_gb5?y5C<9#wJjir1nPCit8P`K1Ns2X%F1#N}yq +V8eDNqKnbfFlhCOxLkGLQ|$*O<=a^Qd|Trv~iug{cQ!~B`8@J6^uxLQ4vw*0BRcb3e?I9RhM#-7R&3j +TrGGFng{fXrjZ3_ex2f_Cti`_WnRtU=$r!{LK9N8+9b{RK^G)%335K!2G)w4(H)*!{DX(V +P1&5X4&cKBAKGO?0ZB`dCj54M-#9LnF=U)+G#WX2%HwA8xQWJgBF}aK=}YjQlM;8%-H1-}6+creMLfY1!r=tc7Y#xY +0To%O3Rjw7y#5Wq!kASk2P-B_`|%sPETL#?&2uC4Jexxh=SAiNC`{pRlVORC)1kQsg&WZZ9#g?h5KOn +wc=H0bdyBsJqH8oY-hy265ST(RTmX`r1HBF=w4pi-r?i;P4(ABZ=f0?erp~uU4PVW&@w}o7oeMtd(*2G +TI;e;LC*+~S_EXH;QWpWd!Ij-+bsK>H>2a2N3Fcj%>mW@Y#1JDtZu5}WR3=0L{V^50-?1ebhES7W>helU +}+SGyZ&n){H-gmm1`QwPt(Of*L;&R`{FF$AZk-L_9Zhv1Xh%j+E}KDGY2~OqnGnod+Y!j2;E*ijC%`a +?aYSoh|L)xPbkY4`KSL5cMYRxO0kNhS2!zoxda47yy+C!vy2sRkU?l8 +av3+bFXP|_4uh^#(>jS2{eL#Q0M1@}LOm)#*!Cbu%TB!hq6~7*R13;Z=uj@p +)f6mQ@+GgKg^OB|m#G~L=;b=Gay6Cf(wg^!J#IC$&95_Tszr#lI@(U30uWh}XQm3cOV1DmyiJ7={ARb +==K~Z!!USmmlq6i*F7_upDyhmPJ4+GoNK_;~T)~j-QgPyf3KrN=fr_B;Hoj4kUJxavXcgv#rxd%$?PK +1>_TpAZ|4&pULB59~2QNlElOhTajq0QB|nX4fI`^COFM8hNq;@)B5b-K6EYF&{6^7$rTCM$7K7&>0Qr +SN2D`>7D+N`u*0#N2&?h*4@h$ru;mPmnkkG{+_Y>G2R^m`Gwu4`4(X@(1*ZqqS>97&}tI55f_rsV}2C +u@id7XtN`*M}aBr`8rz?G;Aw61A{fr^xxgV@MpaU8qh2?bsUS$UKh#ru-T`7t@1LKTi2I4!+59&f+2C +J8)MLr?Im3!o5U|ht0(={1Zw|1@{u)iO^K{w32wtFTLlf!JvkY@Ay9h@L +#Txl8M-#@$~hybYi7xaH85Rx-++!8`Q#1nxbtt$<}IxLCEk6 +{7t-{bJtRc72)(CD6gMnzSjE(~T(O=G@)Pn!|CokKU&Mw=$TDmlI((DKz(gPMUn8LPLlk2RqRaC#q`S +gH{=kuUAJeU0%~lpm5+cmWRLXMXKEB9Ut-69DvJpn^J2YS{O>9c4#w;s +DqA7Xde6N=-o^Fg~MP!8*hw-IudGbs@uBE0)^sT+=2jHl(8k-j(@`7G=Au=CskbW=*++3gftE@LTIwZ +ydaQCI&9tCSkvxyz7o$V1be^FLwM_{#(5Wv{Zx)|=+dtVD5^y{zh3CGLHDaC~%l^i^kgbsKN-l5#4zh +nM!Mn}osGa<_Xrk0!8pb#4^$L6gK?_pn-kH-CJ7BP1~0*@?pp4-)cO1bazAClCi>CDb$_0nh9BR`J;H +qS4vYkQ%0bB)LHrltAIQw;ldOkLx}5xK?u(9u=W4!sAgOI^O=VmkA_C_kvN-;^pCYuV*6HujbgiQ5Q{ +Paz7!FC?)t09S*aXs~e!O;cE5J6r>XHKHiQeBDy_rwDnN4LonrpQrB-AlP*j_u`hip28r?W&_dZE|B^ +Hax^|tA2T#oDV`Er-SE5QBQvr{4R}XOLv~wklKhmrkI4U~Jw%*E8Q^yT`yUVF&zsSHZ9vJ8k_Q+{bSe8o`7LGAY&6>$VQgNz2u9_&! +sX5W4H9c!*JT3YKQ+yv3Y5^eHY-C$6klQo_k@r%rg#t07M-hS=PoF5GZ3j3Ua<$f_Qy+qigzMcifr0pd?)bVsVxB`jQZ#k${ +_W1_0J`S)If25nk6Yn3i+YrTsUwAN64ZkPo49m&(%oYYBvXuh#_{9$1c|KxlU1cybi$io~qUaRg`u5_ +|KwMJ85u%7nC#SyK$Q_xgx-HE=1y89D8=hI6T+UMw(OH)r&XkwN4#=;Mkuvw2BuDtg3c@hBO)caZZmb +b3H;)Vj)Hd-@@P@W|;={V8zyI*G1pf6>Kp97jY)VSj0m*K2eLkhqnqce_NruQXM?#q?e5c0s!Q#Ose7 +qEsx<#;r#}=+?cv0LYV}q2V!8=h+BAFVtY9@@6slZv$*%90aE475`3HbPP2+ +sZr%Wek*p0Q+8-+cM8=Yn{@GRM(oG;g|js3KkaUdi|t5y-#UK^9N;?xlE+N +GU}0(~tKT{yr=Wbs-TrT~eqw9;*3r{i=(!@F&7tWpR%4BczBv;yUg@2=Zw?j!_Q=>a~5c1ldQ2!hqxK +11-pbHX@vrm__TN6FHfr+iBi&kbw)F(s6A?|w^5Awkyw%7bOc%WZVn`U&s&V{qQ}_JN?7o2KJsLIebS +?4|1js)7vn<5oF{KwXkhUpGO?PfQ8*=_Eh-i6MO>>GYm%&5=<1MNi3&b*;_L^isn*J>3&(Eqm_vt2Up +(q7n?=;hdMp)4P9mdiKxKN;}diNQ2z(R%aUITQ~ +pd^SEN?AI24%2`}aNfyPFENwZ8P3Q{hG)MV^OZqVif*H6VPMe=$Rvp}?!^8{47Cyes5D9>39+jxZ4`e +mndRxtl8pb*+O^kExK5Tvl^=VlF@b>#9n`(ocAlgbKzZ4x!)6H4ZwENCP*-4s6oU9(1igQZH+b!8{QU +alEAz8?}~;zZ)&fHDlXQ;0;~2NQ>dZcFcpW=?8}xE|@j^Gsi~_kg!NHsa#52adSK*3d@l!6m@P%fK{M +==1L%H;n%G-=y)2O_h*hlO$7Bh*FF>C6Dkr8;M$4IaIG_rw1<%P7f$S>*(M$CgVlRdp!B3SOqllN;P^ +JR`l-sbCQ_l*k|d&&iu3A(M1>s$rQqmLe$iA>7U=7P)8~Jh9d|Mn|MEljMf}4Q{yTc|OI2b4iP+cv?CIpU2a +`Xa$MTnCIyrx$9*+L-%Ls+o^iV?b2M-h~#fB&EUcWv#{=R3_=}$Z3-KWp~^P|GBJ3Ce1LcINIb~HOaI +DLa)qD++HWbxx>ge+(mb``J=j$UBn?~|`*-=F9j0{Ek91H{$|WYq?69-Cx-uqkLsqp^JdQD$Qvy_kKc +1`%eJz7LXC2$N8lWpOZJ&#)-4F&tZmDbs@~>%uZLjVaNDAvqR=B=d{e+ZiBz^!$5+wx~#p8J;@Rowb; +3r2o2Dp-w|brw899-yFO;q?PV0a-dj5+_! +zku;})xD+aN*%-H6D9?tQ>hPzl?)!8DUE|Srbq$w((MM4Xfs8%dWRK-}~Vv5}3>fb(fQ6|xbG7l4J4R +4;4xGk$NFSCo^;eW_Ag9V&U!*#sx-2HLOqj6a&co(LhXrWVEpJ0(;7&$UuL*OqN$&;mgu( +b_m-p2SPL|>AkEl#kye=^gCW){h*Bd(J;s7pjF*JnR}m!3Se{cw5i_>feQOlYN7FTF-XEpKV}@mhY +|Ij4Z1-Nsk^Vc?s$!Xp|HPYzAdVg%Xtf>yHO_!=^-- +Mdgd`=f|DBHo1rDP!{mjYEHj_}9$>Mkw&poq}2iqZ_zD_FyUW$u$}>hM$L{sq5mc8}8;XILO=R4k!Lj +ev*?P*!D4NsL4_9(l|6Zn?2-546%Blx2$L8t4KGRReLN({+}4i8mwWCH^J5;syXUOd?|GPqr#Z>TkEE +Oy|NZaur1C5-um(?Px2E&`nRqYT~G(J#8Efv!{(va|t)EL`@ehQJ%jK65T3Md6M3tNOe_jk>u7}Tz}X +Gy|0a4Pslnogt~|})vBIzS-&anR!S!It3#%)UK}blZT0)86w1Pyslhvtr%ZXoTJ6N}b|WhV>+6a;)1F +R|wMDEWLGbJP-WFf`B{iidk!P+1FK$qIy`j%*i1*|#>7MFid|%FW++04cXcQN^^N> +s=W)HhasS{pPnlA|BJPV0&0)q}E_5I)pVNe;TG}S`$!@@CS9${+kB5K)2?`{if92J$FvF6d8KPo$xM% +RxiKWW|M3EgmrdG&+4MfagRSq%!l)}H_9tM)O+@eRuI&pu_myse76OUo&wBU;*pz(Q&~egRZBu;^y2FLip1aL_e=?u +}-rv(nMVdhcN6Zov^V6(K+vd8>OGsIrhiwr;ojw*9HfBcIKVo;R!ip-|X-fC!mdZ=j;w6FVO0xY(I4e +$23gwz%e&D^z^PAkQoE#ltooj>N&Ki503iBAEm*|(0`Gy*{3B8Wbp-HQK)bj*06#UNcfZp42v2^Iy`X +m^=(^f_(yfD=mQ{F$th5)tGDWtxZ!rLu*Vb`J?a}$U5j;xdboCU)`=WDAK<=_mgH<86Z~^#<#D5;5

2dnY{HeA&%=Pzrq_@jm`EcQEij`*b$DBB>UF4Vq^IXP&|{><)-41A2*kYZHFrsI$DG +iG*bIB6JL|D2w`6Jc}G?yFp8?$96n%5Fh?>J{LWXE`e`wMVE^GlS1p2E6T?&!V5{QZURv|A-$OEt@G# +OYfK0n=@KbHVICC~*XTGxM`e{L`B>&NSu^g1B^lgcX{~#|yF!0NYuI05XrRA{9E*M=-- +7Dv;Oyl=L27Uog9@wt`{zF2OUow~HxXzFWc(KY!P|q7dXI=kdyktvJk>BRFMu95>la2*yi*@l>ha2KG +yJyld{tuv1DFIwF{Tg7Iklah4&IDo$C7ss#tbzES63bt^De=hKju?SSRAckXUO%hmI1$%Kg~ +5d#jDVcS66EerluIRkOTlJW$p8l-XD;Dl2Jq3v7jN@OA8wzQlKslrII_d-q@?Oauri~DlAE;c3ZtP;XsF7=`%9#bvdsP>Iy`RuR*7@L|O+xWHm{%+_fvr?bmF#g!mN%^9ynKKeLY;5CS7I5@O7d0%erGp +EqTk$!XX1FVzMX9=Q&h?h@jr{APIU(A@06LRv5cb-$Go{SeFKPX6Vdq0IoZ+kxzNN?AEDv(;aVM6{l^*&m%tgU(^ne?U2d4qBGZH;=K{CCuqv&w?#` +ht-=gry`p25c=9%_yQBUZ%#FENo(R)c_1)R()5!y(oOS~vp%+zpl|`kho +d<62|USI6nc)~ed#obTdeRnF-y_L6_TcOp&AQ02nC=W`@$i3L<|v;pACqFw_)$l@||OiH;~k&uNJC~g +h1nEl(`@-(oM|MP`F#)+%6?BLx#Ae~Gh3C51{^a}1wLmn0-`#X`EbOO+a3FDv}RCViSnCf2jj^8*Gsc +LuGHC;ps>YgmYE6a~GE38En7j?@;xw4AfV!}z4Q~$6Hi@r8iwVB-_;y=p7|9{G0`C8hp+-43J4eB +-vBG8n!iev+5mL$3VE1_h5}&+RzJ2q0!ohBn=nHe0NHA>j58|>4D_8<&6Bj5=Q*+K7=#tN;P-cjj8xo +k6xFit8_r>@DZR%2?t=Br1(i`UkSOG0|H*iVaM!#2lj;Jjzqy=xa2<$47PBqqd+&oCGs1TYr^Q`*?|t +$Qe@GpKBZ2(!Hk6(VsleTn=q|3Noa-QZ5nf7-5VZ+5xu|)1)8%a0uQ#qq!~Mzm2D44>96fg|;m^IoBWT@AM|T;x6WPKkH0`?oJq7IOX3i#ahY|jZs`yqE4;RU(GjF?U(>+4ULth) +IAqXB>@UA7%nHURyo8Ut+Uu}6@6aWAK2mtey7DsQxo_Tr;004I>001BW003}la4%nW +Wo~3|axY|Qb98KJVlQ%Kb8mHWV`XzLaCxm-dym_=5&z$xg3aP!`RY|ScP&sDU9?G>92Q8ELmmZM!%%3 +8wwaYBL8N!rIox;e%|L)U=o0p$Iz5nnL9|GNI-Bdf4W$V4(HzLcJ+|^a1LB51ph +^&xWG`vuwk$th0O02ZIla;$Fs?7!_?QSdOuIk&(UdzJWs%><4@O1i63xD%X*5+zt6il67|CCA>a{2mU +C2BN;eT_05$%?PGBG2lkszsv@Q??O0qlej&D=}p?*V{~2_E|2QDSL&NqY+L5%zEu+lLG5odX{8a$#-C +&$!IhpMxc6Em4dN%VgnYSJgXv`{b(SSc6zeHN4X; +tICBdIu(_W7pL(TwiIYX6Gds48C5cjc*UwU4e3NOS+;5gyp4eD +DuJ)r3v_3zI{1{dPX}jtVFDAx-tj`()CU&Mw!Fz1g!r-$J2ty)?Qe#nky;Cb7dys1V%DDoRElsqwi1! +D(-WqAF0IMcPnvY56(E6a72_&J9eWkd|;6fo=y4T4d=eGae8v@C1!9fN;}Ib8 +{aR-6UG%=_eaIwI;D}l-YE^=OFkp6*8pB(1+A7}p?@B4049W|tm8(qn|TLTG#Bwp8#?%>H*ylHV5Pcz +dch2BBOo*tpa-me9Lh|2S@YE`--w_htNm(=_TdbQ5eGe>azQdf7D+|YFoepg+3}({*aDy>wZ`Rv?GxIs5@SQE-G?#8qEa43gHl!B^l`rz!uTQ%uARIpr~Ad20I8hxs( +8I4sDU-7?se+cjSo^1u_aXGKS$x+xlotLgwJiK@p5gOhP6h&z5(x+T(P%#(NVwD6ACsR$yCtAds1syC +db$hFuUNR06}<7}fsK!A5@W=*SFnusionQ7w64GAS&dzI*knr$a|E?&&3oDetZ`J*FTfT35Lv^A2bqk +*ef3ai-9gv=8iD&<&+oCnyO4oDq;mRd#`Qt}#0FJ>^Z3#bwFGmZP!th7cA;3c_|R+V-#7JRI5h0E)CO +xCWM83RR%d3d?OW{>tz8I4o?pvaVsG;z7gO2gQtMYx +(tF-1R$T1i3%cA0@41;~S1~_bpV5}@N@3IU=CKMlYb`Z8}?*nouAyLX0!F8)V&%f@KZd0`fl5H5cA)o +>jL~I&tD+udQD8~6R>olGVfZDK#U>AS6n$gMzix_o^1{NH+Xv6Mnz;NkS7qHq01QZfVo>M5JWD<2)Or +&y9F^SZenzWzHj2yMC_C*fEKx^4@@OjBPV;Mu&VB+QYPvaBF%@Bn&HHK(_B}su))sT{4p?VS%rl2sSW +pXub9UE4-Azb)9arWvU@kf4jXs>k^=HFTFwy3S+><%72x)QL$FmT)VB)F9osB$c1EGjn>YvU{?5B-l_ +(omE1&J-hyqHZVrij{{1LD_}uf|6D>harKH(0(Bwn&25Iwqsa +l&2rp{jkaM93X5=ZPt*Whwxh4H`s7JxFyBZ|DsJN$7>GU^xFay`aD!3_-W5f4FY;vF3oRNkS+hS}W95 +amL8+3BY0nH|^T<*_l)33?6mk77G#N;Boy^y!jp8a7W?4YK;=(PSAjWa4?;_qSSsjVeBUm6#g&{*m6q +vZsjpS-4pp@rHw7v`#!F@qsc%&A1oP6CPlM|Jo-2*V#xsNV&l~*8a?kE@0TUaU-f@lVl)2V_4XFBksKpluScs3@;eng5I;x@@z1kASj4fwtH8p5A9*;Rv$DJ4Ro9ef3U8|!bRdSy5Z7xL=v=6 +)7|Ec>Dc)HqHk6ATY-b}C>Wfu<2<v~aIi7Suoq-TIT0AH7@FX4#S-pyB2A +6GZG$3kj=e>wcgf@S`adBz}B3X&Q1;59j>jVG{fWy4ws@Wp6BoWFooazyb6>aGaVl0w{zN29;pD(a?L +Z<+r+)t%ILkJv06$?bXPRB~A`IEE;9oiYx&EW*}YI)~!5iULZf&`r+u^S|Q-89ueQSoAFH>nF+&D)sE +oFS#TSnfB;m^{bU9L$~1*mn*58=E;zqX@Oz!Y9l=B=^2*Zl5Oi1g1P^g>aD;idzAU0j +Z2YdQYf~O(au^J&4Zcv`Yjb~zLS*0&gft&XxEL)8{&yx`DpmmOCZUp5hYv;(ZnE$wVG7Ns=&`(Kplik +~AE#rJMB1m0w>TEerj`UqW!)#yz52T;_FbuXbK3&!Jq~-2-EiDS +JMdUo9pK+azsa$lXrlxHoQ~MI+)93W?@?{#fG1=>GrEA%2ImpW?h;4S#C=ex!CEsoNbZW(JNy?rdNkM +vI?ch!*#?5_1gS*(sgU`xYStaAwv=g`;0bBR^I9eL}Wws&Asq%xxi;W)ap=W!@u8KU%?scuQq&5o|QP +X-|aCkc2V}$AAoL+2n@E$+lDWLYvP_1l`-{ssRZDA~xI7I2ep-22UJRv%26ekmKs25bAHeR^gNr^AEknAja*_fNdtd6nDD^j{=I0{m&!+C4{97R_ +?jFO$*xxn(rj8$*RaES5b4dGDgJwB%^#T`I5Fe%=vZ{-+%?#c +dX}AA57t>y;b3Gq#4+NMbk)%&$+XFzuO%$A2jqWSNboy{e*L;kA^Z!meG+$ki!`$owcVFPt0V5yyl45 +9uWAGZ2Ns2?HAa?*}>0veotmQZl`X4r}_edw#E7(PwFjx!z$uwP}x8?N@VzHXTjS0ez& +>IUDAhBg)!y)t20UIB;fk`pBI13qs`U&g;}2Ty@Vr?0)gMTVT>QvFNKi9)8x)iPtDn;|Tm8P)h>@6aW +AK2mtey7Dtv^Z6!Pr003t<0015U003}la4%nWWo~3|axY|Qb98KJVlQ)Ja%pgMb1rastvhRT+c=Wn^( +zqjTqGwFoyYFfoNJUhPsXm&mM3w=&TRIQ91Ef#3o%7<0noOl_Q!8G0FnS7vS)9YR3Z_LMx)=|fDXy*y +BSG~70+)@NTt@ZAMnlOaB@iA7UfRxn~fsj+lah+@$&Ty{`o8UjpuYnuIM*j#sGG~QD`*1taH0m9MDc@D4sOK`5-3E5VnQD&X6VU~J2Bg}AO5BNvOeXYa1gV)dX1%~#~@`*+tL7C(Q +ye*fVLUjp1@Es8DS1>xJW5Q_Y~Q%o-2PwdyMxVeG-)L#o(e-ffFd+zn$ +&WuhY%>CDOAyxl;AQ;cfYke)AAGz%pZ#zEoCBfItjO8?V8`UaPj4naQYqPXne7P7&*l7}68VWtH*8Dg +Y|B$oNKl3uu=a$?ZG89gfNW{b*G#J4+{NBZNP}vz0&Z}%^T@$J2NP0?0vIg|aVpXcN3m1_sQL86_b`a +NoF5!X_^5Uze7xuR>sJTIZzh2K*=$A(=Jif1D=o{6r$##^a8%%ug8j4NLMx?=$!vynfxbw!$k)Xa_xM +`xrbdaM5i9JNtu6(>0~NSo(tCZTB?^RGusfEK4F8=UP`SwOid!ZQNX1W6-1q!oO*6@GOXSDn5wyqd(# +H+;Agtq>#cx37F&F|bLr{uC0-H&1318P1%q2-_mVsr%7i89&3klZ6b4KpD+Q2&i0o?`NM-ffV7ay*!l +Z(Z>v*g1W=#*gEoPels8T{Yjv-rDGW4{0C^NZPk$6vn-Ka(%&Yy4gG(|-lgS&`z^E7H*4Gg|@S<@-#YWtSm{)%p|c8Q8NVJfh52 +fn-Tfh{QtFqD5+2qU=U|4L9tXA#6gPz)~+%I0AQ6=DS=B&&8)aA%J4O83qlyVoB+z3*C3&G?*+a@oMb7kpXrVB|P6*5?a&R`XDp6FR7`4W}nUh!X_ +ud|*0xvA$doTqg?MQz4k_Y7Ih_DVlFDLaB_5gwtX*5BfIGLmw7!0}6Z26UfC5FZF8~7ZnH3tU=`u|g6 +03iyd5I70QFBOa`Mhr(K(V@UZiRK+bfsLUbH|v)yK^ +C+^{9hZ=_=l3C}s|x@6gUYH3SW9Kw8KTMahtjNAE_KxO2M@_Y8BN=Q*d+i%nuGF{OrbYmWX +Vy4Ik|j)wfGcwb_oP)pg9Q(8KbMxj;bsqe+VL!y!ZYay`uppJVOzG{{v`}E`FbwJ1RKMwQ~Zx!Vs-F_ +!R#mh&q6YksI2l`2b|P`ATTT963saqM;esZw^}NBqmm?+)Sm=b}Su@06%VDVy+SfHx&okv>+m#{<%EL +Rp5KVRSue#1GNB!>5}!j?UIoPu0hv1Bx_(nDfj~ukB}KQG6ntw&z9;nz7;$V&B{H0+fFbHg6*M8L4yS +i+=4qocaG6BG!l=rKPv^j+0qk|qw|1_r$MV3%w+<$n`J$QMm{%cM^Qh&fIAgi4A(#g25{?Lz{ffpgBV +V&Z}Db_n59EZ#o@zeI_yV#m-FIF{pduYC|T|b1s(ai>;pTDT$dmvx(Z)KTJnd_f{tKxXb9h5oe6OjWdV8371cTi82tN2;K;8}>8-QGvz~8?^)m7ZfF(HmnWk-YKN{Ztp&yS& ++Ld76QJ%esMo{grpw41UJ{I5z(Ix}CQpSA9-8wy$e&#KT-90RKB54Co*>z<5zqz6pKApMIkO9x0N?dRG@l}3ay!&PGVSwa@N<(Kjj^eko4_Ax#?;hLsUNX#PB +UkIJnm(p&=P(avjG$eZ*jh<&NGra|17+jv +4)PZ-`{9r_(jA&y&ajZDVh3T!K?P|)AVI<$LXZY&;;1Ysc9=pmOUQDI?bh>po;+*&#~dnvKis8dkCX% +Kopd~(vsv&Tj2!;;7CR&=`3kB0 +^0#1FG@7-;ao6${Uen2R-8h$1%?BDm)aBp~V9FoxwC!_H2p;i*=;ZmVHfh&vec)>>8TrLh)OtPu?8n$1N&<{Za=(NH=W?R0G@x}M)?R+-U$*a%#Pg-0T)lRTe +vV;ee}8Q1}DWMzl_Ic*_2-=!q2qyhwWwn9QQU+PTnGd-IAQGPn>Hw&qvh<)#52cCgRnf>_O8Z0I{lBk +h%Yqlqe<7py!qF93AiCS7i>_99g%p0_A0vYv6N(<6WKkH`DgKAPx;F;q?>gl=}(PYKJheoTk@Qrz3tpYM^`3%tnVNS!s4=zl;Vmn~1wBc080rGSXso^?9?* +a}Q)slB=sTWg1DlfeNp?W37wz%P>&g{z-3vCm`uIVWfh91i`mH<_rB{of+A~xX{2(2_nHR!|&_<^1rW +5I~ZWY=G-8L?fSC!SNWZn$%-n9H0w1mr@lka(IKZJi)OFS2gOpOZM*4^{ArDW+(7G{Pk&J6?~S)(!I9L3KiI8(*#jPo3!3jv`_jlafl3}yZ2 +hj@#Xb?^(>-z+Uh9z9CK9fL{@hFS$xLVZ`s9461qqDrH)QY`?@j3)_();vCX|kZo6ZwpY==;pF>w0~m +*Q#A-!VR`wIhIf#y%uS)3pYOoG(G0smdiQJK0|6}^URk5jQJ|4( +gYOVrr5K<3=V%E&R&*=2tUz$5C?cIY>&~((IFmm=L1e+xgf(gb4QpHu4?;do%ke4kNQ)p_rNVZRQD)T +e8{jkS6Vs+AxO}55ZYb2@5yP70xzhrSO&y~i^(CmTwqMdn4(E+5@9Jvp)fzI~qoCn+yT*ET%gYjFt5M +Yw^>i!M +Yh0R`?%#%(@twpnR>#*G3-;nN>Q5i~7P +tNS|{+dDyc521rS{>OiSe>S?n$?LC!T~d?VkDXg~yK5*YNT=^xT^{N#TPUZuqh;$?EG_Z9iltYpI0lI +~5`2T~&2gxvt8bMq-a3cnwbJ!dPxt14dwtCk?C|iZ32d+6>tU*oC)(3}&z0A%EoXSbRByL-RzCCnSdJ +)=Vd&A1Bnhi>rivM4=`3nW1m6*u+OutTAClATp6;YMVKi5#u&uSMR2?`m!>I&b7tHbM#7tDVxl=Hkd9 +4(x2w<9$dlo?W1@;h{rj@`Ve$CiwNzIk5d)*u}ojbq5X6W71-dbzt$?}FrfmrstTlRdlS1mUDwig3Nn +k>B)(e3Xuhvqy@*Ge#+|9MsWiqtb{oFvMlAt;Rks=Eq@5b}Vgl}`1%CWA`AD9ilHega)BxL3 +?MxOBN}C;k&ODa-Y5tibn(Y>pSYPG{qbV6wHqFzH!r`-}D&3&by0`FR{WffO)ZBeo24BP%y!xQK!cmV +Adg4HItbK!bYFR&iG}I{K8&Onc_)_0^!Fb*^V1u!zSObN-&d+48;C8KDJ35^#buGS&|B)2w&rgqPh`z +F0o#Oer2!q=5pffY9v3_Xw#-x^ZW1~vdaixPA?(J^Wa`z=Hg9qM&x#+UFTZ6uCpKWRG3`EOu&h=*XC% +LzSnqV@To)5&_&-qs;)*9b|#@UUwoo(;cUp@3crM+I!#Az!D9Sui1xgDWdO!gZpsr0lR1$qQV|vY?LbH$?@@$t7VnmG8Gr%=J*bOR}f45UBR*B+cImr +RmYu+H(tZg?CzH5tAU#~`ksHB(kzwycgTe=%@vj(PBd-b|78X=^aQ2v^}&X}|4ZlA(Vzm>(63+l&~1_ +0wzWbebE>EK8dD#wzHUxdH&m=Jf5*T=m$Jwzg@?iEExlpHq^gilbdaptD_{6?hm0zI$Le2ZK;9rA>93 +J^Q&&*JW_+2{3(TAA)v;)iz+-R593ZguLUq=IgJgeT_s(qH3#!y(4vsTx-s{ZkgO7LM2Hyo2N6N7q|EM +iPQ(wk}o1KN~?asM5w24WL`@9z$j0jaj$8pPUtjz$orAsjk7vsXjx3&v=cYXiFpg;~o$jBDF-^ +upFL_0|+Cpkiq&HaH_Q-f+q*wIUHzR9M-zbtTSP(C>LF*Xrx44YFHkwn5!^fZ#60KX_eReQ|?R2jpNms +-}_uKzdZJ7QMZO|9sJ=4QBflud1A_vhO6FGabi0)_5@$^q_TS@&JP)h>@6aWAK2mtey7DwX#G~lPI00 +0170RS5S003}la4%nWWo~3|axY|Qb98KJVlQ+vGA?C!W$e9wU=-E0I6nI$$t2li7DzDs4j3#F)aU{wT +>=}(hA0FVVs=R}0iPJRE43JA09yiyvuiUM)*r3DSKrfCiuR#x-@_jWR>55sv!GV_VKEBTXj8q*L=6&? +1w!U~&Yjs!g3|il_w)Jw^+hvt=iYOFoqO)N=iGbF-O3+6#F!X{F~gs#GR$5^`{!W(`9A`G*^~a1&Agc +Y=gE5wOa46h7VnSN=dWw{$(;?i{W$;j+wQ*mCw%_D+>zfP+@1fUyYtI#uFC)MPuARVZB|xBfnJ71{y4 +AV^n;5Ne1V)2deuG(0z*iGLf7B8ajsf*{pyYv_17gti)2Nqjt{A3+ISAUPB@8v(b-HYWV+UjyL%o +0Ni^UDuMR43v(7^5N6kijs2f{$NoaYv@Y!-@eN3m7&sObTP5>4`VJ?N141molzpWN{|V5eV_)UdAXn-O +dU|IUcMq$WFE}94ss9SKg7Mt7@?Xv1^9M>wqeQ&VHNfT|ExUkQ)1?#%}T!)M7hqk8+QMVdguSWh7r!R +iDwL3jJhY1h6-Fr@{L%$w^ZB2UJx&SRhq*NzS-E+Gvs*<5g~ejU(7Q8u%+_AjB%@jKGptvM`F3yNON3 +toimRKSA#HrPKr)-#z=Z+{hM2P0sjZayOJ21Ac(B$7*(y@i40;XO9e(GEDb{n!)-KwcV!G=EjP8$Z}d +y4^;F9v{CN1h3tLYqap7a=#wOLxyX$e?d&Ra_V`ku#u@;AOlt#HO>O`@Kx@Q|^rB|uB(;ym(wTPPwtm}jn +C{!`pLf${nt{R}L&D#oEa2gabOic~V$!j@T$mxBH!oA-QWK>q?hQyg37diiZO8*jHFioB{6Tp1E>IoM +lt|2`zGEs9u7tQut$OdJ8ttEQNds-r^U}8W^?9md}l0RvQ1vJsCB^tbqBOOe%tl(DUvuf^Ks0)DeFvk +p+$K!!P^r$>EO3k%E8U%B^4qC!hP=X9lFtH#uZwI0mIyGK{0(_NWyHzcmqm>KOoqpzH&)3jmKDvMnfo +Q8Xo!^21Sq6BQOXeJPFt4-#P!$ZaGBsGv0^{KJF!g}#Nn(5oKi0>($gWI8Yak?80IXkqkCMT0TPV0OZJ~N`-V|>;By*31T%-mdY@wQZDOGGU)`(G~4v^mk0FMH|9NJ7}1Xfw1 +SIK7rFt;Za8YFxsJ1tTXu#mcylvbO&3QR*89?tt*GxV=soHK@|eE$nXio_^CiXXPa^^#>lFwhNQSDV +Hs34>^g1L{=hGEmCeE=1nE^U(9)&#@+3Z;kwpJ-$A-bwtzoEZ)*|K7&sywI6EuQZdSB5;*tMY-yOSrY +acdxrkMyGKGC^kB{}nE+U=HpcB>>vYoV_#XP%cp5y0m6zV0vfSGD)g1hluU;G5V_%YCT#K-=09Um;^wE^hQQ|hPQnE2aFp(j{)Q9-9M+8E%O!itn*R!mkSv2_CZ-Ea6x)4=v=?Q!j4>U*$ +bRs50#ZTbd>-bzJm8^4GECPDhCSv>IfLxkGJeU`(Fap;zMeFUyh2FyO(YV|#(+a+kAO%k0JfkD{&0L3 +MN-#keB;-Lt;3Om*I2tz{G6gZ8C&*vVy2(BmyX3%ncYcnzz7yJ`QX*0*nW($F=#%#46o9zh9`c$Q`B0 +IEoPg1MD^>u#wr3$t3&yjN*Z`~|K8yFr7qB|#aw>;m`K>Ru3;CobS)6Ym=BCL{h%FjE=OOQW;OYI?$w`(G@N|zOZ1)edA^pApKN7qS3PE*8fXH{*I9WZOJOo +p&=o|;bCaK9iQU>7<|5PKt42yqRIp6Eqn~kuP=YcO_Q8AwLZe{QE94bB`}t9%7_uPYk|HdrvR`6h5j? +EruY!RQFLZ4DiQ6NVV9kt>M~t8d_$HDiV?p*(ag=Vof)f8p-YiEH6Rc*g!G$P*)R>_8v@Dp*+?0cD|-iEIyDi@YnR4)Uk%MJ-54w +YN2<$!$9@#b*ZIJP}*8nbL$|(=C@bbLUj?+nhzRONg3j +gPa$q-gE|ZAA`^hphL9BPpS`2r- +HAoW{{&$m$~hF&T;1(p;gz1BlZihVornmcbmf=k{>Jq!LZ#R!_ZM$(7pLIyO#HsA$coVEb +?4V<0w53ZRAbg1b++v!K!bm0xDZB-%`NZPPX1!VCg%63O+x&HA6gLxZzE{K_mwL1}#=NEfRCXNRNCW{ +5RJ05x%UZkCbt%VEN;-6FD4^L-=ZC1Y!R!XV~6+O&u86Vmc?DQEl(w2!6~M49$Fpd{aL_UwMPVj|s=D +5VSzhs2o}qT%fLu1Q!gf!skW$?1v}qV9=R|WGv)pa~UU3(NyFSd5KxsWd$U_46%UZ(P)(_<5F#ZK;_4 +ZjX4aT1Jn2l@>ed&%9=PNV!GDLLSCR3q`yO|?O0!5u`_4GWbuN^TdI7Z9o%rOrg-%7;X#0nySe{v%;_ +t)Sb!~qRv~}HvvPSJ$nQ#8)Y*gDDKKjP2T+j?#FxqCK#zP0*YXuIvJ3Y122fw@js4uuUx5gZIvZslAx +`FB!!TEGF&pL?8smi@0S~;ov0rZNjs*b9Ufa`ftJv7X@RME!UbfYC%>Mp{bUEAyia=ONlOq_26dq7A_ +hPcWeWOv1*q!|wR|3O{!zu#mdX0;O3KPoI&v34+F*xIe?N>Ydl>#?;vj9LacDdNt&+t>^%DC!`w-}&% +i&fx8&Yr+YE^w8K%0*7>Rn(6fL3+e7!Qo+v;Tl>vxhETOJq21Fdk~?PTJq&+AL;^-=nENtNLP)V+6Xk&`Xw~=ORVvvRErB`BWu5aOJ4+v*qW7W)D#E;xx`+ltg +^V)LSgt*QX}gjkE0+8#M!&Z;t+n~A>S+1Q9e$L5AdVqBjNKY@*(l#N#T!EO_oQIyD2FzGv-pJx3plZa +5aLCLC_qTa-)t(;f_?3Ij8~drGSotCO(IJZb`Q2Aqa|xM;lqh}Y^j0?3|z^60gyU#)5d|#^V={;cL=gKD#={XeH;-{0spQiSf-C%Bl(Ku>9vfe6pH~ +k<(Ff3ePKhf|tgO$WjkQ +lO^b_$RPV5Se5Xt+fbhy%%(22ARQsQ7zH}Q&`BC7qP(LOox>8ra2jcNp-RgSSil-EwbR&oZ`S7l!M&+ +eSLc0n*!)k=Fl}6MrET_zS+_nW_h+RjGHvPNnVskE5=&QJQfLS5HJGS*<*6{*R2BP2t;3mM1MYmQnHf +;N`|4!B@bsL2WDml9T;UA(#L*~N^4Ng!H?;kHAv ++aA=^#<0yEhFi`^Yorp8TdC_mw|P^6yOUyF@*lXrR(-6eC?;e(C*Re2Y +Rb(8Uf9TZEtKvgw@;B_P2&|=9ixP;{TTMLSV(6}7$L)f?gi;F_>tS3P@6EfXyp8ds;jKN)e;q=RylpD3=L5y%p+{?o|d&67X{6L3d$p(ZXr@ya9q?0=^!e=0Jv +6~>ErU4OR)b<%5itZ?ahfAGRfO7h*e0Y+jU+I+7Q7m){sV?#XFkxbVEXuXAvrA^>bgA-`YZ;k48}SyA +?;x`C6o8A3oeaW<5WWMKC2dG#X9wAk2IEFfK`&#E;ufJww>qYQn71R&0VB%l!DntaJ|}eHa~8p8Nhdt +(x8+)`_{uWV*MtrlnR1H0rnb}9HSfaf@dr~_0Fj-{j(!f`<{b=t!wRs&g7H-AjiyvUngRaXj)^<^0fW +($Zg{4fnNT#PC%cp$q|i+mDbNmCwztqAs>W*WIvfB86ah$mdOji-RGhWAGxhjU2L!#ikywHN!21EF8D +YFwwzdliLh%}SC08En_W0OR#&)ax2g)K8R0VtU9sTNSFx1W-%&%NeW2dH9_a|Z|>3K#pzlq9`!tJH03l0;%g!Wi#uGSD?C=)`?b)Za>|t^lu7CK4bb@vy6sTgj{wv +Y$;&PLFX>_^rupEa5D7X9Okjco{|wY8oj|xL0V<8U*JbK-$~VJko=@otTahlHD0{gswS47Or+>2xgVxtM5bt&J0iJb1ai)f9N@9K@~APuA +$z@YEv&+z1g2GyC3Y0gpGJPg_?86e2A~gC+dPoEf|QMEoGBP6x~TDM%AKS@2ktNiPvP^?c6>hZE-Y=`aUKR*Ox!H+5x&t21SCRp*gcy7eTY+ +u$27%=mnA2H&{rIg{xU3QKA(74c*VKKzkMo4rPUAMI)LD24B$pLfrL_gtAp8|}RJlErY_50q+g^7`cMy=kfsg7$C^_RnXZM;N +m@gt%cCV4LFj%t+Ca?VW+GUA)^z|o?ZePgjS=%fu(<7(0IaNkyl);}_QR&N)mzquQ*er9%%+t{Rr53r +I)xHbx+sXDi%=H>GhVc(p6RE0SUJ0uikt(~y3j_SB;ElinR?186&k2^@ZQ%z+uoQ-y>KRRB8 +x>HaWH~lAUq69cmTcZfaB+zCcbL-h}63S`*x~2|pm)@!Q#>^)7;2A$0Q>u-sgH`}!Yufbv@MtBJVpmh +Z(kxqSihJlq-KXrg440VpYq#&<)xog=nZ_{;28b};7mKCsTq^UYp6v-=C +fSzF+Bd@cF0|UGr%9tshAK=aQuQps8oVg)*>kC#n6Iv|(%*+UHc@5Z$g)F&YA;Y|kV~ihV@S*Hl^B{` +PxW5I+j6kvGzEX24#Oy^l-Ujut&>`C)at%>|dc1k+I*Yo_s;xQX(U$%JYZ(3-JUA>G#=;Jj@f!`s(N%KstNLG`HUO}-ud7H6l@^%Fr=&Mr??yK_V}3P-m8l66n +);W7zSF3r?G1b*yYRcn33!r(936m?RarnM*+=`2e*e|ad|Yn19zq6aB>e5h;W>*!**;%-x<5pvYsP_C +?)DU&b1Nlzbj#SoB`d)P;Lu}105Sjxqa-=y=|E2H;5&;t;$!lPfZl1WWn5k%2J~S +j7aR+db_CDxJ~0*x!zMpDQj!dzEgm4sYhxPn?x)*gj@q7wPQ~Z`Cq_u#RvqBW@t-|n+#ls+Z1l{h#3{ +Nt)TC^$$^C!{v&<9!nI->;C_v577IGA)EP)~7{J34RqXL4hPU~-R172*jFkAqoI +dxVGuJ5yO(NIsw?NaTLz)9Y#&hn%1aRMcacct1>Qe(ULr5VEZ3k{3O_G>}(P2)d@k9q3%F&lXRqNFtS +xKV2C66Uy(R9 +Mc5J~&SPlzBt)jw$-5;JJ}^$obe +)7|785Pi_>v>@j>RQR^fbo88e8x&CZewB-G2^n12=k-J6er%T8L+)Fc5b~c^cVm|!?(SsV!(MB?f$`3 +P3?8DCYDbxMRroJ?f&r|+6%1gStEK +h=$tuMiD?I{4u7@FlXSETqrHf6GIap$v@kRd_vVI(!<+Jw;; +=dkKav6*M;RZ^`4nn!Gk6l(wZt8Cz6dPxag;0_zWh2jS&QegH6X)<1s1n!Irt7f!~mi1pgWzjczD_mt +e-80QpAc2YJJq9G8s~Z2?CRtj5fz)_^`E9Tqn<>yRjih&~>4?4GXZJX!vuLr@pxIQ_i1FB>-X%bAA&B +^Td!DDAW|$&rnmUxc$S;M)||y30Pg@U9b7!g)Jm+8Fbr#Wnv1Z9C{q=gA#MLIIY4xNgakY) +n+6T}43~1bSjLbokOm9P@>_;1p0hiRO*!){1Ri+`E8aTP70YxVUx9V?2;lu;O)tcTLHt?0bVOGcll>J +IWZi(C{emY5xhT|#WPg6}ZwbM+@ETw`V*~+w(o2lv)EVm?8CeDvqy;{zS&bWDz>g=~)*!+O)qs_H_1Q)7(?c+jX=xdiwnsHH8`2_)$pXW)o%{CP&MVcqZjRKb9P +}0S?Niai@{YIPk8PFaj1Hq!H$O#vU7fjqXFN9P&=CD#wldV-N>kdb7N3mC1>^!z!WK&~5MxIgwO33$$ +Q<{MOHcSFie+m_q`w7fKyB2AJoN_mGPIyDx$xIf4jFT!C|J8>j;ne)jWkoJ2OE0Ol6wNMbuu(ILofiH +(mKN6cSgqb}ToCu4RaJUm1aj2FCQUW>nN~@S9rhB`%^Po#`>1wXJboANOeofzi+E1s<|>S%Np*ILYR= +|q!}aGU6KXN)&Z|EfqB}2AwqLs2+z73Jg@Vi;w412X_uS<}O&^Z$2#uNfCYQ@lF5C2Z{mTsC|KxWsJ^sqqwaW&w6aY8<}PAr9T?n8Vk} +3`M9Lx^Y_vGCkX|1yXf?0+(`yr8g|{*A-W@!Uz|+N!5`)5sTwU5`BxAWu42%fu6 +bZ}3UIGe6mpe}wlV1lDVSX9@xk;@>sBV03U%h|2%NAe@L9ZbaA@A^#-Uk+7DOkDC!kC&MKoG&1w86y_d9xf0<*}X +grP)F?K_JQ6j$M#7Iy0bepCe2HNxL7s>Xl(%MrSsgi50RP2Mr!wR$5S}a(Ek+x9mSpW<4@@aA-GFmIyn#@d(K +*>+w8(Obz{n#&Tm@dy*SmpN4_XDl$qmpVKZY?Y#9RpG}ut_Kk&oU1gAq)^e&d;EAh%k +ff`T&{`%C~p(7V;DgJM7&;7MiU+yId3H(%i(2L1321qdlA-x95T1%JYI11}R%!npYUVQCe!YU)VCigC +=H#UywKqS1QFr`A{p8*u8S4MLdW02ItV;AS`xFl8=VZr%*G3M~9ganDhA@pRuZH89C!(m@5we!67wGg +<4xH*%nqA4Kv<@=lWP(O0v4*#(rQU8lDt9Ri=^zUHOxfO+M2GY#%yyJCOi)5_F_uEp(&83w@BY?OD^Z +OBsHooYj$8$^oeSCTWKTG1x(tHUPnc$mO>L>>gYRtI~89F~(7E +h}xx4`9at58ts9nfodS9X(5@Lk>!l@I28K@eEA?F8BV$g}={^yr`vkOs&ekTp@ +pN*+KOMVd!t3HkF8OOL+2bY%#?I6EW7#Qk{x2Dv%Us|yd>cVy%rfT$$re2&M@q)Gm{`>Hdt=w{-unct6G~L*z$W5-*!UKE(sMM3;19Sj)a4yvV$O!m +`iCKe_GOcEnJ|kNl=7Rg?-Y2A?>0v(T(Oal#gOH2e7;fmOrweYiA%Zdt&p +(F7Y=K!}qRN*t%@M9{3Z23Un5#+z(Cj(NoRj##2wcW~3wOC;c`QkHL)4QJ~31K4ymD%!vqeQB-+QSVd +$!SFbUk&22+zt{)H%x_zuq9IVIQ&WT4Ediv06m^+s9|2KTh&EhRBriG<|GX;LQfl~FtZ-u7ymb^*-jKbRdnwb=^fJoP3{P4|aWB2W?U(Q~a9G +G9i~f%EgdUa3PfP8G1hc7KamZY6+4az+sS8_fxjqFH@XhJ1qhzk-mh7nuQ3p?aUA3^VT^ZTe{+Q3O99 +^l%L8_ryLC7tv?LJCyU9M7vZXYwmZv(A3L&D62m3mhvsx_5ect~OgEjP_YMjb^_+}Q=(i3`YdtEDFYN#o^}9^_pstQAdB~L0-ej^N7PH1V#Fwhj4<-C-IQ{A#PEPU +ynZ73ONhl8LKfZJvHCJ%58$#2MC8ZZPODL;5@XOAzbuukq*PL!ppt3zVq-jmf8Lk1qFyo~rNog^FmMh +6Q{}X_vec_Gl<7!0X&P{VlFk4k_;zYwVAbN&wL+l%2?8361T+TbG@otmO+^CAHY(}$GNXaPpa4sY{Q| +WS+CE=OoxKfKxYEBRIp>Xk!&AtZ50}mOkGa4PF>ps06T21HM{WPaXZ5Z?rR!e+mU;yY0K2ySO=H(ze= +?L^zl4-}auaK(yHgEgN$e91?Cm5Nxd(#EF*yQkI>DmPYIcxv8n?f!$Sigk_%_X|*l8UXa-d0^Ud+!wN +ib7oPZjC9UElUcbQgifsms|_hH%OiWcgs-Kh(-WE3|}~X3^EO!=K>3cr9B+X091}c28~8xMaQL +`Hyw^MRr&R7yTSq^wE^!HtIe&ihKxAns>;3xYyLCR8WpN8f2V?5pLQ{mOOliwtX8-S~Oor&*3Z-_7#9 +#pG_XYlBU#1tb9g!-Zy&1r6@lvkM&Ke`E`_mKCu6kTAOWJPPa$*<#7s3Dox>7Vv@`FP{_7n;W +k0dtdz6#9IoFwxo$sgBUXiz4D=O2WtxB%L=bI#7|7&n2}FC`+F!jLxVewa8SXj2t3V$0*{-#gS*9KZM +nYPxtT0^Th}otRyZ>E?S!7O8km-5Y@*w%3rnj!KnU$)KpCFTyn@1nkY7a>ccF=28lZnvupATv35B2)Q +h6STJW7^4U)sV-^Q5{w&}~3KF^-@%_KubM9?qcm%=b`;#!Vk9o?yAj-Jn1<*IQIn>gw~*J5;P^nHtE` +TWWFesp7qmsX)EayeU&2(PC5$+)E+F0_*-V7peG4mwN?MdTK;XO`Kdb885NuuxQ6>9=Q=oG8lYnh&4t +h^#*&9KD+7j5PcH*e2YF`rBAfYAag)CAP;_o-;cmI&{-jA`Y1_`S3EVzm8z&V +MI_T1V+dC_!q365I>VmPfyYr~eq|e;|Wl7TS8HC(ziWcsBxa+wO(P;DV01D>ic6{sY|prtXst5Jov1M +{d7AY&`{hD=i#1*GPeF=usBtex46`)PlgHD*!TxXan4~Pz+PN?WXwLO)SUCo2eIj)$n48UTiKcmf|3mP75TL6i7??0xx +nneE4W0$qo6h@}XzhVz%>`$wFA9=?CV`Df!>;QZI(dlTos3g0U@|3o}R* +^TrtnT~BRfHTa+y>!4uuDY4-VYCL2?rQicauDZTkkT8;>jx?|E!3*@gG{vxjhBW(^j?7W>`&83CBBAx +@Fld8^sg|YhE>Hqh}Tu{OGHx2TY+>6;E%1S-~zt~t)b~ael*ZREu|Pnqx+Z}^7YYqUIcCC0(h&(5R5; +_3{4g?29snus^U3SNTCimF#Z~#75hF&326Go`3KDC2P9-}Uz3V9s~9QMXOwagYJm9``ezcr-V~6!q1{ +^x!<-*`hwWD&QKqGSOGSJUw`Wnm%ZvJ-?xPzF;1qX}$~C$nI6o;$*%mdl9M!t0za^lVj+%^-9zmt1l4^^3e#BUbkck|bZ@t=S~4tVLM)i-IV&>D~G7r#~?8T2_^Ee0^vEYp{~uAi)3tV!tq +0;;4|LOyS)mjg&q^-`+BYC$P=5J$0jDM^geq8(ao87Pm?h`un+AJ!`)b)+^%G31!Hz-F14>sN3VARgh5+mu1h8KtjL^pudbd!+TU9Jfhn(m`E(LLoR +;G(&J?Fn0*aS=y{|c0kakY5GkQj$3UCY16Bxy$*M=LctxB=i>DS&xdTL6tRi&_GIp}BBA*DAALJ9ZUqJG7UlkhQR6yOpgO^?AEd2A49Y~a||(VNYI(0XfM`=}Fr9}Mb&71=?R +TAKbJ%o}=qug^C3a= +SFB>`Pv9lQ#!h87t(?YbqVfCTB1dmD#w)xLl>A``8Shapp(o#{8D*yK;8P0N>MBCLkUlQf&$Y@fX&iH +>EMh6b+I)y{Iy!p42AE*dXzC*(ej(Sif$&eE-CzP;yz@Qj5a>J5D0C#N8YWW;#W8c_oS*p47hx$L1zz +C`4E1HZAP-LPG|1I>|z?rU#sqZ=+c(bJhYh;(4lW1mIZo%@H^#7k&1(=GFHm~6TE}=jY5A}NKcGtQ<= +>-=$+!P);skLtlipk3D(4Y$cY$!l)4)OdM)-t1sT!CwvhNsu-~75d^9ZP!(>lJ}1f(T$Z#55!T!0hgNlhlCvjn +$V$cj`A*^v%1LPEb4#$KOK5iH_r7B@pCBE_YEamQ!hZEm8zDixmFB9MBF|RBw2`0Yr7)F^_@?hc{H*1 +w^OMa2~ZpH73CA*FKcM!j`OJ2n9H2B7?M|Hy*AFCd#k+!T+(y)We@S|?^N_yZ_8xc#kp|vdF+Bz2ETfi#(+0B(;I6kxI}d5Gejlt%NGY<|b*7p=n-8O +>l*QpW-uA5#veR`M~WMe!jcPMb@uK7$hzNam94DX&xgSQfUEX!7D)PQ!&Vh-(#XFO%pZCR3NOCtLh@^ +EUb`>r%)KA+_5uZM#;RLup3<_S6ZuVA-9w!e&ORq=mPSd={-$|T1U!Ir_P;QNdn8n +j2helXw7@Z*ZB1=4E|97%trNMIBCc|>ZiQw}JW5SNV_;zWm6q02)oE!lltTqjo&O|%19iB5rs+aHpVD ++8UHA=@WNuraGB^dHo18xe&1g-Xo6no)rVFX%%GssL-)I8v)6+etbi9!R8)#Jxwv!9dxvadjY2K~;Ic +)7!coH><-g#gNmK&PpOcBg-w~~c6@6ZkC1oYu(43wdfH`2+p08cE{wE2!lyys=Hv+`N$8iW`*AD1sw&vnLo(< +ca%f3cf=AfvZ^E7VbL#p9ay-9ODD^$OpbIaho3&TFBce*peG%&f>P*+ei9115_ukMK4rV_-Jl|>{ +|E|gR%h|3`s5x=+TM&x1#OVmK?T+{N;m$YySqXntKEaNUUu0kcV5yiwGb!_Tx=zs>O +5XEb_$rXp05KJo0|R98QxC)LGa=5F`#_)*}>MOTBm$=`)avf1$)z6X@lC;MO43S=~eM1H+N$18q4@?V +Z)!cErt6GwA(Fx|>XY31V%%P}92*zX~ypUK?9+mSH{U2mZ$+co+sLfW{6)Gc=4Va=)x&Y +sN$Mc95Fu4Ll*BIV*KXOMk)J!EsknQTh>C}D?KC|UC8Yv)Z`|oS#@Q>+ak_q1SmwFJ!Ie}GPw0{_C>U +}n+|wDa;C%g;d^w{AZ#JWw6N+KN^E%TR63b?k)B~iU~NRd8t*Lt;89O_EAYL8;J}^m&ZQq++Q&@#L5K +8&Sb`9YJPW7A4x9%3Xt4wV84yxRx@iC}ek$0GGm93n9cM!{1v8f42C4z2jvd+*!U?%UpE;aAj4M2yhA +#C4ZXNAHDxLinS}%;o^~TaV$kY>bW9D|b1nJS6b~_R@&HA2tWJh9FmnG==n +&U}&E*ehH?@?MFhqOGS|594UODogJdsI}cTQ%s=jt3y(9dWu)R(W1q`l;iUSMUyJkjAqD5k9@|$PV{vXx2@aWC#3Da8A?{HfwO`|Zp#|6h+)DV*352 ++Ix_a1kY-^m)C5VKx(-jj5>1>5i&n4G+T@nIrP@<1wF6RZJnDQ)GvYkLr%Sc(wmDU+k`Z;jOSf=qLAg +Bz^GUOc;{qS1;(gRjAlo~w!pJ_Sm2spo=;(8bH#b$PO|sJ}c9;qyFGJ=KZWK513oH0(6?{JFcpa@l#B +7yBUQZki-uXHn4aPpC=gd9IIA|LPH&`qK#dc{vjSj^mRrkow9G|tOFwB1+{-(p<1o*Rx#34LgT-`%Oh +Aw4d)Y*l07)mY#aBE4iK!9%Un50^e;;nyzf|)B1yo{zhp4U(+vxm3Z_-U{(7r-!GQG$Ch{4FJT1GjKZ +)JbS5w?F`IXjT?OfL5@egh>IwnI#Nh1hO9BuOp +(6+PodD2hwO)hLKrdwKehRe9^9g**&!F?{bt7R%d;=1&krQ5Bi@c6tNU#PTLv;ltlo?b=}0(92xb4Y4 +0Qi%iBMm`4qfx@75+$Wj$pshAy|1*^RTE?lO7h8DvQvw$&7_CEUEGlJnl5hvPEtRUUwKv?v`F8^K0D_GCI-ju$%0Kai?kr)yAdDez9{`ne4r*Gw3lfdpsv1+ +N`9V8_ra0{wd-#32r2u^&TQ4@Yj}=DA(Z`l!$}3AW_kak0fLcV&CL6z?un@DW*QrAN)1dy>aEiW6Z@g +%<3Y_dbb!AjYNw2gjrgWzji15m&J3wz9%me&e9vU%bs%}zik8u76 +0Lwm8(AkN2yt7@$8t30Ytw4;t59opmpvypWW9OHzyv7JCu-7r|o@3g;Khx6_BX|Fg(62Xc=6>$c?zYC +t{!pOT&iT>9L2JRkX^~eRfSLlR-^S9Y$lo~?Z}ut~fQK*^;Ld-JbKut@orOq3JhlotR)U=r#(8{3fC+ +Xb+k61`g%SPpXf5lt6y@ImE!c9OX{8(~jJkqlCA7D1=V}HPxCH+kvYO)dkGB35SOw5E-f$*c=mEEO(O +Iy}P|(WWP&v@_@zx^tau8^IW(~)zp^wv=KG~Y_MpNTOriB$IQ*J&Eb7{xtdPXgmxrxmm#!0qNPO>REZ +4l%!GBzrCiam#qgl!)$UKU3O#J@yg!W^4mjtK{<$I&IZjXR()PosUsoT +ydQLMUyheO0}|+6ujy_ucyCjleif@Qid@*A;PSuOPfc8EfcJwU-pJ~gwH7yy=V8L-Ox=nH9PQ&m4*m_ +0*oT_KBMr)JdWu_Gnz8Z~q-bBV +r^jE_d#cCqAB(GhNs;Tt^)(;h*)j$ylw@DbXs1BGE_l#dy7gAnOfv31Z=$I75 +04xhLW!(th^P(0q=omFo)3M>>X9xy7OLL|2*qcB`M>^=*~qTkbH;I(2(=bFOJbLjP4U)ql87j#wRagQ +934-B)QN^Wpg%r!wvOLMB++@5<{|MqaaKs^ +}$+fNZhzJ_zBB{2U%PFg8rM|sukLYBv$VI|3{#sZ^wRqwZlG6J +RP@^pk*wd*`ys5dYua+zRj{1o;4*QL{l@hWcpK0+46$4q`-pLTx@;;R_80UdoIdeV9AY)9$1A^&mL^H-dp{m3tMQ7Ouw7&HDenDtGv +u2FSisgV}%sjwMf;nSDHX6QZn^`jCCz$rG;kcE=%?uRv~D@+aV4Q$d!I9h+dBM$ +4U7H>KpnDB^Ni#5EcbM_P;=?kobjbC+a#jxLs_tT!8F=iOyLv4qm +?I&Jy{)0^uEQ2nC0l0?uTQ~bdYiO53(L^ts|y-6a +{KX!CGK9r38*wyX$fK?m^!lgAF)(2ZiZ0s;_{u6X7xI;+unTQh>hhk?ZZdm;K5N@&H{;7C@-_0y?G2Q*xFC0w(%dTzRT-j9hsN5Gs3amC8o2s` +HfcSMsl2)Rbe$QiWwqQa7%tQmZ>^lrexzxv?Fu#^YHZL#~VB76nZk-mDR_Gts70*?B}-w8j=9j=hNs8 +tBbY!$y5a-r(o5Dz|22;Yr*-q1`@#_gVC-C-4FQ?mo)p2MR9)7nwmyYY?hP4zNVI9lmSq?dvP{QeXG> +^+q{jir6C!oC`NCS4Z^gJ4Oc=g2dP`kH+4l$MV;ORii67bFWUdv~mGdD7s_u9{wtV*{!~}gEq#=YR6~ +VMyJp0%O@`#pl+Gn?jiXpFswx>zPuH65%DSpZ_oBwye&wlv6s-D63+|tyFU9bbJu6e9zY!-e@Y+_VIh +hNAARjL6}6hvVl9Q?NU(Gu8M>GZ_3I&BS}7PbH +N{^YfmtCtEp89sgY?HV^KG$YJg)YVlL(F8gLGf4hwgX>PI7)Lvd9v;BewVN_=6em;r5=%(klk#INqEB0@aM +bNq!nOh948GJhjYc0pV(y&)`yz<9#~4&bUDUZQqJN52e_)V_WP_!e34I&-f|o5y{zwdAAqnDV&zVqAH +Gw>MYtHjI&Znq!XoWOhgh*9{E@NM!SM6aS%P|ik3^#UQEcmzkfm7*#MHl>wWMz5)HlnDxatqf57mmAg +tUh^gypZD?EyVjAYIL5eDTM)6K#c`0EP70mwjhzc6Ut{j4_4tMO{_9Jl5dcTBJrS5v<@Drw*ujnjgzOexn^iwJ|U_n+84SlY9sqChK6|prc+PE2s@_e!Ya{d}WoaMehUb +&((qEoS822aa$AwH(7-GK$hEp3sQ*vNZS;$vz{WV=`luD0ML~n_55Br&hcw!qm@zVzmH_3cOyNFn2%g1_R(gj1U#WP~E=(fxo6}6M9uQ&QQ9SLOKst751`x0BN*3>hU~B@E-CH)toX>N3#S`v0|2T&#I&Lz4w0<+ +>V`%hf>Mct%H*x-L@IfMI_!tI`=6$pHo-vI-_hie+&pD)f8rNrh +FPf6hA88FhAIunMGA+&pi3a0ocmIOl|8^LgF%E@=2CZKxAfd+>yD=lTt=EK>Uf6$z^W$bvvP|5%8!WWV*^@P_;OA&Ygfwv5cEN`l!17g +EdJK01=Yk41*Clz^R=6 +aZPHq|oJf5~=4s8dv2DnZ!t&h9!+(l>>i*Ab9t)n!UmRq=)a<){)&53=%@4twY{HCq9kP<>LPytVSrFH#Pt)mu}N>AXRHJ#4@rbFA&#$-9lTda=q<^gpS!!-Ow? +$)vtb|b#0X=6xZzI_-MVs#YGK$~uFcJtf*sw+)}r&k)MV3*T;R{c8(o3M(@!HlpzT`Akz}#j +I&AzxZqF#who-l+_KVQ|v4-8)eqYwgdMQt)(WW-TZY)B3)=O4XTk}2)4q(sr{!e@MBf~d)cAMdno-M+ +jEvAs#T%VEXl0eNq@l)^EkZzsRyJeRjrNq8xq=8bs>22&+JZUJMOWR85bDf1$zpRgoQhAEQ6i>!hnFwXHG~n?iu))Ge~mAtu9!|iA%}eWY|_5%i)YcbP +?@h!&#&OKM!7!G7i8uRP+e&oo92wAW*7zJcQil#-YEI6XEm$AL(l-3Hl&bFij~@3v32A(kJ8)7tlpid +BpiHph*e&LmX~;*{fAbNi*>M~!B!uC=DS(ttt-5o73AIVAy$wlo=KMc;WL-Df~H%j&>6FMM<+ +vd+A(A#HmtH!V#(J#|B?A2|4gD|A5Bm0$1dw#XmPmZZW(QX_$={fAZ4Y2sA5P}=84~<_cU%P0>QDBQ7 +bL-n`8}Me(7Yzd8&{t&Yv!D@|(Nnlck5~@4+xz|AM9iDYCO)N=sb%@f|$!{&4Y9kG!21|B*)?_2APy@ +_q+m9J%XHXxApVUuUP`MO;;C2l5L!DWeD$a +wUjn0thTyn6iR0L3gT8td=&Lugu#Ng!Mc~?CwH)n{e9(# +FLz0WV>s`r=Su6k{kch&p-5Ldn53~|-_<#%w^`^i6b)vMH9^_;q^UWx9iH%oWbyGD1_o2t9&O~4jBO} +#C|r>P@CkQ&=-&U*J=@eiE!?mBphv)-eZI_upC5V2Q=IP2}9&U)4V#941=!dY+I#bM5RRsY{O>s|N`& +U%Lv&U)jAIP1NjJL{4ErL*3XGln?pJ$3QBI_us04QIW%nzP=l@8qmE6T6}feQesL-g-}Z(VJ`$w*N34nj@s&|m~hPE +e&3%Bm3$Lnr-D-&*d`-iycA>3u$^kz{vJp{PCo8E{aZhBYz@7?sq1&(dKg1YIA=xY~`G5^?4PsiT>&` +~e&ogMX-j?^9XG{Q(a>LDurxuf3ggN}MDzTv3nxUpWG!z4WQzWU#L>ft>6zv!v=tBe1@Q;+PsjHez-e +&6P)H}>lUU%Av%59=B3sV84j_&@U0L$5pPsYjjj5}tbKL`yyO+O8VnsfV%Xsn>F8O9wsm)>B_PEbE(| +dXHbc)Kkw%FVg%rPd(bHZ(!~DSHIz@hm44N>S2IPl2FH_ao_aRuo&}Tl00&R}(Y^8c5>;!Jcm +wu`lu6+xm0V4}&){Cx7l>+5-+I<9-KI4}Z_Y-+uTrL;UO(-Ft7@GJUsHa>iw+)#C=eflQtNXnjYmu}6 +gwB;)afsv}3`_mrEc`A7dUYV}VY`p_*PDvU~82E?bkNdJGJ*89%oJ^7%rYH06aymgkK&WAbBbP?~3@1 +VczIv|WE+y6t;RPXl-kM!=Tc=s?$)(I5bl>;Zx%lWjn+keJ +^m7ncKq-kwbU#&B{`l>Hz>&L>4Z;KOAy^qnT!U>r`xs#3!*AM3fnIC +?z1UG3x#lSlEchuRG4of5B#XCH@FrU*veyhUN@VXy`ZTlnM5%?ID9YW`?!cx7%g1|MahpcjRkeu{(^e+mwT!yawuX$^b2+for>N?Oa~G=P15O +;VbFz5Zuh1UnS9n3s+h`fFo!$((XdMVVTh}uD74k+eb?L|_AN-oSbP(^a@E+hSa{fOP&J-KHlF(_NMX +wi~9q8r9x`+5x3}}88ZgN({%eE0nTI7`}G-PuR_llvW)ep!*CsYvn-QX`Ec3G=nWY9{j8@J;o6pcei+ +5ur=GzEjy(mB@(v@@r+pLgm;W6E4{;G!^cD2N3>l#}8>zc3Pi-o{}bOjHhH-Zb>RLLS^U=xLSz%^esI +S)=`)L$B1x+6RPeIYR!_kJBZFzbywHvxSQHc4y!(c%TC#UPc}&DnYC6hR>Q+auKC99w3|57!7+-;oB1 +h4xDpT+ZlF43|`dc(Iy2(eIKIe3=J+E?{<;HFG7XK7T_k`&&<+#OK~;f?#DUP)c6Gyc^vg0;mg)+|6$ +JGhVtP{@NHO=lNH@Wtn7a-aNkT{PIVO{ijZ)ZJj%ET^b1%)q+oJ$w9j#4W&?&aeJ^@NIEV +9QpoR%9|Sh~@3@(2u^>g*8PSh2Cg3?($gyP%@#}3T*}J&nz^*8 +pypEUmYG_qsa?d<(gc&7|M|@GJeLciS#R(A{(k@8_knX~o>|YCIWu!+&O9^5U(DCU2N{(ci5rSz9UgY +nX)6kDAo)VbP8vvo;g5WD8$_y9x@hA~bGW0W6-A*`OA}O84yE}jxzCcis%OzvRlOPLi+Xk`8G2jj0?Zh1ii0MUEfg3O +#BP=3Cd+n7T6DQ)j`zK4L^^T4{pej;nOogAlG-6(P(Ps|Iw$XM?50cr{MbUDM35;jU?=Eh2r$SyyEdJ|SR& +=?~0{b?Y>D?im$4DkTrJi0RZ}xuJ)dJJ-?_eiylDwN|uSi`HyK{6T^E!*EOBUn?zIe0iZEWPe$S=3Lb +cX9}oi+>&A?SWXu~d0gv-MKxj ++L~nL`H%)J}`7P5(=1jTvd)lRVn?>VnxgliB-Jl6I#dCu9J=T}wC525RImCeY3JlzH}t(px)vYaMUV7 +E(2CMl8!5TmwA9JbPok03GTA{Lvi&_-64Dn0=jl^>ndSYIeC4F@hrM%(HjVTQ4-_c*}7LV4jU#%iA&C +_Sh3|*(sb3%Ws>eBQeCcyggk=aOT+{G{k~p=@|GjZ~`_CU8%R-3@^(Jk!x9@wGfM>LTqJrCM22@62!H +m5GXLY*6^UYzhj+qB%DoqM49eMwD{q*UL9lWv{sy}Xz)oiYqZsdo=K$vmI-L;*ln9=`5EGTUp4}Rp!h +hD2Elx=uzAlIv6)QV126#n&Y^|WQnu{Iz6famj>;v;t&j%bPL>sL&droZ;h`@{qwu+f7=>F{3@elmOn +vboqG@+#qGbe^x|{R$+Tb<{owXdXjpyrs>}I{Es09}FlUz#t!~)EYcPa2E%F2H4M9cf{in|yYa-Xga; +F938&5zjpf7X@}FWMNn;ua=bm|0dq_27b>+gHLo +TQy&pKdjqwpFP!pHUEh&_(RD(|*zYsg|H# +dp5p#6!BkkcUx&Bcc@rki$!-2&rWr>VV<298#_ys%>kmDk|J2~ByfqjVB(NjZha)+tx5h?1uc7-MJXX +fDPJW#%#~P3+lef>c0 +D2anBFd>Lknd7dSOYvE@%NED5ZdlpGHwD&D3ij=^rl=CPbKx58y8V)g*bd&j+}P6`D{eJx;eE9F7xM} +104MXRd1rMhx$iaahUsvmsz2FBkqeG7r7%Y-kDNMk>Bx!Z`;6DCubHn>s5TTL!ris{qQjBAmRbroS(W +FarLYA}2YQf4$D!_Ryibu$MYa~zC#z4GPBQc7=40k>kk6PMuF?$uhEAOCIYq?`9mM&?eZ;4&AAx<-v= +v4tQ%gR2CvP(PPt}y+iki}wIL2iQ^px==$i9f}`H?DnQ(sP<7gUw56GF+oP~7DLUFG4%bd^&a8|W(A$ +ht~ww42_dtZXC1v`t^)ciDOTmaG%MHRAV#_`NQEPmAC6;`cE9T7IX=hh?x?=qhi?y2^fLtFH3GJS?P? +-;x(nKD||^tNaPq(%;bDHXL%<(ynxqMc{B*{O%IJYw`QS8Tw7r9(S3wx*0Yyjc~YGx^=}ZasJ#bXcDJ +Ln#43y4RncH8tM{7T9PhNW2;MqGjxfA#OGzsE^{7`G>PVQk|q)4V(rd`-V-(@P-88D$}`X;ZfT%N^r( +l$aj+O6N?RJ&Rg(eYpp-Ehb7~-|Egsf?%-yb)6m>o53Alv==E}Z;&G1D}Pi;gx5qH2AgWq4LVazroqirG +ufqNze*uV=(V=0kY8w~v6aJ3+1Ztx-%u&|yH>tpwW})^h=iR@HGanSX{I83ALE0jJ&tljDx=CQ1g`Ox +e7z*!HSmQRv2u{`l@I$g)yOJDsB~ue2#e8WmWQxRahcUcScbdIYA@7?U<;xbO<_ox;IKWSmc=Zo9h!6 +HRcD#(RF~&Gg*Iusq7B4-=eXlM%-~84@Ram@gGs3)5XbU +C#TuK+%W2pgQAuCmWCv=F2B2PdLxfUGRc{_yTe=LHy3D!>)! +`}Y`Z*j;Yc7jY*@PDopck}q!ud4NmpVIP0}{FqnuZRJw>1A<-obAd6~zSsfm`uA?QrF3Mc?>6;SXKo3 +&7jr>@w^6ZERd}Df!qD1q+7sz7eJ1x9PA=ueACW?sc16viBBNj*)G=Ss1%Z_5nq{ew|P)!au&O1SJ}8 +=`Xg+kRUPDrF0Woa+Pyhsqm9RNJL6qPo*C;k#%iCY^fBQNN=fFt(r*0F+8}$V@Dl-RQ>{G;+n&viQ%Y +En=*{Iw8g<2m4_W&(UM?PRD>mj!(ddMFko7Q9)vZ04`7kbE*LJukWhtf@89K%?-EkFaAXhoK4(Gp +QDn((YCLi;F+P-q{)$!Vny&_0Te)?tt6)CAhqjtT?m_LLy~W>zkew2n)#nDw1GyvCeRTltk8CVkXV@P^LY027KipH?6+|4!67$UOJ7&^!r!=04kLU@PQm +X<88t8~5zElFq$uUpxJTrZ0th>>KgF!h0D#HssH03xWVd@#K +qyd|z;2e&3cV_2f}r!FOUuWQ?ePLf3@l@GLs;X->DUc02Ko$Nl5v? +52!6dq5MT-b`Xb}a6$XY}YQMT!p(9wzErc4@w>J*765J{2fbc1MvB60q$dWu98jHE~`K|(^8s5B0#4= +oiPmtl<1CGIW`&=?Z9XuoE`fl@!Un`x?oMaP$FZM2eqT?4ObI!I_7n>bXIa2yQ^?;|x*E~c$$P*e$P# +dc7juvTaAcuOb|9VhgvYPr^qOpmH2YwZnfCa6cGm6q)n$)A>!H*dv2?IAi$kF7$^5UjYih0(q05ou7G +pq56ZL6&(!aRoacA#`Bh@lA+h-U>O)yzEQS7WPX$A%a=v{H9bdG>3g8tD~{IS>#gHVS+|V+q`p-<%x! +=pEGS09h-5Yd6^iPP8Ft@1>@K2h?O3AwP=G+T0Z|(QtFh<7ZqFR&NrqciQPvxFS*>GTR_fSLf`1d-B5+=%V{rr#t +7W|*t`|!xDW5Vz(l+G}mQD${DsCW>)NL*m7n_)ZTXLhXd_yi)!;O!aEX?4F9ZAO42@|eYsS+mqR^^Z| +;RbK(c7zglF74FByL@ETLzYEFR`u1AB4tyo^$t;UoJt(Vru|~tNbLgxhXiv4^o_qXxCKd4>-m|2HQb< +4F6({R;|qgpv_Tbp7c5LIn$S$Ms;#AY9Tu&N#8EG{7hlP0I5$gmp`?L4U1+miwVpn%gXNeU=0j^3%Sf +_TeRbyv3pXNEg!2Kjqe`s$q+`|R8wzWlt`Zm7iYsmFZnKp?81+6CI7VgkozToOe*s3d(Y1JQf5%0#Mu +*bT=XsP$S@6*?T={g~@UTc*`ou+6+m=NHAYQyUjOe`Ol|r0IaEj2NOa_+OUhUZEK@5m1-C?Z-7}DIbzf3yk4408}olBV(-Ivc+B#h5FaG*%3@r>C~xHyTgIj_2y +Uc{&sM%i=_&_Y^{cOCmY%4(>8F{oUD=ox2@>T<)6g+NBE_^ +@S7kC!KVdeWq4Z^AU&L+S>&xZH>#!6;M3ggp`ukNx502byA|~M;FsY7wzpa$ +wsHj2injGyhnT<+NPq?-gM5vbW@f0*tIp>{e`RV6Z7o(7@np|$GjG%GY$@WX;$kC3ZN03U;^~k&?bDif!+0E^5H!sSblAYV%-n84nv_~Yq-{x+N?}a95e65 +#knddEG=3!GOM?9by9hod*hsLBU^QrnSa7~H;<@u=TFA7Jd6~@1WL_onDw)^GyiR5fnKfkAl382kh=W +dbt9G0Qu{5)P;DjUk|o!_3AFon;?@A4t$W5g-sXBQS@{Jo+IaVRCnCyg~vRS +rXc)r`08M1$fgw0uR2R=3`qWS;J-y=H8sy;bmlw32LJ>PAE7v(k$Lbzb6r&Z2_WmTi-jZ(YYu7T@kBa +-$m-VWZ8;aIy*9;Qc{tH&RDOPvw +t;uT30OZ;Qxn3^d9N|jjHRVct+&j04yZ|m8fhN|ZgSm99D#8dYa$JkS2}y|)?8@TW3{EH=-9oH5e<)5 +QGPDUC-NL0reEb`y(tcssT54DIk+dDkRP&5W3C=IkUUQk15A&AG?1?xXibx4~L6A~8Qu%DS!KJy+ixu +lOil{LR5|_<~(31+3!fab03e#KqY}j$GebqVhuO3(Dspht5qMIc?7`{ePTJ5%H7HvV@=fbaETCbS&F@k3VpQK|w0lBobgMyo0#AWq6MTG% +1za_|hN|T~vB{z(R%*LzSSc4!(gp!29<4jr^g#kF#@szl_&~nItYgV0%%`F=Y%HedTgS^yuy=trWR?( +zslx_aRggPcjJi)ngE3nI~2(%<}Eh3Q~-z%vp2kDrH0ZU3FuXf#0I_x?$=8stttjSwO8tT5FE^R`%b~ +Ro%-KNxVa(#k0vd@A3)>KkztUL_1kA1v=>5u5tT+DP(sGg%BhI4{iIzC6ig^HfKdZROG?=p!{VZ +izeR_RR1IOh;x6DUNn5Ha9Da^>m-ts`%WD;?M2owyNq;-*sm3=k`^W;uOcCst4+P +iXSa5fjDk-76(+0-igBK#>yE9g*s+)gowD$E;Qe&0yvk4#xtA(JTR&wiC!vke3JO09EuUs4Zd~D!Oc0H5;eWUN#SG<9$l|g|RKATQ*>On(1cy$&P8#Nl;Z!eu!RVf*qpgKZ0WQN)wV86ni5KPnZ +`#ZSAtz(XL8eHmr6Cbt%JCL*fTp4mKBO^hf~>j`Uj_FuDe9>N?sKIMwpRM`D#qHQ^ykZ?cZK;pEdYjM +*DnO|VOE%b0G0gJnUk;8C)=R;dlHnZmpZjd|XM@Xd*vDSt +8OfsnD%k=4v&f +f+8xvFNOE>79bFSR+TGY(ob8Y6sw3UazE6l_sRKv%L~rBf@i6SXYd%^`El&+xvIS-P7WAC&V} +I<&UhakUR`afvCs1_iwISP;B3*!tu3iki{@Q4D0JGx_V345&Unkp(NtRG)N~I+>6^+`rIFWhHtF@i(b +o;@lEjIbIHwIqwz*5^;+}z|?yI5FN=T3bhz{X6Hrwu$&e0XenU=)48Xhx8s^N%5j=;zom*-YVhijv7)5YFCtEJ)RL2Esa6ucv1+H~m&IXK5=^-&IKrNwB$k?U!bz23$umgX<@orh6}TeC0>|rmH{yREMekRZ3z^nyTwzOJ +uQz3^9jqN!qiyW3)9EaN|>E2O@$d?u@h#n<>m-rsN)4X%g@-GQV?OeD9izt?}Qm^IWEk2%Ryldwd@w= +aLYDfj&&zpz4XwFC<*KDoAd3hT?Tb{E#Auyz#I6|lMr>uOk?gcYYISbiUF-3N7LxOErPd11vC49hpd3Ng +%bP+0ei9(%ZqGPXcjHVKap#r`K@#UZAa<-&Rz*2Th#UdB=?thhtOQYft0fn&)R*2{u^VHJC%MhojzLB +FtG7xW8jji6sxYX$wniqX*0U088bf~BLdVuPo}RY4i|p<3*P2Tp0SRO3|D&23=4EUa#@o)uPTGcCu3R +SoMG!s-rdxv=(xb(63@0qfhss)2R6u=>EdSXcvKEfv;aSPO+!2W!5tM!=dbtOH;jog||ii?>0-BOcZW +Va4fimOx=04r^~=9R+JwVSO4_H<5_jn9;V)&M?BG@v_Si$wi} +enj*Vw7cK=pTHk3cr43~7!liyjF0-&V)Ew19>oio3H%CgzRqHfdb}>pWZM06KWS4Q0i<{QzY1w74$ +FgIsSqv&v0C57GWGu+W<&j8Oji>v9p_-0(Sqn7v391hy~QKLx?nr7g<1$Ll_7TG5bg&oErn+nXj#s#w +KKFcr8%;-t}e5%W?&wuGM%|y+OjkXiNQyl06)Rrbmq#)<~zyxEpgB96BfTj`Bq><3(Mn)%8kGe;Dja3 +L1~qakUf2XtkqF1&@_^y{h(Cc=DuYE>`Pmk2fBIGczjVh(6NLUKAeODaVQ?nI4)m!-cII +2cX>_e+hBe>7>9vOD)?%x2Ht!Ut8jI_*lgzutQin?kWEJxf)7hemOU?#;Rg?D{_r7UNN0@F}Ry6aNY9*=7&n#l@&Oa6*)#5ui-cX2SZb=v_LX-d1x&S|PW2&|Kxaf#@+0Yk~D +9`)1{arluWsF7G(HSN%e*nWS5CH&xipYa+aM+qtZAbkF~ps(qJwjIDfa9_sFBj&)a6?-1*Q!Djm)J7a +H()IBK0&e*NldBejM7T2IKdt-ZYY!#H^V01NAIGT1iHal-TYNnas&V?PzkDM`;+wH900h!3)HqV}Lp= +5p}1Srz!>K)iQYFM3S#-X+3agbbhBmK`P{jH`7`>MHrjXpCMgtbrz`=u<3OO#>0pz@%KaB-;UxUYG|h +{}(z;lLT$)md>}eGRkN`1lD9^q)@X>C#;<;b1_VCcO%im7U6zg|ex+O&y7J61CK6;MCw21rM6zRB5I_ +W@xG-BD9e$@_uPhUDEn_f;rB$`94D&FrVIHOV|fbZB~P>?#<56b2juKO1csyrag8+Kjt+F`eCxY{l%a +?WZOx$-9cxJ&2cCB5$}CLXADiT#gOOOSAS!!7>V`6hUYWlXxUhI*XDb1I;*iMt|qTOyTg?wRG*c%9j3 +asagc0h9gdA8FW#+~2>Z|Tf8z552~t4>u>@%ZQwZi0tR&b*aFXCEL6hGY>p~Df5KAzMAd_Gg!HWc+6C +5WvNANqrgEts+C-5VPC3u=(8o?_B?-3j)xJYn=z`mL>SAs4Cegypph7yb=Fc8cqSWK{jU<1Kkf^!5l1 +P_w*_Xxog1VIE51fvKt31$+!La>ow7r{w_>jd^UDIS5EKts@vAdz4!K_lzXJi+yw +Qn_vT?as37)IrBi8g;Dy5*>SWqmCUJsk8b$yGO?kbkN-yiJs@bYc&ieda*GC1AZnTY56Mk4+C7n*f{# +jC--4&D2rmfSb&Y)llie&7Aevh#s;!z7S0B-2;mZ*lNUK9!w{dBGftmR31m?!<5&*MV|x1Q%~Dw={V{ +qsvTSBx85Ba#)C76-hj40T>8tj#*k9%O+L|rN-5PW +a?Ka-2sx3`m2d}Lz%EbZWF%LF$sx+sBE3uzUZN~TCy$@-9MCZ+b6C_Qk&I4e% +J<(blGNo5Nh!9C+d?c@nu^6JHm5IDtA+zdgdQs+v2ds*u{n_?IQe`Jf&8c(#UDTiE&J5H`&DfLV;C2E +zLl69HBpGUEbB8|pcj?xzEQdH9O` +5X8ri&XV&iom>&%u&)CYEG%eJMs5qf%mNM9Lh~EV=T4j9N8beV1eMq#?!6ON5BRtjT4xq+VIT1`+H9t +{%Jg&EV-A<5G^iGq?&5&11A1y`hSOC>gSXy$~#3)T}ijD9imKg1V8i?{b;%vbI{WD*0Pnj;m-D`v8kW +?#}6SS9z>mGiFZRi{4_T8bN}h4(C>H(p`@692mfkp`s*}N2U6>iMx0!F&k!-yVsy$CE_vcz!9t3YTCX +e=*{A189d;kF!{6w{!pIad5kf;Iroksp=vXVblldUr$!rbxuXW;*v2-%qlj%lg2Qt?l*RhUd29PPvxc +o}TaLM6XGCPxb=1ZNBaHf#?D4BDQ>WKdsOC@tEB& +)Pe-fJt>A!aOGnnjh@-Y%uKR2!M`2Jn;M(Vw%5{pZ1>zT>Z__3uu +Dk-!A_D1D-qUH2r^?1MKSl?)Rz30d{qN_V@W$#{vJD>2JUL{><5PKb*gC@kdMLrK-z6 +{e0!>FTY;9{@ab}nw!7hs{P|OXLj}uj!sRSRZW{UZ}C7&7uQw~wr}TVJ9O;y@FShok9O(m-mQC +&o{v55@kFoQeKek4-afv5{sDnO+Tf7Bp}Lf@<5Kl$@%Ij}Q8QG~hlM@UnhK!tSxDU(M=M5S=K|jtAot>7GmnA%sq&TrD +`G&A@hKvGzd`_-0SGY;@5 +F1!Laru{i&@kQ{_J<-1`XkKC%lV`7%zJVX_$^W`fe%9cFoW29hLO(7yw(=XR62~o~k{JAVNP*pEXu5DtBN`fz>`}oFNC+1bwbSaSSt +#H|86le9aVT#2B+hMTX_(Wr#XV$r~r?Pd_%#n35-jNy!#g$_MEqU8IS$kPgzIcvF!E;v+8Nu!IzYF)u +Ymq!E>uA#6j_jd}U9TarFCTQ9#1HA=R)oNVEcV3f@i1L7hc!Xq5Qz+aT}fA_HPC&RMP9teV@ +EN@&devGyhPL6K8(X;6@2NF_$$v$9giMx};iiHsh-sf>HTmY=R4n?jD68QJ>YO21#1hCVMVBRfSD1d& +L{_L^kOAw;R1Y^v#Q2@SQ0F2$RiVMs?&)?RLTC0(5v7q@tkcs^}?p=MKRj?%f&uyXj +HF&JJapawTC)I#vG+zFXcw?=<#R|qKk&|$)Ya1-cj6*#JPJJG*Yj5fyW4xZ6#vNY;Oso&oIdKiJ#4{%4(#orWYtBz(4+9sRn= +>9~KzTx`T9}evC#>_D^~XDotrw +=CeNpP(cGyIV=E>#juSpNg!!dxD(?&3boccC?vZ=@JFD;QKdj5W{YQ4ax4+iCzW;t3|9^GUu{XNa_dn +bqe);3|{mUEp$9vy9{=UGw=MOVMtFxAIXR_aoj^n}i&S!eez5TC^xVL}8$ol>#8u*VITZh|38+*fWkE +GW5J#J%fNOyF)kt=jqs~ynENnE<=6)hUFPnaPRWCIrHBBM@{wp8`5`T(Y^Bze&OEnT +Q0eG{C_RIxBt5L>ih3);Ge%<^2hVgjXk-><)j)j^-&~^3{1%)#Mv +5$!H^{z#eKX(oH5go(Qm3jKQt#PBUK-sPIH16WQwfe!f1Yjv=a=e1E@qGx!T*yGxjDthZP1)J&SvMA{`7^5{RB@J<*In-mrwEj$j{574LNiiHXGg|JJD5 +I?iXY!ax#^D+#SMP>rwiUkN3=n$(Xs_30k#_QP}l$K5J;YcB5YI5?T^jLe)EA1cwVI#9s2c= +0|5@TPt&Is&joRwNAwG$efByN?lPGY?rV#DLeQ&f3U<74H2p8q$VavWPOo04Wqeq8Sii#-~4cRJVexB +mxm`_J?L{|Edu@S^UM_uFreP~Pz+xWY>gvI(6K_W0oD4ID0j!#|;~!LfqS*QjK(scbfr{hHhOJtW74= +_04=D!XA{(StI;{ZZN7SAGwZ-^1nicsb4x**!rvljQVA$a!bV?pch9-4DPFAEcaU-%llp@_>IeRdpv5V=iA%n_s++<`-1ECfXYZ)OZF5i0oH|ohDY7@dm(17KNal>?XRy_m=?aU5xt79LtU +9?$eV24++?Gt8Y;L;G@L{sKnZh4hd46RFc44Ju<;c6IU--JP4JH9-@X0YJ)hzksgp*!(hCg=VyE8W#^ +DLBNVjUGS%iKyGn?+DeFpXdefq@{GAf4c8g5dA9d_ +J!C``Of^`I|36>HpCYVn!i(ndofgqD0m0%RXP=Z*3V1k|mod{gz@QwsE7l|H%F9~)LtS4AXu$W*z!4! +gcf?xtX|6Q^NZUp)#-|g6)xZ)59<-vGebC&4)f#|2WxETnKfyQv#IbLrWbQE`J$3KT6`H7(L!#my`fQ +y}+wk@8wZDa@WJn7Wr&eHnN^H(2f&z*yqZ}p_D#e&{&6TDnHsPE_ova{t@WO{=BHm##;cp=m^ +E3)njLLB%6LT?*UBh(j#EypnjkqKIryFs{GsT7>Y~APH#r@^GxUap7`-gXN-+LGL6L)d9G~$lFt%lrH +UUm!@UY(aWJ6`p%V>m%Zd3W=(V{27)@8x~%Sh`c)d(Q~+?^gGIID_6@>)xk4L*X6k-p>@;iG6I!`+y= +l_LNP2IDS}7pc7asJ1`r6diUeD7VngPE&1c2F +hx@O(tBpL2)}>-q1}>0wMhSaouC6b?R8{ZZo8Dt7-N3NatWrK)}F70&=EfOxMtaAJzByXmgD?g +GqtLW6r-!u&A +eY61S7jgbmb@h5CxcFJd3Oje^uFjn~bC7}E1C%h%GPp?Pgfh~Ja=Q1|Tiv>KV;&wJOrz1TkdP1-78b^ +$qoYOH4IVt0B_<}a5hF&h(W6JR!qg}>e*AbgVZsEKm6gTv^72IgF@5@U_PQ~Yz4J^6`=C(EOyeWj{E6 +XgaZVU}HBZMrnGwX^Eskcd%oxkIyqwE+Klda%ylNurxs9_Yc5vpoo3qeeocVsvS@1#5MjhZR{7cTBJj +vPM?>WmS7({Smn>K9{e +c7j?#ugV|I*iM`Ahu}%Da_9Z` +}^rx&1#qUD#H55OD;>S|_5fpzs#h=1kv3V4KDaC(};+IqWqZI$VP5kZ@Uq|tuqWA`izkuSuMe%n~{38 +_q1jYZ3;{QPLD=GdJihsinFlpnKX!;X|0;`Sywy{Td*(7ecsApcmNLF*1LN=S +W&FtZHu2RI-;d(QQv9(Le+tE4K=D^o{0}JpHj2N8;!~cBPE-5~6#uF<{u7kKlaxXRr7(w5SVJl7q7=? +j3Rhck_Nymn*9UWUV-jc8i#WUaK4-U%aBKXI6u%e652g4+DE>H#UqJEaQv4+p{|$=2k>c;5_=hO|X^L +NE6JI5lKwFC6k>Wo}@w-#}Cn$bjia(s=rLX%oNxlPo>9PT}GG!uo}Y^?ermc+YO`UA +lDdZ}ko97ZV*F5fKv}8X6Xn+^c7g9^Ksg_wTBt5D`t@^dC)@h=^p5#}J@@f3@r%6BiyC6H3WPhKGgr3 +rl_i0lIbT@~G?|9j6P62@8)1r})6D_Y)o-eUs~ujERd;o~Vv)?UH-6D=7Ci7Ut#P;-m>pj!TY6c*vGYL6Fa+B0|-N)7#9;tj8x|z=I^WVZt9?VFq%BW`w=hu +_=Jbo`6nm$3mc?u>Fnf3*6?Jc9vxAae{wj24AMSe@2rD=cqp-J46E};`4EHYnzw2>C^amGTu~#?s4Q2^LL10)_m)!>d2Yy%AwnK0)c3c_9&b+R%jRZ8vX}G1*~XcXZ2c>R%zrP*6x7cR_? +olCbCS$3h0GUUe38BS>Z@$ovSsY`*I#F=SFaYb!UrFGAmqW1KmJ(A3SX7K$zCOSV?D_VyLRnj2M-<;v +cdUt-?MY)&aw07&$FtkDt7tuW%lbYSA=Zv+i$3-5abG-^e`qHa3{=Ws~?Zwuql*@AC^ZeqXhTPXl5+&FFJ!uwD2B#rLE5I*K1d@kdhpNfdt$#a~A +8H&Fb26u)kq`;VORA35d!Ryn1E+y`{%&_OKyw-;K+4sPB0^y!1kJUXa5ba3nN=;NJTTef_J_^f@Gp54 +0j=+>u|tIJ~#(0hkRyY}coVOzO&?&HzNgLUfic+Wl$H|x`i0jTYGTd#U ++Ri2n!egUEXK8&1*L6KDf~fD=&)&zQZ0TrX15R?T{}a#OS*8cR*h0~^bLY+|Q~*Aa>)y0!Q|ej7alKS +h;>a25Da1AmrNsZK$3afF#eIfHxng((`>U5PU!Fwc&L>x{T)Fu3&p-c2W6!yte){PGncrW(e*Fr~OV6 +J^efs@9d-j;^?Cd;(gM<6XG`Y#?U`qKX&{gWbD#?@A`hs^xvgbsITyWT+oKWbgR(*Iz$J^J +u<(`*!~0k3Vu6Px{p0EX{9h0`m0 +2kD2GZ|o4wgh48&BF+rm6hdPQ&aOhLpON;__wF>K16NM2Wj~G`*#O^gqOho^Upu$AAR%@C;a$_AATtC +zHs3Jzj*N?KYaKwKXT-V2!}W%Bf$MU#aaIT`|nTRvSrJ364@e6CextY+}wx-3l_waTn*f?J;Ci@J90>Puy~;L@c_yu7^JTF!?K9pc}7^Nqlh>PO%X`#x_o`s%BXe)!>s?^f>0>EFPL$NE+kQN09XDd*hTfx>H@OSXvxpU`ys>d$G6SF|WjvYG${@{<3Cr^qxID7W2c +n6MX6V!%n9x;)^c?{-{H0{~Yyj`}S>a`_TI>a<7FywPCNng8z*hH#iMLg8u^o +0=k2b0l@#jfdl-LPd?#P=bU6_(S}j}sE>X7_6Y#)d-v`YZRNy?6T%J}&H@gKj=K +NuyYB?RjxtAi17Gj~XaU|Rf7J2H%bZ6X=UjJ`bL}C{{r7Y3y_aa%#rfkzL-(zmclns}1*bW$t*u@9SM +aC4-U`590i`Y!_&exn%uz?+8}L8+U7E8Aga#4*Po9!!==UY(eF@hfqQRH=CijGdf5tJ+ +-9N3rf9=okr!j*o{Xh7h#v=}BSSJdfqg+uJ;4AQkLI>J7_zZlHcA=PP7kCoRaz2n~h#~%u`dXqPFLMD2gCNakQ;_)~u`_@CO^0?0#Xa|#^_EuaD8!QFTZ_@kfPG$V|^_pFw`O*E__8eT +U@_~&2Y{OKy9!NPgc1*tuwPl`EJ*PcOx(w;$s(w@;L_54I6Q{51Mv@?t^BxhLxG$_!Jj>g)ELJOWPMS +*<7v>^W8Gg|)E6r!OZg#UK+694*liH2mNVdRfQgH3ymk=t|FF{w`qI3SJBN}tq&Xz2P$qy3V=pXB@bz +P`R)NJg0j{LwGM1kZp5$UF)yaKl)u$Yt=ucng^U&&S1qd~;zSf1hZ0muOf^G<>=whhM)^d0(APCDEBh +brPVoXIaMRv8{3Z(O)S19~2bS9d)4q+AHt|Zoplk1${sId(3OlZ(^*%*oJ4@%mDro(Xgp7h_9cfXQ~_h4J|l`|-IM;oLMnoEN1=aI^6#{@vGy1r4?`MsHchxEub|-wXaHd=>z2-~|&n0dKSi;H} +gN`gmLU7~?N!1pn`x+m~-88a^Z%HclrRs4bv9gNBtd4NGJi7J`Ne{rH@8q9HAU7p6uE8t|Y`3bK(gd_ +QZP|Iue)41*j2Si5#Df9IWdIOHM)Z0qD+?c|R?{@{mSOW_qJfBxwVqJi4N2Smfa<@Ss|>2+gYzAUdVe +>pdlFV5ES=Q6{%nP`|zG|VI#rV|Z#8p;@Bjy2x@0Ds~I!T-e9vp~!2*|Yh&b?XE@_d|z53*uUie86|i +^5^A5!zV<8XwO6g`Xr@2ub@6@X1WQ-508t?yszrz1ot+qR +G0Dg1l&b89ekdAxN^2Z;w{A|T5{ImJte7h-te1SZ;4!#P%C&)2)&v&tA~&t-CZZt&bw{s +I1|`vC(6pdR>JZ@ndCFUT^brKP-}pukGQz38}Co!~*Aw6X9$+B4D6NI!G8r#;GP;lhO#)OYe8J$mru< +Yc~P%^HqzIX^$28w>_MfBt;YuD|{EThZ@87HW(Z;Ek~XeHCOO$fKAK;6Zyn^oEhw{!a6aRRz}etjHKk +v>X=&N1si{@ekBWL&xpE~RG-wb{NJ!viWo7)u7hmLy7cUn0V15s +LK?BADj1vkSn8Sbu^rzrMjD^T!mpOtTeG~ZK;GeH9sFN`YBpCzk8GX_#Q{sUBpU%I6gM&-s;^Jn2e~8 +x?(Y)Vx)22=9s10-S<5Q+g;nXHL-k*H(Ng*SA_St8GAAmb>MI9-8rPK%L1Mgv;1Gx@$f%bqlE!s2HgK +c|$t3i9-zhyb(z*p~wc>)6i7cW_|M681#Z@De=;^JbSn3%}BcJ0a^d+aezvbDekc%W_A0%%a6AuRy#l +#(|3)&tAN@=r^2G(Jl*2FB-irib$_&yVM)zSzuf{Px>1s_*+=e|Y)jm-(z&v#u>#w204~IrF!to_dOB +W@d_Vr+KB|CD4F&0Xl&j=x9g_)*vtrgYPj$qpe^)0`o|?K}JH|ftE%dBLC)hD5Jl+{)5QWc30%)=6?U +|v(MfJo=Hhb0??)v8XkZAaXxwSWKjwF9iNX_k2G;zb;gUv(TQmZrv(qK>1+ZklKf!Atfb+$HvAA-deqSwZI=`jWUNFc%vPl +|A9MXQ}7RDZL|Zl0kjFEi$0iezfI}Pa&vRjQN6F+wQCoyD22|)`F`<7zP9p@Qmz2Z7l9AeEhpImyNX4 +7p!(*-Z-NIfMxl(AILdk=`cafA`u`0ZHt_e}drypk|Ni&CMLd)>m6L_~w$U_3P9xlRkQ=TQhu-6U^*2 +I(gZzX3pW5RByraFr1TLs=v{~X)AxmUsWr@C(+PWCu(AR*!6+T2eK)XbpfKN~d=#y>bA=r^F>In6L@t +o+z7h32yo$eENEB>~;YRkj6ybaty7kCJ5Va}X6ocb&=PTM}fO##F~KZCvq5BLXjA^>m)UCWm*#~R}bd +wcu8in|qmMgFJqo&_3|ez7q+P~PZ+XzUjA1n?Bb+D6v&1^%cTMTUT02Ye4+LYboty^PKLf4$u6;cv_T +=p!1Au?=Z~i8c07qek(UUV2IJw{5vAfNv4kNyL +F9mXSDI#9NoH*e;zyz+|RXQd4TK)13s54j2N;2A}KKz-($4h|0g72K`(+m4I2GK{TkbFVr9tXQ!^#0O +mn588k)cnf_eXi;z{`Sgvy$?tdI4_v5y3I3-eivnc_6mLn{%8lpkE{Pd+y(x&>z~w5Sl53*1IA9sF +X;ck2N;hqcA|_i=S10~9+dT6)C1np=cBJhKSpy3q1Paq|7qL>{@~qv@%i2O-L@}+zp`$Dat4jyb>gGj +BqLa;t}w24_=j=FgX2gZ`fmp0fqf7E$k9E#my9Vj +ocdeg$jdSd0DY +I_HOfy)RvFXY|uEXU)Lker)nyAK2P4;dJ^VEp-HNt +Rdx!+J2*$zA*w9Oy7SLlzE8t|h|*3m%M2OSgm(POLBKPdS_{;}1SHq^fZ7d-1_{luyQX+8G(l}miaFZFQ% +KPEQd$52^k>MiqQ13jI{pXNy^OO`B2w8aB?gU?~&fxZoEs?aZBO?dN5xqqrNy!1Qgd4x;I5lPpEHUWL +7ZT^rercRxjT~t&w!B+PQ9I$SJvcQA&b?BPjmGynlGhsax{0JQrbQ>mFzcg)}1TW6a5I6{aJY1*yZkT +^VU2sDkFzUZzPN>j#L05z|O{|S8{D^gN=vSbd5IQb7|LLhwBCq~7{1~#oe*HrxD=jTeS-Ny-BHAM6`; +gB;H*i52z&yGtL+A~mufn?OJM!B0a#_ECHUa$zbcMzG2x}SOvF)RwyS3$iw5?~Jc_y3s{|SnI0P_OO? +NBD@dr%hFE#L6ZpN|)M0<2H3m)F-<+q4Pjnar}DtVqTIkKjkjcND?t>iX?pnV+E@Lgu&Cv)JnHP)>iQ +Gdi~8-$KU%UEM6gp-|Q}+B|pkf5_i#HmAJy+G~l>4M83U9?HC0**6G0P!{Nq;D-nL+xMQSYZHy}qYbY +$+W$kwo;Gb-_MAC$vQQ4sJ@=gG_t5WR>_h(#UO;((7m>HE>iKU-F;M9j7+YfFCo%th%y$<&QB1>l| +3qMHyp$MQzc#mflborqm7U;nX +M~)mR=)T)pbHln(#&KnDB_)r2&-ebopUNM3ll*ZBxV5 +HW@cuNCtl7c83`YDW6u9)bE?iLD=Pbi>FMdaq2s|C{jg!fIO+oWH5!+#`T~@@!iUNp5yhmj>US#7XDO +}aG(Z1|NuO-|+0$8B<3}2h?NHuW%LNZ&EggCdv=3W70_p($0^$J|lm+^2^qIhO`}Xb6vHR0ei1t5!{` +{2JUw=JOnRBC_fy4OmK$xA9;)Xktg~elgTsz>0wPCV +?O#E=oUtg9xZgtXcq{J2W6nF@j_mPP6cv1(XjL{oqYZdZL*JZU`ad^bPh$MEILmv3CTa^(%`qkdkqX3f9ec;k(F{m!~|>#k55Id8xHws +5B~j;mI!ie9l|#kP0feOJ_{GKQg^sZAfZjSqcVMMVYHS#MDqXNdo6nj~T{biiYM&O9(IMS}`XF?%;pq`&MDJka4cj9PHKWQW}_xWA25yALf0 +ScLvbB6EX~BD&UQN3lHWnkQYCAVUkG0_Nlrht?6JL0dqE#ALk=!X}Z3@$Rpu<&eu}8y!z^^LLS5(5$M%Wm* +AI%viRYO^+N8SKF%t0gV;?dKN=TAzXhEf_75myDW3NW`|?X?j*0Tb9I7Nky=&L5dU5d-Im6i&7R?$R-7Dw)7BgqPIbi_&RTP18jaLD;iNSuIiy;gv(`iosTQZKIkVuD{Cs +`Z*vzTwDOs7>`5|45dD%hvRsU3MV*zBosp)`Hzexw@-uR>L% +MkO)^zFnKr^*E*pO$;7k8`NXKLP3Jc^mGA7{+VFie%-$t6!e$w;~AQ{(e83NkYFy_;_$7`|I+g^LTzVrI +c%gy^??@;fd-jlo+crWvQ$9s?WVegCHKY3SsJNP{4)6VBHAAg@{Vw{|`aS2r!T*r|_x_^-Is~c%y#f~p?hM=)cp|V}(8EFgK~X^oLCHZmK?Ol2L5 +qT33)&I%Wze~x>L5F95A9Rh3~iqFMeS$W(S22+(?U(5YeLtBLX5z|j=yG*rcyK7^AFFx-)_FizNx+w3Ac;BmwkWrt?|9>>*&|q??J!zermrSe!cyC{X+aA{o?#a +_>J`&@0aB_*{|5o?Dvx2QonV6@B3}>+v<1B@1$R)-x~oZ0;&TZ3Y;3aG;kYHzyn=^0)t|Ll7hwrWd{` +#{$B)wMEjk#Q*hT{O|V~Ze(-a_8-hOzwhMVABrhbk@6f)PedqN3uCG&Qt59e>FaUJY#A!xomTT +5%{;jcSe%4fLZfn$@FL*BVT<`gbXSwH5&(oe~iAra$hrN1w^`qJv=B4+V=rzr2lh<~y3tpGKns`6p9p +HVE>W6zr`Hb;N_c8gHeHQsF_c`Ws#^*Pm?!Mu^&-rfkJ@5OAZ?*5Ee*KBs$$p>u?esh0*V+Fu|Dpbw{ +`36b^Z(BOs{bPaVFCRECIvhbFgsvt!0v#f0nG#3P`w2PJ{34Fa9-d`ME%==B|&S0J_tG<)J>bI&DT!X +KBs*{yHWeG_FL_F?H}4!!R><8!QR11!7l|@1ve+UjeReNUJGSHVTD_(3p9nA=QXcs0>OFSCEguFBBU4D%e|In?th&os|WPow9vp0hj`d +cNrSn&)b&x6PhAJr8&u^ZeG6d$#ck@_NRrnA+BQugzZjz0P|z^Pc7XruX~amEOO22l?oH5`9McjPuFx +$@MAlnJ((?Up_BU?XC6M=<|`!Hsa;IJ_o5Tzw!Cb=O-Tr-=@B;d>`_C#J8)j2emwZ-zeWFeFytK<@=0 +pvG2>iANzjmd&&0(@p%*Ca;;yu-$1__|0w}K1l$N{8`vW-C@?l~e&D*m8NsW9PX{}MbPeeh5)qOSGCw +4+?+DPG%UC%Xdo>3%-)sKRwDN4{Ip6aa;y|OZF{ +b&2n_kYoUss9`P>-;zSZ}L+=lp;2?-|f9U{t`EAbrrppo*Y9LC1ocX}f5{wJWue!TR7~A%!7d +heQJZVo5LBS#yQjk)P*esugc)F=bxP-k#orz2|r@@_y3iXP*|nUcN8-zUTX;@8y6W0u9F4m}WXJm7S|g@8)|Hv`mx(bUee13 +wOI8ZKhJPS4d}dRBO(8{_gpRR}bHbesB0!`nL`64 +^Ri0srPxF+Tg3f%c-v44E`keVDR_Bjv=8TLqaBm%nSK8#HsHieS`Xr@4L9~^1cW9p6YwCZ}-rEP($dF +&^JO4BK`Fu3&u1mO_b(s&1ubbDgg&im1hf2SIkDq3eQWPS3R$L)_B%>j`hm +&noB(M|Fw7iEKUSr7~g}4DN%`^bK=4W8m@p5a-pbC +Z|_{+c&=i??})9}u}eb4^eXeW-uXAuaKSaSnE;mci_Tryz1I_v9fgWY11- +D58($KJAcRP77rVj&`K%#FKAH|=I!)1?6>t2-`KUImm@8L!~gyoT5F`raom@U+=#o>4ucn|ev +#(p&maKc)S=)FZ?a7C +5R2;8YVbLYg%g{vWgC}LPg90??e$!YRZmXgVY10at(D4>WE9-xd0d{j}xCbsY#+t@)JduX7E7P{!6j{ +$}l;Sfg{V6M8Bt_{3j~;AhB+>=fF>g{Dr0h8#$`e#WlE-HMrNfhP3cI;JQ1fL`|^;udnN-JQ +wfz+DV0_krK^G}suE>oSyhy;s;Wk*xvh3oUG1rcYN{6bwWI#OLxc(yDpaUYq5johP)h>@6aWAK2mtey +7DsGqy$n^j0001f0RS5S003}la4%nWWo~3|axY|Qb98KJVlQ+yG%jU$W#qjJcvRIDFnT7FNhUAOAPfW +$i7;q1KBB>zI7H{bjGU1fi4`brAGS+n^|GHnF*)<2gAG!1Xu7~OSzAig`-_kW7zUM!7bJuJtyS}TO((f_L-)4UQh`xXL8Kg$rF_;m1$WLlRnR>(=q7KAPE@-j~=ErbsT2Z=>6pVI`vh95%zx3I@TKz!l$G=Qh4E?Fu0b?W; +GkHW-Ui!c!%7FdM8R>1dci(t4A7IA?S&y0K +`vP*N9tY0kP=`URwG>f(aHJV=p;jq23*B*#Oo^1zP~~cwAndOChCQ>s61PaI$t{oiGKp5T7~OiIG1k~ +giXzxHp!8hF1s92T#lP%^VMkiwB~%A{Zo$b?@ +cSbTnA(E7==}+*PdYwF`p8Hia7@&jCfmCu3SipJB)h%D^1cO15hSLlH{BVl8I~e+X1{Nzr$YL9wtQiS +jXDNhAA6>m7n~z-o(K7Kwc%txN}a_}ONyN~CX@b!Zy3-H8(&1LN3(eGJ8nhhKrVs|H@z2=#{Cg=DOPIK`ff+h4e=!D*Cp||U!GmDI%`;(f +H;tE?1WLHaNRwX-Fv>Or^exqB1>-_B2Qa@V=j}Oa!_Jwr2bel9wnmOwf-15k5r_6 +c{=M|fwV|AR+3fPI%@Lj~n0E3aV1=vQJeFQZM)j6&LK+_*XS=JeD4CNZmAUvyy4AJ{3B3LEIuL{5~58 +{`4un_joSuF3LfIZ=M#a^=AaP9<3x)Pg*QiaVX4lZ`(&yb_@UA3^eYAv+6u5*~1%eMfAShBsO-EeN%g +p>5`kyb6o1^^!b4JuY=(aT2KYKHR}C_u{Z>=N&VQx?q=3Jg~WBGlp~c +Cc^nPD9YNj-lK+5vK=?`0@&4awP%3Duj)1o1Aw()F74c_slp5dm-bu4)Tr|%UiodPyy|->Y&b{oLTy+ +m#0x#o3;hNQeMg19+en2vuuugr^k-hE<|w}9y#R@;aXziSmjw%UzHK94`N{ymQbvd@@WE687#CY=NSMSd;}^vkm9H=3}M00S +0YsFyG|pbXSGp%;aqr^MS8AVi=GK>90b$O@M<8R<#naa4xL;0w6w%3OMP3#b02h#SacjQP$a39Oh!Ex +^^s#xVo%Vu|=o#>6zk+t+LvfF0R;yza|tyD +`PKDllDNVrR72S>0?{jMmso^%a7&i7``L$Hw%%}Fw*fmV*DtmRtRs{Ig+7NzSv`;@M;~`pq~TVKOt`7 +VwtTcjsL)=;S#E(@-x43Vhu`kSRa4Umr~42|-JJ`E*OuieVr^Nrk}VrC+1*z2m2L$jhx%b$@k^lzth^ +K|dm669CG`{?4X|dI#;W*nLGZGzk@>Dd6X9QL2RLsbQam0zuS#I$Nl>{uqAd2{zVcL;DK3u!L?j5L=6 +&r)IRuDo830jT77{}Hs?{aJIGVuVI49>8Xh0WD$QAMmc~~I{xV>2CT&k02*4dmGQ0Kes)6{{&p8W`n& +9Kh^Pu7ejO0x$k`{mVT3+&28)n%1-P5W1GkJagYUI +0Dg6yy}E3c5E=)>@@y9k(6yfr@FK{^b#p6InQivv}8+WhW749U@Gws~QN}URDJ_08pYd0ED_Y5Y3yZAyk1JzbCV;fyf+0miZuv6wZ +Wo_wghd>#?aT+-B@9F8-VKi>jd4&01S+$g$|xVhOSQM`LjJZz>l(^wJz#qUZtgto*VINnQuVb^@{-V4 +O-(fm@W~Z8L4x^?5QOE+OB(etASU^M@Ni!L&R{H%K#n>?!EpJ)5i80R;HrdZMt`z&rHDTThM|=)H%;O^?=`&j +ARPN0mW>;?$-OCk#?@wCiwa0hcFYNAWP(#z`_LPF?NY^WfsO#JR)mvgqrDp +R>faKRG#}YR6voU^_-Xza!uMDuE7QcGLP;%h2Pq78V+d~|dZ6j?~LioXfsqlpW+e9^pO9IAUq&D8*;e`nxx=Yy9cg;@F0Kj`0ua?v)q=YSkL0^DeW9 +E)EQ4GeZ@>&^p`wt8N^Xm%Z)N*ctivN3*1Gthu!A3N3Fp-YCSF^BfclWSa;sxh^h%K#wPq~Q=Y)La3> +8BfD$d+-8r^-rKy(S`wI>WQB;pm@o6lpbTn&|Eq+hu!9ht84N_=sP|PGqFQs{Qf5DD+rjCTRK>QwTbz +Sw$OL}o=$mGqdYFwya{wW(&^NLrJ%MI`XiIO{A!gZXlpJa3ANOenG0szbaP5SqMaEJu)}gBfO67?AnO +ex!TUyzOm{87{ze926FY<9?$G&~HY7#yLPL^hy9fc2l+16xZ5EK~w_QX+!iF*keo+-`Vfd_3vx;j^T@dwb{1rORK))IjIH&-swWJ@OI +E%2g<7_fH9MQ!mvQ#Hu#$+gd)fE?o-S|EH+nWcx)1ooDc?Z +zvOD(R{m8QNpi7_G9SCVa_jXUfeJ$1_t5Oq&G7olDkrsczKwWXGCSSypD`{9rRnM0i2q3bt*>AJ}lO> +2C&zy@(31tq&cO&gafaj$E{z4%v-Pp5m6;WD=UjaqbY54_m(I)_ZP#}B0ix=`Vhkn4%TH_<(tzXVv03 +32rejqZtfOAMcI~-&h@W%lA43T9vBFn9a6}UQ~u`<$u>;P*5CAtXvetvKYgG%60zm#MF;M&UxHv=Gi0 +RKd7a+7vF>ZqKx{pJ`xwu0tEDCa>+Da#D>q5zu%+>RI>>1iN00JjXHw$~(sOs{zmh8+F*JSt!gvON&- +z&zxF8*w)v4MNqd8=6n@_k8V$BQ@5?;1RGhzMB*46n_sy=eTBTcYva?yn9N%M-2Z=;8Mwj6Zncz^_oULLq4C(tNNmLkgdP~HNo| +qR`mMQ*-BM|-GDN$+f2_Meno+kHuwgI6kyK1TB{#@6k;X)d&{nMkFc6p*`v_oby#fRaOuQVX0aywY7x +ytT&uW0BooM1pG#QI4c2>LFLMRCMR-(!VZwnp3B3=ZdC$4B0SES4Od8DHTK(zIs5>@PFF~fQ3yQq)=# +BAaU$Pib=#1$LI#ga_=%zBhb@_{kuYxjt$Ira?V>v0S8rM-JOygY0d0#$pKq^nhS5HTdS2{c@b_6rZr +Gu*gnJG(KzrwPrIq3oiCcGeOf1JBG2ptg0WN8R&v$)O08Q4^L>mi7;z9qc%eZfHJj6zZ9`=KJb*J(Mk}UmWvBZq3(6O5M#CWhi{wl|hoY`itz +E%+|>+1Qk~LaWPhECF<|NDC?s>!xYu#qZLv?%Y-Sf4X{Bb0V1(Z9B}UmP@??N^ef9er>muuPRq*T_ +nzKWC?A{HGH~1y_DqdqgNx=JY<7r^dT~vT8O+RTbuA5($K0xL9NOc_(~O@H17d80F?(!c&PS9PHG(2z +$1|H^I#kvB}2UvE3#{Twx?J;sr?3KOBG&W?I5GlF#NK{ +>Pqq0C-lXt9JFqf$@!tql3nUbWUqrB$SQjp546OmnxRRLHk?c;p|NWDYam6Wf&A$M*=E(*L`xk>4FK) +aTA@E#G;9_fiAC`=MSCq(v>O`K)_j{zU)GnqIm`QF;-X%6|`T#hd +!Jo)Wx7$h3t_06V!pV$KZ20Utk%Ts%iVw{v~rOXZ!&a2R6}i%XJ4ENJ-5*Hy4d+Y$X}Ia`RA)@VY8VW +0($t0NT?u{WU@0dN1@@At;jE>UEWpVh);}j9JBG9>S+WAWEBZcsn2y1dz>pk#j+FCGFZX(3U<{X7w%_ +K*aWRF52|XSG5sHhiyD2G20{f6|sGtjc@g?<-B|swB2fJfyAtIp|RE02v4LAGTR@H@Nt4LYQwn$|gm8q2KyZfUU=a5pMsh +061wX6bF%3ZFb;HRv;rSGtdMThh-OnOe!cjb +ST2lu>VN}=i&LL(3t7e%kNyl#u7` +XPu?24Zc2Zg(&+t1>@=p)<~wG%WpP-cAWLm&IJ+FN#2C>wfAgD1DrEv~R~*sF;(X@*n~dF#JJs=1;~?Y(j7L&`l;(N?j3 +8+H}XQKlH}%GGK-UpZfmXDcJr-t^GpKByCZK|o!nL*43#{|&3J{yH;`*yrhP1#uZMOx@~naB=0ZtP7sb{4a~Ikq_Mx5*3As3ZbME1EXx4{{=DTPqN$-a=?13F`g3 +`ItO1S@?cKvUz8NpqS%?p?J$m#PC5n{|lfxy9vY`*r|Asf(KSwbAUIn1Bw{7unjgeki$qQ +KjJ&v8wr8t6oQV{!H)I +*#t5|gOzaYrY8j-`Zcn}%n$hFQ7iwX}0?{eQ)r8|gM|7G)%N@$q=GSQM&WErf8~P3EGG7@+fQ`O;1X` +%lzr{9`T$y!1)^8w7x5&T@?cVZEC_E8k0KtEPS*HzK1P-y}A%0VZWT+o_&w!t}wg +N~e=2dKR!UykHG1lzT_U+$cNnr!rCmjln&>JE01f!wy~TY(=yh4-YRbs9uy5Yc)K5MG{;1UyVzARs0v +pl_^v5_^0!pOdWxa@6OLqd^Bhjzi{cIREw<&g5^XNg;O!l7@<Zg}u@|r~~Tg!B%IZs8Ebgm3X= +jFNN4*5EVYq(}9_90=}f5Ewiv4#~TUrmXmKU(#p~sOmP7qj3P&TwT9F78Zuy(Fr44MD$oRE!@1{GS{+ +B&2<56r4G@qvYA<`Rg(yy5F4?4gzaJJW`g<2b2gow;p@qdrl4st|?FWUNe6Ai2+**pt7VYd$x<%_O! +{(dKT`z7kNcK_>mdbR1?JH>q(BpZs_F%t}BM{9yd>9G5pKbF-J$84tQe-sxtsQFO;+k)w(jhf5_`!^o +c_@9<#k^2)B`Hz8pafmp*epLSF>fs0l>2U-NXr_^0)fo>Ehm7D4u0N^`R)Pv`@b>shf=<2x89)*A5f+ +_RVI?J^|=wxoG*RDQ71hRt#H7CxnW3BBrRpYKht?m-N8;+(_l$s5YLDKAOVysw1($Ny23oOHdG-o8)a +62biNnLIsC1$0^6@f=ytQr^8UiS{but_2|&CWO^$TbOfCh6v-1@aBP|(ZMprH{obN))#EgX_VcB({nB +*KItwPr%JS=$nm4TiD1NAjODt1SZ%8bU7`AK`^p2M=cb)l#&2E0q24(PLF@zq}5LfDW+Zvw67#-0cBp +}&Wrzi5RW@XBz$`Z9<0#cKIc6hoB}s5ZtjXj^PVlJiEZ72DMRfiD^SMEKGk0pLJax4`>HSHk;OIJfBNFA${B^1 +bk-4?5ih)bgd+9l8zWJ%DZhh<7F;6=;{D6={a^Hb_sNCJmS?@n6LI{1bEwkSEzrFYDzh=kq`lmaFBDT +0t2S>n+e#tL;83*NnUkNpP@29E6Kcqz(%woyj~z``^mpK{qF$UKZuUp9BN`%&EXOx@1O~R?$u~d;=q1=+xCztn}K> +xu{a?A4w{J*=A_z>4)>!3d+*TeY#*qq+eo6EYJ9b15}XEx#6;fQ*@tQD+=O`M-W8@%M`_2K%wxXg+I)CZt=fk&~Zm1R1y;(n1TsA12l+l0cz4JlIEiU-`g^a`HR-e+Y)jS@b8bby;D!$Zd(tu3)NrzHwqN*!!) +$ZsAxzEphq61jNvIG0mmj_H!B?lC?0MmdPa)T$<6)*n>{&k=Dehkwu$88JoO!f-f^4?fm7ns>TFw_4r&SJ(tVa1idQTgy$2nG93PAA=WTSRGW0;p +l%>H9EA=v~pU~Z1&{S)8Z9SeQ1xw2&Sx*nstb&?@udm}Ygc)C=`Zkco$zD@Bq)J#UZ5>`-~D&^>PJ-i +w8mRb+=3^G6`Q(Sk7^%Ll<6OB)}zs|!AP*t!-u;Zf4O%GbXEXx-I`Ra+?Q*#`i=GIALTx}xZcP1`Prv3E5DM)H_>gNQ_4hlpORf0aNBF+VIq= +Vm(k*N+v|EdSEASBsCG5>J&<(K3j&SrIUI>b+a`!mlu6DR#>eay--3N`ky}lqg)*^8kDje2tRWjd+X0 +o_4pTvV>N!5lCe)t2?p!^Oip#C(?miOIn=2(_om_Vm^&IhW83m=h*>=R|zdVOz8~4<5GM?QE(&0SVR} +Yhdk~(ua-B}s2hVne%OC=!a9G28g=*X)HpCo;aLxo{OaiN87CiKF}KL@Jnjs8IcboaV;K$;iGgkdERLPiStBYr+Tia~L%6WaHV?XeU@S7p5B>r@NB_hJF#1L$^6V%K;+W(< +7Ha%2gE;dTx=Eaia{zpV16VgDYn3~$@zMwIyJvQ-2$MV>OdO?YvC?Tk(?7{=6>28Zb#!43 +hx+RqTNlRuwuhQumU`n1gQqkSvP9&p>!ZMa+)CYbdGB5C+hw4=%?ufeJ_ibbi)!{Z_z$ZL-W!uN!@Dj +RaiP4O-$&N5~%tDfIAIT^Xt@!djw_fb!_OK?n$r`w?VH*chOOl?NZEVxqE1dN+k8TC3Ked15`}it;#r +~1-f_XqkQ2*p-oo9do-| +A40x)!%{y|Ui{4F=&caa^uyMtM*Sd%mjSj##SdYw#l7Tf}M-(GV^sbHR-HXA5=E0b5g_1^9=D1&C$ty +XsxW^40B!y47ZE*Xn_vm5j|3=5$NO--a!i-|B?(ZP^6t6wu|+R$f4aG4+OR +M5274=tp!AyC`h#|p9Hu7KhrAY<~!g-WWj4d*Q!KcXukGGsHK*U6~idVY0Kd)lCM9aJ$8^zvAt8#$hz +6f3e3iuPtzF66D{5`hJY=OL`SbszIH8dH&micgePyLK))c|_)uX>CY2hkop%t|41K@!9BstG)B--Q(* +mBshf$fzN>$nh*R4^3*+Ft8Hn(k^YW;fT2sZweRD& +8jEFjr!q);oxjb7w@?mHXfdV@sKoDAH^fmBIJ5S^8oE8S)da(*=4jvCfmb@9vR_f>!JG +dQ_y)vzgcZBfDy#60R%@cyK!n?pK=bxT><5Fz6?|s{j^A~Z3nqFw@J^0wO#iK%u})#D8oy(vn}M`^Ui +dnP6SmdW`RJyUd~eJd`t4D`)D_1^&dF6iHC!d`Qu_||s+DvSBgFTT1Bl07x&$UQsM +&oY&aKv7JNIAm*EkhS^MJ=geS@r+Ozf60Uwt1`H{x_bF?If8!bcJw{|4qX+q8wQ(RwB60(7>|I3;J?4 +F7sGBB7GwFy4L~<;a6ml|e0Rd%9;gpr8vJ#^Un110KWW;R#pc2A2Q}b>SAmC4{Gdwkt>H%(ek4L2UA4 +I`AwKw}_zOhNOmh6`Nfg&#cMN*I=7FqMUndf1J#%t2-34?wNw$$n1F +1=o<(WX1{YaLFaI%b_Xhn(mI`p9?g~s?Yq|oPLCYDVfK)ydVGm(6YK)$OdMP^p_{SWl}B$*=_oZ%}ub +P5GOd@2S1lvD5nNeaFtNx|2f6ud$^Yk!J@@2*Nx@I?bD_<|JC{h>+07ib^vGb#Av2=p!ckb=ii!ql4f +5fT4Y)j%S?Xdn^qZx7w#tG$u=xAzUC;tM@(i>RAA*)`DgQ-PtViPbqDKs)(euSL5Y*ZVB2s=Fp{=%A;E|KvOs%s529zl?3D( +MjClBMY@XTw9OJ+AaK$=fv3PNOxJ!vNOo42#!-UrrE`}EEvre5%r;{d#HOHYNI1-O1^rxT`-}0QmjT~y32v*OEYd9;9O4|xKgf)NvyNg +w+Ge#$gI7%fFrbb_Zmit5h>N4+M8sA@%0&issl(j31A(<4y&0~~z@-$!Kggi%pltIln}1 +oUv=UFOd})WIj^mQ}?q+Ypy|ayWWhl_h9M;^^@uEd}QT?JXz`oIEo9|C=(#Vb12hT@fvJ+>*vsV0-M1}*NXL5;L&~U@ieji@ig?sQSzkPtFzG*Rcue!ZMAcX?MMAp>-_A~Ap6 +R1Z2_{Zk)zirR5ahl!(KF|O&lrKBPEosTBqbSSY@NxZ>*1RB5v!`WTP$M))o%;M|~FbFV4W=QvHzt)8 +e>WVP=Ws%z&m>;?zt(FJrwq$IK_Ve~RHe{tJ4lE?e@katF+7$*YDja8j}|vUW*jwlc=sFfQ5hGGAqb_ +p&VA?RS3~%E9cAt;L$H7XiXZ=K1LcL+idy5HJ&3Js(5Y;S +Bto3@$zxG!AzIH0Ew*v-W_Z9ec$vt}_Sg5ua-HS@%X37t8VI$uDd*ZcZhyS}Gg%9}#jkA>>{C2uYE&Y +65Wb5lT&fClj9~H)?-U1a^CZE +Ldijfb9R)wIQ<$50D^MCA8@Gi<&%-rO|z>mo6)Iwfc=hJ=Ic!Mg{ZpBw`0I-S+Z`!^x~`Z0AjHtRX=2 +_jttSSgr$;On~)a(0kmot%79zhy!Tt6cj{@Fo|{a&_GOX}#vxDuuV;&oqTsKOJuP16a*%Qma@2+eL^K +GxzgO&j&|U6nf#p5gCyCyVS+o8l!#U$|-mIuOvfjws#AZ=pbM5fgxxTvbO_rRj+CwZ~O~1QL-zNuRWA%HjdtRCA*L}{ +sErc<(C{r-uMKe!2SU1!61r2wEW7$Xjj_{vcTTTsVuz*He{f{u6|}we$1Msx&*RD@z>lf-Hl_<*M@$Q +cB0R7BF5mH{%lKaze7MT>knI=O)K*oc+(c +x18*G*5kmpXDCI5Dtumnrz1}P;8-8PTkb}w85qePBMn97>ygH{kHsYyK*_H%srFxsVdv4oGr5rS~I9t +byfMsSFjvauB3~eBN+o7-u_77baqkD(O_}dPS3J9clq)x+iYyq&Mkxeb`7XO;ayAjpCOdwOgc}2)a}X +lki#Xk?q%crOk>}Ga;W6`)kO{=WRom|^{ZikFsKRAvYIWfZvuB8`qeS=^YDPkgO>b4)Go#asv4o-$IkizIu>Qnn@>^wNhGx8jas*MA*#@cZ&^w&)^50dnQ&sc$Qy$cO6i`$L+OWp)E?(trF +XSG6R~=hqgi1liANgR_sVR^e~%kK)v_|7>EIi@=xvjd#w5WnVG)H{9a~$D;e}19)~?chiYPu_=|;PPP +;D+d5a|0my+prvRMBCX?;F^wyh?ni1nlC;YLMK6P059hxB%fGF(mEA=c;7Ta{RkSG2{8@IopELTL+Lj +DkvGr5&Bv&J)){$E&~0S$Nhnt$;qb$%~q{CF0$9ss|IB9zRGoBaDu3=2-CAdC=SkkS6u4FNW#Cz7ba+ +%JH*vB)7p@$zl!qAoc_$9Cn-wdd5R<$qr=EJNhrYx%lV8DJ}KaRL=K_E3Qw_ojT~G8f48{WG<~W`qV* +tGr4FfExR@WZ!*3$_@MBt#&{`=5z-c6np6uLQQhpp42gXkHpIv|X_W2FK=8~YVBaM^ZnfgW-H&Wn6F= +tSzM8m?`$(&a`#EJ+6AP3oHL*~v&qV8GBE;<>YGRQXZia?do{wXyFxslUWf*R*#?pZBcF9E> +jr(AL>^U`=kev}pa-z45tLfudJ|xP3g~6ky}m#Jaq3DvEplZNf^ocX2LU9}X$+h03amumYHwHzWg>p$ +F3bvY^wBS&1;SQ_!ly^c42o;7P3Xg6so={&X&J#Pcux1RYZLUI2fOkiyT7Lsr(?%fv#He@tB*B?jfXP +nLJ2)bQornx+(#vG+EJjNbMStI=pQgo?&%!WK5hfRCcw5DTf^;3ZMf0LpgFJ64_mV5aDX*NCl#xSvPa +UaEvTSu)ZZt@5DjAsz;L}q%^>?@#ECDgi}k}Tbefk{>n;}Svn`~z7?9awEsh_>vo42Jd+hGeWW*90UY +R*GY^u&cweFGg>RM-E&8n^1v%B%O58rFJzcOXk$$E4g9#^<PruRn@L> +R_#xZ6$Ya7C>`X3p#tlqgQ6{p|3ZTSZQ=f?0DUNG?OXklr)w>+o565Z0iO*^!hQiGozOLd1&Ax!v^L5 +iSqpe^K0D~hwQW#7`y|!I%gcLIsgk0g(7mwrn_c}VT=%_^}7sL%f2uZQSM?`rtb9?#epwHv~U2BfIb* +f(-bOFplcu>1iTbp4$Us`7R`Z1i}pj2+|XGR-wbn<*!!;+Xo(&)+xwn1qn;^VttDyVyEH)#o9X<(z)0r6ELPLcZZEfs$}-9S6nejjy}~$&T_#QrIonHjjgiUlBQiZ$J`B}OWBMU!`qcY>KpBf<^ +ZBpk9vQ-huA2<@nyYGVm)4%s0V}R%+d0Jnpci#Dld&-40kU&7YD42>Tj9PHXDb`0S(O%vWR$b)u7c>8 +Mze9$V;pY-P<{r0{;2XpP<090%T#~DZQWpmChhW7+kLYnHVAZ4@6OLKnJs_D-o!_cNJL4p&JE^fwxQm +e)yGA_?)X;0H5>GBy#M*(4U9^>rYFyrSn7Cz#8#AS8o8y;Lsn1&jJehkd|?>H1P)^r&PPhG9fg`uQsM +pTD%epOf2CUm!~qm7wM>H;vBL5O8f@mdMSPbNj)FGfrgI3??tdJ@f+Bgh-x0PR>WFKd}|Z2BP})+kA4 +AcMHnZsfL!#XWt%kHr2<7x%=IoCD;rHDGZDWZZs8gIMR#73LiYHt@Q%OQV;6=%U?6&ln;ZGVa=QG_z$ +N#_Rd|W!u0<9dT`YG{+Wl1E2#(4dzcbm)D2bCvl+J+UM*NteZcgv%)I|)#jONx-D_&>?UgH<=iUo=Up +W|So)gCKS#=_^t$`JT07Q>mm1$(^jIBzQcJ%6yoF%Su%o*Dm~C#A(P@Cb*r2tQ`xMN^lV<+0Vt9J0%myOyRmHfCZxQh<_hiem88&)(gvHuiEmC7d|>kcjW%^9!0op+pWvI&3$1u>=FnDt1nR+WJ`;phs +IsYsC6wi0S9j5?iUdmW_u%jO9cWC$hn-tj|yalomk90wW#uHo9SC;NTvD +B4Puy2vNC_gdide5VNUZUu-$iMJQeJI^7hS5K0busm>(je3(M<5bNOUQLcu-nD^>&kvE2#st +Fiqj#nRVA@nFrB#T%9cZBG8qvh{&Pxx0+VxjG9GX1KdmeK)qphgPt~jI%Ay0(@CI1@hjnGY7?6hN9Qx +IDWxpJdhOx8yg>_|bruCMTQ_dR<1EzOMOXRArlHuptY^)l|#5xPf%=H1vC70Yv1Y;^XF3VLd +vb7T$3ax-fU)#VH!s)N0RcidR8)(VT7g}uxJ{2g$BX!@!MAFdHx#Uo-du(VhFrh=9x5kQ3HiF>GG!W?xAKkT;xy; +%CI#{dtRte^8(VR4KV8SOAfLu>~w=ybxDD;Y_wy!|RfX}SZpRr6<%M?S`r5lI*gZd4j(cx|dB-+WA+S0KhioVT3(1p8U9;|CyT +pw(-WB(Z~nKNOCIOK49NJsQgriHsh_K5|`l!;l&WB|yO;=65H=`G}k2D4~X1}($G9GV+eG^eTOkQ!q& +V;aH0XpaBLAeRa3M=*=Whe8^8O88Zm3rc4Ew~KFxPw?C<3quWSwYhFQH!nVBNX4 +Ai4g6K_K%V5l&5VWlLA6k2w8!l(@hv8X!8J%q*VS6218Wg?nBcA{u?8^4=W^xWSDMo +EaW4D-yLp)v+2~%UIGr;4<0YDYWf#&=G#&D`?#NPDao3hp|c4qUX@ty-ISE4|JG-1)ocCTQi#n$TQK= +w?9eiTlwUfV)RawB~taSYcM?5Q1T4ten?mIJdi-qG4XltQ_R;X;g3< +<=m_Fi9WpWX4u{Yx(UtqHb*N|IQ%ju!Uz1zvdhiP>1lCXm6v*)2CPDkn2jq~dVoH}`CO!%suA(#jMU) +*`L);kDOPH2z?mBEkr6k7iON(6z!Va%-ExO^IA(ql`Zu$wZro8IaD0CanuWC|W`*Kvatj050t!``T>h +uzp=U$CPIt=FqD!UOM{ZA@8@bY*w2K6UK%DdMdl^t5N4c|>yH +IgtcuyCi@{(D53zZ4ypZQ9V6$Zb#NZyEfplD{SXL2q;U+X4QzfWLjr-xl$=E%e4}380wp4o@IKBx;-b +7>PZ2KPIHF#pM98_wakPN{qYlVdNH6J-f@u3Jr%k58_=z3{#}%EA((`d4+qb{?tg_y=Fzq@rWOb;LT*(LCG8&3`t^hO|6a{sgbnd1x +hf_K|6Mxo7+zHmBD3GM0DqN^_0(Eg)8Q4pBud7lUh@2NtB(n4j!qY8#J{%rfxq*QB&*Ykos8FA$g4Uj +CQe7e7;kvuagx;H6Z} +rJ87DeN)g44sFEOMyYbADAW;V57m_L2BxlRj8t+w@$CeV}K8Zmy@Xk66np0iES$tQ!}T=&nWOTFKq0l$E0`O}Vfff6GTXryTv +)l#9yotX?TB7c$^$kUOS~j=L~Qj(w>Qk>0j(yY$=W+l8b1Y!yx>65J$(yOd$eY?IatLU+el-`p2#qf( +vdZG$YBnMWBWu8xnC#MNIp)D7t{6iCNeiL3YJF3gZ}%yJ+;Lb*|THat6&On5#UGPLC~UgeDDlXJC>ca +kuE{vA|bah0{-!6OsmPm{~D&*NpjbutT9v=Vz_zD;<(T#QaDfoM>Z*oR&&5xDL}Lg(8<4%1H-hy_WKErv=Jo1(q4s+19 +zYP;9jsGs)G*Em#&(t@lnZN$0WWmbd8_NA?)bkMBX3w$R_Thu=m}A(_{IFS*x;GNjtA9z6@ +g4%6Y$F0&bXSdP|!zQ@$lRjHm#S0L!mmz}`wuv>4#Vms(RIj0>=X|1%Z)g?FhI>a!lv%Y#mjQkBvuJz +w5A(rD~>(TY<1q@X1wIP&7Xh+rsN*mM+bJ6BS&Yv&&N<5S@OR2$%hn=GQ3({^8Uz>L# +~?92IblHocgbW)=}Kmt~(h$bN5LV-kUWK7y;cr5D%-1=tDU_abSWnC8f<HlS>*SOWMTn +pD=;75~hudl_Q4nTOCJWp#G5oN_^dGCi2ltl`I3)F0`U4lkr%epw5sUb4u+q!+e{gf*B3AlJ@XouYf}X#9Pg6^!7Y2oo;LM6|K{XhM8W&k +E8Np-Q#l~T)Io1Tyy#etI_GTUaWoi1!_u3Ga57QLn#4VSYw-M9G~)LdM#>WEA +zf8HSSqm?-Qn$H9RUz80Ol4`Oonm5nr-)kFln3|!*m+`7BpKw-E)n>)odLZ88>h_Jv36=_Ezc$;x>3h +*>7q5CDVHI8C^8sXWO)UHldgEOjm)gtZHcJ8o8)PTygf*)#_2HCL2C)c`&_NZ7vX3WLB#QN=i^tV}Y! +;rpd-;#ZwJ(oV(iHskG=5=zwrKtl+MxxT{5a5m$6-8}T|BwIwZCD;sOsu+}DVMVq*yxhUo>1=ShvLxU +wSkKX=+2Fzu_l13CQ*^V;XFI#~)Jcwu4KQ-t7X8-)(H0RIlzBvCt(ay=@irgX9YA?;Imu3|!02%eHYV +`=E9ig9dn<~Q1K%3N>x$Fx9+tW1B8$UtO0hW!li +Ukqv!X6{4$c`T7BEMDil|8p&J6zZm~|e7$*R70Y`FQ;hK=tI&vW((jt2u9n1Ny118JuJ$AL +8EPW%YsN2Pkes@$j^NLMaV4`e9Aj19^a+L!-It#u7N>YhM!yoG)XBku@k|8XRHkkq%1l6v4vUkva2`1 +@{rpRc8NCCxb89A9&S**{QaD|$!}%6^ot3_-g;{lvtcblKX3CjiD{v}y|gZ8w1iYzGAUJt(cq)uVQ0uzEB{$yJZ0E13b< +5rz6i0roCh#{(4Ptv-*>0+b95@v^tjlHU3={6r||HZSfZ%q(Mh!9_sIw;|oJFV6G|Kq#K29#@l5fMwmo@@A1)EU^HNW}ZAq#!A5vm@_tX0gv&k6bcdrv4{T<;*!e4YO5WU|HY +iSoB#TZ)r!GJhj_0Z*auU|NW?rf9YO|m$tL$-FvpzjXGGO>5i6oi;J5)TgL=uHK(`@E;+tpV=!~42`WJ{X|3B>EkEmo*nYv(eFwTtCufx$VOxRcIEaLGeh6{R~miv?-BnRfk# +%>$;=VN%MBat0qX|2XS=^-n}6JU3UIxO1k}5szFV0h#|}8)xeT5!HJ{Ig=i&S@yS_WLN{)IhMl*i)(d +TjcJVu{K>GKGE_R?npaBIeZlW<@`wvl+(1^SSB(d$tQkc+Ff_W&(i+34m*!T>S+0old!7KRW!qA?z+(vb00Cx5)s^X=(d7rGM`5Mj +%v&>%|>ju2V8#s**@#{j8uOzb3q1Q+$Nj*~ZhVP*j$#@@+M!LN&k0k`!`yrTRns!Ek;$Q!u +YK>`47sCCjTc3k)%w@0bPb6W5@*-Pj +r<*C_H2#haX+-jSSZ2ztS&)CSE4%3=tOcP|PBxZ)^x1#z^OkYF}iqzS&>Y1~P_FJt>lIK_4Cz5o}l}j +)fdpNE`M_($)RNl1BZNRNOR%-FBc`{UDitY!4McflF~@!*OJ1VWzD*GD6pIjAz4>*8Xz;5N8Y+B1laE +*5p@vjnLV_qMb0PwCc%`^dTti;Gix=Q6;Vy28yk}+|GL#Fv}4}B*W#qdruqpd$i{LC;Le#WOLI@n3k5)3A?dIcO|1K@x7{=Nk{dgEHSx90};GqWEO9;k@}rys;%1^| +(vP^3->W^$ReP&N%_H00N-jeu9AmzA)qj)6n$SEr#o1y_e;bG}iWJg9eJh1<=7r8p_Z;lDc?!g`gBj% +e=z_4FT63JW{N|>zXa8b0CX;wm|ob@3w2Vx#-+sf}gd>Ma_QedKqsz{P`;uZv6M~s(AhP-f^aB;tg`c +ZPw2=EfVZKDycOm3p`=r2NB8NGXn;3Tr-C~oz~su +`#+2MPJm#feFP)7*^s#k@bJEQmh-1;dbW|!jZbc8evN^6w@o^iv*e`Yk1pFPP3a$mD+KjIegccZA9%0 +7`4fDAf&V4uWwp#>hr_v%m{sv}vU0$PA|0&`OVNP1;9C3ve)M(IZv#aqJT_y3!brh!tSQkK98NLP-zl +we+NW1N7{FNan9=aRUSu`-6Yeo;UP1RV{qq$Q>piAtSrox(~qV*b`9m;7KCZRJ%3kI7Tv4#wMtm`#kAJuG;&z*@b)8PV&*>3R`HR8n +q6(H~2NavopF>-`Nt%Mc?mq(VPPhok`8)xukK?hYUUR}l;l8d_JD*Uw#cZ>LVE?Rfly43_t8l3p(wNO +6(Ex-fUKn!;#Cncj977LzfT9*SqNT;77#RU$D)sbNm+8@Xc5u?BANCv&u_4eTmo6kJMpRD@tGrX4{{? +rHi&OE~lEvL>9Z;h?|L{T3^G(JFB+HK(`Zs>nct3up*FlJyMddq3nW^RHv3XZtSwufP`$LSyko_#?vRDl_~U6qX(%&fr +mUq}nCINU{EMD55Q;p6Mreo_vlRALHeaUIh4nKDAL~gD6Lyzl{5cH;ke~I%JzC{1V|Ad~E{*d~GN2_O +;ySPUCCa`qnAFw(q}nW?$P)7oFm3>nC5^Aqmsh_W8f0K)U8H1AJ|-y4du!{Tol!mh>0Q{>y*zwLQsSm +1gD8u1-~t|AA&BHlUB8yZrk%VMa^P*@*R+zN%^cGctWu`HV0e_DE66R~2Ve1W5~vOy#BNhNL5|qax{u +3&`WtKKnBTz^?vt%9oYqc+*8R$06FEQyJPNfBp|XtdsIRe%7hv%IZ%kxX}>w@y2!bMR_tyYXCJkO?)e +++mTH#eUpwLLg`snJr+b85WeTaVi-5(DEEV{$aN(O=alTidP`->T1A0J&03OUFe3i7jCl>yd9stj&jXr +^*aWeB2CNoM3)`Yo>o{e*fP5t~Uc1UH{(%FlPGE4fX$C0At}(94!j)sP%LKjAMYL4-8;z{f_~RpFJs@ +F@Ul4gaF2ACk8OKU3%I8#wq`Q3t;U0mGJ*|0OK_XO6|&FsQ|{`{XYv}B=o@m#@3Sq7^m<6#wh~=7^hG +Gw9qiu;C&OJ!z7X7v!3RElWo{hxF1eTD%+?fu^6`~JTMAJ4hlx#!&V+&%7bJO{A1=> +f(%1Nk2wU~Ka^Dy8cgot6$Te!UXiOPt+rIKUYHljB_7fBFF9ux&Rvz?i-5W(OFrZvE2-7)!(c!~w>-t +xXOv*6T{GH#xw#W9w}kU^HxP`2b@=L6ZZF{3sr(*p3s78`CI-j*gvR9Ez*yI70_rkO#Cn4YxYb_|TGD +A7~uK4m1vQI?!0o4>XqMkI1yOg|3sGXRMjeHdq`|*JN`TnTvd=(J%iYJky8+6@I31EI-qT_Cp- +@7gaR_#gWF|;z(mRaip=MIMUco9BFJLjx^$ajuwtI{?fkXBaK7wB;M^EY4oUf>EmZQ46*fZiQ#XT+S*7%%y?F>lbC`{s!*tVh8o*Bowu_*N30 +mh3u-T*`KkB6YO`yGcGYw=0177jJy_$}(jecZPiXH`DM2R7@Ta*RwK=i{t-(W8Nu89Fi4jSw8QZ}j>CTbF2Yti{J9)ZO|thW~A!OIC#$bMiiYH|rYR5p542*7TTn|aon_b +o6pS+$l+e3&sqS~rcDhsP)YTHW_9l@p3Plzqhp*wH5M~1H~-W8;`*KAd=3V2Y5Ps2-(y}>knec2+lwr +qSGt!m>=UFp3(#?pJ;(tdwaUp8u>9p_fAEpzM6?oGq{yMKpf8kOHIxM6dd+wc;0X(BxU4lSM;lkW%S` +)a1?%hu=dhwAeALv_81<)N6F?WFwGZg9i-#zg9$981W@M8W43M)H9g&exPEXaz(Xz0-1WnJ#!bbbDry +Z(;EC+P(iuo;azk{H~+`6RXx^PXT|{mTt%8Bv +7qv`)WtyJ7W{NLOQ&lEsN0V! +Jexz*dGox*uN8VFRa8#&m3mwk>neL+phrSse`_76HfdStEb++3ipcDX7VE@-Ct&V0bbxI8Zd>TyMD7A +JdVM^QkOdF4H{LM`|1+Xc(lP?TDbt@aNn>T13k*Z+TGVL=UPN~9p&5kc?|z}k+O4%%ChkqY2DL~<$A{ +%ZC2M~@Ei@kQFu&x7u3qakO%SQc03Love$j~OZ*rO^*<3qNd7`7Jk}}B`>AT<3jerfYroe$%Hi`R@L7 +AJ@QPn?Z?84jcWXbv2!}`U5v~5(kpwcxQE4nK1y`~z5Un01@>aVCO0>1gg3QE;Iqk1iQ92D`GTo*tdFiVOv}?~RG +@8wYh`rRymL4*jS93KF%(uP6I@Rl!p_+~hIA`9zm5(5)0Ea;h3DO@oeIylwR+Pdw$2}O(LUy)eauDs7 +)3LNeFn)5%&NziE$nw;OBVuMtWP)Z*`~TrJIKI>W9QSs$%*+7D@lb~`V? +SemTimoM8dgIYtSiUVvPm!!sPwd~Jht%DwR>s35hSREbf#-9Y+tid%u-7~Cf#uLF%US_l2=V@L~_h~m +VFAF+D{zSuQOKY!`ly#QTNy%LF2eI@o;F`$Wr(iC`ftOY_<4R<&9(j!cJa8X_zHk}_ZL +d>88Y@*_EvUo>aeu=c{~ag>sIRi_vi6lY-OqY8w~L&b$HEbSy3SNndoC}fAF!l_G_rjq +y)KEqDXBoJSvN{6*H!^>vxYbk$`9SHK3q{q2ksX(&4#6^mv->z>ppXzmj3O<0?b<2uQs1TKn#1+mMWG +ILPjU7Wm +8K;Z4lW+&%QD;Lb;IhhDrmdu?U*gdOMafXtsxQIgCG>h>G=Dink=moG5V1^TkKIjBxWZ?|UY?S(S)DT +PtQHcM}}bME(BI~ESd*E}{_*eO7yAZ=uG@AiPEKAv*&(UYiKKD5c33jGD(DWM^UJcMncsPH8dxNTc1?7=6q +-2(R?FACLxK!{gq^tlbS@c$*E;MgY6Ol)ePd=v6`88^Hz=JDuK=6XzKZ?PkrGtjmlArPUhX&}G_5Z!` +B*Xsiw6CnP64iwaE{I}fY3`^Q3KBu(eXO}U2w&p7ELek+^~p2}w!QHR%vMIP+^FD-EN{^7VxqPJgBZT +wYLT+E8u0qIRVf?76U=EJPT?6I1kv>A$Hr}8)14fZ(aa)j-*!5dS=ZR&VV*6B9&1lOR`wXR0{SK4Kg0=KdZw?j&dd$-jrmIo0C+iinb6=^3ofedP{NgXu(NUPmZ|cqcS8a~`SFWjrzxTiKoKW8G&E?+O5sDyD_Z=jP_I=B`(i*ZW4x0u~_pQi +${X{9h;_He;K-uMvC#>3LZP+5hAZg^G}-;ry^ffIi;l&|sG+j{2lmUzEHKfJBaDt4-3XA6C^{AL6@tx +zY9fcv-PHTpRuC!Z5sQ1OzDlQuS1Y(Y|+!C!bso +Wjms%|7#IEAZWAg^>Yf?P0-PGmfpIkxeBYs&Mc4#RnZ-+A|=!bwYvuAv80${`R45#I7OY#g{>Ct;yZ0 +P58ARx_<}NjpdqfBv0>M{QU9(H{E#Vbp00hh65njyUy~25Lz6LrwBlL5unpyI!Z +bo)!ym61yk%RZyamr{z*!$ubFm~HvNI`Tv6O7v)$%i=uMp#NpE$3t!ksVzgD#o@2`Cdms|d=_t(bq`) +h}5RU4fyui-*2;~I^`qhqgVZB%v&crohX~8NeiytnP*M&Fnb>WwnI%fC6m&yyQ>scXP>r_Z*d7*T1 +`B--k#;G=jYVF73>{sIK2XKBGms!)|ihouW_3&bAs}+TZY1xFkbY=JTz#W;!(ztwlV4%U1U9`SCO&hi +oGJn25C?B)++)lN@sI0zWnRUC~bsz3015Z!_eH7a5HEwu(D;;XDQdM*w3EKC^p%xY|R#p={IcyN-R|G +5|wQr`X=wTPW;yRJ7xU +QC0Tye9T4hn#7+W>3^hEEO7R2AQgOT6{FVpK(g+}X0;S*5D5-VKkbE)1UKSVpPwcXwPhYb?d`19>o9U +ak#i6fv-OZb#KNqASZe@r(`%yABs^b@qnZl{(e7s5tviY!Vt@aqF5hpD*0bt>P;T_J*1yY=kcDVvDY> +ao*nzhrZ5W@3x7r-8MMljw||3RWyY!-a`K4vSklO4OdWC;Io6esE(>4HO2R!+ClSME~WgzmrOwW*3&( +FkC`r-F8r+Kr|V54gfj5 +TDtaVE(jjPg^-CGrBzgDvd#}jcSjC`DH?dG`z&*J0KM`0x{1y|YYa9$r5f3@3CH^fa}`kFQJVld9svp +~_?7w_Gi!3zvqDP)VnyTD>|j<99(GYw|Yq;X;RO$=!hPWVW`<~(jFz6iw2w12PFLy~gIF;$P-F!D@X_ +t{zNLyx5ChO2SqxWc8F;>z((Jc5!C( +zZ!mLOKd!bqZoVCk<<`eihX$k<$YR7gAzy+U#4o}1XLe4P;5K@6UPwNt1oCVl`E2urWKV73*-O#aRTH +n{IVdwY~C_MXuPM(}Pg*btPdn7o +j@XeA9H%HMY@O##_zbAP=J(wA*l9ST(T$scEC>;y#Tl$xoFyR+3dk>DRc@e+jog>T6wfcFM2Ay_CzZ! +{v#i+Io#IDOXVcHDPSwvz)IdCzR;yM{qeAtU%w{qqiT|u}3MYwDzlFIk`)mSS#L=i?fBZ7=dZ!Y^|8p +049OFpj^g04RiLy+NGGNXtt_+PF_{MaF7)yY?s`5TZpY<%}-ZwQFoWZs@fDLs{X8+E8Nn>+F_GMwk*s +0mMtxN;%YLp*72uGt-*P5VV87ammq|^plsjA)`dTlUgbC9ZgMOr&vIH&{^}BoMrrK=|GU}znWxR+tUG +6+)A1VG;-78M!_mbldix(*d|5QEoHsni;AGJdfgTO2!EYCMql(u=Ee^p&#XQ_R%(qiZXX`<6aJ`20se +Z{8#&+!h1_}@0W$h#+T{{;3SJcK}` +g=h0Tv+K+8=)(mR)Sn+I)H9}x%i?b3t1 +ZE5m5m{ow)gqmC(EA^9{C+7u#+!PGPJ9pASa2J-!V1%wP}e4)}2y(*J|qxak8FH`0yu`dp!cZIJK(A+kJijzkzD%kLPNd+@p* +yA>(9)p0Cfdd}I=jC~Zk%Afs06X~?=>U4aT@Xss)a6^V4ci1&`E=%4!U?8!;Pn4g*P&>g6@AQ5^Ry$781r4hz5_s+oh_ +%L8})64dOTcnrl1NE0`jrKE;jcx|W>Fv^JqieN&@AhhUooh9_9jO-YZk&m<@V)Ivp{K$t&UMj0sEYCJ +CAzl;Pcd)7wx=w9pHz)IoN!K(-N34!gKH@3a6O~ct*X#{0bm+~-KR=lu$?E&_T0{UVsJx5_?{R~ufk* +>s1_A78HL)hg@6&>ckUItm8tqfPaQ0E7FV$8X@ +mX5C&Z`b>8`wLw+Bze?QF{U+>t2I596Hl0*B4yDy(*TEm{z9>aPv|H=)7Vecd$bPHqPk_YS71~7?wUh +JU*jpr>7Agx;5I3UTU-o0HZ;Tb^&OoLAy|V0T=D7(OyD(&KTW?wsl7K3ho<*0tsU<6g03$I17x|uI^21kdaNXBDgYZj6${(YM57V~+)3*-oB(%d!Fi +2=ujdmx|t_t{KIfU6aNsac5GoC@1&AvCwpDowL9s6lGJA|iL`RsGD!QOz66|<>l8=rc{S!b6Xz7Z8Q% +Lre&axL_v2L2w~Jb$S?r}3O|P!4;rELCrxhK~?eOA*C<7Ft{Qupdzsl(6~CdGUDky**xD +*_Ivc#U<`-5Jno2BhLa$g8*>*|TvA-l7Iok*V2 +S^E5D*v|;n&dvVJI!6;Nk{>+>{0WQQ|fC0r +E{qVhs)QsV%M_DA@^jU5P^aF{?47aVW=C_M*mc +!xL!k8>YobKqM0Wv#tV8d=Ea!9#H#TwAozwX3Z=2x&!xAa6R}B)u&IMm`my$li)B~$gdiz)Uu#>0{tiWkX>R%O +vvs+k$%4R?#voFrRm-@TnnKhsSX**b2k?D9Ww=fg$MQrs7>Lk{KZNZrxi1ceV9zB9lwKO07D$dE`F124uhD>}`+TG?Yb5ZNzdNz7*_QGls&ar>t%Ppb0MUU!g&v;I*nbQDwg*)@s*r?s-i +atn`Ek%RQZ^;_f}&QY3rlfI89wPW?LHW=401tVeN0y@ToTLs5PrLCaBrw&9vwPxgl(aqvUlrQ+(S%3# ++ajg+BE5LL8#2Hn=Hk``gF+K?|ngO%}V<4O%cYpDo$gmaUXQK&u=4e`BQlz9F{4DBp!O@gsiYj@M?E4 +2fW@cOQN~WRBI3A2HwJPe_cmOz$Ffm`f?U%2nE(E$-T4&%8^MGaBDNPj?!km>9_J +)n-qS)VzUYDp}I9M$q22!71g0=;OH^)3gO=NL@nNbEpky_qd|14f=Kni)9 +KTQ{$e+X-?OBCF06B65c +Xv?#lm0kLlEg(7^{8QQs^d2#tBNZY--laL$5b0GU4+{2VwpI;%s4=;2Sp0n==uHhWm**s73RC*402(0 +orJIF;=LGUFc8G9@2$Nam6h!35Ot#C;(M>X?xu$M1<}&jLq_3oDFl#mGi_SiuS +YgO2EMoc$2=tL$FJ;7&L(Tqj?opxuPr#T7SLhuIU%xEh8NlF`4a9&=+8lX2--I~?J)cuNpF=zY2)zJg +9L&c$=N;QCATOz@e||J|WBMDLqFR2JGx??@;n`<`n;cI+K+z==;7?{$^spXj(eyPYimPBpvd3iO9;XK +qTZj>Y!)j=1X>@4d3enQ^6(U21(8AJD+bYaE8MscTg8YTJq>@^mH+BqjA90tslZgTZHA!ElVz<}SHT! +2Kr^8!diIfZk#cGzLn2#39LSWX%=yZ%{bxP&ms>YI(-#-W%SzHKR7kbb~~L9gjUonumc}QSc^K>Q)C= +ux1dPbr3EFwJUJM +*bu0$!Sa`EKcHeZljuE>p9dBx>Nx-+At`yhX+CX)&o82zmYlh^98q(z$D}hi^u#SA#9_vW8s3Ul}P4`lUJP!nh`juVqlkoKw!h~n9={qL#Y5#(JlN9{;ISmZzKh+jp5R&`EqVy=k3J;V8T +(=ODuXC7%J!_W^Ecu>*H9~Q$L100Z)lH~_ctjBSH?q5?S*_NnD2S$-@|#qEDA2?ZIKZ(nD%5KR~$)}PH-e$I>?bIX$MEl(q@k2N$LJbI_$Jo(avbZDq~kcIk`%>pyslE}&vBebmoyy5mQ3 +>FxP-Wp<8_E%H88vZ@j8y9z9F6ExDxS`9A_IAD>;ta8>I@4<7PDSSi2HE-UBn5;Q9Y0@= +y}>AE^!b%HR5k^Tta*;$LkP(lH(1Cmv9^xf~AEVS0ZlaxEk?Pjt3w< +ljCdywvpqZh{td|9PvnwMGd00FMi~$D?C;lL9stZnKTsgn~^vw| +Se}goDj}+~zrM69qO?xlJjzi2<80Du8d|vIDoQi*rhMdEF&IzPLnZ|5k55ptqlr>R>2ipArD7R{f5ppxs;Vb=)E{K0w2F +aAJk8-w|VND@|vvY+|80g4XX)SOZHRR@U!OtBTlE6CSxcb6sERS~?}b9vc8|h1KT^_qmkD2E5K5oF61 +T!Lo=wQg3Z16>}4NpxztCq<8IO10uG`{_cFgF7gt?FF1o;TZl%-XZP{dtM=(t`$2K!v9~%tMW$^$lNvJtW$n(h3j~22n +}OF;PJld%m-Fn~W*K$VDWi5X-U=mUV}{N1#r%S76WO)B)<^G@>bIX)B^Zp)E9m*;D*P8p_!|jOm9F+; +FHPcZ^B5f;ihZHP#X9%L?`AW=dif2^wgq?dK|k)Iy?ou;hWd~5Ao2y=>`8Vl6q5i&BLL%&x!Oikmk`7ihjZoew1W%rhTE5G)gh7eWd+3-av6 +eQ|*?p7V4V07{$Ih+H3xd5k;sbnk}K%xW<**uusL5w8ML3JVv3B7P@CJmlOz>K^_wRa=_jTQbVSX{!-!pIn3Q8;?zKFHbx)aH4twOix +u6>@R#Wb!6^;|7Xy=$Q_TX~TxLd}4**@xJIaOJSy)Uquth&PAi0Lo%Vhq!WGO6WIh_VD*)T0Lz>f)d) +{sy#2y8QfT3?oWSQ6$qcydn9lonGeoAHPxXb#IA3**JoB&3e3p&hZVtMftih-%U>G9t(7)iu|!STzE?7u++o4_3tPj&C@O1A&1P +9oPI4yklIRm41snZb2_gw1OF|CR!NvR7V@}K&$b{^#7Ui(=?`3mi{Ttq>$-1)>BOD9 +9B+3S$mt#`X+1%OpY|?rKI)x8t#;Tx6d#7;AIr^G>e(7E%F=glz+ERKL!4u3qEAZxh>?VOuwKbn +DAk6u~93aeUVGb1L3W=LL3v;3{caiD+$jw1={KDK#nDxTkU5@VuZq~^033Cr&)|}<$JUKmtd4U|?cij +At%%3n{73NLCOoe%sFek9OZ((`~>Km9B(^(%Uw|cQ84E{8b(@ix>BVe;3B$g7+g_l#l4P<|ycSBwy^| +{Pvme4mi1*G=?D*^N2|2tW@=CQ;%YIzSvKd}k55svfu??Y2c0ayK>KuDp$MH@Cq%${K(91xpKyiXVBjq;#2mdD)7`%2z)A#FI}w{kK)mJp0`0HP6 +4W_QjW8UiZqYudRRmjW^$V`<=hP``-H>eE89Zjhi-a`S_E6Y~5C|eaFsSyZ7wfxBtMw%0q{bR2@Bb{K +Ti9eSY$bQ(vC`>g#W+zdiHa+3$b&QL6c=_T10EoUi-!x8E;ZtiRN7`N|(xuU)4^;o|D%-o``e>E-Ryw +w+4t+rERJf5%P%ft|Yqb?w$&)1zmv;E>*ZLi_d$>px)Npzy&%A|i+0F)V8Mi0F}{?i?MHGJ8&{DQ#|g +#{CauW@YD?AGG9JZS&^mEqLgjS@+(Tl-#=e!wVNJUh?0T|Gypo|2X}%V`6o2W5?+Y@#BpN6DB53nmlF +dwCOWu-gP%m|JL3ASEN6#2YEZyhpu3Db22~O%v=U$XI)}NGxKB3%;n9@E1Q`gZ)Sd?nfXJPrsj{DnQ> +VYb?OTEa5-q4NuFz*k&&I6Gk=OT#hQ_mjrP-WO_qtX?>Eh{8nV-JELqH9hM)uP#*|#Ec8)b;o+&ZMY% +@FTxg94*5`c2bT+^7GJRWiynF2cBWHy5|kmx|mG!o}uoBaGo@(c1op>usC|B>en~!rBB0i#r>85G9(iW-e6#rmeNGR5BS5o6-7=TW)bd}d`0Gz_ +?v4Lx95xHYA7S=`nEfDO17icQ!=F|_{OQ1)y2Xb2srZ6WkeSQw~;ruri{LW@`fsJ}Tr<1}oZrPU0Bl9owEAuJyCG#Wm!Q)%t;6s +jIj#rKc>7=lk7z-PhH}Wx-ao=c%Gj!-Hx0$~gY-E|uX6l?>rh;#0y973tZuBvQ@#$<%VRG?!<@jX!GC +i4&93IM*eneK*h+Id3N`+s4O#=Khh%A5~Pyd8Lsi}jwArXp;RumbXX^tstw#iW-CgjX(VxBn1nuEqEC +bLy`(AwtOa)H@+TPC9yZ_8#GuQgjTFb@(^EOQ+BY?^JcrC1yZ7N3&Mj1Vuzh4hg&(nNYl3&JlzT1W@O +V;C|e#cH#prZ75VEg1rXbV;{aavdf}FH>r^$;o1>jhhm3vYF)+n}8`+q=Vrx4EjSq=+46ZyStlPboXp +!W&(V;eiMu`r&v=mH71KC$D+x|)?}vGvgf3mEF&}_xomK3VWk@VWn`LCHP#$Wj@gv0G3A-&*sLkDGv% +5&EgKE!o(2u2CM8>wVg`??5C(G%8qk5w{8>yXshTuPP8NjVWO~Vy2biBZvwA3Nt2T%hv4)EvN^@Zb}lZ@3>_5@$x{@qOwB-QfkcLj#c~fFo?w!c+@bfdQ>6nzc))b4A^=*=EOdlqt@Y90)GXK1sI@7u#y;4m +qiJkq3Y?(H7?0~42)3;BrKAIFE1?En(7;g06qYucKnVB=6<#(?evZ0lHY&}g{$#=_KTb3!?nyU#l&4Z +ekk)|J&_e}n +HsIlP~e_@%-()dTo%gZ!I){n~Il2#aPp?0X@gCx9=}EjMw{iHfLethEl# +s(;aH#NcAwCLUqR{vdO{y=^OjQ$2WILj<1l4t}4yfu_;b&F^`H-Mg6$zT!js!&lJ~^PSW3^vZ`wHM!) +rP1bO;sSfYH}klk3%c*{vblm30?vRLi(icf;8Gmx+=Dkb`?Hm??li|77Xtv(PQ%4D +P$mc=@xESLX&S_lJQnBe!<7(yNe^F6|>@K+LlD}1RQ#2@1JAL3i#d!wDBe9w&~CZ25I3ZE;8 +aI_s8DoLl1{*Xr>Ov;Y;_va!R)BFUA#yas~XZx1!>lfba|YmSfV1piv&PD4w&jq0zj64$vh<$L7pV&C +6KGyw@Ovf*6fq)9qtAB?Td84e;26tU50e3<7ujLq*ecEgxm+;lQOUBHbiapAZn0FJ;bL%;psv=hq#9; +0+bLhe31SD;1)2%&&<*Q=z{FkyhZU!mg!!D0mGowM!LSfZHO=M>pP^WzsI00{s6wmz7+AZJoSb=^iZSrLE#jF5_(J#&$?YnukI9wieN7i92rQ0f9qTqP~EZ0ucE!#H(8y?dG#V*md3VV(L>Po!Pj1vm6eOOP%fZsP8 +DU-;$P7`&S#*GtXafygub1;pxm^BGSilHn%tpIPJP+`;3b4?gYTX%oy)&dTReo90@?pd`Glkw5VAn#3 ++rq*s8f%7S9?}@RJfbnl3f#B!m+OE(d`az5)%2KYltGvwP_E)>$9c{#Cemlk?|NI&pmeQvJqWQ$ddBL +vJn{WO}a;>lJ1JTNlWqWbGdoEM^_W#zNRtWz(Jm*oAo2oE%igvE%F1>P4O;K3tDDqBY7TrILaH+cxNr +pc#)9xa#~@ZXK@J+?5>15qb6!gBUeZ#N>2Zq^oM@0KwtApBTZk?-^%VwUMJ)!_;$+a&_hYuPgRlj&@Q +yMu$Da;;|iDCja|@YSfR~GZ433@2ip$OZomiaPXNRZ^_R69JWXGPG+o_dnpU}qItlgO(f%`eKn`gC0# +hCBakb3v;!mJ&gzxJn<*yz1g|ZI(KpC%gZhzPOgOFYDT^9azfPcRgHrXe!N +jqVIcA{n7pbm8dg}V!Jk5mvvdpAh4wxs>z-iZoN1@RP$6zlieV?Wh4uDi88q?<3)Ej8&7+wO6%I%Rd6 +Dz^$3ksf+S8|4detBLBEw;93>?JnBtPLL-ZBHCG+hYNRvQ$e_PMD;%K+|Grx8{!qN@N&U27OrTI`RWB +c0vy8gRne@ElhdO)WHKz3<7mvQ!2T|zv!ayq0C^c00{x6N68MZDofP3j)(P-{qoTVH>2CEU-BZ<2CRC +(*W8a<_IHWDnSZ$!QSV3n2tvAv_G>UA(wJ%O1*;ViXZC9R8C0;_3i&WwyyQ*3&Qg*+uBa`*%N_yMFn#hR*z6v0_ +3rHfb@h{Gu|=)W<2oP^;1EaV)~iK!x!2s)X>X6EF|rtxu;C&U>eh73&2%!E<8Vv5xQ{|qzmAgpnQHqp +QwK6lZZQp{s5CW!es!?ieYC%=)nY^%uxblJDo9{8kaZ6WJYR`#8#Z1{QxCz)!D_>kgGGzw#}VuvLsqextO)R-6mTzr)OBKwv^0i+ +4D29L3i$scE+5X2W;lCF!)CbAR10W1fWZ7irH$jU@5Vh@~k8T?Re0*JW}go$Ob`EGBX}(F0wW|b&5G7 +J2uA#@%{p-g)=~jIT@I0r`N +)@3Z8_-FLQGA^8D9gGftl!^7i{u6ueFIL3(Jb^IXt;Qq-Rm0sTp$~5b3w~#?}Ui<+F5LkZUz%P0awAb +6E-lMjjKj8!cuKt*bF71xo&GONwOy$a9M2?_?8aV=b>8yjFwu@V=875*1SXUf|i5n~ucB*wWIVn1Bwz +d?jM`k!-}Z81_!&XkuIf;yzF-AdNCoS^JeT*F>Jg6mn``QqUZiojNg%=j6-!1gb{ +M+Ud^$z6O=l;;~jW%eRCBM_pspJXnYC{PZZ-DE4Xh259{N;5v72h0(uEIZzs2oA}m6cpsN;kxKF#i_| +U$GupcVST49bA=0p)@vap{b;0!_kE)jR8u+Jj6bCIyU3AjhwB6w{h{O1dv3j|y$+zW+!k)VV3RpXB1= +Y{!2!OuDo-)q8tqu}qbaQ|Gm2YB$bkkgEcU;d3pC;p|s=56h*+TMS)|34f4-%bC|hX3pLfAe>%{jo01 +ey-vthhOyzKQ~b#AgSZfn{;Ck@C{pC|HYg(aSaGk>#0YA +D;|5^bzfd3;eoqee@`Tiy8rF&YZzxYLlO#+2;(y9ASX-Lwk`%ewI(f{$2UsqoyWbk4h@;bD~u}X70@hTrhw@JrV5xW;7kD%1=I@|C19w4K?14;^bt@gpqqe1z^i|7*dX8q0qX=jC!i$YSplmBJSpHl0 +Y4G&!#|qRe@no10G^0wxL=C19w4o^DNbCXKKU5Kt|kQa~cheMQJCV6}i%0#*pP +Uchnz^94*7Fj>Hv0wxNm7cfS^C;`I-3>8o#V1R&X0hIzaTo(KZSS4V^<)-xC73Q@9mJ66CV7h>b0!9h +gU%+4i)dETlB0d5CQ+nyTflcRi{qWka_{@WwhI12oojlhxP<%4|x*;5%js4 +faCE|BM(3N8UIj9hPHcx}=Vth%)ySKSn^4<0ipZbAsm$!mg0e%VJhk&03co+unb%0j^jP3w!j+cUr1e +gq8q>qBZ$^L|#06$X!eiZ=iCD>O3{3(F@!2{Rb;j2(6hz8&_ylNjO7dyikzca2ULA(IpgD)NEdA0;N)N^Z(u(a;9K|sj_|$^sMmle13U%aS-?*NoZg#|qBaUL6X4d~IO`330vr|!?H1r +s0OLbB|3-jM_a$U1*yCP_r^2AEMjW6G3P2vs?LBIHTHPXg>U82Smog8@z(%<0SoxEH?DV80LG4}- +Z};n2k<4&ib;KmW63;_In1 +ov|R;GR*S4}hP20LR`5eIwv{fCmL$32@SAj!y-69lo`AKYt7%3u1VATL^Gp45x|kLoJw*AAq_sVDGMA +@ZcC;2F?OJ0E$Ww*jEBn>$ofk>)~4n_6-1I#sdF1(Kaq3 +WX>W{UjP;?;`T)VUxP0X{I3VNTi7=M?3WMiAkqQ2B%g=HgK^6WpnQV;a)2)vaR2K7o+{un)&X3#6!-@ +}2-g;YZV5QTkYY|J6yPO+`#l2m9})BcRy-o=8o(zW<@x?3zzZuN9icoRJpLHS4)_UxZi*8okhj{*3^8qsb5{Cy3N_X5ED=Xu#cXkH7t9Qa4r??q^@pnUcR_z8T$fF +m5d4)ij>BLTL573v+}egH?l%4uf4M#%T;xhxXE(XaD(V*q{xUmp111aRYVW&{hDB@R7YxegH24xN$F!cN4&}eZU* +omm}QA?GbwJ=Xe0X2jM%7egJ;GAD;_?bO889CGY_FTL8x#0{$SKbpT&F40=1@>j3sV0{s);$)84zSB-koSNG0bBrI5#Z$jV?KvG0z465r;|{=0S^cGJ$&mie*yOT0_4TG0FM2F^N +;5a@QlJP&`A*DKL2n?D};xIJ;HMWM~Hjg5l0v%aD-C?j(f`I2^`^*0!R3^z!B~fIPOW71de--aqlqV2 +yuTe@`G@Jut)fqz!9z&IKrI*NBFhC5ndKJLch}-$Gw-40{`px|MricX?JDogP@Y;wo_%0K~P!a7A-E3Uz&)hVT=hDb)s5 +!7E#Tj+(OkV%!On!sX8kq=x!Wl|$aA70Oa%rmoo_g}@i%bbKr(LJIM5eokc^BBVzb$JMu8%d58tX)tH +^7wy+$@~-b^YgD#+)be@?DnzfQ!`N23FqyG)Y&&?1&rS>D0$Qsxoe^-xO{sv6-=+5|GdUaX +l)yjILf#&OzXBoi5)l8rdX7^9_`}JL2c?3jA!}L*}e7m5-c|He#59lbb6%X+>RvrN#%Q3l>S6_d2a1{ +5z%ngT*tn2w!CG(3P*q_smqzw?9tyu&AhhLsr*>Lqpeg*S?gwku%wl!R3&gdV~w`O$%WzH=9k%YvZ(L +cK`{3Lf~^cip5nJ7!dk2{mA-7A(*|Ln8R$oJoW?-+g+5Vd- +@9+tNZpLP%Ix7zqy#C!5+&HrQfmrfnj+Q)Ui6I{sj39648_2T-v&qI)X0qq8@uceI2T15vO8W1hW +bhtJM(?6z=mAPb9;Rg0AxdITP%{1$C6m6PBp1GEXDGSnM@r^YQ!@J;B?Scqq_nh@tX#R0{OxalBhNhZ +3|YN;HCelMEqUdYS6KeO`|i8sqmMpfZP_QEd_s=ze3vZ!m6DI@DA~PxH`%{`KRI;h5IK7EC^>QB1UYr +;6#43_ugG~&JdgiI$+zEr%gRMfO%1tl{wMO?WlHMm>d2)_msnZBpUWWV9};1FfMZPABo$tt>%d_>xsH_&n-MmO=Q{5dIwqUjgBdLH +M&y;d?{)7zlqigttQY6%hV)2)_fuABFHIA^g`6{yPX?1L4m@_5CkGSy)g(gCK1k?KD+#T8kI;Ij@O}`!Cxj1&@OMJ^1PBkb>R{YY7eM%B5Pl7W|2u@=4&jeM +`0t&|=zIGJJ^GDPcnyTV1Hv02{A>uH2jN#h_;nEe0|>tr!taIf5a-I%5dM +1zU*`zlA1I6m3K>A*QK0Y&P}l_&z6A<(zLfknn34;VD5-ytl1nQox%?g_e;lQb@LeGM00=)C!cT_qb0 +GXY2wwu>pMmhNLii6M{0<0z1j3(&@U>3il_CZFA$%7I-vh$;hVcC%{GAYfCWLna +=waMAjc|`oh>eRM4dmluwWG&qllr5FkdU4|gu5XjMjNk<)x|=1+Ju)TKj*K<>_X4DP7`CJheyN&bEvI*cF1JcK +b1Jv10TR)?-ybocAfb-ZBB*bifX@JXY!2@~SuI9MBjNO8Srl@rC5=Q6BK;Ws!O;nj#0hcn2}}qUg +Pi`rf0Ax+46+apG&+wR+o3}T@ZfMyx}!}}%%C`kU;?;z8#|V<5ae)=Rk^F8+J(o(>k=T9$988zbR8>- +$LJAS?GRU$d-&+2gro#RoZ!-NQwWsMML`uwL?`wmagLOL3poRPkcIfMPMh}dXDQ)ga&fW8h2q9JbRh-S`C^dV^s+7Zp1Nq +o~^LNjMdE0#2<@<&&LB2n?L(dU-5@U^JR<&)9P^tqesDY8B{dGchYk1RHgbLbwg<=sh2GUCW8ODy?tX +&ia?*~MhoKF}$kozs6#$@DW^XUGHi^wUq1=bn3xtXZ>$y!hgaWZk-TOjr2egAbTKxMj;0rYn3}@fvv! +^o@5xSJ<^{7dd?RFw+grp81BHIdg`bJ$sha*4C19=gyJeem&20gNqk0l55wlk(HMyc@NA-|8Qz&2lar +CZWwfQP%q2pKu5O#I=aW8qkEP3(htdCx|K|#`^bazI9W+gllSQN(0|uCg@+C?5k~Z8=xodTL-;!&d<= +w-hw%46_y-~UqY!=#gnu8x?}zY>{oG%A%3pfQ|5ZIjzURAh=gvJ42C|F5I|qae8Z@XMVw%pK13LHU*I +nJNT{kFafjvV*Li&UZ@>Q$)wgq$N9=-bX0l&WL?t{Vxg^{41{Xz$I^%~?09@@2S+byU^Na!GMuh4G7L +Zb=oH%O`U3576y+qY}mIiOR&LEcKGm#4eCPhXX)vs;_a{knQ9z0hKiy1T!J!lUOP{B`woNBSKDTsnZs +yO)=zXBgD49wA*^gTNJnbOkfS9~R`-r&rjZL1B2a7R28#EG#%ItVbA=F9?3Pr>{p3W+Y2gxGqKb0RUI +h`sNFTlOObt8~eNS`5`>tp3J;xZraY?#!o(i(8lR=7qR{)e*esbH}Z>H{{6dm?~aLzA6^;P+tbq%S{C +-)C|(DTSI9$4!Hx~cDgLkexeB^Ix9K0#6}v|){+btFcwq+gJ0G7vfBuJGe);7`=zGrm{PWM>1N`Q~g$ +w6lTzdBO>C^A+-MiPWP$pwQ2LB}q~Z$olQEW5=G~zJ2?WF=NKy&IZgU +JTlUW@FN|_3+Ahr_z;(mu;5XVuIM)_D=VU*q2UU_X7Kj;4}|nS0(CGFX$%`StT*xpd@=qH95_HXZ{AF +SKe}ntCdT*o-+xbk_~8dyRaHfg9zDwZVHnU6(EcohdEveH-dnVBNIYPhq;tR$n

h@gZeoFmNV%R~`au&PHOBcs0OVyd~@32wdW?7JP%p&bX_daSo-)!!#rVrJ1O}ZzqcZ`k8={tGpr@&s^-Pg2-?S?T|g;SvI>ob2{e!n{%(Nw9fv({g!k7p+m>ohkBe5p7G^CuUp4 +oiaM?*N&c7{exRtW0ZgOYELNRsV!COOx4w_+PFZZl@&uP; +(RBIiFzkDRsvuk(&o@%5zTp1g$tZjkY>Iv4)*Q+q4o(COp_U05ffDa8yjwlRR2*M`l_mD0YJ4Al%5{Bz>spD)qRurRIqzS9>$|+|e$Lw# +X!^OVB}X~*s2_3OCs4Kb$EbK8A&IVYOFt_0sq<$F{e`MHM(D_>pAY?58D`j0*uV5@u9{r9}N5A78{%?(2Zq` +MOH*B7v(|c5!mVAk!q1mwGnCbYrCFg{O^yvi2)dtNDP_`8c=)r78Krd#ujw?>k>5HlVcxzm7I*VFDb{ +3_p32)-QRJeQ8gpf_AUtANY`TN6P7gcO2`^fGiRsd=YrZXRQuI$4q8S@4bC{Vo`Q=qDJaDH`%Ylv4!M +scM@jjzM|j&kCU&V4T`FjJ@?R9g*O<*M>QL+Rg`nDACP|FIIhomo|KXM1MvXV@||uwvZKOniAPRMQkM +tY=~x9^>Ra!-u-D4}9X?~sJBV~K`w?_?x6y7a +-aPh#{tg*01Q@&&6+tat?4I!yaL;cBlt64d6A{_WoZa;Zjc6}^9 +gAPbv_^s;m!(S@N!rC0 +=C#u7gn5ND*NXA7G}psylV-?}GfSFrErN4~Gz+B{Nzx1z8BVh_L!pK!%D$N^UUM0;NVJ? ++s^kB{+X~uzFXO1-Ez^gMwnvcOeMVi;aY?WrL2RKJba}~_t((Ht}w=~zn93sv2F#Ah078;#Qn)NXMk} +UZQvs0QwVE$N|#RtI0q&XDkz0!=^qn%r&ISS?%r5V>+JJ(4wPSZHoNHeatb}p0V=`b&l<`kIor8x`cb +ZN%nH|KO|E`m8hnu}qMk>+JEM@sW5m_wy`EzDh{c^%Aw(!2p?FKONgbNwx{EMWfj7V%l3_|6L>pUj53 +-r5=+Frtv!esAY~5d$~L1`L)io1{x1x%81PPf3^Q(!1v@MW+x3(pO0#+4>fKz2 +uBe}dUU1Ft6D7hS#E<>bCIJxYWF5RU|6uE4bE&;28dkNOP6Ztl0`1BNS61u$;akX@Oe5R`1dnT!1tJ`ZdYd|VV6I~T0WCryVY905a0K1zX +eMl`>f>_y<=ud1W$DQXmQk+Ph~Vb8DMt26X)1v;%~-8LAx8Tw9xpm78fSsl-zE9FnUkLbln0E$4Rpzq +sVc_Qg+JjV|D1vjufvmkBKf{+$PuggvoIjH;R;ep_lio?dHL2yJ5!YREJROsKDa3)=JINhO){{`vkFjW@kNY#2gXGooHtA(+S +lr0l%V~VdPO@%rs=5Q78vQqmAs*;&qtU-75OXbT;^n$yQ*Lt|Jn-#~b9xkKl*5vbU0b0H{D`=im +L@-#l8a@0e2Y>OppFY<337;)Ja_<=F3lV&uB%-#0(siKogdvqh*V5yaCnm(umzB)w?@3}TsBn6Y&l>-WTJhJv2w9$zGP4?4_vD67C+(k8|7{80RPqiF16J+_a9xppJz%sbe?Xtkp5*uxH^Ec6B +1|WI9(?XKzK-#gXrIW@bLIpK3_w6G8&1qM(l0I-`zMsX77$k&9-#3V(4zbk)4+R4;nF>cxuco^KoL#X|yfXfmcdxggTM9)g+{aExAACikY<2WKT;wyMYTNv1uRF#mW!f< +r>hc9avKlli(L_FLsPVK68cPxt8wC94);?iW1%P>$BOLoSP}X-j~+o(PRqqy`jE}Dq&1I|_Xy4ncCN^ +6nCge*ij|CXt7B@6m@AYll_!i$m@F8|a1@$`>rvY{6K7TC#zUn*TQph$VtNksCO(*R56{(3_&CGJi1E +Fn=?LGY@+3u^ZKRaKaS?cb=h-=&S0wi&gzlb$PdgUY8%i^poFk%I$(OYfXPyptiZu|*!cZD4g1Jr;Re +R$&OhzcRqt|)SY$R0b>k)@qX*Lq29Znb5O5uJA9;}!0(ynA-C{Y|CuD|%m_GGzd&0{?Hz7TBh++ir|E +Zi@l-H-U?963j=fe-=vb0qPG()AY`W41;p_xv_W9*K1h)U>mT>6`Fy1kAV%{5gBk?(cj^oP7z1moA)U +j+oii^pVlkSz>Hhse|m*9R(TxGHfx61@)*#>**od!kXFfxz+Ke)$yTo6io{qlS8Q6sN22N-qC5xajkM +)7h;qr^Dxk^+Z|&IaNdyPy1ct8g4gZV**ccrsju4|Xebq8hGUptT(p*ZmQN0G#Du5$W4&d& +w1d)Y0tNNAZupD{iNnR`RBiP^caSIk?Dey-F@#v~`0%4r<{mf^S +wx7N@j1w-!`gzwx1uCt12b`{c^9Gj9;~NCDQj_v-|CzsvXB1FP__d{It*L(x)y0#Tn`M7OWPIaIO#Y? +W1X@?i~MlWB=q*;3<9>1umP7sJ)K$haL@qtf!T2o%0hnbz}ThN5?nf84m+OUcoQl)J1^IbTi(9)$ldl +EtbA8#rEQw^%q|?2uz$6xLETGyMf=v7OTOTS%q8dQ4fEcjP9fgWo`%W0?K|VPYwBSVJWp6lYPnFG8nH +XBY>(|gjltTP20$nIo`^~);apXE!q%^}&elsQgy{^0Fv@Hov!672mDbrE6hn*L4E{o^Xit#PK6BM_-A +FHA`_)n-E4kUfSE@qo-O=_Lq`$w?*!rWDlI~oIgjZ1@58E|Fk2RV?+-!B2XsB=Y)!P%q&F^Fkw2vlZ2 +#g{2K~Ufd1siWe52&V(^bsw7XH8}7_s~dMQv$2&b@&Ha4F|1;L(~Dv+*@4F0Md3@NDYMmTD!~QB0{Ld +ra|4u^;Bl@TA6*`q@a$w71Ta~TZvQOP+)U|P+nAQsn$e&uDg4AG>%U#o0X=^r(=LSH*oBmZ! +$Hy^?Y;uy0WQhweZ8!+BWGeyg9)$VW$xII%gY&aQt_M)v751!DDX$pmfdiF}8QYF(oLMO)j;$wyA-38 +zOyyr0Qvy=k!KBeOS%63BW5zcN-RSUAvNA7$)1&Zyc@=^Eg@+tWzIw9(s#Hkg{)@cN*#KiyLmOHRqCbO)m&8PJqe9sx +nmn~Xi1beW0i(AyBxcO66!`#!N6gsnj0FZB1h+=$iM7L?&7tQ=jBy_SvN@7P +obP8hQ#K_F!cIA16eiwlRT?0Oc*V%Y>{7On-%&T^TJWmAqB%t&tm{gAIwgb!f80#2b+Ca}r$a}T5WGIE +cjl&@{Um*k9MCo+==)m)fKgl9O5pdVZYQWz6qWuuUDSUy1`y?ONCPSgU=M3G|xnZTuV;g%`VoFl?!5k +-Y$N~QmWB9&Rhzxm{nPH7a7Z!VinwpgS3S8q$J)w(v=%c-ia@6)un5eTf@d`Usa!|I>tjhRV}Ox +!Fbf@HbMvc_LT%<ic69!r90|*+;<6mDWaH&r)2y95=uV;OU;GmfkggvOMPrN-tmUn#*tapU4kVoBk*B8| +KO{Uz8ZqolD^hD3)EM(OgZ^>SjZVT6&Rx0{>)@Y6dG3m=9KxC2c4}{33wp!ZTDf=pA4^eibvUgPWV@_%Br0glm-dRiUYiaMI<*)4BlzqCgch~a!O4^NDe#+iM*~3psdy +&QuWuLF*_ocMoq2Z_O7nJ>=vU6qMpzMjF?iYx03C0^JiyK5Ar?q;qER23eD(S`}$^yr#KWT(!K1NI$7jY9n3z`p+XD<0ZdP*Y8rlOMh0XF_-(5 +HuGy7Vu{;NcZEOq_)Fb>9#{C&;u`;_+5f-bxwK5P{<|eW*YLa2r;!Bc8h##E_-l}W|LX7e=*O=;{oHN +tepgJgqPwyEO6hH&yQvHAiD-C=mnz;h->Gj +V%``m`-|MtR*e}Cy88()6q)lIK$-m-Pu_SfI|=Z>9~yLRu{yKn!2gNNRH>+su0jvhOH;+=Qjd;f!z|N +8Kwk3aeJv#QU(`0~{0ufBFxe^c}Aci;a|`{PeP|MF|ynfkNm&R_WLB4;`ePcQFQKKjVbm>hYuMV5jkx5HBlo*MvodjW^7FAthDru%-LDlx89aB +CpRzu_JTs2eeS%X`FGqrW9BW%DJ}coxnSX<#sAav|4--tU*^AQT&&qL{#t8X{B;S5*H1{AIBD{fsW(i +Ue&bD&|1JCfui!uSd;Hw$LsznUx!E6RVy_^(-p#(UiT$1?_Ek;ntDD&GZDPN#iG7ntWBY4O?AT_+7`K +vMe>Zn4{YKIV2xFi^u~I0XboINMVU0-sj4qe?>c@opVBtPkxzHGz-0+wb#A6n-GP%x%8JG54PouE8&A +3lcYet&uWPJ;ptxNz6R#V$O~yUd;FAyV8kQ^FrndpD$MTa+Ez$j62h)Z3Oh@zSv8DDWja{JX +>gVFX!vXRYItgRY4~V($o%HJ@X+$t^40P|I;mpCpg_zY8}Jw}uy1g~N)kd9HVHRP%z$#mijup}6bkL` +mMG?Y4Iw5AJl*Z7f-ae_mY`JXsAJ$1#97R8^Bw2%(sBMzIKYO@!lr;2pO7i23F@g>V%Q0TG|zcSKuGu#}e*rhEoFIPBDwk +w!wLpq3$I0%O@@E7r}&CvD$re)`*=gpgJOSNT_Ke(-1kTU>5tUcnsUF-_%1{t2mtHdC4{d +u~QjUcNowWwBVi@eB*6_5l%$QAyK%^z54O@M%dtG~6_b=1QNEl|m0qQ1grE(NhTK!}NMRrtEs=qqS+Rii__ +mUQ$dMc-~cf*V5wl-rkf$Sy>r1)ZyX9NyW=3bZEb*q-n(zpE5~G!pUo6Xz{XQip40KtgI}(-lr%(e_n +q6CF%dWySv{RZipS2>*>WlO>e@-PK6sWbWnPZYPcH8X-f8-j6A!|q~to)mYQR<6cpqY7_)PY390tnw5 +$xweP=2E?3|2rqb<*vm!FYq%qYr8v)fW<=2O6Qii6rif-4GAJ9oA*Qy_AQe_@8r=H|@`ZRtctx;;N9J57ereB?v^M10Eu$Umc? +pk@CCI?{*`TZS=T)-I#H5NP!4Q`oNw-)3jnh;7+6V_IH%hA}Twiy_k+B-S7s`Ws78K2=B=Q*xBz&6$% +*CgLixAoBVRqH^d5Q(;!dtWSs(6gEDfLyE +f=)_nbdRM(I!w(?y7&p7l;KdA)t(ak`Uw%**U)Ckvz`8`XVOgdZl?)76GZ3NR>vyPE^)^ +SqsF)jTUdos3<-XkjgAc32Yz)cI2-G|yDdYxLB_N`d^bUo$kgM3}#D*7_^Xy1l#I$tm5OLP*x`OT$!C +pAxH{Tjlz4)A6HksVlou03l-eY_S9pGE7bfA%;cq0Zlf`Rjt1&gjpK=|RjmC6F13f5w6?wVkR$j$KvR +K3~_xU-ESd@imgnlNxv%WFX!XFAT&B!=wg$o*ly2{-HEJJ1X(%IH)!2n!cBHjoib!>UOX;mHzpDN%+W +-u_|xyo_LT>{GZaActPe#fnsE$^YLIlx<^Est~XfEf^GDs`>;l3mzK}d(fcc%8C^Uw~ +pl4^siJXYMm*baJ6D7tlB{8$%T2+3;)lGm$P7hPK><4{_V6H15VLzSv;imT4u%-GJG-O@q5AFArT&7X +Kcd?0*@{#uRiD7T(78Ox-%M#Zb1!PsK5cUH0=6x50ZQM{m`jr05L7MhPIGd5g>({=S{U5VFSiPv3;*I +kL%U59q8>TrzsE$W#c)iYmF&t!X`7cwWyh{}fAk&aV*2**~CjmnnlW+qMGKFn^Yo4VeH@-AGo@5-#D@xh&peMj%BTH7$V +HS1=3jde@k#JWYk%DU+`vOv`~7DPD;+fdpSOlRG7H?hV&h@|D9$K~ +a3^#jy@JkTJ29f$j|K9RS3_R(c}HkY2U^X1cf?{S(lJ>iyK4?Sx;#lYH9U2Iz*THq9<6Ry?Oy;M(aR8 +P|bsIK{=zRJF@fXY$SS$at>Lx_Jwuc)(<=4XlKN1LVjn3vYJ(@VT+PrO1uC*+yzuD)B85tR+K;T_XmG +F+w6vi%jtKBBi;t5ZVm+E7@MJ;Ie_uFAbm{_9oxw}~;YV={a(*?YW3vU}|Eb@Cq+=I7Vk>ZGVc4S2Rt +M{7kL_4Z)ikvgVp>qR^cU~TX9OA_s5TS}*m2WvCbH@xG(084jUTjFsLwU>dcU2L0seQWhqt&VwBdMKV +*UHJx4zJbhe!Y`lV4ePGj(hgL9?IPL~G>sSTif5pBZJ6N|!Z(=uLP{g}l{WbSDgH^i);iW2?RHzpf-m +7oaHy08U6b}gs|QV?plPX=muiy=2*;sb%&0489rHs(Jqf3>@7Ra>1Y0EG9Kky1!kO0RL!p4KyFcr03u +4{V14)Jqtb41mLxbBFch|We_pQ)fn_-KUQ@#Y6@l9ikye4P3uk*#{&5~<>EK4`OAR{9odsYF~GdHkU +v96&l8q(-oq-8HCpvkC~zTSIUYPM~BUcqFV1m|R^l;%*#+>8Q>9h;Y1n3t0gYb(gH(Bzfs;8o02SeQL +KSEVo|uK@w}6>momlSVL9U5;>GqtA@!2^U*Qd@QGT3vT6R{%HEG5~ViS`^@_PF`Bj4653veP +qSvr-G#{fZ)2I2zI3hO{T!(yhcFtU>8L)Ox2_2xBb4L#>;d($fnBHe);!@>0_kmnem3@Y9V3% +}3eMj8<nC!EBNm~Jx%#`{0h`FMPG?>_}GE8cL&7KcdPGd*Bv=yF)68OSvYHpUuKHXB3mXQx`Q&Avu +_A2Oa(c8l_uF#w@%RYN{MnMuW5F*gmYmzPJhHT0*HD_w>yzJa`l3KVWhBMK;z4ZZfK+i2cMY;6rRdwvE`GGdV*ALgz1o1s5!*)r6CU=P-F5jdZpHoO|y&*Nnp22R0ZL(&&5jIg&#o(Kpq`l=xYr^lO(h8!u9vlpzZ^6)`Ni=@T+#DNX +cf*t0=6#s+&P#3m97f^EdL2q_UN-)Zdshetb)IrOQ|20j$V*xNIWComgR{`M&I;cODZ5G8W0gHg#hIksCo4EjrGKN!J4d7X70yc(T&ny_ +lz*v82RetbUH-VTKdJCpukw3Nxo=VU9Z~)tDE|;2$qS8V?tE`r4wrlW>hOOw{=Yl@KN|o4*9VHG-0f@ +B_pN^w{J;ME-uYXPCXc6jwD{|OkbHRRNA>-LdWtXowCTU}Xk(YyChpRs}aHxKY6u72KfUdIi@h_^5(w6rzmJuFh +;>}1&s=ZDA-;>y@Iu872OK9_G;XwoK)_|6g;S4rGi@(+^FCN1=lLLOu-@rQxvo+7^R?5!4L%l71S%p6 +s)gTcq`~suu8#`3LaDNpn{bOZd7osg3A;vs&AZrmV(n2v?>^`pix1+hR+!ZPbv7Zf(I2`r{FRL|GV0d +l>Uw99sk?>f0q{#&Bxc;pYUH)x&A6)zREBB>dWW**FJ$QKGNUV;`85z;=lE2`ShRkZ~64#|192r<@5i +$3^aNEkBh{*fogrm!%Iv@*3-x*W$FB-J(T~mpGo-SGZHR&qDp*H8ndWazzr0B*V7+9ZEPX^B^M=(QSh +}Z3~y3!Glf6;)TyUBvC~gEpSro_^cOuTOcQB>I`P9>J~XoA4{!Z&=%wM`Ir%A#0oag5GUhQgE~-@Uq8 +d-HSL3}w>ebrk+MyD@8~fM5#p?M*rF$~=&p{2>rhUOhHC|=cdADkT<$vs5+(QZ8NADYCUPEvzy)phe0sj_EV;FLOk>Ie7G!7#7D1zfU$}lMe7vm#q4;?EeII|ODUSv)o +_$s|8eRS+yf&rbSIgnsqWsV_OqRgcPw{*stD9V@MkMxFm>ew#?pY9^f>j_3c7dC~-A$V^$8FvlA5Z`x6|k%r6owAA&YP$5s&hlB!cBnZG4?O(cy;kuSmQNSRI!!H?+Gd+FH61 +kXiE+RejgJU>i^0W4K!z&D4@r% +02b?g5{E#of<71Sp66`Qm$q&JvF+>aTq&LCn7@7Vkg0>i$Cg6+84ETjI=bIRNncf)`w~F9sGszN}V+f +X*6+a1nsLUS|oNJMBiwNE_o@9)|rx4t5Ey*yM0ry`k%jh7%sc}@kWS&m&Y@DiJ@l=lVo+S4R1g}bv>4 +Xr>NM!66GG`Ioe!Z+0ZxH-!D#>;$!js_n8)&Xd<_iRSPLsIxCiucM8U96ri>ND{LSc#tUUjo{424!fIYZ(G_~J~GPYSb@pzRjLLxR^NlRS`n6v4b?89txj%gGXlO#}}sGvK4CQhoq~XUTLz +WIRt +s3knD)GTR6~TOi8__ZI9ZlzCMWoNiO)PVj4+q!H(AyzNT130jpoh2WYZYI}jhe3G9#B|l>bK6s~$yOv +nIFh;!?_w+>;0nDy2G4=5T`3OC=6~tCe{p+{6$FnzEqU@T!OrWY +xeLL`>t#Aq2tKo3;<9C(4na^)-?`G6Qz +sOmlrQ8wozLS@y*n2?lMEIJ77D^%f}uPJ+eTXl_Yn!0WdYugIK4aPfAAj1PX3Xhax-74)uvJHe#4h%Pdx5bSrDcuVFOg1^$ck<9f3Bi?3g6PY6k-te}h5#K1_TZ2cb- +2gnI%z!wjznnuFtN8%j6I@day!K>oR1int|ND>b8f} +Zgdk;C41Xs<>?=_qTsF=^2x9LjT-P)mo%lk_+Kjtcb8E&OPmvo*?(WN4a9`Vk`-T?Wx3=JZum$&%Ex0 +?IamP9(E8>{UB-;@ +fJ?Zr!P4H@W3UWzLLDe7-wcT`x9@*ge~`(KzhZ@~ft_<dO+DPNdFvizW_U +>e}Vk*P?*IseQD1*Bf=j(e00BbI3v>k4Eakt<CTy_df8=OEsT$P4U$jbQHw+02c76Xg?M%T*#iZk +7Y01F`B))D4Lbbwy+hq#j-VdCiX}{410aaNcQ*QIQH<8S!~PNe766d>)5fUZ)2f5IJ(;Sno_R);@5YTA*=w)8Cfc$$-gtw(vu7h)`Xgtr)pE9P-#&Ke&>{Br+i$bu$B(mj-+h;T_~D1_lTS +WjKb$_v-ua2M&p-cM$VGK^HT&gBBUp!hdZ{Mi)0hzGId6#r3*{}RQor1&Q&{wcTke +JOqn#lMN-+bI4@ivK*t-%at4Q~Z+@|5J+pCB?6%_&-qmI=A?P`_dSV=CJuRuUkd)m5nPIJNi8JX*4$E +CxRG1IfU^~CNh5NcE-P1&3Nt0jMurvZ%^@iQv7g=PxI@IH2*wGY1PskiqEI`%PIb26#pL-e;36+LGe$ +!#izkXk{9Nd6u&jby%e9?pIREkaARA>$58wk6#ov2{~*QRO!41!i_hAyB-VlIY!9}Ig;BK~&W@7g*Rn +XqgKlDcNIv5e?_&J+M;TxJ3ga&yWc>JNZt;y2e>lZYp!l;Wei6lAN%7ZH{8uUd4vK$(;!~chKc@JnDS +oXh{?(Mib(BIjrEoW;@C>D}ms0qgQm75$?581|{W6iWy4yKBvzoKBFLQSOICsVGOz{U&{IL{&62(uW_ +;V@#GK&8Y#ebIKZ=(3SDgIH4|1rg{af`2490;cPohg0~ir<&wUrq7HQ2gl>|8|PMg5p0*@pn@E58dK7 +ev;+m?i3q4&NR+s7UqNjp?!My?AiBPm#=ADd|aH_93MM&tjU}_FtlI4KE1EKwwIQIIgY&PFOCdmb8=X +J1i1EEqwnQyNj=g&t3CTED`pLoV+qJuHv< +MI;0`xEqy(i1f!Ln&T~r=EU*cIt8l$@b4cwFoDVRV?`Dk*OEsefa0G>e@Jv9u{hBZpD2hB +IcWSR{FBW?Vt_(CrO|2p_;&5uQ2>{J^6*y4F@r6X!S&?dZTxtFLKl~Rtijt5)h65$Z%!mGkMAys=sI4 +B$Jmi3(@;-?clg-k#N@;{i^9^S@hC1fa$M|SFP-o8$^*QLGn-ug$s+~_wr-`<1z8D0pqLmxmISH6-*n +Be@QBu)`nGZ889R<-IWjUfw!uF+d7NoNbQ>S<;be?WM(T0qhWwLb5oAJifQL^E{A0(GxW=;vfAEI{EX +FUW&4lFG#IeyNYmB+4FCS}Q(1=76@iETL8|j;cH@ROE5gQ%X*jvgErEexdjI#_I*~Hr|ePT_VX=D>`7 +T@?uY~sy%<>Gon@z^RFNL2ncf~irLsE9-;BZMj9*Z-Mg0^IdVjd4NiUW8T;akFW9M5r&vu*4g2=nZ`n^j{vgH%zyA6w`|Y>i*y=N!y-fDw=iS +=b!9A#>yM{VCs+X(MsH2-t9o;?D(LKw8_$D@l?_d-8L3TTThppxxvzPg4>c4B<;!}s1L^Jw)>TFkCP4 +S0Q{1}QKPw{W2__tI1yD9!-6#o^9e~98Y^mG3ir~GG}@_%)lqUm++)Txu$3hyWsKX(f0GkEY|-1*qa* +r`)Uryc{k2exU`jpVFj&(J=7`t=zc6lmxlK=w{OdiCo^VS@s@4-Oj~#=7(z5IVT4@8BQ`&?X?DTbCYv +LI?Z#hIUg9Mq}uJ!Fs)aD8=dDwoO2%kPZU|`|0(*t-Zbd`x^|Myjpb{(A7`x3x~mh-GhB}K0OEH>Dt; +G>0cG%(T;3>y?k4@4x{?jqfckgF62v5x{{sp59`vtU$3yigTtU1iSi#17S=l~tVfujuM0gmqtT;>-1% +Q@U~Ci?;XKvb(z2k=EeyirV0U-9K7{X^Q$!HsW!u>+c(fzvt=wL3mFs`U^Jk7&0bd;X4({H)JD7?WD# +7};ZrvI?ySQ2s>c62foLUNTY+U2`U-fvZbp3xXpnAYpbdL~!;}cIjF^&42*MIoohp)c>{`;?~@A=}p@ +4h=t@Uvfj`Q-SsT3I-S)->*pscqxjQ!3VFF+;IF-)L3>dq+6(+OIyAHPHl;;-31`ITXK5aoutgE()!^_IXNWk~g(qZ}??)J_@6hwS +Ic{Q~@{4iEh!_}A6daq5PI{6|Ga^@SYc1^#cp{WgF7_18I-Ij1qRsKekt%Hz-yAlf +n!d&;~%>P)|@sz-{yQoM(K<`Pd_zM;_vQ@IKDNc5yzalJiM#a{jl|oc~%^_YT#SF29Sp8~!_X>{#8qc +kf{|hF?kTCCWq40DQr7@D=o+EPy-ADEm)8{Zza#gXiEk@P!OOt?45M;biF$^%r8znv> +n+I__z!>d3y6ny#{IeB6xC7C@CoN}M1zHB*!Ug4lIKTyA8rZ%vuDq8>Sr3gph0^zI+`n!=IA(o{yaav +?J@q$f_VP$?PK`^c`*Wso4(?F>X)2Ptl~ToH2h1|XOfvwT75nw>oeMudZBh@Sq5D?Zw$ihtIsAL}?CFw!>f_PRUs4{ZzvvINvOs-+U84c`Q@h72A57;j%pb*{oj +004MKnA{G~h|4_Hzc&FrDz2@`a>9tIwc8tIueYh8!Ti@8P^ZXdwO@w^98+D3UqS9RAea3;CzIwi4qZ) +H#g~jTX>={-7n<0{& +CWXE(k~z~9f7CPdFEq|_y`VvRo6^x-9nomPvt{uJ{>p-p{G~gh`SV3Y!`#vQ*V=FR2j?UW$wb4=UlR> +(^*LVEXVW{fO^SM3_Rm_I)Q@QB^?I}IlE9zF_bY}C8`hJ?D5bz3?IIv#1~g#IqtOC4^tIZ!41VZuF=o +KCy?6xQyl4b}nP~Vs(XfGNc;lfw{>u;5SJc>46P{wnhJC-j_H*<&mC +jRLM#{>=TV~jy+jL{PQ)ZPpECwx`{Z{P(8oPam#1Mt?$1Z}+g_!#{!XoURlSvH3MlW5pVG;CT(G*DeY +eFhCrDH5zp;d9pt|rX(eMvdpV1~gX&=KMD;UGq=8xrTa%1>CIVSEP8tx(*mJ$sMi3U7P#~8 +P~(|r2_{7Dvs{F7Xlf|k4Px{JT~;){ZwE1^T91#z9nU*)??ui=$M!|OzYsLwWLF4#^>hdz6o4W +A5jMuEm|aKaF?&&D-%G}sit$R=AIAszT_HXpgvcq`rPEX?Dz-xqwK9#E6RaC|NQe}?1iyRd3iaXJ9n; +&hRe}$xiZ0nHfhtME2z&zLo@A6OHW7eY1OJ#yQuBt{rdIe$;rw5nP;Bi=$8u%3%Si^<11FI5cT?#Pd* +Xt4#q;w(E_~DH=wP;SP0`$%m?tGJ|BJ7&M%y!`Nq?8UG-TTV?3nl^D3$fzlZ-DZ@gikvCb3?|A7Ms4$ +sWY%uP>Euc3BSl*3a`J;f(Xn7}7bp3EyMD)<8rJiyniStIbl{2us%2J{8!Cp0=RhXD;}Pa%is3z5fOh +nb&v4*1vcH`mW?7-P(pV+_=1v`G&aB?A55oqvrQHL5%@F>wjxhh%*<&HIPF_S$PNQXS^x$BT-JIMoRb +`*qh{C&mc-_U#k$0NjBq%1Dzdtvo;X@37Z(@v8*aFP_v+P)_wV1I)7VpN85SG@kPcI{eTT3Y(^>eZ|H(xpp(z3HZ#cur1^;5*GLg)D&v)Ck*ho!VP02lpSbk<{|RWehMD_(e)ohrnKR^GoJMX;nBJi9xZJKydr!^V|3>d)Y& +6_960eyzHwxiJje1X5V=8L%jAnF6^2U?4f0Csqmn>QGF6wD~d^}&UV1XzH +&;b0$jT^_OPoFN_Q3jwvdqIOX@5NjU<7>!0@C1Ymfi`#9!k7x-sV%v;ckkZAH*MN<59Sbm27kyVUdR& +Go8bn$u;y&H+eQ72jg93oF)@75ph2P>;Ey;>>1a;2w7Q`|$PwBD$Q9aSl%2M|K{#Q%?MnAA1pY+#is8 +eD_aq*cqCWrgpZ^pzfInC_r1~LfNKH-U2?+^8w$`s-FYpJi!E=~_H|hb}AGl*|3i-iU8}$Hn0CfWCq7 +5e8FH$soFNr?zAOHA=hzDL1pPbaT&7?kZ0pY%z-0o&_-{VU6Z^ZZw;~%vDR3BHuj`{`&Tu|Pq +vm~ctEHP)!9MQH?T^Icu+8W5WCWoj8sFx@c$O*~-ZL<4#2xg>UJg}=M3y34S +;Yy&sY1sOtJxclzAIkj1$pLTzMoAx3O+8MM(cpyKR6X6B!pzDbzp1>O8Iu8$zKZ?5xe{K9v{4NCzTD# +aB9pE?GAnLotJOMI=zP6b)eSts9MjJz5Uk7pzSpv^dht}dS{~zajBmCXvA8ka_KDH?>fLLRnF=GaQ@W +BU#e7o~qdl3$@1X+h2eE@LR_D5)3``CX0cY(kA{FnNkm5@vHL7+oh???NAwhsM~J00Nd=FOY=!w)|!< +XNl3ctN+eHji-=?2s94|A5-e=R7?<|0}q=@OSSQ-N!KQW1GvB3Ep+<)`|F_3*kW<@P%xl?F20v?leAq +_D{ssAq3=3keiMO*XK_U}+Oa6>t0dvYiyJs^2p{})^|}3u%pdKTZ?v#<`iOIgJ}M%aToYQb}uLAEy=rkTLgb?-2!|DjgWPcql+{~a8g;JU+wf4E$P_Vm#V-;MiAeT@F*!a60Bl{B%&iDAJ_y4tbuCY;ER~#RbP*A0+{!+;wT6yJ9NQkhMN=2!k3JG>w +As58fl#sAEi@nCrU9fD5jf>l29s;K&Eyz6Voxpl$cIiSAaFUisN*gz=QWq2C(zJCcRUM}W2b|POqE7G +c&Rl!E!8V{u{lb;TyX&2~=ghh1p4b1*-PzhSu_E<8ar{OcAExAsdlbIwp8Zvk+trFWJ% +&9KG3N)u-o7jB(!YdVx+>!Hh=^^=MGVX{42#5(DdLTrrPpnoj9Mr--`AX4?&aH-_51fNEBB(Le`6Z@U +lKN47c|G*c)D6^qUz^P%>N&8+!i*sPuR^@=@`ruyb+uWe1)1gwb-{uEvxs|U17Z$*y-)txBK_+-|vG5 +Vkhzk{3CW9UxckDmL*Q%JKodQ3{K#MU_9WR)U?5OsL6w|%|xFZK;)oRB3~$1`8|0qbcv&piOPA1o7@e +&>^uLo@jkG!mqzYXx|q~%rs#vD?_T?my5<3y;J=3dan*{p_+%Y(uTukDKWtgg4B5Ep%4;_6tJV*=^$~ +msoH0whzCBqdGw>-QfAxzv*XLe`!T1vc!wdfBwS$$i21Y%Yn!KXV@$`_5dxEz~eeAcfHZUIa5sV6~6P +$4MZ{?*uiavf^M|9H%dj&uKc8WgcIT#IC9~cw*IR6*6eNgm?f +81DUD*g^Hw4{Si=yi5IcJ$_u^}Y8e^MF43QuHy`!AuuB`j~>#N%|sB@*g~S(C6j@+UPm2H1IZRs^AOM +girspW=70#=p)Mt30|`QU}J5}3Ghxged3CShK8zb+qRXvu~&GYZh|am)Yrk95)R%6&O|*FeFS3y+h}p +{rL86Q@ssUA$%E9#-U;kGm3}G~oQeT6{ug%SO1ulKh?*v~aix#c#lcs=CM3q?&~JS9Nl9y&OCPg;H+l +St$#(AC=|6PnkdL`YzE6D4eZvbf;PsLol(->y6?Ik9scj#1@CD`s_y|~Gb71MX3}|i}4R-6+f9BSfEn +BLD{V!Me0C@qq9Wuf8AdAt#KU#18xJcpz)Tfh9efPBS((-z=nv&;X~!sYTY1wAPejf-_gKtPi&c( +6L-=_m#*E>{u5(w-MY1E$BrG9$YI~UebVk>ckzALe{=zPpo`FUV@@}&UABg=T@iC4MIS5j$FZ{M=;Kq +Ub5PSo#^hIGE{@mIQ?W2LHjKruo-49Ou3xrp{{6~?K5m-O$M&YxkiVn<7yUn^==*%WzvbrU%DOAqbTA +mScJ10F^E-G_wm{iR#s}Hl9=vM3)w$7nr6pgk1yK4JX?W5)^?Z%>-t~7ZYl`?MCnsldUS3`U_tDhURK +0%v`Zv5@ueEXGMp*~myLYdwU8vj#ne&SL)!Ihnk?NCa^eN7}By?-q_;1021*^oomw6z*9$W@&NyJ&!n +l)?WeNRho?NS775q}JUB~mvoEG(4uS9qwct(9`e9w>}N>42&sD}4}t;**Ms +ic+D=VG$$oU^hAcOgU8svJ$dyD=RDeH5d;y`cAT866e(+9B~@}`!H4pK`8*I<6QaRkNyyTEnuf-JDx*i865ckbLi?d~uNIsfsL6@FC7aZQ`x(C|h^iykC?wSPtC=?1w+rU~?Raa!ZkTv&>P44UKJARL}C4J}!TO;lNo%m2O@ +X3=Wt;2^8%UUtEk(!gj6z`L^qz@hCf6*oGSHnKNpg;Qi7bzyG_bfnsN{eT;K5 +nMD7Fg)DYzcKzgj8_$}g-RHsln#sOR**?i=&K;OF>DgP3nV#8oKf61Aon{}Y`>))?bGx1?`4s*zW2*0 +jK0bc*=+T!Vk;sR_M%_4e?AVWvA3r|H?!@Eqo1%|u!!YFk#W|1Yx?b4P(Q!7BNXYS2K8$e|bNY(=dho +Oh7cNj|{aExdAoOpPc}Q-IzMc>{$jU$2>!5N)eBFLcc6CNw&$;L{F`SBL)SSYWJ@c-eGZCL&5@F3(-k +200YxrPjG1pX1=un2hIsMC=WAsj?)Kitc1?#m0y!J< +W1R3oY7OdZKYT*QTf}?Bdc>NeUkG#)ct>fs38i>E>*iPZGNmx05%JJ2eK +DNg6BvYFS-EF755@G9F}&2)G(!iN2)9;=LD=GVX6I8IQTS*_V-@@C(vzfyuFcK>1SI$)+4@XrNEZlN{ +;?K}mm9jX%1Ftw&E8%M~kDNSR`%8Oy)C9g +I*__;R=YbG{mXwI+$a@RQKTACV`}H+EV0{%!8-vD5HPKga^ChzwGc3hjqj_2|d`>j2sv5z@B2e8}P!y3Du^NGFI9?`sB+d8q++HB`c +kKAYNGtQYFxy#xdEz2Jc2P)TBGdMFb;mSwr7G-) +W{Z+vYfw208!R*XMk9sq6KKEIVCu>t^b6EZs;a&E&*uG9&84i?e4h1(gIG@FTLV?=Nf=b}oqEN6dSP> +`}bqsChcP9UalGXfoOzJs<6f_D1`o1JS|gNY_|b +O{_lF9BYlW#SX+eVqLLhtUGo-))VWE^~VNcgRzm=SWGkK8fiwl;W6eJUSo-oXA~GkMzOKZC^Kq|dZXE +BHQI~=Mu*X5B#mz4ywPtA7=y-$F=lAyTrmGfc?$wv*d3u44^vd)ay?Y~e<0|XQR000O8^OY7yP+wat{UiVYgO~sS8 +~^|SaA|NaUv_0~WN&gWWNCABY-wUIcW7m0Y%Xwl?LGZ>+cuKF>#tzz%_9{{%tv#*eSYiiIf>KyHnII| +r`=u0Whe=<8A~J|Nm)^L_kX|n06>5QCE0EF_TDXD8%q>000x7>d||NT4IdA^aW+ZP>pgE#O^3h7H@%( +Sj`u3dS4DDtQ+dIwzW4m;vu}p*&kOIzB#l?zdHgBKLn!t(8H=PC2{tLi38z4L5ZE#pFXZ?Z +)?iK_(O!3R-zF|?OfMKW4c8GO4ggqVx8LRjZQcyEth9Uh+_hSlfFi_?ks>g4$1?C9nDi<7f+dvXA{+i@(0Or7(mVh_F-2j^ +XTt(F?$Ct?rkS$>VE@Q;Cf^w9WRXm%C3ARZyUbi4 +z%6x^{6LM=r~ISc6Y}cLx%vEx4aRlmkKcv6QK1eQea$FMF6um@cew0uk^$x=`{2Edo=u`cc;wa1}>U#U|%XpUft{MroRtnc|WB9H2=KALl1ff{}nlk# +oXdYZ}KnvF4$gN(PCgbbGqUfM%m_Ow~k8y$IG+awnpAlmrq8J~_4lpf0h_z(By2F2W?z(f89;^!o7S` +|o`NriL5Fc`njP;7_1CTY>xO=;DXy^e^uY-o8C~wI1etTbR(r_s2)CPF^2I=SP1%^!rHUFV=xx7@!LQ +8&&H0e)uU%(trx~jXALJDzQB?-}ZWn7e;4?P@xdSuYm^!h41^l;E$(&Nax>O{yese_z?1k{$mMYl;BVDOI+X=E`%jMgv*=R?|RTUvd8e~`{R?d!&e9Ahu+ +`uJJ7((lk-C$T(uc(^I!W;XCZYyepixNEt#flF263SicC+D(Rw9L2Z5fLnK<5OZMnjXoI +d)|HU4wmK2!Ssv(Wx)$(k?{?tbc}Z$Ouo(eN=PmxO`?=SWI&gjKpD%B(>TXYybP~<8$zrDZK3&Xaj6d +woK8gXxFrYD2U`?BaC>OIz4zxyrCZ$$6Y^BM+_{X}dvn=lD>YDz+7RyySdsvsaR5h>GblGeG_y6^XFX +9B`(<74AND2c^oyMb?K>Y=AU(YJdH46rMT<$Id;e>>Y$qGs(n|VCGMO_9Pr3#l%uexSEy2-LzD5p3`%~O8D1!HrRufP79{=T9D +fZEX_nN3J6NmwcHNP4EKs6>d;3r-JDy%*2_vma^@^nuo+lJ=kj!81K(RJo#CoHgK^@c-+-D3p8UGX=AcGW2GIRa1#2=+idams^8$HH5bAh&}~8{ENflfG^wbOIr2z=m +;>;ZNg-n`|+gMBEuD!5{20gvUEl8er?Re#%$;{*oltEBi+fB1l3@VeEeMw_*x!d>cL)slOJ +BKxqbYX;SD=#NRZC_PjrfIp_7BRYYh{%PXQCL +ELR577=`m0iOJ-5Z9&I$(fx(t0jx95SBmBJj>Az<6zxfR}ZV9Z#|-Z|I>J!i&7P1UzkGeKoC_q}R5Uv +~=u8P!qEV6Gw^t*9Rwsk1NSML3*qFeBJjD*#;6byfG!1J+}v)J2v{dg%*k#ytgpKF%0TSGV1sRLk3}- +7O429tXp)9WZHAl!oFf9*TrEU<-jFP+P+Ni2g_i}|fUqok8c=L1$Q}*42D(@bs--0%E$l(9DEo!q$93 +{$Y9o|IVQo5>ivx{S_AkMgsm%(PcTm_abLo@tJ(MPClPR`z3PhwKfme$hx_g%k$u-`e#ELZ8E@k(}c(xEy*H!Wlkpl2PF^(5dA#hM8>tbKb75&dxl=qr;|EC`g58pPI>HX%M=DL#sv}Rv=6;Wbq`WFLp-X)?*o|7f}8yG2 +$>sMu>_hed@?P(LU>L4T-)EGt^l{aD(r`M8-u(mNMR3U1kuhbx@j45O_GzLM&gL#NXdwWV`Tii?(Pb* +QV_R*(}rc1>*~I1=8)vtBOyRXb&}oh`?S;gR^b1| +AB{X0W+MA#=9!5v%`IKAoLB-(?!m%-TnI?=V0fOwsv+Jw?Ry$Yb21k3Ew{kC;+W`Z=7G)JUig6 +@NxF}|2JQdOC+ZQ6mO)B6L{jk75jU32y-v>Ap?-BTMIZl$cuBH1kXz}YM23>nI1A(2Tim!Q$%rxs~d6Yhc}nx=C#i-vK;NmETpQ#E26RW#nMLF6Vmk?A7(0&BJDW$hxPF0pM1q$&f)!oMD!!gl +`V?ZL(2Yo{=`Es5a6;Z49rMvLpf|Eb6-(ln}!^o^925TB42=WS)^i$r!Hf47Hj3>#yz;_FiSbu4#LbB +l0T@3;cn>(~*6;#Mxk$ut30EE_;0-=bteuKp35t?`S|SQ8ZG=1GcPAr$b~&^)Ej)KI7K4`I1?E&8SQt +`lmL(XBuq(G2J{;2^xf2m-({$ess2dbObfawH5p!jJua-*ok%&rm|#uM0K&tYw6NaKTQ|PuAG##WaQ; +Akt1K4vxBV7Lv}WgO^7gze|S{hEJ_^{nlNoip8cLHQZv34mG`Fu0Ba8navbb8#q(QmM}gI-T=m}UNl$ +tWldIC5`Z|K!k9~6KwSSfoeC&$A;PsU!5BFR_eK%>+w#ff7|iiBn5HrYB7 +b4^d>>8W2wFUz$1pzlU=Vy3e*6Ch5~_4odoi~AuYVbkL4KToT_Zbhhgjn)RLe(7#jvKC+Wg=x=70|Bb +zYYfLohx0V`~|bz4=7EUR$KD#}64k)ZZ6p51oUQ+224o90^XLey2bu%h)`gx*0}0!h*to{{jTK0~#D2mBUk3682;TDO%TsudE +4e`f{}s7=_byK1&@Re-U3}Tf>L>kApjp!NhPZleP~AlR$eYKvup~=7l2=1%87|5oXxoqaU6!b3Z&83*)j^%Od +wzlKk4~QH8T%y;raHET3>;mijix(hfk2f|91EF^WvL(Xt +K7NEhu>3xLgvC=2MU@|*c)$^!$YWz~4A3#~cpycpWdg0iFJn3}$7EbBYjYks-H{R|$vCc*eStftnFJa +dfKiv~^d-tBx|jx~kF1fPMiVz669my%g7G;(9^*pfaXMb9VzQPIzI1_YjX~TSVIVB;9|>$FY$ic;KsU ++Y!$xm>E0o3CfMehgC@?|+jIiikfL1>sfsA?}4H-|QfkN&-Fiu11lqU`cdgxN;17c&*pWO)bb1i^q_G +|*fZ3$ORCDO2G3|c6HyF<@9<70%WX3zQ^@=tKFv=9NUT@G~z3wkq&TgQKdhHOi^iurG7qbnn+${r^&S3GM9P6f@8YMKN|HYj4>I +skNg?|HH<5+F)I`yhSL|M*DDAERq=$;TR%EMJyd^ryT~g8`Sf#pIo8IkX0$aeRA(Jy2{-ESmbI}ZWz +=E-7K9z*{IEf#Vp;D(pd)Bg4d!FWS13Br9^sdR1_1QCf?&CzV+%>uT0|M5(>#wK$Zcj{{%xfcs0b2iuS<-$5qy?eamy=7C2a`jw-fx_umu7hMCDb +m&k8h`xa>|lh$m_F$Agy9EMBBzm{F3oG5*nJtR3ko%?_i=! +BKTNbmdclbC1G7*(uNC<LYUL<1Wlay8F`=ctcSI^Q5HUH6q7* +oeILoXCYM&qtjT6eSEg2j~q?I;{CoXtz?+}whUuF)=sPXu`U`}J<=>S+US{x26fOzJ5*!f*})`^(aYK +}S2V))-Rhby3FMbe7(Q~+^pthYnO1)&20*U|Beh1L_V$6647!ZN_}Fm~3j7{95prCUk8msBKuq|oU13 +QX$sKCn3!L4qrHl3cBzly;%*7DcZ`O@LXX_eM-H3`PnxnuBJSbxrV0cA50W>}D?z`OBn@T84vIO|bP8 +}3<`X1Lac@VNhoU-@F@`;7(RztltpzYhCK@CjJZ-ZNMEh(%)hO+osXsAiAlaZ0hUQt+g*B;E2q?CxlR +m3_#Fq#h3C^pWyHo0!Bpv6Rxhd|&&Ba7rPDr$!5Msb;y0?Y=F}^nU$LlUha6K1!c`c`#Itkl+2 +qrFUg2P3lub$wp+gW$URruqyzt@t2<)i-{T}GKY$#{6}FFh>_avWI>@GYGDa8Esbh;Dujj`2pho60xJ +pgU?PS)Ke`O}EI@2K#;4?u}mpO3W(KphtL(81BJ@{t-up^~5faAZxI$X#hfeIdhP%~as=%T?SH$vwkD +7V;sD2dF(tkSAuNS1CacZrGY13)cE5zX2z6&#;#dff4(2U#d@iF*n`J1xiqh&GCRg^h)nbznHEZDGPZzite@rrHk=+VqDJBwWQ#7ZV6XL1W +@xK1$KWOs(nm1(=U9F%3I&^RdD|fti-sOrU-AdXa3}hw-^(?@*+}1s@@_ZKNW~{KdoDP8 +w2Uy7bW{5{;Y +;Kk{f2*Lrf<3SE+^Di+zo6mhef^ZxB0-KYYlydDg4?e!q2%XWu=AsT?!qhFfB3|A+&ZhO|&L68;zJIK +EVy9E<&XKVP8ay3ZSLc!A5!~=9$Uxy)W7==T=uE(%>!tEg5%+onkosgx +pr?IvDcjlruA1MZi+9)cAWE!bldG1tHg$$fDhHsfb5X{_`Zp-m{)}m%7$bdz>R2kSfNRRlFl +@<%UsX0Q9R>&74%Eoq3I?A=NVU4Z&M1?Ko2j)w`N{^mn9R9DTNI^^`3{H_sFy$0~vPkN|L9x7Ed=&G? +;>YqeIXikQdpfF%0PkzrUF#jQasD_r7TahN){B=$?sy(gf(=C6O>fY&6z#?Ekq$XLV#lx3%H$&liWsn +1A)$4AH+whBTeJ!pMDa&qzh5esgc5=T^zPtfbukclBV`&8Mup9_uhTSxyaZ;BBH^d}Mxgb?S#nnWpQW3H(q@Y; +GdWR69u-@!d_yXtp+6?Q5Bug6#6@SWCi*X}PvMbb{v$7AYCbVaJ2D=FV9m`{QWe>f9Xj#m5iq8=o2lN +f{Wk2IP%aUIGffK2x@?d!$nBsDruQus-TBfe+|fxOn-x?l3hX&kOPVwX(uH_GOi~dFy@J%1B3ntmHqi +P}$%u^AZ!9v3CIzs9>%3)B(;|GzxLc)+eGY>U6u`0e)w%>N(udDQJEk7q>iNl%HGG{KfszXqUH0w9j+ +f4m0RYJmaHkGLwUE+ykO3Ixm#qnRf`rD>dO#YjJM39oh9%U6AO3rh})h-ca?{#UxEZv2`M$>n0NUGhf +}H(q-WN8UkaloCo4nS9K9JRsz!IdGtEO+g@rx%y}QnBCXffZ@HQ@Kx4dH(29}qV@o>G6Dn_-anELhav +5FLO*8E|;6j_gVvn~1rzzkevoCugXJ5}I-%ataptAh?+}FR)ef<;8eeHM`C$CTR(OIJZgzaJfua83A= +lI6fM>igLY-5`v8{N9rLyl@dNBuCQ486L#8+upJV$**yk=Q8DXa!vL2y1)icYI{pG2qs+5(LU*Of^d;C_B6R);O7%nou4OPaaE +t;h1Vuwg|5+1*Dvd?yQD7UTq8Q-O$XdD-OWh>j*n@JddWBaZ0KJGhxH9DI79iT(WD`oxQL6&d?u3m({ +iJC3Mdu8O>9}WB;5;b**??wEgR6`=)@dtJ$~H<#FW6NWQ0#M7mZ0sgBsCg~$(U|vl>^`T&@X2l#c;}x +9~HH7k_jU>38g9(OLHdK0HaPna2)4w$VuLo30hIHQdT6_=tin*pkK?KHKReumW2j){7Mb0M&W?7+K>s +Rk#|JS3jBDImB^zj0#I +fzc;yWtYxQ#t%>5m#s-oEN6r|NfJr-yWkx%xXqNZm!4ncZg;!stK?KHYMtzD^r;l9F{2$^fNYkBPVIJ +=-%cG3)a8IIOTzh;RMaoGH*vX`%2P04wG;gOSZSID4Zb=c87 +ldJ6l3W$BnA{=CnRAKf(5jJwCsUa*t1^g6}G9_$$9~Za*En<0>vUefNQ}dmRYYazm|$OKGB+IOR;t#e +5`hKT_MRRYpmabxtI_oqB_S)@bDosR9xg0@R9En99$T3GFuJTe=BK7BE`TN?mhvP}N*HXwNegP*LGwm +1TmN8imZUDsLXB#q$;bX=RBlf#{xikiBexA`K&GzJx{7M103;-|-G66AZ4F+pm3-CyWklOn8AckGtax +d_(SY4!1p;9q%=$EE8d9ni_}Rb>?aeEelfXaYvr1XF8#?(Gt%_lAe;1^ziwYeV^_Vy?6K^J{(uG&ntS +!2pB#L6dD}XE^S!T<5^aUVCpcqbn{?mc#lHg8t&i4|BeAzTxWMyY)nIR0<0&&PWdV;b;=9sXCwo;t|RV6W&8qXy)$T6h^y?>>$p}+`@iQ1W0!A30@8S##?6DcozURV=ih%DefwfdxZ +kV;3;+SpeL-Tu&7IvIB${kz_W%i>xJr!@9>^ALEz$(naolWgd4nD?p8xOmT^1f<9^_hpK1r}0TvQ$(R +{xRa>LNyh(y7ywxGa&z_dN2$$#5pJ#dhw+yy`SBa99gyh(k09(QiB6yR58~HFyksFIyBUz+MYv$Rtp5 +q?@}HHsmGY$PsEpm=}X{XKW-jq9YX(4UXQOMyF?oz^%2xp#;9&@7p=yWuI9BOf%}(6K-%K5Tr=Qs{tM +LuOS*g>CPtuGZA)uDTiv?x`A)&E@O9@E5cvAE6R>eN|56{eK0~KKAH_koB%e=I*1uH7r)K;{e0#B79+ +Rdc8ra|N?l;t>-AopygNO(IC}Z^FuFMS{+v&g+CmA+DzoP69!oHG5T^7(==^SEC0Z>Z=1QY-O00;o{l@>=M?`QnO0000I0RR9g0001RX>c!Jc4cm4Z*nhW +X>)XJX<{#5Vqs%zaBp&SFJE72ZfSI1UoLQYC6B>Q12GIl@A-;R&JYB>@drI1@dqfIc)NzIQ^gL|{yi? +e&5S&w=NRKhud|V&^ea=vI{J>!!?rFsK`l$oqoVOL@?g>@tbKsRXh?3DO6by#6vA05|8kw4mX=k0)5} +<=6yq-L26=gU#)A5mzLs2mu6f%9rO0N%LTQ=u)iph_Xe82$iIO9KQH000080P~d=N3V)6WzGQr0Luda03`qb0 +B~t=FJE?LZe(wAFJx(RbZlv2FJEF|V{344a&#|kX>(&PaCv=G!EW0y487|shy;b5Eity9h5|XPK?VdE +(xFLD!yw2qooG`eL!!6%?!#Rr5l!+vJwC}(SiD<+w3RZ4J7}q1e2N)1Wm8z$rgQ3WB*<4Yxc%_ +)7WPMkZyg=2ft{`Ck8lWIY-=h(%9w?Y%!c?$&*zO-U_fPwW$6ZW@J~o+5?uGo-SVt +ae>p+=G{Z>^gG)OJHN8e-X*2u{1i-2HEogxCPPm%9DW1I`EIfo^D&!mt?FaCftQ(LO)^EG>rsK8JI1lBrJuErzcg|-6C@u{4EQfkOY +9=!XMr1a7ZgEJhGjJh;_YpHzo#qNWDNH)I;)ElW{e04Djf0(O&Q*eqW*IWMEq{*GUZg0mj3;4aU!OnY +XRpk>SR7@$&5WlMNvV(QD|tR~1Gov!Nf$*ExuWk={oeIuo*>BVpTFBVVk{~X0dS$J*50V$? +KNOY%XM$RXAZo)kb>f@aU0dp{x;Konj<`wpOQDAv-sNg*A;a#!6P)h>@6aW +AK2mtey7DqIx(aK01001&%001Wd003}la4%nWWo~3|axY|Qb98KJVlQ7}VPk7>Z*p`mb7*yRX>2ZVdD +T2?ZyU*x-}Ngx6bueG^u*R37I$9g4vyDGj3jHrkL+Fqff|xcYNFu`GY`x3-v0NiXFq0!lGX`uh(6dPr +@OkUy53zqr{?iDkIkxD=jHa9>DtZX|G-~PPEStFi)w$U^X+wOk{2^`_T=fA`EYH`+e3R@mF9i5X>YUI +npagIK45 +Oss>#42SA1ef_^ergW>W1F=no4VS;<8+_3*G3*>%Lc#dxJ|js+Limds* +1ugg8GxK>#|}{sRC)U8i_qQY3swY69a$pVEN^YzAk?M*R#d@k8j_;dH3Pv_vYMus5^UNKdxRX3;2F9!JR`+RLj3j +=Ei;1&%0{vKI4w)XZ`~?6DR#jK5Y4xQw7 +Ql3{egOHM&DOsPaw*o&npIW`+!}yHFmX5QgTN&v1O6OCRX6_-u<|ws^M&TonOd5Q6tP6$PUyrOOz!zKX!j{|i`uyp)-#mSC_V1n~vgc&5$=cx +5$3=c)4FCY^Y7hpB&hP<%MZ6IXNDPR=(`QaQmfZ%h!nrB(IN{Z2?s>l9t?f3?LX9#@7=7b@!6nk$I&W +4_|Loi(6zbt3L%Zl(%jI`iv0_Um75+paFvDW$`8-D +ugPH}8WT>Om1V!H7OD3UQbFB5ToTG|$ZH+OBTMW#dW)*F>daDg=s>kb)`Mt+K|tAH-K8aVa=|B*(mV^&|HD4qQu(Ipt;d#GSChzY;qqMhEqRYXBf^@T`T(@+R)~|fzE1 +mW7`G@vY+x5gkfnqi{Jofk%;vD;`RGiuV1}MKsB0nfnIwSuju(a@E6STyou~J@)=pfnvC`f%vs5tpVr +Ii%w!FzvR}rJBHJ>()lu*@MrPa`1(JpY9FsJBW|n!|+#zmWw*imUHB1S0I@*6!4flj#pF5uZ`OWt)Lz +cR6Fqxn-rTokxuVBZJhro-VgRE{UlQ>%D20X>i0xbS-Q)Js_c8tPt0v>{VpEn&Y7xD(6(r-+e%op4Q7 +=D?JgB!4Vj8WqgiDDEOP~0>xhKbehQTLJZSF`S>;&#f)jiKP1}AO%wrdNx-8Gq39s8 +a1{}A~>@!aOxA{MU$ATn+E3Ouq*QNra7m8Z7!&tV}L!U@e3`BoReVBV}+Mx)>*j)Fxy28F32Pxp{X0l +Mj*JL5IpM@VvY#BAGGU0cF}-k1%}uM4ox^(e7zA12vZVpF4YQFn_~{d_7EhcmQ)5kc?Mw)00W5uNKI8 +XvN(Xjh^!(w5UeOM2< +4+iHajNgr6hsEeh&on5T{wr$eB10hJ9T@45-`iKUGIo0VF)$k7L5d`vZ)?{Xr9Ws5*}Bva-eB8=xC)M +0*XKb=ahkMz%TqOnAXFaE>5j#%?y4@>NWS%UO6J*9E0UK(Pv=5lC^mM!Q+ +32MiThv)cI1r@2k0$siGMsV)R6)Z)nA2fYwG2Q-@H@R%Ex2AK>Jjha9#V}+O2?DRC5;sSS%oc^=0kt? +99Si8TGX+W!+ZDD(=J9{Uc8-U?&v7F{EAL3Iy^RpT7qBXOC%P6@X1Ekd|JszRYtVmDQ>HV{Rqs)W4`>&u1M8mb@T)~XE(?F +v6^92!k(et$qmmw{=TOQb?ufJn^EvcrNq%hD$D(jxASPgxt-+zc3NO+sZ73icos5BzyAHc@XG2$75Mb +B!Dj8Dug#pyLjgzlY++b}LFp`;*XPO4jK-W?OzseruvG>m40*1E41odmU>PlZ*r(mQ#>}@lO=tDSg3f2ZfW@ +5N3f@K9ht`leCs0NEEhL=j>ArRSIsq;|5ih`_ue(kbr*u0nlY&$fRhi@s^+~(rRv2F*FZ&0IqlJ2CH?Qp#M!@+RPY@o4KZnb!VMrz~_`DG1OLRldLBl+DGGZni~<3AVqi+47*=iGE52H8S#6lj6DuBsc2=X(W_ +D8!TqF5>1$_(|*x>40bUC?QTYjuUZ5$hhf>Vl1Td6{b64Iw^o75`45Hz-C$l?|YdcApw{tp@g|pmhWG +`OGb`Y#5(GVJqzh2ec1HdpaL +#$r~S-;5mgWvgjT~6mmrZK@mq8!gJVcpsAwDB=);3sm;z(!(E!DJOWHS*6YpgQ@X<1%PnpwPLvuIu9Y +`UXB#fsx1YdO}w=fLE?1Af-VAFbI@qvKLsB{m(P5Lu8TDlY{r?# +CO9jtL{9 +8edJJQib&WxhQ;ar;;-;n}hM8xSM`kQgs-N{BA(xB<;(wXgAoA +YvDS1Lp4Bab2q?ua$8Ek&f=URvCaDA)csA$SJASFFZciat8l(iSxm3b=<6^shcrVycQ`$hZ=c3wfZNH-M0(6H9*Q-v|*UJ+TM2w|U_pQpGz(`Uf#FVi`Tw3$wSq2W4o0XRfs0S_3WS`qi{2mM9yY8O-5^XVmkf{ +$lYH!xf$8kN#8$wR0QN$y>E5`byjI)iAEj& +vu6<)(B>eJgKrcog^SGG&X1gZ1YqLWmaWjZ?ZiKRo>GE4S)p}8eSL&i211x2NOJ6K5eJQI?#wNkETZJ +VQwGe&_~Ze2hB!`NI3S??vdUDJ0N(~obUu(Q3ZuUDPcUd83nP=b1)HbPLjX*r(}<4<;3yMiM#`(ezvE +9uRJ?f;*xf^5Gi}`w*qs)hkmSB|ltGdF3^owid9HVhQfh?_r4M^z{}-dYbAhA0mH`(ysjgD4_cgR*yRUPu9}(R)+kM*%GewT@^4F> +LSKea8~vPIOgIMexb*p^{Jiu$lmDX#Z-|&*iusDk4LD`)z#wEnxx2i%1_#pKS_o4oR7t?9F^I)FnC=) +qMF**MqY1eaB!EsM?0Vw!Y)Jy$9i9p34Yg}jY@Dp2X&6&r=J%}UDJF7<$L3Vm())N|%@6~+et{L(4yK +nFF2s`&d#qHofL~Ui-^0Z^zT-HVfo6p)4g*&KJ|4J^#;Ny2pN`67apo|_4B{>~`>wcalA;Ku#(cz5jc +`n(#EDQe(YvC;wFHzV`vkj&yMoQigx6~@UVnZ4mS#e@xX?OUdl3|IU3wAl?@_v^wOD7s6P*~-e2!soMw(TF@5d+a1jn|%6jd-Q|W3lmZv&mN38h +l6b9zn0i)K_Ki)*cl66xl!1xgs|i#h7t2gid{QSdv%v-s%u>FF`&@+=nHJG`%NWxr=bKKeGoC_CIEIMTMWAYKRx +l}zK28k0{0>vN4U@;_f4=nPYmvr~pS7}_?!2#p++yN7D24FZ99alIS68Iy@d!L6FLNVs#52g8D%^Twh +hZ-Yy)045nsZOLDmAn& +u@dcTCYzq~gKlNPN7s0lD1&t_!J55iq$3F)HDXNpaMM?PU?Qu~`kCxn30UoIx9%-}KezeBRDq+?ZlikcXrpR0ac~7YuXyRjHVks^-VCU!+9AnBkrH>VZ;;q +=wOf!UPK?y%x})m#*QM#(Ue)-3I(nKeq4k?sFk6CZN))kSjQBzXKqNnkG_2)JZf3n;>c3cP!YTjB+TY +ig6pbkF?12jpplGx^_kw#%m=C8R~<+M7KUGfu}vx5!xSv5wd5V9cw=@a4|D0c+2v)2*6SbyKBi0J8@a +^fO6=d6DL;2WV{7-!&?(f$NL6CO1^o%RM^;zNwkgt>D5lEFX}?`0vPa~8DvWo1JISVhnDL#-ZHkqj_O +Q=aRIXTEW1>bU#lcETyP?j9pw1b>NyDR?!TlcT)P!Z|z%zWc5hUr{mWg--AVMlI9iqa#-Q=H<2+Zo;O +OaSQgVsU0-W6cx$)IB(zsj0iSW`p?r}0_l)bY{F{U`@vA6 +px}`&R=AO{zpFVU|8}EIc^&>B^fDwz+ +31n8WBE>8rkC1Dl`ELqsl~_zOTlA9)MP34etxfHKTx{wknm-;qV_uxa#gcI(+W$ce;ftWE}?WON&F_OugFN;TZ+Ci0 +|_Hr=d$`Cg5Y!{BN3645C0aWCEOoBOi4ce@b>wOKmJ1*$%0WYAl4yeH$H1P5K@XHxJOQUBOFC0iOgcJi2IvesO9Waqk$rA}fR|(0xAMjo!7 +B;d&SF5%rPfuSfAnlX-4}+`M5W!h=qdLY3Nx4N%DyUbu+uPQ7;L)x7q~`o|0_^> +#GY_ez&gvW$O!lclFOJFMOpn=ee$& +n!+7UH^MqPz<5cI^;Hk_R+%U}L3O*rDOcLDtn2b|!pO0kuZH&y+@z75hsCdq^0&_AsbDY6(xY5|U_#t +pwZVx6zWJ6_7BlcG9eRa=c@+%5ibU!kIRaB>qHmy_ekt;0{HDygzGYIZ3HfYI$)>S~&;y;k8PGfM34Y +PZBi9w?PpB!F*SWmN_$ibhG++igPz@CDI0HYU0Zw{{Fd_xiP~#)faKx#+8$>n%8>g$HYxx3BL)R!v5P +G_unWmCt@A^SDbqEGs&C}n}i@D4+O{aRVZ0v5gTu_gm02I6$)Vl)^2nnPHyxzXZTUu)H8b0JW!+GecL +tW(gqo8Sd*9DFkj9o2vavJ{8%d}{(`K_DL)(p?Y@D-iZxy0DWd;A8&MsKUpd^vZ+Wk;ZoH6{6}dPp|* +6ipif9Z$}pBeu|3NH^94jRlPU9rj3VztDfnFK1t8J799P{9C^nEatix6CLp(tM9QW5nCcn4^Gx7TN^u +Ri;Tb#gj1moJG?_Sjq_aQIJWm3&&c`Z1+{gi)UXR5;eSZzdOIa&en*cm-LWGBI}YK22aW&+KL=or9X` +^;JI)?^em6XNyx@l5Be>q1VjMqlTwq63FN)~-iLcM}d;&I_?_udio3)*7a?{4{4{?G`J|Xz-?-<1I#~ +#;Nsl+p_y-K`ju@9(S#P4)?B*o~B4K;jhxVVep3L;mX15oV98_n0(_q6TbRyDl>+Q(V$N}-@n#9sZX( +tc3RH*ae9#v(2x#HleQSOW~>&ETjVka87yS5xzng3-M+c?OjYbDNEnD>8kHnoQPorsR8pB@%_NEx=|p +$Qy#nW%!B$+4v|SSheF7+VEjqxb9UVM@x4DkJl^8_Ow5&$@1by>awH=gWBvzsm(^ovYGz;;yr#B +oT_~ViKcFaUwX2`}PTN<*|mG+5y$0nQwZQXZof)=3v4^T@31QY-O00;o{l@>>D767gG0RR9w3IG5r00 +01RX>c!Jc4cm4Z*nhWX>)XJX<{#5Vqs%zaBp&SFLQZwV{dL|X=g5DW@qhH%Z{5s5WLSX`D+tWPOARcSjW0Z^K>F(;9Di`=z65}N-9i(_UsSo-q*%Y(N8INRjf(~L& +4uKC^KhYU9rP}AfpyTGm-Wkktuc`8VOP0j_66wbdOE1`;In>%nB_*fvTo!N!>(OQnM3a0t{bC%Nr~v+ +`EqU!pRz;vIhNQnqQERmN=zytmF@y!h?M3-?Pz|X}=`T6}AFIT8(;q8#0p~)l3XDcIIVtwWLthhqVf@ +8%l~;zl1GQ?n3K{zo9NMqJH9?V&QPtewV9gnBO7rQ8VYoFML0S8p?6s`J7jP`YA?M`$O_hc51E +4u=0g11hDFQ|hpGp%yn+&)m+{HG*qm7Fyfq}a(tm3aG!n80McVb8Qfq%!2=10AgD|PJBn@bW;Z#X~kd +EQ=kbnMuy_rQ&*;>DTn0pXz^p`FRJelG93gm+0-Tb~M&;(8L+MrK$4))kg@y*6ipp1Q(J6!GVOQ`Ibw +@&a?a-v(PjgDKk(>yEt(KXPoqKYF6ab`Gd<^6%9){b6%lcJ#-L!cszSxVa8ka&m2Yi;Ekviw>@07Xmq +;rlB0W*u5&(jr@6aWAK2mtey7Do|3NFeAQ002 +&D001fg003}la4%nWWo~3|axY|Qb98KJVlQ7}VPk7>Z*p`mb9r-PZ*FF3XD)Dg-97zx+cuKF`>()C$s +?6WbmF+aoLjfgv7Oe}B=)o1G<&vJp(w~=Op#iG^vCvkfBVf001_ZU+u3&Sht+#+BoY`5fcc&Q+-IX_B +Nk<|IKA9vWicPU#wTn2wLaU+R(E-PxhR;wH((ntUT(0{1!u>1#Ue}DIGYzYVb0mxtW0NN5oc)toyMHA +cZYiiAI1kkaa*u3ow2>652q)GZ+(9(3&Dy^f%F6*lFsAHGAD2>PUl&^l%S#g+FHC +^WqE<<@<`}kS@kXF`kS~DYx6u?!pmS477M1Huflv5=R;^2Cir}<$nUn-7w4`CSj6HCTxeDQ7`Y37ZcfLvY5={gs0(>d&Abt>o9je73Sk*c*PNj6B5p?`F +nzmMDwZrAPEaxa_brG&E%Tr0`|dtBccUgavLnozM3UGy?~XN@j07_aLy-s-F^JuK(1!B1^CH%QRXSL+ +tFLK8AoGdBa9xjn?NCR-1~sv@~AArX~Jd0$??h2e;w?dPTuT}4`4?WSp+}~h`!&z&IU0UtnoxBNc{$U +7KJIBa>kdd;*P=aVSagi_TqvqfFh=xrz~28=_Q{LCn(;Dg@RS41Or$Arjf_|8omRIAtG#*XP0@nWQd@ +15)GtbPOvM{&CCacaUtLV_GLRetd|x&LZG*bre&PWdca&Zz_Zco?TaAEZg}nw+^g0ekQVVv7N@?|cBm +K)5b3kyz4edd{|H`oqI7<~iq6lkT`0YL@u%a|#BKNe{?_KbxY2^0pNGrY)}|B5&3`45l6_*K8IiEj0| +B$LISNYV_r|~oE1+mm^oC6RO0p*0Kj=VFu)j$cbb=yJk{^FA@B-Fz +vI82{&e(V^5&Prcl)petqDMrXnu){GK1Hu7fA}9iZbWbTRqpyB%1%B+ +(P*hXkJA~*XWeWXMpyV8gkf|QUUJ+m5^0l3kc(9k7rqyGL-uk2OkMSwNGQ-)e({@N26aNjL|OAv&x#loxF-^8Hbbn74#6H&lQEd2rMBw_E_WW4v&!TW=8fNM2h`C? +#FhP7vQMvh_U$!dz4JsKPmj3%(RaQ>iU0g=O~vp#XTR +Wl_Tzu=Ep!745owgxjv)TH-{%2eDb{Y-+qh)AhOaU<13J9Kcc-hI0zjtxRR920%(4d^*^BpeZf8`nk8v +C_JaqokiYjACisnd9?UpIJ`Ck7DMNS +AUtO<=ZQMN9wL_8{i{Dufb14(A030u(54sXiTEK2L6DGGX_3`<`;kqjkRW*2t>`=m@z0hCt?5F@7gxN +S4djO50+vunpum4uZFA +FKeRp;@c;m|pi=x!sHN3@`_Jd8PHuAW(H~*~wOop1h@SX7EE64i(L`!HuWD~<4ErQ=R99`qBMDGLBrD +UJZ=!CS`X=6LOanjMWHh}sVjvbK_*-tU5)v4t@O#qLKv|EX9vn<0ZAG344&70rnPE8(#p9LtC?fO^!9S?nGk@9&=O_6Df9d;i-r$wg1zNhG4!ju3=OBh@e0}e7g1{u +gZ357J6I6$9a@Uld^6>VA_r7UGjQK0V(25iVueq+G1t(QJK;g?|Kff>a440@8Ffr%p8dZNt7;F^e+aT +21z3-f{=Lj{1$vn-jZ<)BCwEs7Y(u_oHnnB=#%L*Dbx!qGo=NB@1H{(Uj}&&kE}!MS+01ONHKvw@;;i +p2n&mn|51@BGQR@1H?$fN`PzB|y&x=gs~b&i=o3bpPGp+sEj1@H}|^E6s}f0X-qRRi;CNY{gT9-gqjr +Iy)X^bwJ#444jLdo+#nVWms@7qHx7~6eyb4C?w#yA`Wwk645W;FdXm!nU?s%vJmh|Ai(q~1R~~peUAj +AdY;ECe?S`Qp#Z@WeG+4n1Ja*9!m;Gjvf0ITd$i@A+Rn3-tiwkLN-I;+oL8KJ)z=Q2skF&QlogH4i9LVda1 +1*dlXo^WFmBHOi6d&~o=5|bR?@SqiXq^1c)rRK=|Q7wMUBi@ND_;}SBt2u`%2$`tlANagvuVbQK-B^DGrN_$q1l? +Qq7m_7>X&NrUToZU-MLfipjY&nt(`_Vw;Q=jaH~|3Y3wCFJ}{T#e8q??YrF{$GBVX_N%XZ$H(%!TE3e +F%4iTIe${!vzGp8CivqY>o5M1sShsY00~N8iLPJX(8CTLc5IoF*+oko3^23z1_S+`EEv5fmG=!@Dq^5 +Le6YCr^**ZMje2ESKPIu;nOfA55!njM3`--?-{Gj2e1?gf(u+vZn!)AvJT_OJW67(|55k+Sgjl9gHbd +THR%-2H$8^(py!pI@pY#t^FB}ydqQfIUh?pp;jC~&cM4?ZnA?O5D7^Rc0&Uy!E(zavs +x{mGddazbPq#7)W04gu!dkI{H`u6<6Dm$RwXZ@ObVe*GnMSGy-aQWiJ)A~z;_`TXob=6rSig^^-+H9c +%R4~I1p8bWzxXX?rET%+3uWpBMRj%o>1U=Rf=~Jim(9r4aOpvUEwsIC*h@)-BqEPS)5N4p?mVt=&5)r +Joc3Ntvt?R<~7i;}L1eYlkWIlMyjk$H-ed)eqJ3&G +a!tXwN-6yX(l+N&k?D|LxAdb#2Y8Um_|+Ua +Fi%HGC(|M0{!b7+q(YNaCYRXI&yC3lYx1^kwK*5uLEz0qqeIsP4@*N+X$Qgu%|`rMZ<7)5`r(C_mB!{ +GCIs*C~ft@ykRVEydb1?$sGHxPKgeqLpNWS|Da6?XI%gSV?Hdh6R+%&ed`wy>K*!I7#dprkJ-cdvI(&p9y|~8!btujI4A5EyKf?UHFI7qJ(+JHpLnt^c +)Z;xP-`8HN8j97?VPMuRZQ*H4M3%WKg*w=KclcTtVvy9K(PUo!xPbBp->JMr)u#^(}!$i +)U740N7vA_D{1)1B;;^Bs6t5>R&+2I_0Hp8I_~}vzA{Yb99pc^#I%Ymo&ab;~J*DWdeg#5g4Ne +w>n_f_8q^~;C_wMS#~4n+{gPcVn<^jRu2<`%Q9LpvBZ8@vs)+>Xwt43BRk_<$;1&d(IevxtqLPf0jkGs-#^?r&1PAvv$JT|4GN1}9mF8J;-c(^Xxuy6GQm3BuOXj;ny%&CDC(gH;Uk44Gz>PT?2ATlj5lbVT*W;tZj +0XE?eT;NlvKIXJf8~9jlNR +r#KlPW56p>~1@qs-=G3e;uW%3>-rPPekZ +OjcbNOwErx%83r7r38H?U4#rqUXOwN6K7+z|Du0gCh+>ijunKZ<5dNo}2dIuJF9>CO<1H#{0ufa%^a{ +5ajq=w>E;Abm2{x6x+S&41)QXGGAF?9HfNJ>)Lu}GK?nkmmM6yk%R76v|(&3uF;KDoQm8@f8vr= +OYDH80wi_ZCt$lmfTdwP!f_Nlq8bO7Y6!vuL)RKdO}9a-muk>(L1h(d7oRj?bn;#MYze)y1w^wl){~X +74dHXe^OPrA!AjVr^w&X+;_QE>7TQK({_9{fcx5BI48LT#0Rv+iHsGK-Oo}IV+NEMPgzwmE7h!;zs!Y +>Qz?LvC&R)I0cWBi6c%(IL0OGx76YcQR9?pcO6r-Am1&HN0LH8oVH6rcDbpTb9b=FR*r;bh*`N!ZTAhqVU}?FWf +=LfU%y%T@wbYeGjA+#*v_1xk84!;Yrd)R)35VEU?$=A9d)wqbx<*Gdng<;PHujTf@HLsREDa +;#@pGzj=Nxa6AV8GZKam_Se+J&i=;Ei;HKEfYHJfNo0M+g+`wJQ0}i6O!~dP6^*ft{`6qx(L*}VWQ +G5bX+t{FU#-}4~oV@*|IarpgACs{|GFPt}#f@Hri+l?VjxYBx&g}MP4K%tRgJ~KnFqn+cH~c@2}%Hv& +TQnbtVk??{n;fMN$B$vr9LlImqb{1CSmtO=i$AR%wS=)rAV6<~hu$>55nzib`3~ao0-FYayPp@&3<}Z +dE-dc-O*JG1x~e%rMU~1h&QkbLu(;e@5~?0>Klr61JO5$ZeU2v4bG`PUXd=)8t7Rdeyc@&Di~o5tc%;n3&jUhCUae$Q2Vct@EzW8z&8l>}t!^KnOP$XA7J +XAWoOv=;W%Lr!of)u#t*$V+gz8HA$>cYsqfx*lypHfni9Vev+nTmNFHKH3a +sUc~Ex!V@CorV5L0K?v`;z-6%WR6lI31(Jx-xjJu?T=}-Xjz>;Ua(VwJs3-o?A4y5H;`f@Oz>>RueaSWcKas&eu^ +4RxTO(1Xo27mc=ke|6o8XoCduwyF6>R8?j7;HRhOx>vr^sj(65#)j=q4}bZ*5M&%Fumau5=X`?CMp>Z +eMRrw!p7GObedimxK3Po2Ns@i)dhiibE%)Ls*))T$)W^Z2)9Ii%P8o8!=6wNQ6T>R$@^h+%g%ysj;f$~tx^{=;+z)NiE)v}b31a2RAN$Jt&~*$XNUC|E`x8Jf^OVcLKk1 +@%Rj0{b8NT6MlYS`pUo*$@4vVJ_XfQoi)+A`W^3Go5>7MMlwDM@vUnF=kjzOoGRZ9rW3!PoK<#?@jsf1N(4_q((H3Fn5s=hXw$h1{Li6*6 +S;5a(ui;Ob|SbIvCh_OO&IU!xD2)?AKYDlf1w@F7?QSOrS3^Q4F=aJJh0RSosEKh)$2C!|H|*$FXUDB +LbtsTHd;cS2E@xiUF?b?PCx=0-t7?VR1QoGu~f68iRZ!xu1urK<`Ku#xoyzp?8d+afvX5FBYnjM$Umy +q{O=-u==dzx?w}t6H?#mW@t2dlZV?8xREz7$c2tZY=3h>v2+r#J(DVS3%rR&(AhE)`|Csi07e1#bRoe +i&oJ=-lO2r=0P(BWTMZ&;(V8SBHa^}xkp%NYlVDiysTj!$U0-j!LO@qzv}Xg_AQQ%H;<+XhOo4t6Exz +e(8yweX<1z(u_y&8ArCMPd7E@Lm)>CSy*Wg(KkMHsB0f{e0ck6KnAk1G?^m?|jePO2L=U~)&Q@g( +LYfQApLwwJq0F|BK};DNihoz;73RwfC{=BP$5zl{g*9o{l%OHrdcV7OH2yT%KRAAO^w;+XA5JHyyC** +$kQ5iZFaQ-z12Uv+4r%Nq<`G0lN#ZEPD2tsMu3|ERU1q8dN$mp(NGxGTUsY +x;Z}eGh*|`hnT6jeBOI2Rm@;~am4Wny1bEq22phOpJ&&~tc1+o&Y-Q*^`6POD}v$oKOkR&yz^FTW5sp +dayfT&M&&p7CkB`wihoz+q<${co$!b9kzNVOf<&Nu)!h>)h)80SasBAtMp@K9ET;XbdZ=!otwm}L=_6 +7g9B5X@LPg)UO`u{x3bPSsz!DD$j|54QP{V`vE|GEBouoNWVi^RRalbPT;nrEg)>6)G}~Xw6BC~dh?G&`|HQ4iQX|**IfYecw&8&#_!T0y?wgp_6lz{)`P0sPgU +$k>^#lM+@~MICV|p?D|B%?al##SESMjYm+;8;$mnLAo0T$@4;GCy)l8eThV*J2m{ +XNFHR7fYK-ghx(*)*XJ`8g#!&`wT7D0Y*JbU(PCG*F}dmW*=x-j(6eYXnMsH0sw#Ogby}ZNQez#fINo+OoSpU=SdHbmW3}RqE{) +x=I_{}_ka>h#omr`&I1ka7VAO4V#twSN^3U2B=UX1?QQa2ix$n%yKM$h+Dg+6(39a>HqJ*1T`L+K8P) +h>@6aWAK2mtey7Du5&I9p>`007fz0RSif003}la4%nWWo~3|axY|Qb98KJVlQ7}VPk7>Z*p`mbYXI4X +>4UKaCzOmeS6zBvN-y`KLuAlIhGPxYdJ4Xee2%iBu?t5j-AJLHtD9hDkae}H!`V1QgPhf{qA?(0OF05 +oV4fO^V4o)i3A1%U@({&3}!aBzx}hZ8C7v{na-2J;&x;6kAe6+U)&by?5c{o&wJ7C&dzRh92aHuYFSo +sGEU~v4|DkaUo-W4Fin1hdI$4)MD@z3NXn%6oJhfYao~PwiKbof4!gyK1!xA4(k__r$=l+@(QJKu=3?s$P@F*DA +_IVhvxdo1U70Do$+{>G*{2FTjjJkt3E0@b60|a2)sN59(D|3JbIQ%1-RQ!~hy3FVE{04eWcx2NQdt2_ +&Twg$ec$|MusFzGeQI=QG3&sm)j4@-1kay)(4CE7y5icH9Km?`&pGse`^UE>NTvnwpQH#8wc5w(0E!7 +*Qxr?6;qw~|37w-YkilM8`+3k1hc6#c4#%3cRDkbASObqt}OL& +wqj^2hWazgb_~7V +uKYDTS`ry?e*F6PjfC?66qyfgepAPvcG=BgX96Y}`Iz6E-K0iIVID_AP7=^Qo8p6Ay^F!$G!P(I{pbs +!!o}EHVIP6dj2lfQ(o*XhLoDzHLpa}kcdyZdmJPCsrhX=<1?;NX}#c}R03n1{(=yF*ti)1v4(rcuYXi +=nD1y3_tyBiywPUkF%rx6uL%DgGkDnTL#jtV4RT*p-u7n7^>b5ahl_{PR)^cj{CR0pv8QRhF-lFupr{ +1131ZzBA_yPd)JgPji4h?l?@3aEfjH6Q(TxwDfzLSEYScxex-O@V`9C93uxFW}c6u;SrxduMlh_i;4* +Ztv0V-p(+3umcP_>b@+}egw~7CSxkri~a+lOg@+Cl)xaAqv@WpT|`fxK7RVd0{WPN{yn;ej&H-Dz-pQ +&*W+a|6L>`etG(pz(|+(dk51C$I=M}XK7N}!{p&|(DRT8`bdlcxAIqi#7_3cmzd51_D$R#7XXS0FzUK +NHG+L?eNl|3E`cb9VNnNN|PINJ3Me2KzY;07;?cN5Ctvs6*3t+%E(~acIBw18~(P2^K1($;Y&|@e8|D +NO-fPfvT9F(`$^ECSu!L+|ivuS=)BAEf70xEhk*olfbErD^JJA?cAN61#0**OOxNTse%p51cN0S1WI-mm_H@eE_Q`!X>(0TH_NPx!9Z?DHW>^R4O ++M6Q%43siUuuuGrO8b~U0Mt!X`aLy}C-HS+4C4YeXB;|Ob3%z~4({Vxna_!|K6EbP;w8KUE{$K0vdbL +5rsYU#$qRzr`M9wG-2`G8sO6bLg%3L)qaUJ&)I!$>MUhVu*vUZz8qf2|r*h-$@cHT43#nd%x(}Sjt6e0MyqK07uTI{MVDCA4PRJr(D +Wb^0c@sF&ES*HNY)NB-5)z0Xut^@hcPsw-Wd}YTv)Upr(=TSljpM_UR~J8xP7YopmcyMLuZ!35m-Kph +Z6F(y0GRVcc572{C{P^T&U3wUVPOPsBOCp^nYBl#Z&VPBW>+J^XmBM5Qz{c~R&UE>Q!Sb3gqjHf)*bW&^G& +rY$qVUBdqFn0dhoj1ro9XUoICU#qDjJzkTxtbb!MbBb={ulxu|Z^rHj)P1s9+!yl(eSO_R2yi)s-T86 +>mYPIzv;U)b@I76_wyVClRyO3I|@zUvS1ja&%UKPnwXo>))Z!*;Z@@&-c+J?q&yzbx{NT5CsYqwH+hE +1dcB5U3HoyQ`G0PIGk=uy!07g>LdP7Wejfg3~|i69rnO3EGZk~um&enHrD7IAfjk{$9Y^}S4gCu#2*# +ruvsI-O-Y#kVv5vqZ*7zv;^w_~CHHmzTiqVZz3@(bcrT{iaMR#tuiNMiCx&!)UrKn@yt`BiL}ZydHzZ ++9xYV4zpG8-VSS&-W!C(f=ek#y?y=c@T^AbpEN3+n1*OCx}4{6#Us_31fE?7p5Zv|0jBEr%=t~zKo2( +l{f!*y8EBAb3M2atlIV3lO}OLz=yN<@CNyOEq>AT*Z)xg$boBC=_QjoixQkL@&5CUy1WUsDs6G +=D1x1g^jUy{j^tRNTXuXKgoK!sO+g}+_AmkL9tf-?F79&gVM4_;_IBD+*f3oXCNV2{3d`|j-M;!q)Am +1KjAQS|Wr;d9-zRg@7-{#qtzu`%krsu6)%2qH2o^5p_b)`;xvHXx#k)`-A7tUyHSoEnJiJPMBpG5{!P +AhNR?Mnn}g5ZM{7K!odj+tN+56m75R?_yH_dRU;a=j8x-C9d^uC##ToPJnZ=9)5W8{FKbB`@oy3%k8H +fLrFJYqSil4Dl+ZgmKB;xCOKNv;~i0h_v9&Ld?u{3hXPW13t7AJ4kL@L8|xM+)0MnzHhul-_ +qbo#%N5TPN%j!urvs6qBaDU7__ni+RVY&@xUI`hlv-W*Quv0l`nYUNcmrNUCL#MdgP*M(1PnAnJ<7xs +51x%U%x@_mj8Bj66t>i2OQ8w;{@1;cnSTF9_+&G@EuwM`b*LRu<7;_M`3Lp5Fecdmr`|AFZAYrb$D81 +^=|$fGuvsyazFMi`(i7PbcVwjU*j%pxA&r^i7V|g)$w36sB4&QP^^z_JN-&Yg-C5&;vnnp5F{q2TL?p +K_4eqMVDA%ukNe1_^A)tqhKfQ%6xR^&xvtFF9ixoGJ>rfp0 +Thg%LLa(pHIeOd|4_fXt@CJ0;K!&{{1e)*dF$J+rxnt?WIx)A_caqFq@I|NaAKDKuGcgYReKd+Qr4~A +Uc4B9@7yf@4$!*%-uAd#1-ijfEDT!=>(-9fm5$9l;8AuV5IPqiS)v0-gS@87?V-htGdUW525G_X|y6<)=k(|lRbQ8Y +~P42Jh}tz}L02wd>B_; +9Y=fjSD|HSA6v_}p1q2^or8AI2p;xF|gLD<$BnBF|k*eW_Ep3?zE`YM`3_Y<~v??dF8S!F#fb-IID0c +Yh=`)~F!0y8yeE*2+-6`_$@e@^K`1r}*zG8J +3k2EBEn;(%k(Px9T8)`7+r;q;>?gk&M(&fTI`x(WR=FmUQmfXV)8?PN0FbAhTixU+q~*b-n$4lYeplo +FW3cE(H_^!qi2vOl)od1BQI4m<&*3>JFdWAMWfvve^Oh%p8yJF73KhAF6$_o?>4~ry?fcqDjA>y?rT1 +Swmp*5w=Lr`LL@GWv^q{ErH(mVR3xE&Zk`^+e=l3iws~~vplYDusf%7R^58M2v67({rTbD3-;v(0>fPAyP|^PvnRigiuU +nHx3gWr(hU)0HzF2s?YQf`G3m&fok5@h(ubS|9)q=-q3m&H}c$^9zf4g`OcvL1H^hiOxFy5Sccx;GTs +Hmxn|Ae##ECAa+*(nX(RhigPI8;=-UEF-(|7$M#wq$8v`3KC?vJzoP>%E{Tqu;|v%`2F&fnV69UN0wN +C@JuK+rJhWgfGvt +CeL8N{uC$Rv`=lM12I_Q+LF6j7koX%mM#NtAkAxQ(2?RoksQI +r~N%`^@8t=W@DO^UGGJno0ri|W<{YkY6&M}l<(bPynsLRJ}Ifho>*^im$QLwEzy7U)BI_8 +)(8bvK*Jme=k8&yCZCJ(?zfAY^vLF4%(dtTTP^7Lk7htgZ0T2$GmYpvlpi)$G_MrJZy>b_T3r2jsC^Ip2MDcp?+MPy*+ +te*ZcPeZ0MsYv|Ys|9>{icG$fvmo*kVWoc+>q6mdfDU;7M`i_{u7^lEU4o{>2_$93x-q7MG#$&+3^7? +XKkCNvU86Hu{!4zP^!ByRG+;SprdRVJ{mE(2AiSPg(BNP%FtS-;|ndV3l%OZDjMIlUz#8Xa|&WbXsLd +Kxd#(l$=2neyeI`Nirof<5m1QA%cY7l7*M?@5$c4OSBX^OmxenYTSU_ +Js?p8se1N%xI{ZNaSE +MN~*~~8;xY_5fkJL#An#XN^28GMzfIl?Om2zpL&X}5`CrZk{0gJ6-$1svjd_EAM=bwwP`JZ5wJz2MDL +UOYA!SN#?yB3Q&+S3o53nPWe5@OCYtFWdY{7BDz}%M +QoGub1sWPv!U@-S7Lxix-D4j}I;mUj!W~8$a7MfY%4_NAI2;U7X(yf`!58_2KK$@!{VNkM9O#r=D~4l +Pjy3yKNqJ{eZ_`cmj_l2KZ06*X!A%H5!TWvh(ZC!|#6G9X|YZXSjp^b)p9b=m+GEzq9-6!|%T9SoT!C +;SE3xDsi^DodK|W_moWUi~IHW4}04WYdL>2I(zwi`2FMEsElt*JbAfZmK91=(b4(o_S2`2zuz9}L#mh +LfNmU!dwnu7<1^H>%mobkAr#4C9-}i4pQ)}Pjsvm1Bkv|Lt(EF%iv^7^RjM&+-w%y##GqZ;OUk}}>&z +Z*)erW?38uNhzd(ak?DEJ`H3ch1uM!iEJ(%WF9)0BiA!;#R?gb8?B{wYfn@FXs{@#i(jm>~`-Ll$|wZ +jOM`YE5w(1^(UUi70S6a~gzu~UO?=xofa_A$U^<-kFew_5qQLY*W{4W85RIPyD4-?iZ@Dz8M1F%g)8e +2x~e6gJ6A5N~hdVp^^szyPl{Pm#>BdS|`q5W`=Kpv(zTgmpPzmRH^0nk{%oVlC6tI3Mmtzup4G58n*W +*d>94K3tJ0sn7bb_u=j~8mdvLnBjfW@v;g4!dZR8empk?TAd4&oaX5ytw1-N#AT)KCXlI~K|c=w!fP= +DygA>;>5f(NBl@f+}BpqT_ +oYzl@#A3ck4?{lQa-%~0e>xE$ZZv{m+ +=sKy6_u-3DOMtdbPHv+oU%LtQTnWsoiFi&jSHdM57xEDQvVxC`JY{VGz2 +)dX#;XSK~8$^8Yi0b^{AslWM(ut7JY8tlBd+4%hP07GJakK1e1j;fGD?j&c_h-c&bNCdnre&fxj}j@{ +~cQnfT$k*hFBAj&fjff)w~)PM3F9;ef3lWd00&^bEGX~y~EzUw2{;+$gF?OWoTJ&lf&p69V*%}i~A55 +lU;1UyH4rJwnNd9K-!v5Lm9bC5u$?HKG%Yw(}O$#c#UOgAZ?Y%8{*Y8uHsIBt4u{L!ud5{PJ+Z>AU$P06!p)blvNiJrBh=YBB-yTD4{ +0g8v0aRyl3$~JCc#5Y|u@yIOCh5eBE#@%CrdTYv@VIwtpy9nM&=QXRm4UT)RQz)NMxAS+8^S%Li8O`S +1BPGVleyliH+bCUlfmHl3xZ*1aRO=-fF(i^u~l+A98af2+6pXj7f1?b$<6pT0F6UfG>mB(G8~+>on4wZv0&RXvVw^5Rom7zY7_W%ZAVp+Fr`q#w8i~=`0OMpdCUCQ6#fc3vMav^Nr?w6Bcy-Vg>F*P@BqB3gVZ +F-$3YHj`jsYzfU(1UmBMqb%r1d4SggYxBD72r)*2NJ~09HrX|9PpV_EZGBFs=ozP@(BR!ZT0874hj&Y +%$WnGNRnfh}zLKrymzO2_lHmgA^WK1A|6Hwp9d^&4(B?;9?3c3P_?|w>ghb5Qqz#QrSWB;8gSL+M6p1 +l?G)=mu1KM@GU`sBKAAFh`vv0@WGM=R +yYcN7Yb+_s6+bYz)-z?;LNT)IuYB~w9$hQ9Jd +b*1iTSj>=zVf%CdDM@x{Q;d_5A&zW$xR_kp6cz}}J6U8W%Yt+yv5wxs5Sw!B +UUQJ@y(=~DkqDe~C?N41)MAxOsvM3h)TFz%{btv(BgSm8sP*&a23t*fiu-6zwCxOrDi{#PxaxJ9b(zK +*fp`LlDdn-yMb&|Ktn3D);ru_+WFbj~);l8-#$D{q2eQfneUn61l>;tmd7-4~D +^Vdf%_vtRbqx(|~!rp$(Jk;z!+=HKz;u=g*Xb503H*Pc~X5nu~SqVch2N4V>PZ?go}b&8RvSzTnsj2n +<4dUwY_M==Of_m4)R4uZ(HQ@#L9}4SiD#f1Z+P;R!kT%JONq&UZ6)uS>4|*B3=fY23cmC-=*6q`E!(I +<%#?wyCTVOp(6ep4u$Nn8KS1>8-YbMiMkW(tzynBU-C>sYeugrwSBL)DgTzn^t8gs;N~#^l;E{?dSR| +pPi+xcQVi>rj93oCAe8{#Q16)u`7Nb+KbIy($ZO43LDCSbgDZ1pB~}Z +bsaG(>2{L?OQILREssv$iF&y#DbNtb0GJN-g(jvVdI +n=bc4dq1=V_Lhw7)$JP(J$dNvH}e-$M36=jM>GKX$gQT)*mbT;+vHikVtnrXEbAL)$o8MA7?eoUs0jw +upIBF-HHBYsFCQn5uNBwTxVKhi3a!*mEt|L<4S?-0)zcS-^H8Tl2hmZ4;fQGFcRXvm(J)PM+vq8+M4a +)26fP^+&>KB|Iv386h7H)7W{L1n%F{;E_!0Eq^C0UJbOCBWnX3!SPuU6!2|~J_kY_-ZwO^zx2&@TQ+N +mc;--6va&Fx6nTu`Vxx*pdSbbpJMIrnq(~F9UmGilj|2_F_+~GlO>k>Ut;bScuer#dq!s@;+~F>|HnO +!OnrIXFK&{CRYKc=7G3_n*@*fXc|?!Zq*>7;6m45ZBLj{H05s-RT+Hv$=-`VLyL+=1CoFCO~OR`n@?kd9h-o0At+_F(t1J3;QO2FKcea0Yseyc3hz&D1iBDZ^+EC-n{`cfEybt9(n`BFHR<4S1RX?(&o14QPlCa6 +>i{qq3*OVo@gYW9gxQMc){!!1EMh5fnpAN*FEP#B630?uZtLsO48CU^WfP;csF-~yX6WHnA?X&N>VUa}dNDw$u1BCVWfH*aj_8}icrN7C8 +4S?U!>*^4cGtoI~`}08^+%S03@?@h-td5+3 +F(B<4a${d*FtWzczrwF*n!HODe9BhjkNMImSP!6Ib`~njL+BS)E5+#MrV4n$FW9fxuZ3$WSc_grExVd +FteYc>6l!ojc7dYgtD(vxac|hEE6a{VFU;BwwQ!~&PK>A8mWMJ$Y0cFg{h?+C0N|hhrn*L^46~w`4~{ +aU054N!i|pv6`I*F6rRb!X{BA1sIeSN4n0^jw_5th!AGI0e^kh?o(x|}v#x>g-T!3C+aXeTmP7eQmeSYT9j7g_bZZ#7~uVT|$Y%RkDW?uUD2bgw|e$-T`lKT>dJL +S!_eEq^qEZ-~Wc)Yl`}PuWsno{|DClE +jUp0;Zzul_K2BLqy;7Hj-%g2{Q)1?okn}9Ngm0hMSzjWPb30{3KG=&aPVE#T(ZOhoBI?*h^eWu53C!( +zJ(4vucKhy>nFY#dsbtUQy@6sRur8H6!N$%}ORESjGI2EOV-xGQtjT`!Zbr0Xoa%d=l5}w +kHWej6M4(g5acL{~IuX8Z$t6Uf=)xmzJT*8+bh?Pk>i5E$y!OCK64R+Le%K1oP;9Vb+z|!D3QOnS|Ud +KVxVd%_EY|XbJSQs8r8aCM$x(GIqal%$w>xSy+>?@m@Wy`N@q)zmy$WyoCwSWOF +LW`0UYIZ*M?M13?(NNw{&^_j$P~a;YeAsd}k{PjP-K75zp}Es((B?N!CdP(0r!wL|kdr1GoHM67HS3B +aw>!_VdE7KI`i(Pdj-ClHke{w;G{1%@)<-FX4kyrSL8mr|qc>S2vD7?l9a1qkOo&vzcD>V`qzXjmjLu +ao?N{gTz|eenmEb16?c@0wn!_d4of9Ke6P*c%@24*plHuBv_V3PbR2f^PaJ7s9#;-TGsmSUEt!+N)%fnp)H*;)3_#9}-H7Z`I3|__<`vyi1{$c2KcoBp$rKi=ce>z6VakFJ& +w+288ieAGZht#Dva@Hw%kZn-GTZ=?Oi1bG%{fm)3$*LrG7vE+nmOi994c8crG5A0OgEU${s7X84k*-$%Esf9Vm*|e$6oUc!eBK|yjbEXeGwK6Brw7OPs^0@^-hv5lA1!laK>(P}baBZAq+N`#NG7L;NqYL$Du8X +vgIo)e7`v4jnLhv(~1IBWiFWFPiq+j?_$`10sI<$=>B`4mjbBW(WqVS7jk^gz3I+#wWXDYpj&YqBw +Hb03iHa-p8#=+ItYma`Osg*%r3*sX%5uipf88)wS737#Aw(h_fGP8=!?l06GnYiba&BMPdkET+ATg*W +p84~<4G!KpSm(%?8DPb@h%xvw&)>7?WhL_s#^{pf==c$h+yTsvn;Rf|O(*f4+?16{Pmp46%>2WdOK+B +g^Ke1fetc>_bofc47H?pR(nLaZ>{U8{!LEL*FL_1OiK+%z(r;ePLF$P8G{3gz_00cg*LDTS^*BXti*v +hSO6eQRq=v#E!>D_gQ_&+b^;9&O_!bp1)Kk4#%D*?5YPLXGI-$8DynkFJ_-MO?c#Ez#Jnulo0K50(5Z +xYmqo0Q!*5O_ujzTUX!vNcsNk2I=1F_QNNSD4lHQ-p-T!*Bxw?VT95y64Zx}ziSDy(a!4@@h!+l)2{q +&iv@-Hf)ulI>+z*Jbd5Hrf}`>1ctEvfG%u!2C%^5f!8DHj$cVV0$;C{;TnGpGS)$rBwM +dDic+sdv}v+-kYvN+I|t5Ra|3bhBDgcUrkkKmK&cDip*42v#?;1=#?v)a|MTCD8A03nI)lFs{`z0X(C +cI1Uaqx4+5hcxW`0LJ`lEPo(x!hGGuoyIl%Bl(fcxoM-vgrGU5tzX_E%qlvE)czMBI_pv=WdzT|wBTn +g(hiem@v)@9yk8tw#eW!IqCh^g?}QMdGTm@KF*9bB6|51au_a +E9quyEy;)?tr5^?FJ=x<6jCWy=J?hCM?pKw=xSP!{G3$#oLGf2MT2NwWRRSE{(J6yQ6RNKHHfa%mfVo5??gdh(x3<4?kzmTx(ziP^6xT`p&5|SW)uXHY0r>einWb +4~<;~@`ZY5Y(61bDsRA97Z}vEQZhWEsa-YRKRwQJLVSTemp`S4aopbUoW6yshJh +wt|Xit)4I!{UpGhL#6mqY4a)oIRo-2gdGu8hsqhs9&DZ&Ojtp8WGlo1lVzu0fcVeycunVb3zU$OiEzR +m2|;skdA3zX#FQKK=V^wq=2!TfmDmpiP8M%GBAD7{E~+O|RRRVTuj +^NQ5)!9G6VQGCGnCCrWK9c9}=MKCU=oY|ar$v5#AP8!w`Qvg~3>GWWlTlPUChZYfHmM{TvMs-B``Wny +74SUjh`*e-L*KX7@V$FMX@EB9u$P8QJ0~!5q+^PdssI@n1-I?b78m~N|KLKsd@MV<{*X$k1x2Ix54CY +vtEnd=QT3G+y4BJ7x1b`hgy`LRfSOfdZel0(TfCdu)cHH!SHgJp-Hp!P+)y1R*h;M5XP8z_DpXASEMp +~iDs+9Do;iIQ}!^clPS|~^<_AhBlRBodYNE+A~$5XA_n@I5OVW0%VKOCLqm0(@5inp@|iu=blJrgU5z +pC!f4pw{m(JsUus&yIY^YDpNW@eWeKG_@YK61*4Q>res`)F_Y&;_KtQFW<@PdE#=RjO8PuPj$nd?%i! +V@b|EeEi)<>%HMBrv?kk?CnCiRl~J(>g_&xytn)P>UuM`-uK__J>30%Wj(_KRgDK!+k5!%yN`ZBaXQr +nA3__C9vcN~1FfI|ulF7|P>I1cPeJJV+jrz`BnCk(hOk8uI2gz)w`>%bY>TFttRtDn7+^7-Q}PR7b63 +_;L_K%=(Sh<4M!{QAcbkWnG4bN$WgVR1{sp~2M+)(4m7e62$#Rhb2c#hDvehlKrICG)ePJhwy8I;fRw +x%M*%lrtn9OsRg?am9Gdjnlf8@z~m0VM`c}(%EK|M$~H77u3ZGi!)=mUX)Q5yL9n}f4+ho$kY!G}+uI +F=}KxR1QJ!cKJPM}ecM#ynTrTUk*X-Yld*JkfCXqc17p2M;c3v$1MX4XJ8z4D}Ipq_(u*Mc9(g>+n4) +xRAmnAk;}XAxRRiKES1wQVXml&*y~yqo;0XQCxTU+@q%t_a1%!*ewW?>fDLI`yukRZ#3A~K&@4ImR#q +bQ6rcxvuT`FyrNWC0JSJnlNN=R(h}afN{q3E==D~hKCqzGX16>sKfvQ4_*cDg1vHEV)-E{7B@`B(LMeWB^FRM#Exs5i7Gdk1y3}Z;a`jIRZuyQ$;xUG2w +_sEmcMh0SP}n^eRi)YIG`tq>l|tx~B`H|cy{w@Y{^_zwrsS?yejCP5YcnjK=D+gr7b(wsCaxQ?UiT;= +M*C$Pz@%G_6FLQLAREssJ*$f1zVqO@5Ds&6r&`-|^2=-S4^!HLBy6}vXemdG{hHKvM^ud;Dzs(sh@0g +Di^3NCg-yKHC=gY(nlgR`Uak-S;i3$$+rTJjvCy^7;yI0!nOE;yrv44jG;BgrSeQb=DXBhX` +HeiHC2t~x1dGeRlG~f6=(;MhoPFCW%w=niYz0g+s(Q4Qme4+@g{~(_w#)OkZ{D1qT^zm$ZJHoreo7ZM +hcWqrZO>C-#FTRnm8oxj8>tg*j-W$p8j`>pZ8>zdO!f-}!FMVL07fPMVwjtv5Tv#FEgeqKl>~)|eJZh +XPjojogzXZUT7zp48HxVPXNisCZD#S!R>F@t&N<6ObZ4>cl4*;85S|}P6nmMd2_UwtE`yLu4Wn&xG*6 +tTN-Ca=BWjLP_0%|@8Qu<{_ZD8 +szoV7`jg`$Op1UhX2WHS>D4j|7_YEf`<39uSnf9%SoSi{~23v`ofgzNFyxg>pY?JcxUT3C%c}Qo%h{8rh$ch7G;ARZ-HOi?)KLD^HVoxPXD;bH*!x5D}t#;_I?nK3k}f3wb}Ts}|tLjq{5iM}yxT +{-3DA*KvsH)}CO{5C!zlRreq7n7y;FPJ0w|cTvIHa6J$YR_)p5<$tvp*4YOa60&C1qR(2+_CbW2Cgr3 +^$8>4J98c3bpot|=thf3cx8bDxn|8|s^W=w)SWDyb3iQNilNMK!qN3vLFSU$ChRv=T5t7_ciLeWpM`~ +RjG26UnaetA+U8f=QLQFs$Y7x9w)(zaJ(QXoz?RalEX}G8Il92={x{Q{kGi3U_Iae_8=6QVwo$czlzI +o?npA5|OTVN&?BZU&dE49}K8VKHAyxe{&S4yUsa5e&IW0Ke|DV1fB)@nIx-vmao(9vPJI(@%JqQ*=B; +^-jmB``Ej2PtpRT%u*n* +c<2PB}v-xeLRsN+MBSSwVUK+ergFn6%KLntKxBxa{Qc?#KogbY=!<{FOoH&lAm2=5q^!|4Ywhd4*+Z`Bdf$`3T9%|yi)X+Ve{nwv2hc!klN?uLM&MFz@4#s8nZtB%8r>`R@0 +A!q@m?gsp8JkxOK+ertFdllZ55kprRqSJ(k`s5`I3+)QJW#KUrt()fd^*JSsW5caiF~yaG^6LAVG~`> +YPRFxp9GJOcA$X?I1>|qrl?n!s_Woux9pQ$?O}`=L$j;#nLndTr^9{B>^hZ6n@Kk?2Nj- +21_Tlmku4CW>qjaw{n(2DTLvme6ve&F8BBWg?GVJy$=+)?Z~|5!1JLwDz54YrB43``T(J?2ooc+Jd0; +joE7mDbD*iBDAPs20;Y4x`Hj%WNrlH;IBb~TSS)nqrvWk<2T<}QMmi%a8XYwLupbQvyAP2##f+oaGOj +Y*B+B}7s{>3iAhQ${lh^aY%JZ~{slf8jc@ExL6VEouZF)$pinvd058IC6HtZ +0d)AZRy<1MQM>jK;79i>Vuf8EuvJj96oC<5QCy%S6oW$(}+hwW~RSb_C?VL7BQqbHz`py)=;pV^9TDk +Vh|%4v$})`^!X8aRXZP+B}Q)blM<-tB`DWKWoQjodF89-?%Z$aD7ycZ=Q}<$H`x1=K0@d*AX4UFdGC# +e4wcglo8De^DT5*uZV6EM6H(C$NQh5ILc%@gQ2}fY&*PI0d|I6969?UVBH6@)tI=EPud@W+|D}4?fA% +vjA&!%NjTPM;(ZtLi|PzHgjQ>Dy6M8j-OTT6b#1s-*M`Ba*#`qc8V$!6?WY#24Ar!Uxi@C<@{VtMb8X +Xiv`KsLf|f{^$97f|8h7*PGT0aKNv!2Ome_oDwu$?8marBC5??%@EO{eEF`iMiPXYrVtYCG%FL7;ms{ +23kvg=9Dsf=+jLciBO7;&0>AZ?0~fWC*rm9ISdXfdH$D^@P!hSzP2T@^(jcWH6mewb~TwiHIz@%W(|2 +&_P2Xln|VjuC8?5^Ah^uD?&xwN^wOKMig|8QM^6wN*^R(qXqpZFPwCLPZwe? +EG>Is^Xv|rX7}4CcGz(Gs4)J3z5Bw~O1?OJ;e)$-ejL#4@NTEy>3v)^1pMT~-rnxVzO?sYh`-u~V%S3 +HYaAl1GbY0(Vi!XY$F2;FlzX>vU7I_@?bkOVWfaNLz8?+UlA^rv4>#W_T_WK0InfWQ!u@F13y8sK4}` +aclW=o@qq`g(aKw;xx>66Fxs15JyL|3s+WsbLbGBS2HH*krU1_B4PmQ}1v&c33vVZ)dNIs|e(z;}31= +euQ-wo9HbvKF(y$VGylNVAbMUN^6Wyoz_Av(34^Rtg{IR4TD_iX +&G0>CAFUo}^caO61y=P7f{Rfvq3m3RJ5tLRmMU8;!|T$UUlHhdl*Bx4UT||SO4^qs8JCd$900pUM~&g +D548FbU2Ji98>RJKF3<-Guk%n5G^5v-%TdWwF-j{-=1&H*fokFD!$+X!{YcsE?tCepT3vY?-Z=tiUm7 +b@qY4?oukIU;s(L_J8EA>3tdzsE!&h%XDP+CCs7{8EminS?7&XvadR2pUa9N{bd3(K1#q(cYI~C{Ir* +$eGpZx4poLsGi>hqsmRLAqRT6}iwws@KPv719RUmm?Yb%&>RHfgA=>_qjEmpLuT=XL0yE1m5tTvM{vrJVI<4WI0M8bN*d@r8y6~_Md_u)9xw6m$BN`HpUvnsrx~M@Rb*y6Q8&w@ +>vC515bndMi{@eat-uw@CHzN8U-$~S0S-+9lvkPDm~%iequcd(_$rxp#M!rT8>)d-;vCs0qbeT(0h|F +NlFqWcNJbcjqjWJb5Gg;Ui!$Q-f#|>@fpKNgo5x4Zh^VM-rQz)>SP%=HC!Z6%Hav7I0v0>SZ&B=HX3N +KuDDK9H4A0IQC|qMSwHaX0#T>3Qr9Z-)_9*V=kJt*sUjr1Lf-NxL%2fGXlhZr7RPaWFr_|Cv6~s8Q<4 +FrBcBrQk018iaFdYzwsj!oxs^O{+BUKz~1G7W*76sX-+haU(QBe`dWtk +|%&9;|fL<5L=xI=z`M6T*jCyOug5x`p{oBO00*ViErP^eB%MJUIrjFWhCKDns|Y7zk|_$q(ylyF~8}D +MFG+~DQ2u)d15Xid87k{`_P&KhFkiPZVPBsfz*p6kZ<%9G(RMi?vnBx770>j&*W&)Z#V>7gXlNx{}wW +6c9n^?iY*vE6GzH5%3>LM4}t2(S3L+&KiZ17=#mAgn~}QgU=%fBaYiR-<%TLvRLH|Dxsi83N|?S?NL@ +FVz^DSEghQ!Cjpd{ymYA0+s$2~X~uOp^*T!DQ&JSdX4@3k +761-EK+rWuax^gu5c=ui|WOdUHbO3VPmpr5k}`kh@_-;Yp_2s@f^y8%Lk;5n}2pNrhlgx<6&D&Umwu-8~lDV?)>`$mh{8+$#8i3v(fB6Lew$;^KyXd(tv2A>^gxG)knt) +$bfXPq{{0@{-{E&-sE^42K2-4N4mh+E>S0l9?z?6lrJPMQQxTN7;NZy@};V)+Hqw315h1$l{3%M*j&X +WsedX5wIs<1jE%S+D^ri_`A*I=9xw{i7XW6Bh5~8PNkbp4kTW`oN3^deI3AajIE6zwsxFh@V%rLnxtW +(+zL`gtM;S)W)QLx|vr5@)8@;j^y4th(i&JR4!ulez^4aygG@*jLhR1ke>;oF6Ai#+jonAojUwgVnj| +v#B$+x`|Ddd}BpLWm3=bX`)kH2^b@o>Li|ADYrN&oBK(QeN60>ho!z20qR;Zt!K_NSb1Aq5wxn(;1s3 +gH*}9lTFNm;1&-V8dFRpY-Wu9IU*qL;(Pkv7iZQ^UqvvsQse)dyGZm|dPVy4K6x$(cni2ep4&x_$>B4B=Xq@!XW(-(FL_dC(5HXCE<$;eMi+oVj^d +wE)nVM15saZpyTAd=Ok990_HE)f9z+H%9&<+ovHRdS)CwBg9uWap!;N{xp;r8XUyz-=<#)Zy^aAw?qk +Z7m6HDA-z{aKg%pC$ABhKw9!+Ni@csKl_b1XQ0>234|ROMD63?hWhIrdDtW3Sago5m{fpS9w3l=RB)@ +&C#ocbvA*tSdQoE1U0$;OO!fFL|85tNzvIhFkqKWOjgULG8jsV0G|mUAd~-IBGyoMY}Z5$F{T*U>4a_ +;D}5TboMox@i)&y9byNV-l~3Oso{U}}Ui>82=vDXek_EItE0dh&OYUV}hb&M-q`X>T(p5vyJo>$=or& +GEsmCVT=w=Skte!x#MKVJ@h;l@r@)P6f%jYPEV>ggB)(mP!2Mz5$sFlGnMr;b{?!p;Iq2+ +s=l&kmoTp1t6J$oKDmx`~Tf8M10vRt!Ud?`!oPr)(kd0#xV%bFIXr{uTM6NO96_g0z?v;%qHdG>)KtT +Z* +V|_6b#MlpAUk`e}wpQva-e&#^3)GER94t_3D%A>T!s8}13})r_VYmqmgH_!h274U;bzje9&g5BQK!R( +MmST0O^bVBqFNZQH4nj=?VerQ6InbQpiS6-dfakz)#wd0MWgQ?lYj(>Rf2aPs9chNJb~i#GI%b*^+0^ +xww?->gAjL$^m#%=bA{I{eJS9?fiBEQb%eV%Y&FE!{vN&GQpq=-=Y@WEi8B7iPfN#t-Xp7)j0{gB`*) +V32=I*|HatYG~a>qc8qkF(*cR|7V3(*eLGHDI(%5rZ;orG4>a)wusDKE +d%$X=k-#hC%qOS`Ys)%QMIIf)$_3Usq-9JJ#{4Z4l!H47Q{*8hzyXpmlI^am&^J5w&VH4?~!w|x8D(h +__SZs3LAlyOX8mIf2Qil1kzU^woYN&NezJdD;5J5(%Eo`{+uN?%3C4?kCRJ^e>_1i5nfbIHM01dyw+X +<80zzXUChR-1THNSCZ}4JwFw3~ZcQ4;HA7#Ljc5qFKE+0xQFG8R +r|T>CK;`B}k0r1hmE!l`}qLXi+UxgGNq_CdHyfiLgWuQ=j0w>%mjO|L@P?>TzFdyo2L6`+eQvQzOJ@% +-^?;rz?xyc}U@NptJ|IbIOhKuO0Wh4|{+;_(t371*+fJVe2_Q7`%diUYd4iB~2VrEs-Y<)G-uG6Co`9 +U4cdz5MIvp36a*^t=-&Q>j6=uxo34Xt1kwrVI)sH(X}W;la0d)B?{)648j?(qtk$?RHSaBhbVimC2qC +Z)ohV1T;FG_p4>$!(}N|3&#Mp>Ca#pp7Qm-nr95wVHz-!9--HaVLd(oFxF +uM>*yghVT_*refLd~f4Qws`)wx$UxGE99Dd&&Kz)Z-xWr)nY8$I>V;o)K9DO`=3GvsJtH)o{OsUSIZW +pWUWwjX{%;#EfQHFE0rW*!XypzdftMv&ys;mhaCF4E%LxzJs0d@tMy7=sOD2;z~Y1D`OeY&mz6NwGTd +hc+J&@!be|Nb)r3X5gmK4VaJTII02XQW}L*>qfqF|zDj1(ub{gXkzDPLgahNmVyFOl_8yWR>CkbK=HY +SR9{?o3($Z_Q5ooGnb!nToaO>{VUPU@^;{i>g4Tlbl=QBcR$+g1{=G=7!3|y@^lqm8T}UGtyUbL}cTRiRL9;B(dEf`q9tHEuZ}2`42L}L?^qS<$C4sZ_LhB| +JgD|g2g=!X+z_MCKVg3;@#q<<*N1)r37Y +E%A;=l!m6;3zIz`((mE(O?-2cL^qg@0BzJ`3>Q~p?k@|f4cnT0HckH@3Q@$KAmj<;*ylo@&8S4`#%|q +Q~t)wKBBH{K~%V=`z@3uvb+FKcF +5mzHk>nV~M!E|Wz+vTo!0#pmHHEGPL*pCzw`ur@|n^Mboj>qHTzbGR4wbF-t=5~~rfHz{ah_7*ly>>I +7v0>94jd*9CC0b@`hRz^jMjaJ@Xty2@T_mboF<=xkr6%ra&o+`>tz%PAMGai!q1FYx39J=@uJ1zYEk@U-+c9f{(KAuLZaw^ocxj+ +<~v2=TpOq$Oo^>%|F>5_4x7vix8}!~5g)%b2!{1m>3+$+zwE+>{`j!t(G|&1j#rG=dXr`kcg2S-p5Mf +`Wwhg$l`cqPHSaYxgzbOW2@EKH{EpQ;%AjnM%w8Owg~-gw(-y9acXV4STi1#G+AvWqmCXy+>SIhHEI} +j_eBv!!vytaNwRO+DW9`>{cHD-bdCi*ZHsn(wqrAaEU$*QAC|ft|2^b3$mIp|K-bOI6cO&n$oYrDrym +y>9(qIDcz$-L!3(br|sHMpTav@x2yab2}`d>q_!rA)c=TzMB`z3iOO?HZp{C$w8%t~3S-Wf!tzM5TI+ +&I>q@DZ>YO_dn!W{Tqc;s!>uYYcS{mafff*s7^?SRXRpIX3Z`6^lFIqmo)eEyQP5%nW>HUyYA9_n|xd +e!LuOw^v~f&3kS9f&&^hcgo1P32cDAn!91)ZGUcM$-;@1@oRJCCQAVYN0JyRNiojLWFO5!ZU8MzZHC^ +gc-!d)o94@k%{~H#Zj6$pxlenGtB`U~T}xzVX?lT;iRFiPnG236kVU`E%V>MPwT%`%OOs +nxizO9Z6!~;HX*yJ~?F;&GK!f!rTzVCtqJjf)v8zPaWK=!8Og-J-inaoYAgEgBUisI1CB@CQ*IkVfuC +?Y!upUv&-0HYATJWe1Qv;6Y(K9P^q>caqn_U?0a1T27ru}=Gr*yUH&J+fA;i0&3(H^A?ye9d;%IdeCt|_z4u}7$w#B*4Zm4y|9cRj{$6PWBzI9F`Sizin)__`SC1t +M$>zw!Jzuelq$ra`{vM{r&_E|^Ll}`B9Pe24FTY?ElpibljQ+@Lae%upJ$##g!RDPX|^C>KLT0yAdi!I)q%7LG3N6nLUNjw} +jV1K`^5;)fL`-I3XTDs(Rrv@{W6Fw^wPm^t35p1jR&am!V4A~~!)?+XWy}FlgGYp`avvsz1FJ9eUOfG +~A8f6+q-2P&9?R-eDjZ2{JG?xtDs$JF5mMQ&8GG+H7&ZZL=W^P6^rLV_vtX-Qz(K$XSfzTirHzja>ug +)z59_)CIx3xZwwyhM7j1!;;2Xf%dT{fVA2O8dsq>Me~0CgQ~qJeFg&2`oK{70UuZeN1bWjz-9rZ=rJu +f|V{AzA|AKh}^0<2`soV2VNdKDZX9+D_1vh~q5s-=wN9?>MoEOyoprvFsZhew$r}R4}HLw^|lCnrIO| +adVTs_gxshS#{W*rBYJ^>q`nSGiGOwu&*wibCNhN{b@p{9TfgN=sb +W=R5DOuk`GCc9zECcHu`y?oQGOIAtgrBpFgrrw;LTN`U135J +K^^SIKHzkWQ&P;cPql8M_(9p9$Hl~vE%i|uUnULl#f;J`V1-*Yz(VFIx;%Zrt2MBBdnZN9WFlqsX(?M$R`Gf3KSmLS$ +_?m!0THxj>mmcxkE7#`qj1-fLYJl-|yS2QL;mF#Pd6(X6<(o7LtW +id*97WFaRj-Un{OyMSQNTgD(F_iMxPs>{pA1V<}Lt`CsBirc_4n`5q!-}JE82N`Qfd4*%9NlUbM#Mvb +2s);Qt*U#VAqs51m|Fn5>)K$5xodPXcs4zHeZHj#eKrwh5opF5=oQdtB&dg|iIWWQnl0TP`6 +HNC!bzgxl5P?1)($#PvJGYZs%)%tcqP +<*t_R~J}6r)XZ`hq9gnLh^N~e +2p!b|71Z8JcWyCizFV_L6}!EDBn~r)`Mty+6q|xi;+;4g{|i|5DqEcCO)ko5qU8qPdSDsX*3M$LY2LU +%svxI`GLldaDkOD91{&V`o%$wG5B{(Y$d+WEP6tjg?HRO93KBCRs2v?dZH#`iWlOGhO1JDdLG>*D}W{-AY%}usV%X*A!Y#T{e$2PN}g+dnjnwn%!rLuC3gcBBPR4hacrs +i04o4f`OY5-eSeIy8!8kvLG?*e!lRN%7d!3Z<+nG%LpAlufIWunS*wo=7qnNL!pQk{2G*t~fzJGnwnn +Z5&WJpY7G`GB@>I>4zDES!$Gxu>4X97Xnb4Ye(`DrP>%{HCiW8(h;_os$PW +>P&JknKY1ujawoJCJRGCThYK_^gj8;N1#e12GKQbn=WgAYb-Ago(hxLW7x3b12~MU(hu9N}{RjwSLAp +1GEN6WNqmok?20ELV$vN#)f;br1H0)gK@o8I<1Hp6q$H;MoVnXqhiB`{c6RK^wSbLjgyDN0pKFtcv-k +RrEGIn=@MVXG8F@u+PfwrD!SB-4)`A*>PFy&hFTp#}0vWsp&gq2lo1gWQe=1nTnEII(iv4Dlz7bv#Tv +B57ZWczA@smnWtHLn|gcI@5SNJE>BNbz)m^p@{j@iz21jitW3KlV7!h_aATYe~NuDUZ{7F~ouI1te=7_e +TVD@af`Q{Cz&(A*zN751pS>V6YG(tJYLGbzuWdg|Z!QtWiqw|X&pj?{!H9B;VBMH@V?2rxMP{xE +%n-TZ{|pg&eGCXt=AtrOmVi}((*1se8Sr9g$H6bN@7`K7iK-yG%R8~giARK)Q(`|TfBNuCD$FN(<)Qr +`hBjG%;ln91F+BOWNjWJ+qg3rSw8KMROG*7G~JO3^_=t`VET+uxoQybBPXin0c%+J4TykL_h0+^>e$O +?$3M5sl~?@vPiHkEH1iqDESghNEE}KDm5NbIo~`!+>?tRK@@{k9Ri4;AJ{<99S}vf74F#kOc1kjxgS% +Qiou}90AJn5r60pUi;BhSk1`Ji{VfxPM)O8oP3=5p;GDK_v=>hL$G98ElC=^n=oAccy(5>mNvlm)+r2 +vWwF<+F{(^LEFH%X#RhNSZ(sbxCfKm_N~< +|Cb#v&HeFVdk)Y=yX3|ow(DvT8+GO)@QyAkEwx@TfK$XG`k!8IaAX})vGQRhS>NrQwcpJx&U(>Sn}yq ++h)w2j1|Z=dD^*hy%HO-GH{vUru9%a?O=MaoYi++M)WRG(Q`;G%X5m%GtEK +H9;}|snR&kxsG+{!NtE?r_l`F_X9j_p_k0@>Seh4JO$3%-hrrT6V7U$g{(|kxG^8USF}qPiQgKA>$|F-jB3zuO1b%ZOzp~qPXRt`1K3PoU +JXwWXnB149z_a-?bwxnL^y3K8$8WYaB&3Al+dUeZS9d7)DoW-Xe6|p)Bl_Io`;^sA@Zy9##8#rZLKNT +k~sdAnT5=Jv^O1$r6W?N7?jRLyKVv9a=9CUhKlT`G&SQv(p!K`d@LRH^ShmWJYpkCdYGZ2k|2K>A0}# +xLC!up+(F(bvD69Q_FR21k$Cg0v@P90z*01ySDv8<7qvjP6|QGm%KSsUZvdvtR|Zh54OchxLel1VB)_ +O{*q?u)m08gc)4lk%f0u?OUI6+nY87)tNr9__xMoZV73tzwK$__Hveb!jruoN7_020o;;>LO{o$C!*z +(+BU&>+es!xI&amkOCpOx?5ZmA#ChL#v`Z?YM`0ph!`PJ>O1D11L1}rZt^6IY2+SzpK*^s|76#3(iKl +wRMs|py^RWiq;apkaOcs_)}%j%6+Zslj_Up&VId*p9xZ(Nj13h%#LDQwXK#<$?n+&j*z3Z2@}|6yS%9 +7opZ%e6IjWm=YOSfwzT6=qKa`D6hqa@FJ&ahR3MLOg-ODTH}0>iYKW4l6#Uxse>B70Gl|DHH52-$cQX +#{sEn9lENUmv0~T6qVrxrZ1Yv+>G}!A2u{693hsf?=agpSL#@da=l?H9&)ZPLvw32{-dUb`E}riLRi7 +Ep&6CESQ=bp->ebf1tJj`-h4#y6l^vmfRV6Jo+F3ENd-$vd;W56<-IN;_Ie!~gqibb$tL!2xtyw!t3WnYD9tT^{-LBjJ^>0Q^PTQcP$&!%+ZE5 +M}SS42K11}_o%F-{L1JySv4=(*P;I$$1+;2V<0Xk-bd>X_C~4sRxM@H1ICO^?wctUAt%3ahi9wgzWtZ +NA~lcChrhs$3e!^UYcvh?VgXPcU?3Lo2wdCBmHe;dt= +3=O%iBY20L49{!q)M_=-h_eg!IGMytI?UJRcIVDC0Qv`BK8)+506So$9Uii==WF%J+V=5dr(8F-Wy_p +Tn=-*LcV+TKv`AcQT&qKxYs}q{=Dy{)iKC9v3b^nnz*OI`4>=AZmO=MG&nq*u^i@3Zkcx+Zx~4?ddT1 +%}Yd~dI)yyS{$^x%KNknvA&g>q%!&}Bsc)Xm=C}u6kG^+!wB}LJaDh6*>{IIX$q5=>bJr14(jdEas{T +il;#73dOIitte#DvRK4VgvKIW92B;$DU$pEdx?lp!3adQ}i7Un?~=@Swa>wh{xY +cyT+B@+w^Y643wQU^+k_v6rHBZqf%@f(9tZReNUdcjM^4ZOI($)~-;v_CJ2`etM$-QL*HKZ)v?;$?J! +M2^%_cy6bQcJ74=wC-Rqu=#SigaJ??ZFE*yS&ErC&1_w8Hgn~YqA!g141ztE(fzl=7A!=0 +T+yWgXi3C1@l$k8q>Cd+HS6H&^cwo(0xR87`rOx2`zw~MCBg71ckAYz6@=ae^e5u5iuHQUI%KoJA(lU +&CzUdjB{(p&UGk+}}DW8bPpWy8{|;Z51F38h0kgY>)n)@t@0RRBX0ssIY0001RX>c!Jc4cm4Z*nhabZu-kY-wUIUte +i%X>?y-E^v8el22>gFc8J>`V@ms3Am;`?4^)H3;A>VOYW+cbieEN=T?`}hUku`cV@2 +6*Lt<}^1_b(VNCkj1ya%}ko&L(Uj2FOQ*!_$xb;SqFE?zBoHHq=pLGsRHDUKFJr87M)EiTWVDIf6rI; +xLNNd4!qr5%7&t7Nga*i&JQUR+pK43%2Zs(c^$2Cz#RuFD-UdCL(iWU~J+m3SvImti;hCETa_76&d=g{x&BR +etF+{)I*tPv(@l9|GzPZO)}`pDjAq?e(9$aLwFEvYy_rAeV|###ry=qId8|U-@(edO^FqoEb~uBaE&TTp +#^`pr|iq`meaj=P$V}j`~~u)yYr!4^T@31QY-O00;o{l@>>jmU58HNdN#@Qvm=W0001RX>c!Jc4cm4Z +*nhabZu-kY-wUIV{dMAbYX6Eb1ras&An@z8#j_J_+7t(quE(WXH+)tMVixnR+dVaZe2XOxNUcPy~)fZ +nXV+0m6@z6Y0muj1LOto8vv3lb@x8I{q$oMBLYAG2m~Sm0pu#rw!PneTOGk9&t*5@u2STbh({9;C&+drg_5%#+>v-o1-=&wGF9z0G#9`dj_=U-x?IfA@EXG(8 +J9K^}yv;Qj9^XoY#JFg=6mB|G*1{h_Kb4z`bbdAv`9FphdRNxA8L`uFG0pFjKN{^PpZWOp5;Npz-p+G +okGd&I +@51`mefe*aiM+`yx_DI>*qT%094RZn!LmZw}DkzTP{M9V;pl~QY_zbM?+_n?T=)mfNkh0<_mt +29`jWv1E(cdVA{=;=D#ZmXhI*Ujwb$$C?sE!D!gjD=>qXlvE2=_2(YJow{-?wNOLzdFQ4sg(NJHpnmU +Qv3fz?Y)ODKfZb0i?X=T(@9IHIP9zaV4r7UTvWZ)h4MqF+bX_!)XCT#SSYe>TyAuoaatHDcWP{>O4oe +%v1}(tt8!;Jd#~2JOz&{L2mkTyA3ZYbYtvf2{+2#LMrZ}!tpTm8zN!VN;RpZrFbc}xQSrc9*otYrYJ9 +WeXSLe?HZi8kVcje#DS+1SbPPoA!daPBGp?l9jLXLE#=flCwJzFGJ6^xBH`thwRkt-qhkcrafvUvdxu +$1%w%;o@4H;FFNn^tdverjx1e|65wWIupUY55gZ$lUW)!oBCV>+vP?%vSprEFK-r5zu{R|jRp>S;aft +`3=})d&7A{Xx%dTL$g5^+NGW;rYr|gd}yg=8@B2RsHuaO95?Eg}T;)w?}p}RbRfk9c%jSWn52wlpU67 +d{zy?*DmU+hTg-!-G6kd6|FS?!B!reY-E?!4HSP@3%(gqPFFJ*jq}oI@H;ARy-Aq0^T#{P_?=p@C;Zz +ZZJCy$px7w0O&R!67M7p)eyiZY+1UfFrXDKU_TcMtPj2wUH73%Rp_MHS3KW>2@^xVYc1I(ru +(J{7b|7*_r0OrFH8s_R3fLdm5+;9&3brNw*?+kPXt7yyJ~qVsN~UYJbt4`l`x$56>QX#;Y2fzhk%_sA +;bUtCE0fzVE;~wehvwpE;|U$D^M2q73e;E$%SJm8|{)Ra(pT^q`7OrtP`q?8T0dJB#yeCZxFu5H)cjT +B+`muj{&_>qCtH5v-F=X&UMxlxqMk}_;BFImhuXfXBDd4^%qg8JMzy2<3#ps5mR0^vZ9y5I +!6R&q{dp&jZB9Khd%PYYvrfP3u}gNlINy}plzP8~>E&dA5tQL(wflHaB_#y6hJ{5Vi1_X)2 +B|*4aiiI7bW&GkCp+|MpO?o=3%_zo#8ffXEWrySGtS)o96NtK2u$pe+zbYj5L-q>7&T#^6njIyPHY>EcN7!dKoqZnZcT +C#FU8s`~M^89fRUHdS#K)Sqwf!i7G-sa)tT{UaF2)Sj2@g0!u=_pvVC3yPlVc6?JKOp}p5E(n7rFnO| +tcI3Y4Jptk!NiFMWcw#sN6p)U2SQ5e%hwXEIW&XJhh +IX9Mx9Dv2p>ktXC0}-l;flTkNjB)^uOjGoNm|bANnub%%c0^A$wdz6!Mm>v$J_J{x>9I8ozulBG%r3n +dQmzBhQx6SP;G>N*eho8F)b(y5)IZJ<{-&nmX8ctwj5}Bu- +<<__dpoVsNOZqepY1ZAy8gIHiq@Xs-fmPayUbaL#B*!Yw7gd#Amv?maNdyn>>P7!pi1}ls%39ztE;`U +Wfpz@2OHH@bhli4BF&apw|SjqQI>s$*{jfU9cdE=a8SXHCUW4l&A3q~Fcjv?}H~%0XVVtISlHR6rMeZLGwxYg5nsx +IYO`!dHYSGhmYVT&FLk)R+bx3lIQ_)i%L9ekmk50iIdjAz`_L#BXsW$TL<{#7=s)p`i{)+bQ-p*04Mr +rY|QVjK9U5l$il0Y?0HSnq(A>r6n8j@psLaUpOve2e=9pT`FE;-dlQ+1hLDz#?@*4q^K_OuInvhnWOl +&v0Vsuq}LSN8S$lzy(|rrp-N^eORVbb06KOP-v;_&SbGj?rm;s!h3$t{hP!U0ZQwp;h6PW4Pl@6#(U{Y1e$^P;>>OEeEh)3$4;yz6dt1)8FH2T +>4^80N8{weEbz(feV&=bMG-zp^X#d#qA|7g~`w9;1Wp`(>xP$P21sie&-f=Ge-(*2A+&jx9)_Nmvs)( +C(r_V^bvdHcp%0HU0#!dV^kx&}Pzo*HsjU9hQb8UuP_rB+ku9Mr~o&leU9+RYI|!~@rIFDtF2 +g+8m-y@J_^pa`@~aku+Az-2U>DsXHHMk4OSTpBf!uYLM8U*t(iWG{rL3EuGy#L6G%T7wYLkW;TBM>8G>9E{a#l +PFJ7jnWY>WRIfty9+o +sA*%e1vsqo+4*W*-#*6Q~t%vZ}$7-wH?^CtXA3Z)o69!de@;FiT$5 +D!HkY63*_&8Cv{9P-vqcpYtJWdjwz;C?xMp`OvlamzLNecg%F-38bqFTNuh=QHc06`U>zU`O>Ew-ApQ +7iAd$GN49;vzgsP$p$P55GRTcTb1-g0lR(WbpW0El;46^$GFKq7%{*Z;#_wN{Jq)@C%DU@3LinoWd^$ +KyQ_LKS5IF$>oWTDw=F}Vz|l^T|L}?R84rHc84TLzkar(D36O1{k@A?3i9}bM5u;M5RCr|@ +y9%(W9D7$qlq6eZUu2u}1kIw3Ccb{U`O$tsD{s5rG!R>}I1pAe^2mYtkKt>aHnXfNOnBqv$k3{K#OC- +9>a`0)w+}a6(z_vOB1oT~@E&Q&f$M{|{UGr}m5!n}trZIH9oiX^`wXO>B^zQlEF +}aS?~7_tGYsbHa@Ke9{5BgO7CDf;j0$sewCfhLw76`Mdlv!k^Tq#v3_8azdRRPKevhDU0fM>zBw5=c} +@#b>UY^1lM`x!2O`#7PzZX?YMyd-*|vkKWbh+Dv9_f^ydF(-gni(Ao~4Kl+WwYdtxs8BQ8~id%g?8@= +)Eu={;-$M0$1_;Nu=QRHJ`=^jMV7!#qpv@(u6~PR9uw_s%M%=by`@!EViEs^2Hd)UiA&R0EEesserw^)on++uu$B1(QX-Ya@{l +O%XFFzOp)Ec-VCdbd-c@g+6?^D<1chI~t^q9`~+vMUQmIy#DiX@1fciSIKQdqFSns}vS^$a+_UoGKkSA3-^$;&rc6dzGc%?8?(ueZwfN41@`KQ{ +D^MASyZQv^n1s}7qyD=MOEf>@>naf^JLCxF^I1S;ueYt` +?O#jtmv(d7sw%6z`B59R&5z3PGVPlakJSy~@UwO>@Vlv}VtSdW{V4G6y-N2HKlhV7SHf}~>`G|L+G>_``q)Gbuc6 +TcZ`D+6gFOg>LzH9|NpL7L0P{Bss1iSjPJ#Rpo-T)$**a%iK})O(Y;$`;eqD7UbS~)vrVIwRmo|v#J0^5xKsV2 +P9r23lS6q&UUiZG)(X6Oc`J#FztnHXRZqw18w0fp|Eg4t*~e%#aXtN!h*-&6k`_MbfM^)5cWf7ko)>c!iNYC4&WMvoh+0XC{nZ=YQ}fA# +j_SzXs~Ff(-x>$(O{da9bYFJ52tUcdXx*}V6kpWc0Z^6}NXx4kz{-v7BOH|`I0vAWzym+KGas{Ct3_q +O-p&6C%!d#^7(e!O_!d*1uYtB)^xFW?wtLLv&FPqLj +ef9q7r#H`EU;Na2^7QG&+mB5Hm!ZAhxX} +{_wU}e4b4qM-!~1-F`XCBKc4;Y?$ujW*Nfhh3g#K<(P#!9p4L1}h7J#}UOf5u>HS6T-GwV~&$6l+(@v$naT<(b9&J-K*)q4lD&J(cTx(QGc3xtx{@Z7i?re}e74{&$} +h)gSsOcTri;G0Hbq>ywK#sdA0}b{kGxE4>0P9O#=LH0b}N-wO!{!s;=&s@On67Y=xtD<7o>ANqs7@r< +5?Ngg)T61Z@opW6z?gT8^T@*4U{dE$d;(l-v)lXb3k^rn`+gf1L#y59tC^`ki$-v(h0zCpi>8t5>X81 +L>$w$65-1}oWqCAb{T3~IkmKR-Y0s!)AfWq%3=w42&+I}yNz11&-^7UOvcRFSMr^}`7`E0Z*82Wcds3 +kQ6tbIKHK%&>(G{9gHeMH&D+=)CWCJyBU`6vgH#aC2>0xAM^m{W6vgyNiA72@U$Hq&3`jUD$Gz0SV-48$4;~LBvws3&78j*?bD&Lwo=g3TJ&mCOLocFC^9#F{1dG|E +a8FrkR2y85)4)!QX1s**&WwPkLXXnK|Vy0uA+WCWm9T&A(9MKLs=OWd1ecPN0JO6(6QBPSC1G1)~Q>O>x+Mh1~fXHlRx`Z;8@a4z7cKyW?=VzAo&!xbUCJsM&;m=&j{2OEU~=UH?JQ7QI-r`bWz_32?Vn(S$w6=viEV$V^b;OjuEX+%(7W@9tp&wPvO +nG&Qt*cdf8heCVyC(;7w_OlNRMn%6c*s%XBSg&Iv+{#A+B8SWe1THqDjLp`N#Me +TlDTUp_kyiEcncTyW?`1r1-o|^bm4&OVV`}p>OHpY2;9SCauTr+ikdR55Ec4{Bg{-47_E%tTUlhp}4H@~o;62?)^aVV_CBqgDP( +P^$o41d8Z}-Z~tTxRHY?`Kl=PWd4ojtdu!wBkg{r!~4JAa|1>6}0#u+N=|ih#wN0>Qr805!2Sh=zG356y_Y +u;;A$yfjvE|i!vyT&VCUC`FAXo_H*z2ZGGl+c9(-uh|~+aqL3!S(BI`R7+q*5I*z!OCMWz +v7@kNKnf|Su!eb5}Dy^QGNP*Z5L%g!}&lqE!@g8V2)+-iV7-z3a_8Me~nE3$?2+@{y#Z7XaZE6GykSvf0F$&Z2eipIZZu(7Q3F +2i9ZMXJ&m#vyg$oLYBU9cdJS^B*JgtM?DX2m#GjpBn^s;6Zq4AnuJ-8vz|V#JEkm@3A-@i`%ZR$U1Y& +1)#dG9cy$-6c?Xg(_ll3(Rc@VgIEp2ufFR!hkMB_Y^fNJkse|6;h`dN0cHxne%4edKPa;66G@(tSKaN +|@;Q$3BVrw>}}s4tqYy=8~RsidjgGs{0j^s=R~-NTWeKzN69rg@%bC_jS5(-9Myj~xPwN9=1>ykr=RE +R5xRjxDt991Gq)=1HJu+SI-r`q12Qs3oS5JMU63QAa&&J_eG+GfjO-VTTJ=KD3x3Auo3E&_#;EVjzN! +$d|@dpD+kIVqV&6tj5N&FNaaUBpw5G%6PlhEmXzc +Q@$(=AgdxK+*ISwA)@YZ0~${V$j9Jay}=p)?rCQg;Y7Ot=vgEy8u!EUO~)x_}`T+BDlpqiESM)=k!al +j^P*nTTEbJO#;a<|5Wy_GvDq7!fBPKpDcw>(^CfxV5_L77~~zF~vM(^7rhB;n;9h<2xFbfn`rT~Wr7- +|;0svnI0@3`x%0_y)e6xhnD2o@pa~Z?o@JW0!^_X!y6;u0pBpo|wK3h=80-cyMoVU=qY3K|N=dLq^Nf +ylF(ZBVqU{kvWmZIU}Vm@7pLlfTzV3sUn)n3ZIP$=gip3MM?(F2QGy#CgQNsDI;B!GD_7J;>5Jxq4k23|^Q9#|NU>5?FD1>3 +Jwl-1%;{*cE?+fv@dtna}}{sVV9T0*zC!*T;K9o2UV2z=2z}G-tI!f{& +!F1lG#hz3=Nq9Jt3ONQ4{VgBqsBJgRo7&dG&EKl+`M-?LnBTc1Z6325XaeXId71_WPBL`es{r9R`^x# +D4dF8(RUn9B{0INaIW4_IF+GfiW$B7E?TAmf@nCgerKC2V32~Ukp*2iU=cqZhkz@i%!~@g_1!iJb3XY +qoA^7&<~3%=yM4Ut&H)P@GK;{7^*g9&WQe|VgdhMat-e%Qb$KSC3kS>+Gm+4R2TbAG0NH5oOmH-sGHl +@hmD(n$?&J8V!sKKEk0J+0v7-^978?6Qpi_G`ae@3&I$QfeKLJK*KSN}4{lM~PX7vYK%#3LN!1;)#TR +#xc$g1{|C=Ky;X;z+o4?#IC@m{GtI-~)=!hSYV_yYuCxdhPKc+UeHW$(H+-lKibLz~D_y)p1gCNQ5EC +@U|pPt9igEEh)ykR%|98~A8HIAV{1C}T2!Q?Owq^}TeK5p{bno#hFYpz{GV0J()K>$1w0Hi0km!6y2&_mIu +uKE3C&HL$SBAO&W@)zKPnlzc8}WJG7^B1N2h;^N)N5pobKDko4bIp~O#pIbz}Q28Wsi0oMTu!BMbQ)R +ELX!%kgMXY;hqpV=})W+NVTXj3(?vWQS?RGDT74ViF^hUgK9No}(*bOZbJ7^ty@nWc@XxOvW_h3bFIU +qqtKID6$#2_U46-w(+cn;_Fy)RUb84@8*0#k?+%kPlJ&*C)rjH@K`mFfD2m-4Q~90&#*P4(g3^N)-$) +9}I4okm@MXiZ7Aae`WELWF%jSeh^ff=_lQR1qBDhfMy6c?yI +Bx_1f!YNgia#df0!0wBYcZ^*O@l{TD00=Czw+0g7%_E?3@VnAJv|QoyflcGM&wc`{nxUlnv=e+nf*o@ +JGEb$U*%A;q+Boq2XsI7U2=#+VxKMh4+G +@rO%E$JV1en=l!g03D3~=XEW3tl!#W{@Utiot)DIv(5^#x5v0_lmEOay@yE&<1mPQnc3`pF7$O#?V*$ +*zDB2XZ*u{lqblKtdNTnA1L149?U(0z<JtIC40S?U_8)a7a<5BJxxM!ceJTii2Fy7q$e)jf4CWks;uW{AwXm +V%_DaX@_emxJP9f!pXN3$~*uWp3@pWnhBYs?BmIHX}KXSCm^y$Y)R5BNE?Apkd`jKW5w_|>cb859eAa +dAd7TAe0k8G?tGyY#T=0mI>A|r?89MOc9#?sn-!ut-rjfVKqRzMgOXX%+0{-ZO~7@KQ3#-^da2%8>h~Qrw#?0LRWY=e8Pb?}RH8*vW)i!{+-5c4%(*jvA +F+7wLiU*bIbOA?ivt^|)?geeBL_&z-Pz`i`rgnn@b!|26;<_(8x0nZzOtrtOz2pKa$sfZZB3xZaMaZ~ +`eaFIh6z+}NGXFw(kLk-)Q*}!`NIiUGK@_i7SXH}p&E8xO`nlYs}J_1`R(Qh(>a4a3L5k%lLUKO7a=) +{{C3bWsM;r!|elvp5NJz;oi;)wwb_Ex`GhqqyZCiwyYx+#q(E)+E2cT^^XAaF?FBF*-=B#do9p>UBM@ +fZqa4-ryUP*cYoj*^T43i541{0}4|2vFC|LM?%sTc{AIz(OH*g?+w35#OPOS^*VVs5MZrh1vkMA{571 +B>Wojgk@}D!1$b5C?I@8_>&sZUOW$J>epY$p&8+PD3FiqpoF8j(FElHVQTh9mjrM`f_*^FQh?}xuqU$ +uGqq135pV>nSC};T0U-N4yY;f65&R+yD#x2Y2>b{1<_|#~bqrP0jPCyc;PciyAR5k$VD9M57Kt4JpV< +=Fn6k*~4`9j?@Wy`Q1$EpIJU|?0DKh#De@o@1sk*Sn;T>sIY?<)L{ngmLJWrf3j_$q=N0Ei0p$Z9?Uz +4%CWQ2IwXd)5NM2uSICLNM|PYo^w3LWYi2HvnRoYB=GGhN4av#efKLeD1>;d^dr8S7inM)%I)^DJX_t +Z3}32by47fLAt8V7MwU?Ojw&c@xL*vk|RW+S{pF%gbaPl1{)Ol}5mh98O|Ugo23h<`p7~NGfrIQDgSx +<_Fk7HA<#7^qGg^irNZrB}}6zygMaHN!Dd^^rYQn(*cq{P@wL~lKXLx+>Qx#?R5YZ;-)suy${t2?-mW_Y>2fb*q1t{>Q=;X>Q=yT>Q=~b>K60!B +ftX&qq|eC=0~tI<O>`Zxhe%t`QWH{KwX@G_kn=67ZVcE<>=0BqGnJ}EjhZ~5{FiYrdgogXvVesE) +@(oQpH@l%}XX(UCT$7=w9@9QzaoEbY-gqeX;-R;gFhbuC1LpTY!^HD&pkZQu4>U{yj$s-wzthHj7qY{}OHFV*C9s3x|xQMrjX&2$GWry +)s5SwiH6LICyzX3g;?fn)Qq_dRTjXB(g-fWZL`INAg@9c#MR#ptGG|doQ4o7)*|Lc&timJTL5P$v>wGH1m3-j& +n0x>g2lU+7!B2BYBdz_0x$7kn+wHzm>4}U1Cxb$VW?%h4}sBNfUlO4fGvE$IFCH9Y=)KWR`6|*`*H9vXa?cPPmt}Wpk`^zVaM})P~LNimNb~iG +0-KA=a6Ld5UCy@Wf|9cY7C?own%u0_jE}=CU}7b7f~Cj7^SI1;AS=K3yw12ogD>L`zLRc#I4*vr;OnJ +lPlvPnQ_}VTn$Jl54^7i*1md>l5j2&NDY8(80y<6@zp+$L+@Z#*y0fShg4xjI6@Y*0uo#v!=H|Z&33oqQ<)`$2cY +w=hiO|bq*wrP7s%r>KRi-$cFENKrVY-k5@wv$eH$oOn`>qGobqJ>yRl!jSuI2|E$t`K=%oGR{g7u0YH{OT37|4g;!C-xqODEimOyo))PHg)?}VMYPx +yQc3JS%XUKbh9eJ!)V(Czxusf28Rc@~R)i1}XEv+IFyBA*g5+mB<&EQH|at&3NI+tAcY9zJB8vTB +WcGd>aaD*h5TXRYV2Uz75wVJQOpN)HFF#{M9rcf?*;9@r(p)vTfNsH|dn}Ib@Sux0dtFW#%qQX!b8X; +IBJq`oDG;YuolE74BdB;*QNi`)k9C>*WU@x4{Q3t8k51UH5q}_9OtBECEBiQ1!0}y<0Qq|H)wMOiXgL +?F76Z=;aZUp-zWxKA3b9M~0rw9T+l^Q$Wpmkn)hE!xfgurN$*_eB%#j6ve4_X^tZDxRkc38>R>SQ+4$ +FWqRneQYF`o4H>BCi^p9Nb>Bb)T%iZ!lTuq&l5P~8+U;MFR@gA%JHm|U#{oC>4@fhKH)jH+Z4X3|%`x +A4{P29^e7FGm22D$v`s+!@KAz#~}gvUbn!)2+Leqe3vQSsr-bBv%L%LmlE_3=Kx^9Bj_jUO#3)@juwK +t2_t?!&;n{7IfhS8{Ip=5~>j6hCGzeg%>ZAChQ$VORPuhv +IEAfkl}iEHaEd!ujH;+O?jk=GnBK&#@(db9Q@o`k5$nm%@fYfo!ZVN82< +olthISNLGJkp8CHJp)eg&a2@BRB@)(3ycS|AksA>KHj=#wlAK+X0El$u?AV)No1}=Z;B0vl!bW-i`b+g^_?wtZWntKUxS8vLu|c!7v!OQN4-tkUSd1dp5R?LtU3eEFw+#jUe)@M45z;8Z_6c=2|- +hAF~kj6{L2MNcDA_-kMV54a0;|~eNePRJzxKOeSjFcuE^}%UiqCKR#282fw<2DKC3YVy`91~lfjASGn +-3cXh;ebt)kUqYVsQR~8uH +6Q0U_cwh2Q8dUKN+?ER_cN#`t>yf|Clx$pHb5XOoPrEif!Uk+K5Z)+uP7Kam1GnshZ>?c>chw35(;19 +sFBrlasrs{&)o#M|r|E+X&~#$emV3qlnfv8C0B5!b$^k$HxU+Qj-K3>XrhPJ#cKAfmHk*un<>Er*D@Kv2g~kKJ*@ +(d9bFrIJ1!eP4>CH8Zf6!a*?ted&x7Q1&?C?nL^8%>umekqV=Z$jcx>%o4{SsdyO>?|YDZ>m +^h?D^%xvBLb8?YGIXWC<+)b54&;D9OAr&tW&KOKL37@WJTqv8heFm +GvCHjU<1z+KbGlU~Fh7l1Xpry&8(};8rgy3mU*-N4X`4n^b6sdTlaS+f9z);{8q+C%8cs4c&A_miw-I +4T2(xni_5OBK5c8(WM(xrKr<-Y{1CjKkIF0t>DSt>vwId;gU3Oi0SVWf!1Oc@hj(K(_ROpRkC?`jIk#m+ +^QA|L}Hwo|CB|CET6`-;!4JNbqTx{5xYv_zmMPsPgnS9h1uW8sKTwC*2x +;|I*-*&QpnRxQbYPAEaGG*<3%;b3%CAA;U@zTf2L$;>OA8T%o7jisAQ^;S#B%2hmQqM43W%N)^r{1V< +!x5PaxwLpuyjI#b9@MspYfi_^>{yJHL>x&FIAm0(Kgr@So-IykdeO9#6q@r6KBb&Xz?<4E1(uA^W@0Jz;nCsb6GQYA`)tF=jZD4v +}h^9`Z<x9(sUQwFEaaAx4To?(b=n?yOr7dXgUsxLmo%gt4L;%Z*40F)3L!I +Af!}%*rc8iL}4r7!iCanOCy3hPueILuRR2W6hbY&rs8u6UASP*lSY7|g5$X(-1n{!^y=75A`TdQ3`!c +(<)tOSxZ+MHQQO_#|K-DN7EyZTki^K@CLs`eUqz1kMz@Qyea5Kj9V)`}!Z19y2d%c~Rxs{&Z4Z9fH7it9N$@%>V}YW_f`#nWr%$@-$&&huJ6ZvO17H$4d<-; +e~8!4l~VLtM(4TZx>9bv4G=X!^OZ!$9d&$S +?n8)-)Gpu1s?l4;Lg4*Z=uDdyAgrKw?Tzu@*ovUJ4=nOXNK1-D4^m7Ua^3>m-`c^YKo-d^p`*2spwKJ`3+zZ7s0t +Ch0I@hJA@wg#KCJPQL4K->cV-MD8AEtIaOVk=1_J5J&WMTP%3rI90oshap+JYCIEwUrX>=$3G^~rX^i +s3i7zYB5kwR!=CyYDP?wBu-#nz5PtiZfzC1HH{I~Q<1{k4Wcqvav6hu}Kss+pd{L@1@k;MN4fBnrc8A +{20L#llc4vBXd-kaxaC0;^JkgEXZCR*6IUXRwO?CLR&naW;lp57rp%vsAnkfqA8C^GHus(C|Rg!3a8G +vUgr_Z(P(C(_0;Gxm;)k2$l%8;4O^`j^|lNBfC10yEeDimG3x$>K5xo!f8Y>mGr&It +WJICgSIZ)`&_;jqz3U^F)#1=eYFxgRK0l)Ghx)|t?=i-W=ilEQgRv0qkV(KV;5N9@KFwEZ2)&ZiKnSd +Yrz-@!4&N^jD!~2>I{j;yXlXG=sp6M+KL{c@F`e<(_V!#jp*YIQCxoz;=N4u=(qup%D$=oPOFVEs)?2 +ccaWiTJCP}QEt9(j*qJn>JPmG>z~UbcdO>%amgrn0h^nt&iUW6u_ +%-``ku{6fXA3X{*Wwn0U8+s_w&7MzA@;0mHqqvNDk6@b?fTkKtP7W6OB@5Hw#LMYPg~;OAJd~tNJ!1(vz?d#GB+TB^1UMr8;;om98M}I!t(>1Kvr<1Dof0&@oEBwE +j++&4O!UZO4&Wgqe=9I-TA+Ys*1q@(LpI1Q7`F0U?guV;Dnn~!w1>-W>5Kj?gYyeCobm0N>!5N}W +H6oysVD#1G)UE_<;Q+5`k&X~q6E^9Dpg}VYQ-&>kKxt2N9kl%fP~EnVMsRk{444(NS#4@5gpDHkH-aT +iX7)D(+aj&2k9*y`mgpI11ukPejNM1Z``%WqV4UA?oDvjCzIX&-zcJ7DRq}>m+0dhaQ=Dn86rMC0kc7)==dpSxF|7XOk~VRdf2Bz(7Duv5m@l&qN +Z*0Y#MH(*U*Iz%o01CGN!yiG8qh+{no8U?{FfH05%X3!0y7^I45K= +znv`6vzD~1)Q%dYq^5^4qu8z)4Tg*=4*3cwn*NMVO(O=EnHSMDP=}m!JhEZ-PAmq4LQl8A#@`=yA$x) +bab;^))A*JDBG{F)mduD;$%)1Of90@imiW~nDC1mz+mfC;jTkGIG?i;JSN^8}@naw>V45iKeTFO~D3| +vqmVh&O2(Zj^Hv^Q*`xAzVTwIDUx|Kg9IvmyEzyTq}r@|*dM7Xp_AF|G!n-n9UI9qVeV7eDEWH`O@HD +Ng4m!OKw%?MbxIo*t4C_A)624g|b&nJwaD-#k$s205Q9W1mc?oy!ID3w;ZS4nsS)GSbmilOLw`H>xJ1n|%O#PE&?1Qr< +ur2?F00lyKl9p+r0ChbHh{LK!<0?hTSq(0DJR%ms<(f(a=TP2sy?Le1cTI=U5+>-(wBQ(G7&nct6&r6 +RW&t)!Gf3<0qc^#>9m6ZL`IiKpZtx-vIDA~@&96TQfdhZ>N1yw;hb(T +M_!6jG&1EFg^W8ifT>VeMw!um#ZnB0=>Z+WBE`B0$)y-&2zb8} +;J6=-)Gn>>=>3Ge7u%&hcl<<9sCEBggUykF$>Cs@sIs!qCfj}yGAyd^b&Q_}0gb`%2iULC05+-ajPtF +;(aDmN-gcgA4w_m^ohB3BYWgbi!we!Mnk(~}Zv9LC3#OI2xH{Eo;zM1qXvb~Cp{3Oeq5Cq1+IJp8Nfj +Sb}EH>@uCn5qZ99XiZ=i!j1P{CI~3W9%GDj6$Zct;w$j7ZP4jp&di>;cfV^X;diVZXc{IFtcKS~QOI%H#;!0j9{oNl291f`H#$Y8o`9?Bac +MYbwgWKpa+WcZc<^og!9gE`udxp2${l-UOnc$(rcsz!)Ms2JxvJ}9pE16#NlR>A3nV`TN4KO8!Qtx>_ +L*w`*6vSC&N4#~r<)CwW8K~^@3)`=`f{0Rmq>jaj4h2Vy)GFC%W4xjF$O~m@Hs6@clAnCh0c)=ZUkHW +FTpe#G}dgpr3-+INV9U^V=8?XYr0vxhb=0TN~Vt)qNq2Obfh_S6JLwBfz#0&|_=~Dz|J&ObwnNT%lFc +%=re^~09Ccq2`LnaPx(`h)h5fEHx&n0(FYR@@gWS*BqaPrgCMqT;GMdA2^Rf4}7cjfOCAGE;S*9iKWQ +Y4zK)hV)_}%NqPhpD=B7#n0cBkPUt&luvlYb!ffa?{ydxu3^&5H$-Ai}NPD?rd4zb +yh72c;xhAnvHMfuKcWvb;*+;25u}6v@XGe%r3(mSlMM$M$o1t3JA}JFgx +L%U^RS6lP0i;FK<=Ag$-4k&Kg5M!oF4p$asWo$?w(!Y`Mh~AcUif;Eb^Ej7afS>po6?$~dJX*b&Z?OW +S)gdZOIKd2GH2F+^5Ng;-_uZ5)B)2k&MAUVKJ2S2Pf)YcC=RFYOz1GlBIxH3}uZLoo;9l2bpauFjgWy +gB994J3!H^k$SRV=8HnR5YLc%kI`_a%ZZ7SSwe6g?$KWxS7EmRXE50;F`6bjpic*9uCXKp(;9 +RtRz3ct8ltJD4zvvP}X6Wy`D}o-kY1;X2sLg9xVzaO>L~WMi))l-8m+_Dx?D@+C;qn*bg8(X@IS0*Wb +zHcq5YQ}nMZb6PM@t9lZ1)v>=t;l&1slPZ+hK}O6*L5^TV@RA>#DYL%DW9movtH#*f^g6fhbrYwwuytta}O=HNPIWZ%A! +CB`)BbqBvW9}*6v~?8A$dJyTrc<;%iSq4OE9!dsGJTi+T?1Q6O&DuHaElJ0O?LFV3!#wYO +ADW}#ZSmG8J~7TBYj{R*&fJ+W*gU2>LjK9Y^2@nI(>FRM#7J3RvWp~wXOmH4Ho-C<7!D8;K8Q0L5=lq +HVSUT5*+Kf`YqvOtKZs+Y34`hQ$80tSp+IOnkjNV{Y~cXy@7@`udM&h`;pF;zvOSQ4roqUDhDU1M$N{ +}-Hm8%o5Qw}xHlvX88C;C0LhUkb?cvr_pUe5fIT}ImDZ{(c+OCDp=BoG*A9m2S&RiCu`yrz|Q4blAWF +iiKc&J=Qt(%BFHit^u?h*IJdx2~@^iaqPV({^=IRzU90A{?s)CXcJVX+fLa^x-0L~vc7~)L*I +yO)J|1W}-7R27Y&>L~vn+8JOsx +CGktL{t}qAI>+Uz8*ylhY`L2_Vz&pUyz(R0NT#mfBnopN63W&e;BmAYdyTW4g}gOEG?9~algD^ +LTp*k|GV1V_k3OI{ZutX*6TEeP%SRq?T5jdnQ;pEv+8s8deanwsoWo$fWiyK&O1z~nE1IQsn~F+ifQw +4dC_Rlt?=0Sm$1#lf-tz6Y0HSs4%+;Jw?D61Zb+?&tY;axVHWyt$P4e5XX5+YZrV@iK4x|E{RoosVS7 +RW=v|&2M*VNGo>vQjBL_V`i5=rR7111N-NY-b$EYATaYBM*V&DZ581X?&STmHr~jlrdbFEUaGXNSKTjO@!V{Fp25FMNsP5{Fd-Y;s>j0L_fe7kkvu06WeY +OzTs{1ALIJIe#fX(_%y-%J3HfZR~BLE$+VN-VS1h7#v3+A{|!Nx7!1z?i~W+KZ9Hf>>jz|LD3wL7 +cZ7(S)4^M-CjWuLTO0KvX*>E?hvZRjS%^Ru?UG*%a_gc0m{OZVKs=KTgXN4xVuI|ehr%=m$q`KX0qKI +Ufp(C*xfA9$X(<7cv^6s#RTb304H+VOivZOq$6LiL&P!`RQw_+ifHX8fq#cKqhVvl&0g!Tfm(o7Hk1@ +4_rn&IV-pfm-MfzUw^*_xg{z;DgzuU&Hht1~zPAL%=32Yy#MM3qyU=w!SIqn+{so0I;@=DcYEhTG$A% +w%sY(olaZW6tH;R*CwE{m{e5%rG-8!8_$E@F*aFE0&r-*2a{kLe5d1GVyNaP=49ld%Tx%lc0PA5G64{*^=w$Bk$ViPk +4D;eOI@rda=Bpy%h!MCm^abT+7_67EN15YvHt|G~CZeQ)jZ*xrZ<*+#VEukqir;;Dtqe2rrwe=i|A6?=Pd(w){QV2 +d(%i;BUY0L9|}#i+DD##YTC2+hAA8|7L&I{4nTbx%G;!Ms!H8MtMb2BfRpb5ndUo5gswA5I#w%5guWw +5gy5?5gy^F5gz%d5grk#5gsWilxESpl$wuP&FCLub_~H#Qv5b_XlfB?Nz^YUn9S;Vp7ouXR@hYE3>d|RwkU^0IJ5Ss3GK`Wi+%IECleDNXa +5R=dZ8}SBVn=7Ss9oAw;i2e6-IOjW+y;Ze*ekX*ZswK4IL*rWumg7pYsDf}zJIrfZ_9WW#gUqz+gdEb +%Q#wP`8Fukf4g^(^>Q#%jzz6j>OT#}v$J%lA^oQX>0Emi#^2>5i}C1&w)p~PH(y$4$0pag#VLf(66@I +aG}yE5IyOTE_E}?kXX!S_s%_G>$11S9use3!j=i>Hr|sBhE3j*ob!@&JTW`n4+p+C-Y`Q15+|wKGiS1 +TFrsHXnUk~QsahalQ07PJ0!FyI5gd0ZQVqA!hg-39kr-N3nHlXj} +*)KbW%)2UwrrGC|t`gKOy=@6wIeo)$>caM8`HMXlK-JahOr|*crcih!G=H*qmV?C7eX%@w{aKka%;xg +F%o_PI~ed%{^x*ea~Z&w~MIgdI@Wm2d;uCZOtO)JN}Cy!Ne=!hh#a`hgoE5KA&;M#wx5ohWL<5I?@jG +MIx)4^tP)!a56ss3`11A`p6$e}?FUF66hM=o+~kYg7)G02IFoEqfRMV=evxr>|`q&*0(_}!k}o{4DQf +8V=TW|#5qJ0e(>aS}ZWb7E=a!`7zLU2}TX*Vi(nbaSPDz9Mzyn ++e)_8$7c#MZ6H4cc@baad8WVcb*_&i%3%GGSzhJ(gM39?KKv`X@>g*1>*F578#aEe>+krVDA2O`>#vX +Q-MhEX<5hB7wXED~)#$_P$Gyu(J>{X52WS9m;(R&t@!RxFj{u1Q7WVe3!sfhFD??>NNo!KigL; +k+Ho*Q4>hVfp%DD=?$#nk^BP)h>@6aWAK2mtey7Dokc9IXFD003jk0RSTa003}la4%nWWo~3|axZ9fZ +EQ7cX<{#EbZu-kaA9(DWpXZXdF_2`ciT9!;P?Crj&f!r-?5ZO_q?+0-gRC*IXAD9cpkgHIaykSWR59P +O;T3Wefqy|RRJLJBtcnroW8A-6H6pe01AadRiUadFNC=2&uS@pnQ#ZaaP@#BZyVHntr-uc~X?qD*Y_sY|{Gt(~{NkEQ_n^&K>c%-mVz@qMB1#HqB +S-x~fYSFO4^Kal!KRCsvwOpfEdIr&+>E(T}P6X!_|au9z(RIxa745bHXXV`!euioB}hyq3?K-?Bipif +8QUd0fUbKtgpG#nmiL|GrwW^3khe1Fd)~vRN8u&oj1U9q`XtoTT}puh=Y!>sS^#j7sgduM#2i1SjAyd +e2sIS+VDzXKYo|?B?;3(dhhrtC!i!yk?6s#wzcMG_Tt}EaUoonVqoDwXcj1Zk+skUDYp&lBJ9MxUS3e +3<$6S)cRh%j#oZl&+pv1ldyS2!y6~X>`72NYixzC8)L0h$_}+(UC^D(*>(f;P(^$d#t=Wpc*TvfZd +?>;QiU5r+dz)97f4tf#=a`s$irUy!>*YV(mp4FAxAP3mC5BG)LS4D;Nz$XE0iC19p5PZ@zV)4tU*pk$ +g(ntN_|C%9iCyH12L13RghK@(MVJ!wA`0C7wJ>XSGrfKXV|(S +T2({RHOL`B-z%R0uNtSW1~8L(s=~@o>tY2jhotsoOMrMh_RgLomM|>i${?hdJ72fWmafHRX!V2+k7IiLoSHQZ?@JIXwRFHIk|om!83Zz1jeA5h=;ayobp|_H#S#Eg7VE`%Qy+J;KW6FKw2$Wyr7MGwIH!^D- +ctuxWpSA%L>DauP-!So@KLo*O&fqG=YX$eyv5#@Y?Z+zCA5&)bTLI>F;E3HxH(T}=ZLCHR>F=~6-xja +FA#j&J=lP?Ic$F1jo#a{2mi2R^R%pLF?;INH3R?@ITciJB*>wKoQipZaUi|wT!G$nb9S+d9O%s{6~`S +Mye%&$<`bWkBSm`D3eqs~{prU$`kU1`@(g&B!1%_eW6nrsStXWa)31XAnxW=BP@j_($`1_q9l;*cVmp +xR_v3-G{P_kgS|SQM1h~L$aL{rgo7=J3tiBQRW%(Ldqgdt1}%dbJ^2b +46w^_fO68t@&wca6h@(1`%*&~|u(3IES5Lfw7$7OvIFJSVCg#Bw#dyy3j +dWw9j$g?d@OhQ^E->;%2kfp-gMnA68@}e3=_oGpkE@6Eok@6@nHbgb#`C6za +;0mcG~;n)y-EVv|}sd}7eYFZHhWHb`8jK^FX{D3cY3do#omiuWm-r&{~*6PtwbPqN<(2=0Zym<{%B#398Qtd3-h`xOqIKXsK3>V_NH_*tRl!x|TDG7=2maZX2P4E7WDH;_q2A3aq7f522~EF&h%So +iJ1eMu!@btA1RrEIiVq^qyd?oOk)n#R~;W9`Nj-|nCSZbQavKGye7p8?`Jip@*h^jZD(KjA&HMgIPOg +PgU3(QO;n1j^bP(eYgD8YY(lDd+@b9Ner)B!llWX~AjsoK}D$VKc5c!vVn!HM)dRH8NDmy}79Yg1}=? +86N*X9K`=4X$WBeb>&43)uEXs@PQ=SvU++)?Uu@9uq+@06&@i2+-qp;o}p<8C5Dh@JhNyP`#Qz(O7xs +Q_}H@bw8D8eEjFS9jFXwtIP`NYo=yp$u#!h{4t=M}lg~iEAYdleQcx?AAcr+ulhf&ln~z2x-6I7NQS^ +R?D0R6BmU}V8KYO!@X5;N+uxbebA<}ADIYkUuGN{*E#P!<_|JZxJYd +ne%T!_jE*EQ*;I)JxJSIs>h^61G~SI)#-}uR;N3Ymu(6yPooRGd5=Nra5t7X4BP +|kGf%CHX3Dz7;2yAzYY`Z$gZ35ThB45Vk1#Er?T>}#|1(3!D=R0)r!-H;cV;|aG+j94St%VaP6?pK4) +vL?JsJr`Onw|1X_yjj7)#mrm+>^W*cCQHh*dnt>K=CarHxQD$#fjKcP%-(Q;#-%JdX0|z8&uf%&;z~GrLRMqW+*p6`^5=CVA~a4XUEYF4N1a4{A~sV0LIyR9BlcEhK* +KD_I6EjHg*qkvQ+{0~SUOY*#p*UF5|kW66Rgmga#UbEh5Uz|Ag;G?@rFc!CD02`CXMo?J|-B1@BXWm{ +#f&(ECKJ=QtjF9)i*{-1cVf@)_5GIKNsZM!-LO((7IRnhaeFBEZIAXMtf@PdqW(eswK(-cXwves@8n9*Q}HA1C2?6Z#pbZU!)B;e;T}jq(7EngFeDECIp>hNxI&P?8 +0C{F#{eu}Nu-`+-hzmIp?!vxVMUG0JetoQr<=D6=Wh(o}m4G|>!gVsZe)y^;YM>RJ+LYjo5MdiWuY5E +*vF*O-w0@xeX7z`fsA#x<=B&cZ_dUb<+!A!U=s`9>-%Pxu{;t4E`M{p(+obq=M_P&%O(K-)ZM6~&|4|avtf@y7(Rv%uW+;}3<_eI`rQE@75-4H0jbO%6q-tf5$K=| +>)5nh|4?ikmjC9o@V^T9v?$^gP^wzD7E*8V@cw%Lh$hy*az{;E?1|^rql +_2H_Gt7aUOu>`0r!>+boNo4Y2tF$+0+J@YN+B0@1N!dT7*IlK=ZTOBd(V0{{It{@Yo$nG62YITQTVCQ +UeE`OkmSPpf2gA=Z)txVjMLD-ZPQLM!Ynm9Lk@47O2@Vfgh{{4&ZR_h@MVf4OHL-r)K&J1ZV{^;ZAgJXK&D~&=)O|q$0haSJD +$5u_E-%HlwK|XO}0+H7b +ff-}0YU$s}QyDM_ciX!5N2ZIw;y*?A3;LdA>X&lCD-mRy%}Jfr}rf!Lt<{ega)Ww#Ybd>OFJb-duE>B +%ek#3*0KXBoSUvo-Gp{rm_2X_YKN-TBN*;a7_$`QvR{!lF!c8)&%`{&I7t%am=-3Tg|#J}Imn4QNoq?1I%d#Ls|NN9c`yihgb+(Q=+nzc<6$NTytC;2;e;wz^JNVTU(}ne-OcyDLH*|^w +qIi~8hJrE0t#@pmyMX9!R#io1hh_J2A&z*}a;GW~TZ-2ucmcwe|GRBr!dW+BXFt{;VxW +X5!G|viL0Vp0ds9AFS&CpY2R;1r}kjGJs2pt(b{sA)m`umQ}x|QcSyqk0OGM|%vcsxooyp{2n#9&ZZ? +g^FVW^7XH~(y(o#AXP{2t`0I}3*Yo9<*Jjw-Nj5SB2SepC%aL8(7xB|6aFu8Pp(F?H6rDXA(3*VUFs-O( +L3X@>{0O4fj=CJZ?tpSPdV0=g7lauQsghLK&CoJiofqpY;Xdc*WG58M%@F~?Va?2=eKB~+9>;QB9V*0 +iDCpx*%%bD;(TxqerJ7@epL1%SPrvK(p>eoufqs+bYvyR99gXB3c6F5?RDT6o<5YtAXtQWXyaJvy +em9Ihl<52Dfyac7QYsWdcXaE$E98l~kya0z$^Ys(9qQ_ZiMV(;+9T^7^q1m$5b!;*N*N6g4kMU~5m1<#8~`xz1U(0_G@=<@t&Ea@F{F#|@VRRY-6VH6BMhxO9Zc +b6V!%@&}Gxg}+DNGy3A#cG@^&y&=V+$`UlRzNk=~a;54qI_|vU(_8A +SsESV%Cxk~?sY!WKP^6$ZIAe==ww>@mdzYERzc-+FcJA +63#3`c^zeSqJa5k`XGv{4NE{C` +9stmi}nDkt_&h&^;`k+2!Lell4ViPIK1^94X!70>foQFB~QSLIGl?Ad*4gyn +`lsT(`%dN7a1Qiuma&Xs!q3r<-9dz~Z;9fxA>~(bC>}Pb}1da|WRkL`-V255Vr?^kArlEx6uPdm#A4G +AlWT4=0NyY-#fz{FYlaUBCv;L9d1nSfT*Xn*1|%AckW9zO;V<* +yI^^x)y+$E|pP$|JS=ZD=zN=-&$He+K#I!H&>Z+Xd=8#`Y|+(Np}>IiRV&`6h@^3axa%1i4{nHJhEwJ-PS^m{J_b5B+tap5s_S(~y1 +ne_W#w3xx*5^3F~nzWh_oOiz`zD)%6`qHgFSwuie?=|huD5Bzx;RBM7W^N1KrQ%lX?nKAy2l-c8|kpJ77J6KJLq#1Hu^jCaI0^$Iu1q4;hqTKIO<9zqaTA& +Dy!h0DM+XoidwkPg$2dIs7!1SrqUqirpfO5(7$nI|!mvvoaL6!ip?$ +5kUou0ah8W{vUiO&OZDT;!LZkX_L|lQ4-;g`TQ^Ae8R_t$74zK)t<4X~4;`K~ +OT~Tea918n^F#DX8FH7e*C^D>Mx2RG9JlffK5d0fn#{#OCLQ3m8E|-D(Z9POgnH!`Vxs ++I5lA3*fGmKj)a0)Vjxzo#M0Wp>tTnh=1HFA`?{YI^ztgJ|KhlF+&Ht6TeEa(#oy(yGoOYv2rf6_lt1 +C{LO33Ng1DaB?I#G6Zft6-2k_xP@(lN3c_)0d{N)|8jp0841Vfh{O?e>Kv$O(%WCo05d}@uVVOcsLcy +?f8znONuFg(-I_0hrfj6O>DWXb>J>$k+KD)9RrL9$kC3VZ+h-V-AMDG=>t$tW~T!_7^b}- +~Q6a%5Rjz?qw(r?iJ|!qWUlx+pBaOw^F`!y4v6{!uLSK+(v=lDWgZj*Cn7 +g1y2R?rr@zvl;gwMj|Qq%pVxNx1hbvcc7iEWiky0Mwy27Ap70Q$CC0?!*DTF1Mh+l)Tj)>w3Q9iZ6`j +4rg95XU=&O6XHtlHlU0dt40E1n2&p@ed>&V*mjUA~DIsTLKI(GKEi +#X>X&wBy-V_rgn`#n+1_7!HC=-}rV^W{T`J~7#XJgNb+xI4~ZsyaKb$?G^qEhWT472OF=x=*}@uOVbU +<7lU3a2`|R;o7bVvC1dpRTz_#wBwo)c|iq_DojOO%g%gxE+n>3)WmaqFyl}+xTefjr^cMCYLgL(UGj0 +PB$i)DC9D{lG-Pw{zvWDM091s-7MXRxEslFVz@zEMSnkeG5HI3-A?h&yYqNl&O +ECi2Pn4A2QYEBZUXUs&W;JfveD%wm9{Fj~C34nt(+!6XO#{ziVOU0feVFmR}hedfK5F_;1a=`*?k#@j +1O4oQg)St6VqV1&mXp1yoJsn#ooQyXoH@}inLLC~#2N9w)CQ;EGNTg>60k%~;>J>@NqN9%e%`HTAmN8 +T-FK(}x(#xA%4U>mb09!6XX>n=Kk`U$LupOV-%gn{d^x58@Zh-y_Eaf)=E0XGzcz;F0Tf$lcv4EJ$-( +gY|Gg>n%P6Fetrh2BDm9rGPJ1QAQ?83P}|9{IOBZqU#VmABOXGv|#~Y7KY1t+Lbaq@T(-To-17bh4df +npT+Xa_3jBF_Bmc*cwHsb`zG*?Y%-heJ)I$bm@1rDC+3<)hPPCC*49Q5=r@V>G`JQdyUB4Re`q6zj$L +wZ>sd*6Io@d-9`f$BF%%8Ue0kBYk5H|nJ{ +jhig?&7BThl|#UY?IzUB6M=`)`W4(HvF@@=53Mv#o2Yq1NJXmb@!>s-Q?{TU-nnqE +*saENwKac#eA~dPB_oFlHu8n9Zl#_FAFh`FnVyN97*`7P_4gP9xMEa6h?*!HYEObTC!zv$;JrAtt%NR +hW22-a!qfrJal7n^M7Y~(!nb%xl(S6SM>mL=C<-OT+<)wCDr!&LbZOgoAbEdEI`3q+{dJX6*@{!V2xM +z#hq#sw0qpYyW%OWCU~dkB+YS@4*Peuo#=lqS-Fj7W&G1tzrg!?W!AgVe=@cL`MqRwemg?SbCXcs#5j +x2QFcHnzL=w6U(1^#^XR)($-Z~s+cvWv%r!zi+xJna_p{$r){J1V^`ZdG+E_AAt06t)H+$d>Y;!Oa&INjJYN=PK0 +(b01DS%>LOWrnaTjE=jMGzMtpQn6H>Pbuu7Sy1bvr^6+o5_Z&HOzQP9BQ5Q&m0=~**h0Pv2VmL`G)Dx +Rq)an=S-|h#wo5sP1-uEg(dZhzjDt$WmY$49-g_|%2JvRBJrfQ+QNoj*34OX)Lb}kHup}xa8|PpW{*8 +UbH#HRXBl65WqRQu9C%mc1g@s)YiqcOr?~c_HZSNT)i^mnE8R ++`H+%JAIdz??uw;7CXk#k+4ybtM%5%84#q3zsG?r0eeFTIX;^n7=ky9UaaJsDQp}OUL9fK)1K%O@Xvj +yz^vW5$tWU}qt@LtEd1>4VAv8RrA6J^*ksBZY?aHWZx+kUkw;(Q-hjalm;`tB(D#$4v^l1EU|6N%J`NNJTeA@WqM17V3#HkZ +aa%y~eWai)=J_aPejTe0L5YYAsw7C*5Z&ta?$klQN^5isQVLVP^JB8i654R{bdo>t*n4k1L`oQa@*Cq +!o$?Tou!@_0FKD6Rb1>*sFtp)OXDu<3>b3Oy@})f=|KOAk9;tUeS=MmHcvW1h^lm~)frVf394>AvTle +&0z|@B4^^Q&<)oGoSG$&gmBD1X_osM3N5P-#~XSYGs87p5L*w!$R9_zvVVwb6u0aot6;)zw(hgyMdqU +a?+r1O2Z^}7`2+Pds6xBA9WY>^SBazg4X?63d-=$>BGmC8!kTY;!!2P2en+!>SGU!ad;V;`xYfs=Dv$ +ADhxVRZ-Z3jMa4(a=)cwv;Nv*+<99JNE^yLmHO@BiwxW!~QNGSHbSh1OgB2S)`3v9GJ^Xe!UYs~Fl1! +T;zY5^LR<{hi=xvN@fP-k1o>d@f!%>M?s>|^- +P7P99n@vd`i1}`L*iQGgNMb1No0&S|y +Tg1`@UweHaDk$Ltl$s(vw}B0@2PEM26xg(s3*)WbkZEf?LaFxM;ERv_zfvIayy#=3~tJj`iHao&8WWH16io9FJR4WuH#o82pA{pRmOYI{ +jnNDqd%}QvW+R)p_e$2LaOhwB3=()9g1MbV%5-k^=(BusQfB+mC$Im#$U&{GSc+Ty>+{-Uy@Xmq7pqOQ?UHMm>o%Xdv3>g1Z_Td-SN!2K +^e>FA)WJ9^|>dis8Dtvfz8yRLHYUCpXm+%{g9skk~=x$AMSR`%T}gS&0+x+?~XM>jRYt$UL)$Kv6Rvn +)s0lNM5a(P56<;{nP5i%XxSy~FkPhRp3j*=hO?w7Dz6ARC1f4gXrMZkLpJWlRq-(p)vO1^HD6;LlE){ +<}77`Ze25de;1n8pT44qJ&eQMO1e%zfB8vPwAuvpx22Y@_+BZiw4KtfZYcV_8s`3Bv6!b$vRW=nmx2q +r@Z#Zu4^WFuq)jF?V|jbR{DZMed1PgSOw3c6(FufTe8s}>& +yiF7AtDntb7bn3XgJXD0lR8{ySb_eWPpPxrEwULw)WsJ)xXPfrf!W0~}!wPv)Z_S~I6>4IEcgT;?p7k +DS>|h5_$}At*6F>TR;MvPXz|Icm#|c}(CPOn~o|nkrAp77r@TA7!g@ffkA;Qoe|MM><;8Dy&0xSk>18 +*Un%32>y|FZVY4wNCH3-(1CZGWBN=6$`P2(X@z^*$I`e8xKOzTg`1t6~;s=}&ZpW@N5)oFr&yxvE1Zi +I=peML^J}#jTDtAV%a?ufc-wwlgtiz>yj1LLzQ<__?h``U285*<=PDnthYTItfHTbGE~MXLcGx>vG*eYm_G<%k8 +XDlO=qGcAakWQab;^U<6MJMorp-*CM}JLx83ceV)R{JU~Zv2Bs1gn$emh$q}9Ar4AA2vuVSP(!VcX2n +?A)laB>_OD*Q%ay1?*)4CLQ^)&>(gE)Ia^Lpvi7xxq- +HR8u%Aa9c<^voMI?lg<{MZ-UO?AURd0UIvd-Pr+J<~iK*rg34OZ%by~+6|hUd+!EnFX;+ecp`6sKavn +n*MQX4wEuB4Hwh#~30%4+d83h16#2yq&qIQpoo}-j6giWNyUAV<=d``|AmHZ)NaNKdCIw)KM-7cRIED +P!Aqt_oDc!c=N;}@>=juG={3j;XSh1MPis%^FARdQ;U?RW^uMH9q-88}XYLZ{VHQi43p>Qa70^>eMHy +6LdEDoK6e@E9dMQ8Esf=+iZ%LqxxN($a4Gq08|Sd3N^QOLfBc@umra!<(~I6~e2=N#8sx2)qA0pQ9uh +cM2q^(EXNQ?AFlC?+f}vu$X6K-U2Gv@!P#DYPXA$@WAIT2PhqXpiKo$H@UXSu`v&9^pHl?5jfvpcF(q +dDZUVLpwZ@ao<)mndxj`S{##hTkU4ZcG`^qeYpOs0vuEp5dG-nZ5Y*P^+9MX(GgD;GYXicwu+k`JLpg +ARI4tDzgMKpFb1o&dx;U=4aB!s7t>?J?;ddwwVUCTUh_@~Y2!V8Y{|@ +6@__4*t+p{O%I1UN^KvKgGCpWCEX@b4oylT6S`&z7^x=te{rj1&zXXleSOa|T)ns5a(ih+n`+bGT!MV +Z#;OVcpd+_zC(=IVVL8+OJo+9>e0xSCB-kGm_u9&@NAyG$!=<fA@B`F@#IZF{T~W4ol+WaZB~&?y^PEf7CD@Y!MR;`NfXygxZFq6&CP#PgHFV_+j^MM(r);q@#6YM$3u%3gJ`S{7B^93Q!7)xDxQPk_0^?8&7@G0s&P%gHcF@=y|3ocGIt^0GLLUjZ7}PBC*Vko%Hs) +<|?Pv?6ErB*$|`5i@>0h1}aic&bDuS=U`A94b_l%5Z!XBYV|xK*to8<4e-yr#iE*KK3g=j+9Is`$S}a +auS&#MCr8FuyGds{g@KuIv~u`63T<3h}pQQERtl^?)zs&UBg!)T>GfZ-gO!PDj$m0EA-uQOA%>~Mk=I +FAGy+aS|PdVzN{7Wr{L1H={`S@#-dGl|TL92EF}@nyn3D~bzLIJqpgS``)dXTv)x@U$*Xpp|sKm7Z%Drpf(tob +oxYBuYz%_Ju!A@xYUuw4ff##R)X<@(pXih)Q&_>fyw+kj@y)H{VOVn)wtDx|vwTd|VEYvlv~%E?Lvjz +fNuRH+VS;p#U#G_sz#&trut#c*Cu#!nmp}D|_8xvfEC34KEe254mqS7M41*neSY8S2#QL2VX*H^he;Q +V6B0MCRYjv8fW!1MkMcRq0>BlN|isl;ffPFOHCV=wF*BW$3?!nvjP@fzP5QbM;|Al>7P1>a5RWRy3;m +l&Do1YG}n@@L9`vs?XbKEWziqJL?ycU7w79)h6k>EZB6M1_SnPo??&$#Ij(X{k}^PbcHANCi{QfRs)I +*w+mL=})IO9zgWD5}%wM3H5}Vuc*YCMx)6fq|E_m$%PlR1byJsKab*9_Kk5N#|ur1%YNrC8vrxpq+-V +FKS1Lu2#%X{|+NA8OLB(76el7Z-Sa#7&Y+)uT{e_^SBswLaIa^PSIP%e!wjC6qNfcs# +5YrWa45j2RQ<1CNm7I+x-b@`7St+-^1LESWXKXq-u_98`Jbv|g5wujZ8xeiM)*L6az9~}LPob2|7fgM +#}P1_#g8M0%0ZQ)r4$mxg~anRF~-k6jipQJsc58}B+mE1vRjcLxALTJyiGPXBwf6j*i?mKY5nPwAZ^|)AaTI4LE%(;+Ew0OV8&(R9ruM_`KofO_7!d_7eR;GjmjVB*}?wqQ66&9pUL!k +Z)fYit<<|sOZr19^Ix_ZxIqZQ?cpxotsx}ien;Gj+@6SRwVKYWiHC%Giu<=H(+6xZCuPd@MuBwUqJ&O +GzbBLM`=`&2Pmb@4tS=PbF^YaKR`fkY!aZk94JWxFZu&hq6CKyKn~^KRc6a1*(|XA&;iHAuHPVtJ%{< +EhIqUhHo5G7c+eYW4!2q7-2Argrtw{pIgJu?Oit?h`WoN!7ic&bNNCo0%vW*YqX0uU!AaT2>&=YdPT_ +O3&*#w7q|8AO3NQJ+ZtlGgaDGu+@00hsRch$F{=304?v&LPejYZe%i08gaj`FUeW3Qd$zyR>R*!L0F+XlSQgDD}-@ +G#TADo3TDIuer{Z)gBz%=ZzN$CGd9;+HFirL*y}pE4UnFND%j|@lAAiF>8>KE43t!wX$jd|?neKV{u! +E&1Z;}m;aIkRO61^0Bb?NYn+B-x5ZRd8yHx +H5njI?Gbi#rqHswwu&9{2?)yRK)ruH+y?bc$aEQhM;AXiI)XkZaY3Q63|iDF>b1#4Y0>r~>Chc{WE*l +~0tI?U`)e0QijOEaHrD886b=?>hCl7iF;|y!B-rZ_&&{@%?xRZLTA4r;y0{WNYs}viEyThNouiCeMPJ(vq;7tC*R*Gt1%eF%W{0!{fR2^HjcR*wjtI^bI^aMe +%q!z7V{bxk+nu>-=P6(E;Mz1zSixspO_5qR$)}iM?bOg2=GnSBH_S0c_fR~;q(-CZzhMI&pJJMiMzmA +&nYfy?ldi@2mcwWq`HeJiDoAX_bJ9H2VfYL;38Oik)%BL=2H +h~3dOK&AAOe>xo}JriCj)xLVT+IIDB$j|lm~Ag&2d)#<@+VK1YxV&?;*Q5>ASv-#cvb3_H*`e&pBpSQ +g(-+={&#GY*0>*>)Ul6Y`7k9NL`KxJ02hho*M6n_3J)0rjrwb{#-?nYY!6ZwL718i*-}e+}UZ(CxAlL +D;$Y+8uj`PT>QpaX@wcA61Z-W{F{g=PS&6rV1kAyD?qZ3WQ_7W#l&0dTBMpGH#AHK;<)rdonuK5u6e( +r)mBcw+it5ixQn^APum(Wr=5mcW-W#O?DkG%x|HPO6YeTE6FvbyuF>VKN|$MdJ{N^*?LoPHByXR(K}( +IC#(}n)tLHv9KAPdCVJ)}TbQ6HK>oeX2MU^;fh98v$-GKJx>_9snj~)DaIOT1(hYjG+x`9d8588w9J? +jVrSRdH0MMv=Y$lhiV-f#sL`*NToa8vq5q=V=?c90|KlQ%?C4!j}Ob2%q70p5Pts8f9*U25J#odu6k^Jb~}En}? +sMcB=74d;5-M8PayB<-XU2r*qZafTKDvMW2g$v+rEZ-ZKLT&DxrT-_sf7pJeQ;4sY+y1TKM&@qLmUKU +6tBiH`FvW_*pSsK}%9VuM!q>O7Vghmyy!vbp>(bM=q?=U4(Z1_B)fczN6upeoz-`I^TaV;l4dldq9u(u51iydb~KpOkCew4-L*J%2L}L`#*EwFy&`RdyMp=64 +JH&E#>DCXZ07LDwp}iJS+}MOSi>LCGa{HyQLD{+yVHXWCxiv~w6@CO1l;5h51B2^gfnGX!Ouc-y#h$_ +v4C5!13wd~rX^9aPuO8Swa6BIZMt3NOj(202p;!OBffewc$#j}((k$|37LLuOyvsG(# +Fawh$*o;WU)m}&WCpB}s4oT?QEpB-4VIE_p>B$s+MXR30phPyJH6q+rrWM@I@EQA)A*J30ji+$nA@$W +23|d*1H_a{*Qq@kN?=j7a_*pv87_-xH?wVIYMbXKCeNja=Pr}%K3hM>)~`d+`WiyAdS(1>3;Ui7CWIzUOYspx|v9;4}i_tO=af!f_lcNaNbk!)} +Ji^Dmbqxcq^VeD^-L}vkFJDTf~-$`$rdS3)>7y)a)}y|Qiy +m=2vn9CqOgIS&?Kdd_WpcnFPjy7vBuH^iC44Wo*4lPe}cB^chdXYnrE1R(3}n36c4k4+w6XBRt-9Ssw +1q%#Sl)8f%TRN>09az=91oThTUfJ_HS7a$fa^K>|!5Ip+m5wVM_Mji=;lTdY5k}RP1~1;W$ +fc*kwp#sha(z!@|{zTyK(bAB;yXHrr`2>AgbdWgW#?RW!qD2mPgZ|J~@x8u#h?9B<`8D!N@{#Rupntl +m9nZ|r#&>khXXwT2y(OhpTB+srPFs59}^B{<$^n&Ex&c->6Uc{k!Mw-#szje+M{K|YiE<$kwU*SYsZX3nn6wuYQuU2WBKUkSm`U6P&>PCFo!PvuI1;`cRsotY>OJuuoQdMy?^7`fNw1~h1< +x@T(-)@N(!`R&gyijt*^oV@pPj~$v$c8axB#xd*nyexiVu)o*i)6p3+sIzoIf3jkB@#DIviMdJMb{3w +Ma5Q6hZwmLDNC-+o956{Q=?}S7B;hjLh~Y)6@c$X(q4E#u|3~!yH{oE;zoi;~r2qd!|I6Te>TOE@EyE +B0Mj2Jf(h5(o@GBs9&HvUh{>_Uah~v&CJR_;0Tu)%tnA)$R#`l2X#VF>oYjkLyE;dO0KWe~-@8%J) +Pcs;YR_2T)$dJByk9`A`VxQl)y>moT(en`6(!Z>zn{|Yu)52F8v>dKuZw`}pt3Msj77H`w*XF>XFV`x +S-JvAitvoz-^CtxGo{X)0fFTSR++OW^tHDJp$B?ark{B|!q02|AfWbgRpdY%e5|aLFvQ~%`8W(x1@o* +xpq~LX^UET;WcncZv(RxQ>3qJ1Rgf;ui4zf!XZ+zS`7i)V)vT6fypmAbhp*#4cEO?4u<24?8W8w|I?` +W%o)v|lffw|(zs5SB#i9m$Jr1jJ*4B6uR%6lD_#v!D+17a9Ut({*RUFBTTp7fpK!rVR0_DqH6oQw{9_?gP_9ez2)C~>#XqlHiZi5I=4U?#IweA7 +MJ>h`XHW$uc&HOs9pE~KLdLJI;lYMN!oiA7nWa_XKP@YGg+(s-B*{3kHy))$(YnUc*`I3)TZsN +f8W0=W@*mia#6-f3QPrS@+UvYCq4DCSe&W#`IFH4=o}#TCj3r&(=WQEpglh2$^=G3sKSJ;O6bLpw9=> +AOV4#X`#;q+iekwZFJ3&;v!s)g?O4@9<|Rs1tbY5S9xFHAsf5?QbX}=L@6D?@z22O5%kmy9wdgy~Ro5 +!McD+|d95TP@GMidAJ|gBUGNHPb!sYOWHLBuN&OwRuoGqZHrXh2B!M4@-;2`=R5!d3ls0i}-Jf3kWKm +7^4D*LeRQQXn-q0!qxOBZ}$GUJNo9#Van1-X&C?-+((HU7IJU-NBsVHDjtw&YRkKuR?oJT`oGCw>3vklkN^f#s1#f)r5VfzpAo4Xhg)bodfSUp$od`w%tas;?oRNmAo5uL%fh +}(8sfjyx3$cS+ImgxwCW9F?Alpdj}vwH*;0^KFMhh*#MR#Q-Cr +Hx{>?)|DS1R%<@ahC`H50+bcR>wAoF6&D#{toQCx1FaHM5cch&9;{zd-R<&|z#?YUyDv#!f+yyNaQeI +~kA0a6G~h<_aFsiy_RSu1CoPc(O~+cxFL?Xcf2k;xIP0_S`GQfO-1ms_iJCwJkF?beMB6d%%jZ4byFX +Q1N3p26PBR{hwLDLEv3)v$g%2m10Sh`!}#wSLcTt?U;(Ue&uOYGDU&>dff+hcc1?TYNF33BfQl4$1L1bp;(DmyY|m+D_mA&(J&V +y(_CU8omFWg_B^R+4NfQFd!?gp{oKQqi1I^~(zLsH+zDQrgq&Fwg!hEyeybaPQ^!0DOuHYIuIBH@K($kZ^ZLkBNGJRhl6Uc)7$gwkQ}Zxa;O>bmx~<=-Ng0YIyXQ$QM=!xF +JJMXBM(hCDwkQ>qXdLI;B__W?KtS-D6j=GRdrtat`2NFmnc*7L#JO#y8iRTiTGQ_nc +bVtFSfH51QNAx}GeGn%LlPCe2W6H9Yn98n+CJ={=wxH2y*9#=e|s@7UT&eq}6pm{9uST7}Zz`1Tj%+q +Z$kN&@=|#N%sa>R$`{y`#*?&kdvzvb8kMpu$W3jrd*L)aZ<%OXc6l%oROpet3%Eq&CIihgnR_JGSO{& +3$}Cp*Mv{b|wqIDR@#A6DEoC0_?H;ZZ}Lcj<6cxTzQQi*6N +i;3@!LPfS-=0ET>7g(_U?POU9q +DP=Q@6aWAK2mtey7 +DqbIDGUV^006~6001BW003}la4%nWWo~3|axZ9fZEQ7cX<{#FXkm0^cx`MhaCz-pZFAfP@XczmdMk +%IW&XTbulj+nhF+U5_`ttd_x;~U@Z_ZCy~uC*#(CpRCXeDST#`tEb53S~!bn$l%P19Gs#s>IF?vS~mzxRv +Au8QKW8aInYWySKCQFIF`;$ZlrTKmior|)SnZ_w;ZzUn=>Kx6XF=3(~yBfxr$b)hhj1q2S%MROp{CtC +xsR!FjHpZA}~`6W=deDne{oNDKhJGMpI;ZP1CFx8){d=PDY4jb`NHRSmqha86lQg#4yN?+d>C1q6UoB +N^+pk4-MEy{${letz;0y7lTP-2GUC3S*^&cl-7VlA0DS4+yD(k4ln(iEvaMawiC?WD1hNl7NNS_N@TT +$zcB_GyW=fSt_vLuYttFS3e4u7cQd;9(VMR6TjdovDvp!{WIGajNl>@?^C#4tcJcU4Cd(WiupBY=oH+ +&S*%lyKI)=cylf6=ZHc!%8?Vex{>RK9tw>cVE{W}sO{)$RJJM%MV=mteBB6jBi0S$YE+O`Y2u10(%9E +_Vy(`!KWU;HnYNQsfN5pyV86?cMBB+yEu7^T$_*N2Ha02^LZ#y>Q89WY(@El$v~Z=VE~FMXm1mZ+@)F +|cqtdJ9BokPffMkNga6*y^^_o@+UTS2tUR78aVE|smRy`s0EHE5g(DEbK2D4K8lLO}}x57CIn_A1OC? +TuDw;YlwG80!xGNsk3$Z};ZSEN;qZp^*;Skuau+Jo{VGehHnHm4d}e(0jhr{@CSW%}gz-IO?$KKXsx7 +rr;w{-ilpr-q?7wlAMG^sIB5W6nswS>M$Q_3WaaT6iNLg|;4D +e0sp}?P2HB>FL|kGe~fO1zQy-qZ%|dXLm@KTxhSWkRA-etk5NFR_URf)OAA3R$!`9XhoqOiei1DMOaJ +uVXlX$D2StXkt{W-7%k1w7L_q^63d~Yw$zCzt5W#GTzytDUtj0U#|^{+U2L&HAES((8CYoMV$qyRSaX +*!x;a>)k9C&ix>4$ehK13&%yLsGFnYjX_5p*@0|v`As;to01EVJ&R_eJ@cTVA?{y1qmo}RLyCr#<-PX +qI)kOnbvY!yh0lA4__D@@XgZS6>rrY6!(a_ +Ir4`jZzA1A{TBb6v^@^vfu8f530aDTdQf6kqmw7^kiwTGBE&0JlH!7cQU)hLtgXu=88#?(bdg84TvpQ +805y#Y66+QM>Y&>aYD>g$^B&8B`b+jnnE-snKZH-l1Z&hMlzYTlhG-gS(%(R)kMVvJkAqmX=2la%WaHY;3s*NhXZ#9k9E!&JQ6^(FHu6Ycr6|3zGCtj< +zCOC-iWGFGmxfd2bf=f(&r%HI9V-PU=kL~w)$~$-Yk2BxUFX-clam+D-xkB|`eAT}TXC}DcVbVI%&D( +6WeS{1_C%61MQ$WHyxdPuoWnnjk(^OYQ7tz8@WedQtnzE4zvSGAb2-WVVkxGZ$&1J7*HGWQS8CMWmnX9q2Dxtiuxh{LLvt&2D!%N+*3d@A_*OjLE9L2CT-7ZQW +*0jva5tJErE_$rYVz5R*rFRH7rnDu56)NXmAE)q%FX+8et$2Qa(a0y9=~1xc{Px&oseMY{OxA_aNkd7 +*RumNajqyFAG3Y0@UwCLqxYt^;2S5j@yqQh6MW0jQ1wRFw-gI;mv@~ +i#qutRSSl)dX6(Ra?PZBG}f`)+?3fugo +_#o`6T&V4K)UHksiS_9&rrzEx+n$cAAidoJTG6{TF68Bm+Q;8<=yGLI(pbiqem4zGw}$|kYa*)zLzLnNw +LdZshf(fg;6)9oWv&ooRdAf1_T1FPa5k=5`yrai&xP{GiD175Q9|SBm^mkslTLd2+N4pufqb61i67Cq +<@;%&4xgsjL=JE#`p_7IyMgor`FkZ^ZqQHCTCcvpT +Ye=A6}i<3mfgzY<>i&E^3G0QU!48v>gw|B>gtF8xVrlB?CPYOGFFGf +=Q#Icft%1^7Zh2(v^K5d(qo}fg%=G!%9sv*O<9h@H4`PVaXUR8N-sXhCFLA(k9e_W{W8W`6pnxL)LNE1NEsBfY#JeI^2Vs+*5Ay +xpI^HQ1Kz_$Dr_%10U`yFL^)~g9wyShl9dPjwInoOdetjasbC;#K!>~2XH)TK;aMo;{c2UFkVB3km5j +!0~`)iIHAI^Pq?6P00Hl?L^W2rM(nlQ5=%{0Q|vWjuMvBV*lQm^)_w@esiP*Y0~$ftHHBRx?3%)^L+F +GFb)XYsGCBonU{F)?)Cpz-26a*sO956h3@~iOnkAsH#W2iC9s8{2A$4LChk%8j7buJPiVA5J*FTG}!nJou>`X&<45D2$~SN(NJtHwnvNDTEx~OwidCq6jh6;T3Y%R!LfumCZPSM1mG=S4ov~aHTV$iXpM!Gq5kOrL}fhM5ifC8@zz@n48iKN1!NXIdKS3|Z23oGx*qfOB!LZ?Bei_uY+uji>Xl{5fNKsjiusHb*-q%|m5KGXsa0|5pC3dX0MC%~Gpjw_qIR-HEH3V}}kUB8r-wJn$Nz25 +UR^M1Yjk1LaP{TpBXzgNK+{)g1RpIFoab%MHMt2+5-dGXKk;$!8-uPY)B%LkOsdxe884}L{q@WT0Kad*EI8)vx1e{ztO!e1Zi +MT>V;M{0!0g?*}boT1>{Po3~KmN<_K7aA2-`{*jukD&8?|bLZt8U$ +kp;{~lv6-&xccL-h5z}{qcVaahn{qSx?((X|+raQN{CP5dQ>eZcy}4Pe7Q@ZWv=__nR2x#h_ixneu_N +Dbwwv|6tc6zn7wd+jBzl9_ch8BY!?5|Pe^Ty#Bi>8ji}gdj6b0{Z^Yxty=HnVtHXTOka@9U5KL%E8-dsq(wt4b3{*zNbT61ek2Oymk2GM`W)bhb5!vp30;C`rvH$BvuWgKf*e- +pHN{Pr`_Vdt&T(82iXtANEI%`;hbIR-ydk&o-Nzwb(R5fw!n11~DeJdK*u)zn6;0>)Fn0lc&~Dy}46* +=l#GpL;qnh+)gKtO6Fp+_X=A7C#Q4Om`;ojz0>fOdKX)Zw~LjdOgOMGIosi{uRNfw-)Mcf;3=f`gJiKykr{RV5l&M_4w +E|Rg=v2m%3cy(EGH7{snf&4KUhmWlTpB=E*&`2PR$(PtMLJ3NvNv@OJ=vfSZjy!riP_1DDFYeJA5u4b +n<~D?XY+h)D{llSO`*S4YYh^&-mAucEflQGy3(n63OgAWxnEy8+`Zrov*QUKvl}TC;voFPG(wm``T2j +{@|qcpUb@`RxGP>;>qfPrZ-p!<4A(5^l-@V)USRQvpA6cUY_)@@BEjV;8U{Yxu~QYr_Up$96h?p$db()dm`DxY-^Rbe^RE}`o} +GL>}z3%ybC*ahu`TO|MF`5p_DPbvm|%FEW?zMkD+NMGLSwC-4VYIFN;H)hI4WN(2k5^Y%Po}eBswHJ@ +SU!Y(cHRwY1xtciYiT9CzwP(tv_EX+bqQl3X%f$RDV!zzmuM-Y%*cQg`aju_9o +g@16D-q@49(4LgJ66Spr+!)S?B3n}*^bJrZCC9x+fH)r-+|+gR#A-VB~m8G)8}Ee$J!R(JD`;#Y|jeX(Os6tGDI|qD;%t#kI(1M +K!9^TMefXx6MU!SBhY-(XzM}weEY_H08xKOGVynZK*b#Xed)q^Ohr)m0DH0;}#vJ}-csYMqgk;9~EzJLKAMVVB!IJupQvVp~`A-d26@Z{BZ +hHPzkzRsNsIn9!~b~^Wp$0z&FbgQCak2+L +O3X0Pz7rbU>W)07*F4uk%GF4gv2g(IChmG5*PCn#8Z-K{Sb9#sCD^KEF<~b +atVIEH5tV6>Q@oX#~KF&%Un4-0Q^t(r>(FsfH2N?U!A6}f1)tCn)L9en{gfhQ5D!YYaCMwBQ^X+B +FU5I>NuD9LBhv=X?-?eOR(Z7vlEWQWUY1cC`#rv{Y(QkT{ijGJPW&7h^JirH!^0A`eCnOGzlgMk9A^f +sUrm08jNS1;=*2f%6_2)$lSFC$!z8rxzuq867;D`d_}fHGZ{X(oDW+4!N+H|stEAoO*l%Q9Q@DBqf7L{&9+b?CF+0-9i#F*kD<*D~)-qp*+?t +Pjm~3&t~AB>M>6>lxMo-nQnQ$Id;$Wm=_w#3*GWsx4hmQyF)$ZP(wM=El0ZLcysKI^_UY4Xy^ +Zv6DhQ(0`qx0w%qFQLgf7vr15|JeE=__=Qx#$N2Bwn7-_h@_qE0zC0e|zfTV7%TxODOn!NGavt~5${r +sreGoJFF9zFUVp3o@=+{KZejL+{05f6w&36xh-7J7@Hmd;W0YV7TT`bRbVbrcvx0>DGPxGf#B +>8i1ok_vqT(jsA}F6P_46ntpC}Vc@W{jrY+jUr_NW_j1uj?lRgFpn?LVNlT9S)IlM$ewL6C5YWs=_^D +(F&yPRp`r0%|TRZX!@*ps3OYCwkw@|MaK5zFvsLWhUm}n*x~T;-XiJY(7wHVm=Etk7O$fE&X9XRI53N +&d%)zWl^VuGdvpZ0wbKGuA`Mj`D!^4)c}?{2Sw1L(}*l1RJhwzpuQNJ?{Z5K3OX|_3TOM)v}fb<^L>j +`5zxbfC=+>)#`m|JC-(T=c0H8<|2@ZUEvmH;SBh%T&hUlZ65u)_%$Ex0#Y8a{xhTDMV!3`;9)i}5skP +jjOOOjfny)oI??*4yaC?;sW5E!F#T-mV(zo^-Phk)9}TgHWr)MrQ?#aN$){VwsT2(*Xr_XdhqO +Do8HmO+FL1kt^9_x7&LyhMgKfN+AdOGRTiEnh!vfZI)5$!RhykNqmc!m>sjdQ~b-2P=cvH>D&eTQf>l +=){lnPs`niciX>q_7aw6)$T)L|UT05hF!TmCc^`7f=N2SivV27DTgW$}=7Br+=V#k(@j8C0Yb_-l%9% +ylHOucidc@kc;Q{Zv72piRvE%lsxBdGa2zz?Y9@g(~xdJ{#I01Q +BoBvkh~9f%_Z#fWVML4_b~k3m)2_BkEU5si<*3?X_4nLrW-LhINAP>Kf>60R1%y~Q7wK&`w+X#NG~2ja4!6wnC_%iz|_*zk>PHzCO@aPTC|_0BV{*xWk9HlvAby=ESg}g1 +^fwnZg$ph);_OQxT*VhPC)*1tSqT7zRvOM5RV|T4bxG%z0#KE}{n0WdKLvWSsvCkl|#NHAmy@BAN6w`E`irGMpVG<-GI9T0mz}SBQT%3uT^28YN9lrkwktJn9{dJaYckpqL(=AmF|x!vytY3X^k8+TQubsX9&w0p|;p0iKjo?(I-T{&6 +^Q5D5g#_RF8KcI%0YS%s~M-bauwKX)u90t46K`G@@L<7!cK2AyazvA9C4fFjQbd!?Cx)l0zI7C&0mf_J^mK7Sgu9o0MDEx;5lUhTg+Y0?0Zn$`%V-+ +mrUW@vyeUnqJp%`G%p7t +xD{TVNw&MZiqI>GIS)b{3rbOl{2dWxblb;S_T +%-^!Ld6a8@qh`=PtGwy$e9dGrne;Dn0Nt_<1!@z;W)RDC>Hiv&CNHxqwAV9ABT82T-R_J_~_+1IRN?> +s=HG?$`Y*yeZ%wGiQ4OpI>y~P?ecL3vvk`Z{`*gEkfkS%T~SKyzo1nyySoupYZ$;2p$Q(&#HZ!N_S?l@H^AeypYKW6KKY9B6)q$h_ZQkGsU6g7H6?%O?PoroFi`cTI& +CaW_Ce|&ftmkK}mvf+CgXG^}|2+MGknOy+#9wL$vt&wB*jen>8p4+NaWOZRlHJ@;$}!MfHw;2nsFP_C +m}~C;02?0647Z+#%tV9`xYtHbDvW`nWLg!qXW%sp`u5Q#FvlujOCQSgF&}Y{+11_13rChl0B-2ds3P9PowQq5=JkvnKIs%QYvx%!%;^Zu3l?HxT$zp(gPJnRW@dvfBcHO!mZR>}zmm4c(u?H$dq~DSew|2;6^x-N?TGv9klPC*2XTL~6lhe-l%jjw*PE(oUC5-AY>B|`AL(+U@X9ElclyuXqqeWG$%3j|Vae1IEJJd~ +5HNC#W^dDfen>$pj0%-yN)|XU(gswecoa8y?f+#&*N7%u|T&7*p`jghpACgqA@(iZmrvvY3?>u14TTP +g-bV>=sANZ7j9lijf!g6$;hfVjnIMPH3%29Bf6ZZnAn*LpWV_U}PId}=iX#T?Zmn3HLprc& +`rRN1qZ*0LJx}h +)21~|?IgCV&h!(OCBl4EgjAsai6)1R3sC3Kgq8SZm4cNH89!5y%%_yWqgB6j)(h1H50M%cn9X;M(0S +8~48J-<_Jk`6Ofq4_apJWH2)s(d9Xh6) +Sn4xhN}%!9;h+2s3TNozJ}MUm2SmlkqH$(o0TiyN`Rc-5m5p#q<*6GVuDvMsOm4BA*l#XXx)g{hD&u$ +=VdJH(rq7}2P`Lk0)d_g+M^Ivi9#)PWI4c0CR-^PW0A`lN*5KH2>eEMikV0T&&6%yWMDU6Xjt^`Peo9 +Y1hJ%SM0n+`*fN!bg$<@%vI9#WtUy*9W&kbc^?jb*IVmBKJfKH$BTt?1JTG4qO@pB^h!NIh4v}VPpct +SDl_%7zC6DLn9slhlqPXat3G0WM&s8q@-n$nNMwEp +2wtt}hBOl_`W|@@Oppi6ZG6EYct^7ON3p7n5sBYEM#m#)6MkFgLI0XuHYo0>BhDv`+HDj1nIOdVeYg( +a-1rfL=v*Blu<;+N}bQpx_zD(8Nfy4wp^GbA;8yP;%MtPC=emP}Jegxtlh0$Kgj6m93E|Dut9eF;)oS +7gL1GBmV!?MRXQEd{1SQg8c6)iGNo~bRDpLOl~4|;5(E%rld;lK`rYQXu1p!ytz&YwOf&2aqi_58ojE9`B1$3{I&WJmHLRcnnyG*J_g#} +pML)ocY?-sgCBZO@=iG1#8OHz1|OO+DP*d$JeX#{h^sqtTqE)1`q?4C*zn=?ZNIUUe2*^@bRBXCT(xd ++B*hffeQ|f(d0J9sW^EK(usgFIWcHF5(D1DZoWkWQ-hn*u1L3s@afNsz=~Jp`WU%+1+*Zd$w$Ba--^= +&yGqx@AU7JQnrwP7bI+6kf5%O`^wNu)u?nY6m|t$=hE59RB`U0 +|?E(3!>PU^VC9pJ7CF&}w@&u?$QrAtM`_N*D7PWVs +rb7kkaz3{pssJB84wYsjn`ve{b{UXdm__IJ_`_VOU`Xkh+p!58?K6*?@0wA!43DjdjCEF8EOS2b$?+a +?ZjZf7HYNX*GapNSE8DfsGwB$Fh-(@xkf#l*-^0_EB2Rw^%be$AeAr)-NUm`^in|%)$BVi;kgVc<{+4zJxwpV +j1izM6E4#iGzz#RXFK}Yj=zHraY^fropX{6IIiR#0I41H4$vM%^CZn`a;i|-DL2X2Fai1e4w>{-jOCS +a|K-zaQa5R{YUDL%JWT+lfv&81$x4fWZh}F0=Q&R6V)*>|lNZC?c;9jKe%lJIX@u!4kO>T#7_d$S$@- +kRFwQ+=*52J{sbn2OD_&b$NloJ;Y6@6nT +Q?V!=6x81b5C5Vx-EhB$H(=9O^+}{p0ido#>#m8Z1`sDhppLhn8b~FD`6FK@^A*bVtd3kx(x-a3trwVX^Lf6GF34Gl&Vp%o>TlT{wFFGnoqYgOnz(A$al|u*$re#@ngG#x}2&Y=6xyD?3 +SxQkaIi~;te(YQ%R!OR`)qdP}6%D_GMdKk&W#FFsA|hbbP_?m&h{Uj_oH?ipv>?&i%kV4rXN|VrD%-;t3#jK +Ci4=@SV2w)?b8*ZZisXgzXofDmr>&6TzIZ9t4YB*u0KRW{|GWkE%wPU10~(Urz-T!W7GO;XF8$)J@j1 +_%@LX`_?g0fFyGwn;TsmRV71V!zXw2fQL}Q$a`~V7O_|-CLP|Z +e8Cw^pjY#O8a#jU9y`N$L_$OsF`h#|=-Par9T&b4@7^$V=AsdiuYlmMH~?D9D-Xjgy)vm4d7&0xh*lR +bYb{YGf$20ECb~SZ`7bmQ-uzEE%@cIpC-Lh7A+xVSJuV&kCc*suaFg +JqrWBP>=?%PMmiTTtNVBaRv!0ej>&P3n0Iv-n2I)l%`!RKFqMG%flZ_X9o26w(4r@i{d7g-f0 +D2TfrTibvWzHcr6NFL6k-drQP^3+?;V!scHZSk}P=3v66Ve?}}B`f}@4?-`Vv~BJuEW#v5g1^*D58#H +?h>Sth{>TCwjU+|-WXX}^hx#6~fhH4FC3`!K!vj+_UCZ_SDVC9t6Q=6$0tJ6QyLw&p4IJx18F*b#7>v +g@dJo(()Ha|*)^JX+u +Kl%Fv5tEx%4+$e_58kNAKMrm8ytkiH5)ebPHsXIU#KKjM2qwq>n&9mJDs3!JgA6e?GDl1Y1$?guFzOcX7I>9 +*j|pKWzXprMSyaAUQ+^zyEz-9xTECRtu~x!}9Mpm;~9u^<&LQo=$;#Zjw7$I(l#78A_gq58yl#&$9*BqPvG?GAPM=T%_juPrYN0Y9gD3iaB?ocKvx +wM3}wa}#R;fSg?c~;N;bEFWFudv6uTD^l@!_`PvDJmERM2u91q+awJjr^;}i@rvO4UPMdscle)(WHj8 +zQ^ggUcK92H9{>=}4nkx+JDiedeZKia*3HR^PdiIaTxIavhyKd}3g!V7f!^Jd+`lYc_xh10iW#SJ2v) +^82;?>k-zQ6i&Bx_g&j5WTYKPoR`AQ1e$8s$>Y}yuOgeLKD_=;chX_>w&yrALSZ&prX$P;$ +;Jixe7SIS7#XzaXD_0bco9Z-m`_4uAwAWuCzuY81vho5lOu> +z-FygG^T{dhwlh14tAEeOuJx8FU*B +#Ql6vWn}|DRqVl+|iS#UZBY+&gb~g8g8r+U{nNaW7S6oA)0&=n+(yfz>l&G-~mo()4%Nomckr#AtJay +ltFh`C;OM|cOp{1z!ze(`q8EA_KPk63Er&-B#T2!j0*nz|xRo4tjn)n<;%Qt!Bz&&io0q%9jSLVUgMD +T5P$p57nD=3{xt@Sc?sjQFIWn4U`a!C3$5p^{Qy(}yVikq8)9>h_SEs6?=zVtwqRe>+y(WkvHY2U0~U +F7h^O~3aCYcGAr1wR}52+~#2ZbG*z+5lYeWfXk#*2uN(iCTWBHCyN)lb|G2`!Jw$A9^u?oi}M+EbEm~ +1I`6_q?@)Ux|LTS(J9E=5J>=2>_$DhXD`!`VTSB&^7}+T#@yJcQ?scl@Wk6I_ +*qd?I-Pa`^D+7bbz9ojd$SQ1}c#c^Zqb&XpoJcwlqQO(*FEb$g{K&G389t_E+ftOcUd*v +&nb#wP{XFy1<bYyL)gz>k^a9-%O^J_*d)<>UImonIt45BEdebOb5N>F4#%A63=kybK-NxhFl)-lNB`0KOvZU?zl +cV#1#pWayIJ-41|00TQd?d52-Xi9`oCaArOr?7<^xloN1`n(Df`0ZUa82DD(K1}+kI1ORAE`rnQw9En +jlQML#Z*P0N{JFYbp$&r1ig-_9ZqA_VTZX`qhnY5w{+TDHEzX$#~Oi~J0rlI|3t4#H+8r8n0f`SRk`f +XDsJ13(!CZWz!f*?=3W{k&@W*8c&;J2XO9KQH000080P~d=N69 +J+`$iN10Q^J%03iSX0B~t=FJE?LZe(wAFKBdaY&C3YVlQ)HZfSIBdS!AhaCxO%dw1J5mjBT1dFB;!wrX)A=q0 +OUm<1Ex@Gp1ZbQQG2#0%&BY>=a~aA=qP<*t)4u4ByuMg0GP?R%67M1^1_6jsQ!$gGeS**=SAHm|wN?Q +aia;e;SkRAJ(Irg$yDvqOQxoP2Bh8bzgM%;PjiBLxKS60w5vC!DhOd|+x+}hh=CaC?BJCocL=gxQd!W +v&GF6sCrE@Ct9U1Z^7vSxvxa=BvphTF^3%Y~!o!qS?jrndt(hbFe< +r_+Pz_*At4LTAjU1VJFl_uB9Au2-9OIC$gkkn(j&3SeCc2eYKz)6}LU7@n-R7q-?vaHiASy_Aef?R#ZnKq|t#cupBC-(5diw?V!XY!P@VnDJAi$i+Di>sd=X45~#39f*lozVGeR)!-uk +pxCv@h2laeSEm6a$KqJjbz_e@y&1)m*{svq{(!XU76@gQW!n${gL@79Y%1o@gs80T*3utrVWqH+C=tRE>gsc6X +EJ`fkzKo(q;^%ft_re#L`M#Z&t?wLaadE(kZ@8LYBIzzfW2$#5TIgM69jT@k5nhn~%!G?TF4>QQK +*aVw7SwsOh>U^@+X#&o(j7qgm?*qRF(nuQtQkd4b`-ex8sd +~?%CszlJN2S!6Wcz|#@>RLdj3)nqoJ1(ZF-3EZuQ-Hd*T+UWq`#1#85`v+@T~+K(QYS`O`zm6dne|N& +*vSYxI25cnn=%wbsgPXAlqI%F!h&^oQzF?-7KNSU?^VF&W0iXwg%@Pib&$UgI0z!xsg+~%aTxLOYV$y +jcSE41tEwAj?Twg&Mw&OFIVKO`AuR(26-!M3g%+WqSJtf#FJ;{BW(mEPw6Jnt`t>qYRIVOpl&_V47aN +5OI~_S~qUx9l@01`1E2IbPT@R{THk>vFuBdR4OVJ#+k%jZE41YHmSI6A7$8E^awu +w~W^e8bR*Z*G5i0eic?IeG*z5?AR1Z6Ns5gPwV7q$y4XV{>%rFi>}N`VB8jLgVhpHHwR*a$X +)S7i3r(~fKj(6ltaw*K;nYaJi7p}@nQi17or1IdgzqZIDKoBH{=;1V$yY>*ZyCQg5#&Zc6ovw$#H%fs +H@=qC?%lsZ!y=RBUORw;h>;twnK5i-%obXx2=Hrd3mYyZ>9~C>%x#=S;%scbh6uY_JFBw)#94%9(pgd +^cJJgk5CCDbOzigVSsf~G;xhX!aL{e{d!k~eYlQE5Lj@P-W;wqOdS#r{I~3wOu*X7h>cT=`&Q6U*?62 +9E=Sef!+)W^s(3fIY~X<%WY#l6e(M8b?fU$W47;rFlBWP?mDrxOgx{!sOnNKYoM~~1*-$!Ve +_{U<$Lik5hYeWiBmIZ|0+0s0w-rvFHyb5&Ni0g~S$$6NUi +h$8S-<3#`qR-ge`0oaBE0T#e%s5NXO&;y?ftIpex4{I%vh`pUr8RVMkJ#Gm-Mo-rAPM{PKgf(to;Nod +~kK!i%n2>}@>PLb0K?h&2&*l|6JSoNH=dq`Q6PCm5zF=kU_Cbe&~*48RDP~#M{3e8LQTrx*`N88DTfN +m->6G%#^N-DB8=w&A{j2=-I46%Emf)PP$TH+L&+uwmy0Do_zab!zzGW~LVhckm&;XC4xCnbY#Nz<1(a +a`xsl{|rJ18dAN5)k;wkYdSs*;SI7L}eT^yOe&s> +u6JR5ty#=ws#&h-D$HpKd?|XwX*fqmSz-$D&eN1b30HnkrBhp}WmSRcrd4ebrPg~sg^;RB!2QV6#ey< +)z$FqpFOW+-eV9X-$~^EPp4kU!Jeml1we-qUx;$o7WEr?8PmUc>JU=)TbY45KQlnMNn;t*haDL?d!}( +s)wMO#*gEiu_gKm!VZgA_hE(a#uXx_DMu6-OcoBFW!)T2pr>?+&CsdT9Je4R((`G}8p12#dbUb!xDl6 +xxl-n@JF;kTIl+`V>?28iR$4K?XN*_x*DFL=Li6XcJtxwhj-U5f5X?b_U!RsImg8 +r^k4Gpk5^uh%wqxYbguJaxf~3=mru>3{;=%qUB2@EEzDmucEX3YUn5K5;fC(A_q*5#ZhHal!G~SrVEC +f<>Mca|I}aSJ^Z;#o-#mZz?B!FjKa7{6sUbB3|5EX#OyDgijrP~S?3=b;|s&5V^VBUH#G-tS*2~*=~b^rFPnT11s+ +PlV``i)riZbvSq-c=m%-Il;oYagZgj(Y5k)v}-VFh||H#Sx&mC;MLe;(${oa|n6$*1TTyJ96e#KhiHl +E!)ZAshm?O%CIiN%bLu4Z$Uv|{Jq;c#}opZLt=kGW-vtPtW?YTm>jLFjqJi*+a5;m9!iy3)VZKXLEjv +J8yidqxB??@Bf=qBMOlU3UCTUWKDX10i}CZ@mew#Nq{}@4+w&ekms2n(|5?fd8rl?pZ->JP3I +hDt0hLF<9?uSY<~R$gQ}u<7_UOx`YP8jp&S}-^6GMK`n}J7O1~8{y?{GAn^t2yOO>ALMqjlH~7Uk$-R +nI0Ir|h!Tw4;O=#|hwHAVbfQ=Lw9!P#N1c6OCZ1`yX{pBK*v0fP^sp*8H^)syfUiY9@c`xDB;vLZ_q# +eRoLx;ZcdzFxJWnH^R%-@AN`#9wot(N)P* +-ln6AM|hu-i8T&*w8x$VI8`AAOkQ4?4^58U-b@wtOe0u2barUFo(Bg1nqTCz3f&4eH8`ApQ5oHm&Q)im|Db$DX(;t%GMTcovxVxN{C}86vb63ZC@S&(nzR2Filk(Y@}ABO9!){T#dvvp{*bK}U{=BT{KB)L1iXKw`Ao?hc+ +F-`e8e|4$E^w6C5m{J(48z9$4v#1W4OG>PSGYo$H<7dP;e{veS$?&q+AGV)X)ML3yE%GNbuPCCTpNXivbr +_mpi))6_C65`A7%w0wZt7cq|?9f3__(T;wn99*E_{UxL(W;a4IoJRkNu%K34nLna0sMafP)h>@6aWAK +2mtey7DrMibLe&^ +r-1V({BCD+%ZD2xJneNCL{%nw3h-Z0;dLV7L!J|ebr=P<|jj!5J=mT%K**9mE0y6n-TFql7iMBuR|0X +g9X;KKnKx#lhX`U&y;-_1w#y+vmsd2LSVSrGVvs4+7c5Ex-6EZ=ph6+#PI4nL!Y +-U>Y#l#Fu3wpxJicv3gLWh?AZZgYpexxDNI1+#TGMmxhiy!@a8kE(tov{-_`3Zf08hAb9T=-*QB +Vm_l#EHuX#$)9Bv0y=YHbW`ZOGQzmDP+8;xK0kUSxq*Lytni< +n{I37#(Id+RiEwhflg=MB==nFlfnfSVVuoRmi;2UCC>er?;jIc>WV>o&3d-MntK4A0}4 +b78_AcDUm##Pv+q4*+hUwK?qL(63J%;oxk78F-betH&$f$}|XB;YNA)Dn`)FhTUWf%WnoR{E-Tv!5j= +ngVj-L)zE@c|(JdAAn&)2f@0%J5XV??(ee{bmIehy01$r%F(N}AMslKVWP7Aj2Z*h#A+Pde8%qKzxxT8m@qDL>{w)C0$_SXa1~r-2YJ4gOs0T&F6|CL6?p~RY}obMpODan%>ah4Bgi}hFypKK;LK8mTT=O@_1|!GoBIZ0AB +<0%V+23=cmLEIGZi$Ysn2@2#5h)QYs&tTFw+;14@J6H|3w;tOLrx{!DCPNM1rv;W8g$1hDP^ypr*)L7 +WkZOQnK)IfB?Il;0Ny&aKMsRf^+7A2m(7wu~w#e}D}FG}@@cJX}eB2u#~~4_`k%PAy|3*q9YiN+F4PG +QTH;zD!$1eu8~iw*np&MSmeAh*YzjXCer|fWiT3nckSj>N7QO(Wn^&ssI8CE!+1FLo#uo7Pq^U1(t;0 +SVggwUO#6z7B(bDhX!XMJ5ew|E6amqJW@7RKl{7Bz3jNb4~7E!Xo!Zc3_aFs9<9Jw993Dc*faJL^yCD +8=o!ZFH;7VtNuT;hLI&CPpfMB1r!+FANqh;Q3uZukGzF&0KWz+!pbJKejDdb>OI{|#t}=C&Rrdsaim{ +UBF#t5_*mMUtX_;YIH-M;Q-~pQh#~Se1cW!9nE*&jw_YS%Oz5CNhh6R5mpFey^HG;ap$zJdH{pr`o$K +<;cg{$xfd=1dk2QbOC-Aju-g;I}?&#_!z%W&h@2=U8!XpCh!?*VRj;z#H_W)!rVhj}=Um{7nT=1=Lwz +b8F91n)fc?`UFvXlF#uzOuF)%kKF2__0QI@b%Xk*@5)2jp6RP( +Od6(#e?Y`W!`>zD@AD(9dVYQu|9g)AKIUK45+FXJ0-=I>2u{ax1lhoton`OQC@()y>Y`K6@ +wrTpfrrnJ72HNTd$zLwv7)0EaXvgR{M>zVxKc~e@?Wz83o)(iQ~X;WIKvgVnjbtb<#Z%XSt(WYZbOd# +4-9@6kx8oFxts0qaJ@-4z#(tdrY!zanFsSnH$gZbxiR?P#@!{CLHUtYW&d_msK!wJN$H<9Do>`-Lnz+ +d8jIcMU!-?Oo<4;*w +cjV7$zNW`Up^I((a!`wry>C7WBOK&z{yV-@!UHMlO+)#Vh900cnT5kli&Gt4?@Ar%nZY8k>=oo!@?rz +k@5;7C-TV&2K-O9;gYjjIY5#6Q8-|9>R7((dqz&P)L1owNIS%UHk}%XIV#GcF!jnzy5is&L%ul8h3Q9 +3!8kWjNKg1ISF!d3@=_#VKmamL2ei$|g@8B;Q6gYtA|c@UB7-}}pnPhEIGaug#f5?4pBg2zj$$}|rHU +&JpD&NE&@<+;$~f1{7wN&g00i@$afI#m3!;H4J%uH5Hi4Ys^9%L2lambjJSJ)cq?S&{%wx?=M}e|&VC +2K3pE0|TWJJ>WE=Yk<%BOzeA;T#i4kMo7W@z9~`FvQ0>r%OkoG%1eX@>`o1#6A>$klg-#y5zDF)gBni +^{fhoXED#MEH0kLc@_0usFwGhzYS9e3qE+donHVlV7#wih6;HP)b2e%{4j+Or7y06d6*_#6*GU`H-B+Rjw>COrx;S51?dBY3% +wprb{3Kam*Xg6hp557+IHpkfS6MHcBFa>##qaVIu;?1)Q6NMK{1R%+}zd(1hk_#ej|@V6tD}3qmDfn^ +FJ=0G?|M7$wl3W&0^|IK7-LCHWhTF*zdZrmlnyCnmeTrE_+TF7q0~gpu=JlVQ}H`9lStF^_IU(G&&6AE`G6UY!7fdcCv}ZSeXpIxh)bGri+0EP2< +Ulu%s0RsqwZTwiq|qkJ|KI?Bi3uu?mKjEB?Hj)wz8CKAlV)as*%Qk5C^is}NrF0sL%1@&XE)3heWPbW +s1$uHp-@Tv9<`5Jn6nxQ34DNK=J35&7&Z?mP18Y0ZpFRR)>&dEn*Wl;?0gRwobsk +a&TD#Zw>%i_k}j7)Yhba~OQR-dM0UoSh4+vtZ?Oelm;`7-dv|tl> +HKRo2IZMpl$SF$f+zYbp!Rwn%DYeHcpT#Y!uXLeNe3x-j;%cMlHFS!o{(kI!!hhboP%*6%v{4TM=#5U +WNHNb{D|c@95J4a#f=70ywZ!1kkHCw0sgRfMcWz0g}7hR=8}|73 +)nj?Y)#_Hq=e3Qm2`lIKLMK-5&1R3Ja1cB(R$fXDSOAeGhN3{Gx*vxXw7~o?yhM+VjkpIh&hh{*9*H1 +U}h%Nh3_kYFwf4-eYKm26q*&G04B%-2$0-)4DyK&k!U~nBf?-30P{VbACD25k0?iq31=y0urTcuGuV7 +Km2d0d`%z8&m6My3;uJFWDj=B|)D5XSA1*Die1Ow1lH{!XtYCEP7tB@kasxc#`N@7xzj*SCM;pMvXlA +47WOonZhPopH;AE)@NKTwjx^v`2R=|bM*mLfViC}M4VJC@D~bWWgi0=1n$IY_SP4-}xU@CfF8NZ*Go +xP%(`E!wIH;2qdjfNh&juCcA{m6XMPb$H6Y6iE_?37wAhUuV(Rms55tEZ~2&*;VCv|?^)xMEceDC;K%xSN8f<7=plSP6 +K-+fSFOE^Ad)bK*~gK{l-R%)0gbdzac{YD*FyDi{fRfJ+^Vr17+{N$}mfcjP7Cmg5I=+#GAk&2hNj1h +)x~;Sc86_~s_68sEw@B+sKTN6Gea6AP#qz5-t9&hZa1(`tu^$cs+)p*Q0b9ML? +O{)fE8jgW*>bxuQIwU>_YYV;{QX=&lmTK)_3mYCw2Iv~{y1VU{3)&i=Gk7{jfbZM>;gyDp_}dSv*xU} +fauG6rFMW{uEHK=QN0Evr?9U@^)*29rnOEkl%n?4hsxThrd#aVg&|UZv<^G_d^v7u!ALOBGVwSFa(#F +`94?;|T^AeCY?pfRGv*lnlYa-QZLBW~niI=h37!^a+%?^#BR`vvdD&VfLbov>uP$b*M;=qz=)^6@7M5b)Q57_c-@l +w&qWbvy;xHsCyBM#;wSRI+3HLsY_mMk@{Ho4U*QAlxd$_(buqtS>TZe(b-HfoalBBapGSzFH~v=+YAU +zX4fah*Y2UJN=#T`UP5kgh`#We$E5q9}D(Fp$8X1&*3kQNv<1%TiPj`z3pQG!mUKrw@Wd3qm|S7Z=XKR>t2Jv9wvR1b8bm7=}w0&vzsw5xv{Xm_*q +DQA-57AC;*6+_$h~Icao($zC{>E->i=lT|s?1tyybOlkx1g6&Sb5uBtQERRnrHzBO(9zUthK`Pzk2Q_ +n(-=8=tx5=)q&g^_NmGA1F1yn1Er3?pVGkBiHToJo_nM`DuQOC2=Z1>MVPW{J@GSZHRly1XCPhqb%^L +AKkcg&r|d(XyFzU_D%EkYKQkWZNIXpx+MNyBw)KFewV~wl|x+;f5S=qWx!bcv{n_wy4A(L;5~5o~1H{>xuBIJKN-S +@+<$;a8t||naero4U?$(j22{P`Vm$9cJxC)h(qJ>2(KpPH!G}w6f5}hBubJpMSq?!wfumu4NGtL1IdL9kwIX4 +OxcBl7qevrRE)=0p9ufHtq{=BpEP(k6aDSp6ae@{z)bBf$j+oiLLgtvX8f*lF +AaiA|H{sgEOMRn3)bP>|`nW?Pb&9u+i#Ytm5BCoa~ppHk#%u_1k +d95p$1-?ZY6SrW$^b%@4h~pj(K<$R%7msPFVLpWbU^Vlp5r3@ +HdZ7KzdR81-E7rrfTJ5~`9Ij?O8K}r%ry@J80a7F&gV@IPb`vwy=%fr_$?J3)yYAb*RT__}2%R#Dz3yN3UKi)P9&wOxW5sR-$eMri`j*%~?`-K~W^Gbg}UYWO)n +8c&^#1aMLJq@_+YwX-n;)KLx@#?(kx?&qx;!YG&5x-Rxe;zpj3&~UB2dKBCr(C+qca<@|c#S`qQRq+2 +(6NBBa%buRZ=P>wbHZVjjmCaE6C1}x@trQ&E(7K1YFTaHNyDTyM*!W$sfR1;RzIf+LjS;P3Cry6|^l0PMk#V&_^0S9rllao`s)Zh|eK@zJSk*L9cf>$AbSAm1g+)jrdIQ^Vwnk9 +iOEnsFfn_)Pga{@#xVxWkz;Co%$5F(l{eoaRntg^)3EwO~0C)*<{qbQ=S;J=*D%dmo`*-?Ryl@YMQf< +PSbB{60-aNF$Zd)%G6P0TMVwD4)=<7c*#%4dZcNOZ)Xb-=TOo(oW&)Fpg(lzgF>CT6s?RkEsvcV@|(V +KVnjYUDHaFdGb1;AEekDgdw?S7Zuqv6XZXL1si7r48C?IvF0MWwUmLc^VASs_cZUUe93@AS0dkt2;N#lNy{(JkcP +wl#X$4g)h*5gaA8(O65s`_>AtZjF;kPkbL{Cu}PPQZ57MAqj5RzH5HK>*Wg;IQvD)Q%CYdWm;C>rOYO +H;$K_;ti2#PF2pQ1T>$U-om%LRyl>Ro#FDqH6CuQ`P(kSqcX;ABIH5g?b7Wmur4cSF!?p2cw#mCiR4< +NUckvuYU1X{J?#KKe1xGG_a?miI~KfPP_u0kEhr9k}Y|Ny3hg@aFCs!S>w2Ms}*RAz4&7; +6Dt_(@ElB_Lh2C>vepi;G2@B(nY&ia&nW-_KxJXWdVU_;2=Lkg&UrJ(dCYK??M?o@OMDjWI>e{A>(_{o)-MKb)HQDK^KK`md0Wq>GtskSP{E6BVcU`PD-d@>{;Ix{;7G1rErw!uv5$+O*>txcEt+2RTH(9Flu+Kxm +H6r8)TH+2DTx)0mI7=7&&wYz8;xm>-duzAh5u7k^&{PaG|fvK?lbflcjiiSM~{UKRZ^3zfG~rZ@w}b4 +m}N9>#C&%xo|`juZ-V^bT_;neGz2%lVne#P~sWmajs8O!*EPt4aOO%$q)~1X#uW!Kdox`}&bd5 +vjJ8)qE4bxd4oCMh*>1Lks1g#GN>Bpeis}Eo)bsExR(0*uPZ9It5gnV%65)%0xkbVpdjk$@@h-H&=81 +n;&A`vlq2z5UrsAbK)#_|)UB|zXGZQ-~>7b;8l8ta{4Ny{P!kf*Yg!hzsneIIE?6>im53*mZg;`D8tG|cF;kM1bdB~ +d_rqN`&nU}^&)8B`{pgQyM4*$AoENb=o91w{c*%Hct8E1v=vLbrv8 +9VXwzJx{SU}aQZQA-fyV~}U-R%yfh1TLsy1dX1aH|VcN?&cPLXV9ux7GE>`C6y-pU{bW53VuA1{YncM`QrO`oRChH`PotA?A6PQ<#I+F(x(h4=ns72 +WR#=qOXPEzUUDK1k4G}u#;|1B+5Yk#n=2!C$bX$mPxF=V$Lbfg;=2R1t0DLl-?J(*5Fg+n4Z?&Lbf-` +xRuz5^-{6ZU;%11es}g&ZMdK3)c&#UcFRrwO^>2gedn$=bhGLhMQ~zU88piN92-R|`c|cC7>5_XVoDe +T^T{58oC4tFr=m{sLCtuDIw@D=RucpI~n54_G@OtGRYkNT_Zv| +v~;%F$fQ70iQS_AeeWpQmYt=mQB;xc?(z8U-jOqBmsAw9Hnfh5g7mVnE|8jfTepFW?meeU-)XO{$*DE +Ev=tY%4(wFzN28fwgmuGy6aLm#ZOvEs)LR?fjEg%qm33pUR~x^;t5AgK7To%LMELcl)v_LQaLnWKRn1 +E_;R-LLJXJhXZ5@he9r3EUb7WR7;E2#SYcOiYbS3!sH)W*bc>@L{u4mDpJXd5*Oj106D=@& +=?K4Mam3TOo7-MP422*E#DLRhsiKkJ$E`Rs7;dX4w3&Ngy#JD^JzQx<4+wC*3F-5?^`}Q`SF)6)*zwwFeCXX@7aALt6 +m*la*y>CmY6`tkP`m;U)L+wid@PXYtx}F(n^=1=ORgxmw4+4I3wS1snJl4vkh|A?9WHh?{7oe=%7`I< +K>pu9?U7sAQZFKK1km%I?Fl=ZBru)v6R-_0Y_-I5oZa-YM46&Z%LIU``DqffNJU9`x9N*C+w0U1k)A@T_R0WCCOA +5YRV7?i+JS?5Ep4XfMqDALjWE^Jwqbx3?sXX_>rBZEc~>)(OO?eQ9M4)*o}J7MY124o1aHdtgknOgsK +R^zhnj`RwupMXQ^YV=%<7x11wdrflJlNG)Hm+=d^lJ|$D)i>JTvi0rRI6pSvldb`pgD&$DYgfV>hb^t +b_{2LyyBO$Es;?@TIAQ^~q(~Uf51}{|hqM;Q&ND#|H%;hVMMZHr}+)1^oqC3|nT-LDJlUKuZG>IyH2w +!E@)6@8M?gjCyaE7}!DMp0LIQHl^s>O9xdL192+cvv!q%NTF!kVuF9Te1ArFUY;)i(ZtzE(^l6N?irH +e!Ks^8DyTlgKD)GL(|s0&oyp0tN3C^LG+&?GWc1qwovdW4#sg%}^lLQzF_}D$aJogfJVZF%BFMQr>XL +u#QZU>Fq~HqF7sW|WR;MTU(GQgFrFPsWozW5gdLbSUx+mRB<+x9>@0p&e&012f?#f2}b!7WYjm^7*On +dVz&>MB9a(Yd-#@=TL`%{iwnF_%+o!^v2wH5TFOC|Fe_bRfO)p2s+_E1939UuR75lUy>v!|nTxm1{|V +C2i!U9;{5r*ci`wvf}2a&p-?I=a1=zXlDgXT!5{cT0tKL|8?UchezBvIFgl83`oCQ(yEMCiIkc%WfgI +VGmW^gG|2%Wtek}!@wDku@BtWb6~%gn453p0$(}0wiI*|alg-}pJc|)zJuaJXzW9#L{W^}22IGRU_J2 +KPZmqz+avoLjrQMnr62tZP)h>@6aWAK2mtey7DoU80006200000001Ze003}la4%nWWo~3|axZ9fZEQ +7cX<{#CX>4?5a&s?VUukY>bYEXCaCrj&P)h>@6aWAK2mtey7Dpn0`^1$10015V001Qb003}la4%nWWo +~3|axZ9fZEQ7cX<{#CX>4?5a&s?VVqtS-E^v8ejzJ2;Fbo9meua(+gg&6qYri2JM-D2ERV=yhuR}~Rb +Z^?#jueX=fEcUQLWsb}TZ(~SRZ=y=YhGaE4=YPvpk@xT5hgY&KB;pqB(DljPR*HQeNnLa?x1O-*yx@6aWAK2mte +y7Ds;$kWL^0003|T001@s003}la4%nWWo~3|axZ9fZEQ7cX<{#CX>4?5a&s?XY;b5{Vr6t`V_|GzbaZ +lQVs&(7b1rasb&pMJ!!Qhn@BS4crvyUSxzO7>*lCCER)SGtWtci~kd@N>``Jl5+O^fmAMYbQ>e%<7bv +Mbxq&3)n^eli)@NN>)>%9bHPc~RTlrRmp^@g;wLX0jb)ukTQ71a#}Qc8HZ}k()Khs09sH5-V@sPW-iK&ITOU;&?S##@6aWAK2mtey7Dp9#c{; +cP006oQ001)p003}la4%nWWo~3|axZ9fZEQ7cX<{#CX>4?5a&s?fZfa#?bYE>{bYWj(Xkl`5WpplZd8 +JlOZ=5g?z4I$9s%SwXwCAmIOpd)Yw`gTKFa#^cCbmhsit^vf?N`r!kY6a2ZB2aRV{Vf8Dfp|AqWG-81=r5Dl$h1(2d<+JGf5+}4B@wqxSR?ObTh46 +UtgDLi%jnHEY~kd}st-Z=5XY#b7mV3nq2s7Jg^GxE$t2gqIMqhzk=UGAuBOp?x5A37hvP%Bbdub1-?X +jmEQ09*PR>BMBZpt@<v!7p!BoB +T>=9WliUy&f^YD+sjjisGf_0+wg`sUfV>$?^Y489Vnk;AR=3naaSR0{{SU5C8xq0001RX>c!Jc4cm4Z*nhabZu-kY-wUIW@&76WpZ;bY-w(E +E^v9>SM6%sFckgor?~SdIFRK50%MdegF#oy+Ks{}Mz!Tut0Ngn>Bq+2efLVT6DM+-bQ>GFL=m&5*){f=Z(` +)PTI9>%~&oCMrFe3Byyb&}0KTXAH=R17KSnWX4$cS{Lj})h;TVk +75w%fXjuM$c7>C7ZvydGPy*mw>-SJfC6tLm!Gz#fmj)v~M2~3uOtn4Mzj;DUcEf69XG^cFiB`^b>b6h +0s;{jf;GVNk*$uzk88Ej9Ke04X(xIJkL<6cz9y|!uMIJaKPPgsM)(uLY4Dy6p%!aG(koTma2s)gxg{D +A!fIcl;)i?Mr!m3=Uz9qAC$&N73ZU7iF>e$@%Q!JWY}fCxISpWZpBUEaLFSgY+IY +PC2Wt>oYY6+_V=_n0sqMk2P0>IrEA`n4K1~AXZ;>G*2Pf~S!SKTW_HLrTDVu%J?nO%Q--sTW_LUt;~q +^kGNF0C7xo6Y%Sfl#rvvrHQ)kPkF8npK#z_Rr($9ocHk+Ruv2A$Ju&}5&>UA766fJg!IaH|y_E8uWYj +js?0sZOf9SxQ?-;xS%RpD**H$MpiiJiU(Tx6MD`j&s>dU**K7Z+2wzhM@QiPg|YY%fXS&DKJ2%CzB*k +}CvU3s#G7;Y~z~|F-P|nn?ZL(ECZ=N_8I^RY$-nb?FvMtRCW{;C1P@CO-jCO9KQH000080P~d=N70jS +2+0Nj00b!j04x9i0B~t=FJE?LZe(wAFKBdaY&C3YVlQTCY;$Z +qN7%sous-Y__XTryMS0=^nqEUUM8Y_xpL)z;jx_xt;Mxc^I)a!<5WnpyQjmMkwBGME{))tPMA;E^vqZ +n?#(lwqmAeD&_JkrJ*bi{Wu^RS8(TQTPTP9g +-A2~pe4F6Y%+au|+(-`RrJ$SIo#2UfoS; +!0M+8T*vg;ygOZbBQSu%VN(#y3hZDJS+gag@{@7O{zwa%@Tg4nGjTjtup_f=j#1ibRn0Q88+=UE3IXJ +*4Q$+8vKJOgy2z?@}jja0K1Gc6%0l}=q83-aGiJ~+xr3J66`A8JNsGTo1MSg6znI3z2{MOSTxuP?5(# +}l>YW&Jb@27Ued^(}jn43em#sc3v7L^W&3P_8$27Y$o7&^~U#LLZS7?;|j-touc8q2p<#49tL>!FDTdz;>`gR@R&KgXU0F_4@u30QV4f4y+&z_=O_J6iWSI+(kfR0QrbsVGt +fbS;CVhT_Ws4PqaV;Lgn~osft290gM*Ay_;f7*9-jWJ8L!w{&kK@9Ooou32{lL1J;OGICi2ZQ^kW;+f +5{b>Q9%BqL8mc9lWhyq=e*(W%Vv(=Yp>Taw#fbz}FS{wlf#uIYj?>bPr95qfrTVvKW6gIwKtSc|GEwT +9v02ma$}7&qfhuEdcizZN@%J$%4{m7=STof!$;{T-zz2gIC*=?(H@5z3paVs}G?RXaa7BQR-$$kp&ki +W^}t$Fd`26Q*!aqthq-M$>7!yUj~!3K?P(WxRw!CzMk#G*fQimIC&c_lB$0AmY`w@VJmUPL_!3A_ih- +Pp@<_GN;%a*2~sL)PB*A{(o>-KE>Ygc5c`SM$*It9y^PlQxWNc2{L9t#x2~{Ht4cSm3a#n!O239nJn( +$t<4HYOU!S|sCp#25Y7bU-3uQ`P?b?AA`Cub7q}`0stA3T8y|JLbW2j{;^RTtjxJs0kCMw;c1F>7$co +{<8tQ8%sOg*5#raY!nIAvHhxAiS!w&Gw0a8+@v5$(Q=DQAHEtYXHSE}qvrJM%ENyu&}l{ +;2DscfZqPT&A$fI2@R99+zD?Dp&YL^VK0h6Ke`Gy@~Ep^zf=fpHy|=FpyPmu2=s#MTReI`m~kp`ih(j +vBuNSkz2+!Ne{cE9?+j)#_oXwPCYx~U!*xt|4dO66#sGttaUZThG^7EElYK~NYwHh)|ULucj_ft>8_! +)?<4iJN~#{);9aOs-R+eeYqy2n#K?{~Xqp}o$EQADoXeM&q>?|yag`2qTL-ArzXAum#%of?OY;|%>oW +(fSTAIH6MZG^pny3qFMsoTs?=6n3l-3ZALP +=LwEgL=l1J<2iQ;lUH6097l~{0mS^0|XQR000O8^OY7yIIrZPu>b%7U;zLCDF6TfaA|NaUv_0~W +N&gWXmo9CHEd~OFJ@_MbY*gLFLPmTX>@6NWpXZXd38=p3c@fD-RBguY@zf3f?IK6SGph4W&(q0BKe4V +dYh&d3;GrV^L{+--3W*}#pDSQc)U3uLH5C!6bZ}UfZ{s`cD8|Jd2ou*a3n8H5JKmUc8y{$11($|q~*v +j@~e8hbf@!5cKl!~gcytr0S;`Y#%j*Dz#lJiuANQZ$PX98NKis+IfiXN*36{cVGK2kx>$R$kJ +yx&TKW`dSho@65EoDCzDY{6mL*V0|XQR000O8^OY7yW3^fp&;bAdb_4(bDgXcgaA|NaUv_0~WN&gWXm +o9CHEd~OFJ@_MbY*gLFL!8ZbY*jJVPj=3aCwzfO>5jR5WVYH3<@DO>zejj$RPx`*U-(Ouw8`K9w$m<$ +w+e2^w)Rfk7VUd3z>spzTSH?mfSkqfe`Hw28Tj`>U!$}$b+|f2q-4MfJQwjudFFxFsil<3atVq1leFq3y;eaBJ-$Q;)2=wnTZ%azXn_DAlOGVpbQ*~EdK=)Exhy*W^CN?=<$70px +U{H_PQnI;a1*p_?6TwCQSp`tGGqajvLt#Y}6GMl<#h9r7Ib8a|vHql16>3t1``~D)KK)|AG7TKAf@Pt +tLXf&7EF}iD;fJemlNDWjljg^Z~3%3+c&Nf)942Qzkgu3^h(S$iwqJI?9gcb3CZ(1UdyIeZW67&e0^N +y4T>f)mru*#iTGx@_EYpqEOF^p;r@c@JTn_{`pHgq<@Kl<0o1A;gDUxMFC?S`wLJ@0|XQR000O8^OY7 +y0x`qn5CH%H>Hz=%D*ylhaA|NaUv_0~WN&gWXmo9CHEd~OFLPybX<=+>dS!AiUtei%X>?y-E^v8eQ9* +8lFc7@^6)Spy2=M?U)KjG%+Fla1+$;x{u!^zK+HTaoz6Lj>QGKz-J3BMG9@tJG6E2~rPjX~U3Bgcjdz6|yveHh7VbQ3nYp-X-i_&N0tv32eJ7iLtzLBrQ=fmsEetQ){^f&6s8_}Vv~63%ezZaNa6#x)HzN3v+~Z0}>7n^M +N_9eii11^D`BEuXG7Z0>plKlGs<$96irkNx|4+5DF)rxV$BG=nyV3!lm@Vg-|C$k|;5-}=R+rSr7=O- +ys~AlmuK05Jdn0B~t=FJE?LZe(wAFKBdaY&C +3YVlQ)La%o{~X?kUHFKBdaY;$FDX<=+>dS!AhaCyxeYjfK+^1FToN>5^{k>xaZ{cyJBnOv;)GM6-&$e +ByW$*>R!S*ZCc0m@P@_up?907Z}lDJSjBoia@%aNoPw2f(h1EFnR#DrH%)ARs)+vqBQO6j@wK7U32_mfR8sOvl;nL>zftiZbCMMrz8e7{mKhd2)RV~wU^p-vLb2&E4h?jsl!KT^eGo{cFzib+$DNMatJT5?c-RUlWc?EUR|F +n;|QMcm=^I)`R*}I^79FKd@JE^Cc|lmR)_n|<`c+#r{gDLE7FNA6L&rYv?Uy<1Zhca;*jC93Gv_Sc%3 +UAbG<*z+I2xw5rbLPa@&yw!?3>j)bg$|z2lh*y&3rdvLI_bKr8SG3ALrm1QMlG;!U&VuPl@|_!WdM1AMq3L-=`4Zlbz{_+80t^Rvrl7}P7RYD4 +)+c-i~NvTt_z3a?#hD*^9p8sJdcH>Ka%I4&vkRuTO!{HoWe(2hksM;Sk_Xa_ ++a?wab3*`q%nJ-%DDJsj``)?NS9tcmoW%%YyP4Gzp-K%fAZ!#Tq%ElGo7yJP%~TM}fNLR|^vz@4$~B%q> +}2uA>^RQa%n~j_7RNMY83~zx3~8GbhHQiC)?daso6W(2kI2MSaQo@j3O&u2$( +F=m_Y&&IScuUvuF%a7RF`7&T2vq{bm?-pWCg$zt&8yp=;yV01Adv9ziU~ood`6GD8)4$_T)bx|zmE&Q +`c+QH!#$M69~G>xAgA7{Edx=loXkVxJi;GC7by<9-jLVIeR@6eSp|Ee>iiDC+CnrzImGKV;0W*sbYz7dvT*k~$GEQr$rTQ@nh6k(L;C3iN&j1k^u1QFNC@NJ! +0Tx&RSVibN$!Jt7+TBGnW%JLiCde|pMj;o-v2FeiVZ9L_N;9m7Tjj@;fz0rD$qYn9u)zSvX;vgOwuqT +H6cvEU;QM7!f@vuHD|a!g#cZdCgJEY7NJ^c>Ad&qW*I_QytB`~G|p@gO?Gs1k9Kyp`c1r +b`4niBsScv@t_ECHQ_z{rbZ3ls^{DmL|sIb$$h1GH(~mkksax1Sd4tdI=0i9sM%xdqm^Wy!B4MQJGbp$>g0@DJd88JPE?--Js^aw78rU~ +lS+viyHqCz3wVI#+6g{Oa=Ej1#u~^fDu@VC0%|UK6tQ$XCG#nysf%@SY6(ABlHDG7i_I8**St-HM_L;PE3R{}SwhyWNx9hHn5)d-&8itI8^1z6!sVp{IRuEB +lT?-@uC2#(?~aPOu0O1!lDz(rYc+*1213K-TW3`oWKy4yTN2>Gj}iiD0+e&G)dZ#%-#z@qeP;WBX;~9(Yqd~1|G(%~9Z`R +UI-=^tjV@Tk?`eF;iV3M0%znyJW~tZUUY*+5y(n~D-BHsSNVXC76xI1DLOL4xrc&nGVZ~!?uUzoe^}r +7bq=8(kigK#wzDxbusz=aER8?Oi5V6k6IKo_`T2WID-k5xLO>bL_kJPSB=$0pCLfC4>Lk>v;Dv2tBP` +_f>eb{q1@v0zcw>*RPuzHlQHA6Q{tGYADxdJNwM8@4pGblm@sVdDMm*R*#w=0QNY7*?dAON83%L#Vln +QAwU92S94g$j)#8ykb2s!+lnLKUcv<~_x5P<+5ie}DD +z1@VB#am}PA;W*f>If)$%qRE3ed1UeP;(Gqt8xZ^uITs}OKaG5t?#JYEMxOQ`Sob4)$KD}i{ODv*l@E +1&$SmgPN>RvZ`AGUJ37*sLLE(35 +p;2SFoc}p^FC$UTo3&hr>NbFtLN9xdt#zvG`}Irm)ya0N$HcB7R6ydEO5AiijQ8H!P<+_FIxjD4rpyxjJfQQ312NkQMR%m~yc6YVpa66V +BHL(P!rs{0;w4#2G&3Apeh{dT9n&wprx3EX#`pwmwGx8j&^PV;lWvtk~4NF_rUcY~Li3V!I$3atCFcfvnZxO45@BeQ`jQu +S2bTSU+vrP>Uay&A7?YgC`%Qq-ZPU-$B3nk*wqwiB{DBU=>8-=U>8HDx1TD&e4uUH;nRom_%HZ~>S@;t5#B39}+PGW{R8f55Dl;2dqL$6VV +{DJs#%H7wh*dLXVkzx}G&pULpBEgmF})h*bsi`M5at^?@arcjsrp~LmB$mHa-$8WV2=)J8T#`!#ru($il)~> +fnJJ^Z2Uv2x}v|{}Y>ggkKS+}SIW_*z)inwF!*ZMa4H()8A^Zb5Uz4fPF18<7r +KD{14;8x&aM91T?prTbC*^{XMMLJ%XoQM17yY@qy60JHg!Md6JtnT*I|B3 +NmP)h>@6aWAK2mtey7DoU80006200000001oj003}la4%nWWo~3|axZ9fZEQ7cX<{#Qa%E*?y-E^v7R08mQ<1QY-O00;o{l@>?jTwf3x0ssJg1^@sk0001RX>c!Jc4cm4Z*nhabZu-kY +-wUIbaG{7VPs)&bY*gLFLPmdE^v9ZR84Q&FbuuxR}ebcfaf1jpob!BfgKhU$Oa530zp|?CQH{r}+b2-SSLvkD2{c;froc=|k5(whSQ#* +ml}epBru4Qb3bX^%o%dGm2+OTE->O>m{%M*U?Yz+5jY*4_#`y2T;08P4umGdMTf`0nx)+7E5WQzgdRqV0US;l*ss<;?+g!0#xY@ces?q)lso;$g?Pqmh*E?6<(FfYy2n4J)W3b%Wy} +sv(GyMSK%z{t$bf0Kczl{~o^MIfkH%cEn-XlTlBq5MJW|vpoPiCcpe{bYkVPr+g?n!4>EfK+e3Co`n@T4MZ2(Zxgajj^fK~^U- +78f7eQ1nJSdFsJ#}>O#&P)THZON+4?|}nr0yXsSnz`>HaTme>3(uV}i85G$dlSaGH##zfem91QY-O00 +;o{l@>>!Oo!#-1ONa{4FCWw0001RX>c!Jc4cm4Z*nhabZu-kY-wUIbaG{7Vs&Y3WMy)5FJE72ZfSI1U +oLQYomNe6<2Dez^H&VKSkzuP0{U?>;6s`X+69^v*md_(6b3DgZ8ntXawt1#(f{5VQj%pkaf9R%+ZsMT +zV~LR(P(rHxw97YU|a=m4W%n;iv(-uVO1Mjm}&!sS+CJ!72v^C1xa1-h_LpqR6j57eu2W}b;$*kDYbB +rd(;6z$Fc~6K0<1!@Brayhb_nyo?OkpVgbQ1jxy!WqF@2x9=)~@woHO%N_{(lYyLIJ+T3cQhUi{<<7$ +eyksT%kn!(40*i=5r^QpRVW%}hdRb{Z)A|aGD1vu^=wg{#Q=+`E;??r-6JVj!&q#56MUQ$u;bsn6b^3f1Z@KL^H4dIDe;A5y+5MC5ypHe@8w&Y-iN8&7`C +eW4R4Sb{$b(w;bZ+vV`iY52S!fu(43Gnz=Z9IyN--+0L|J>?N&Iycj&4DRk!H<4y9<82))1F}%WWq<& +L79s8H-TbGPLGw8>;Z@cMie9Xq2<8G2*I0G9gw|m19l^}!&P)AMnFf8sq*Tn>a=EUh&6Z1vx +AT0i6*m_?E +rHj~qr>!=>XV0hb;lsm0`wdNI3iyu?@e|KCebQYiLeCDm*uw`CwsBa8D^`W-olsU0uid=~W2MV3GI42 +~#9i>XwFw!6up$%89w!-mNpM(1yx!kl+nPyek25uVHY!{>;ytffjfxG;p??W{{Pk`i24}EQSb`DU5U> +5y@L1Z6!LyPx#Q#AiNijgn&gewjUMBR+BqYGcog<;6tC#3NJ0`@fD{CHlH^wVZ1o1>^&gVTeFg&;R+E +~4^sg+&M%2JnB;!Iw@KqtMt95;&6pF|zA&6y+@Wn?{`HzUD8hK>ah)|cG7Ce2-Ca#i5SYQhDZZI +ySk2Cai#Sb3wuG9-JgXgG&YvxO2luyMZ$CpGhbq56a0KPE7|AROxh9*zFI!T*N|v91q&r6nvUr1*cd= +%C%AhxT`)?v06562^v2!kY5ks<+vXi2r*}u1_f3OP2HLqlmI^%z7yw%b(n@(@OH<}d}U$!fC7#nsgI= +s;`8l1>$!*5+*<)*sz-uW>%?QfOG+-)i&bFcprGkQ-Wxq#t)r+Dg&hT+ghAv-=+{s&M?0|XQR000O8^ +OY7yy9}waLk<7{k2L@QDgXcgaA|NaUv_0~WN&gWXmo9CHEd~OFLZKcWny({Y-D9}b1z?FVRL0JaCzMu +{cjt$^>_ajtb(8tCST$f`-m}ZXx(HpumnMEYz17;piY#;=5$n!yeMv$|9$U0ejIs6$#T;lh6$)6-I4E +$@0+j7Ms3*L-Lf@pBkt~)+-y~27@uoZwMN|8-&3}bAEcJ5p0c)OTZ@{(KG6VhrshA1(lFs+!G75Fz7@hFWTmJo_`&Oif55i}ICjqvc&h=hQEb}?V +AZgtYBt;$KmhQFzfmRlJNP{ULSP{Q0swvV1kn>voV+Fm*o?hVHAt$G+IX&C^DR98<%Gcp-=4EEAo^JV +n`Yb--DJvM!GVa$l$MX?tud+|9ooYF!|>_NxRdS8Xl*vt=yn^q_h^LMSR+8SHJl&X46hlO_y#nY8L&0e2vLL`2!NfE5gNX-KLNWcB`52XW=*?l02 +?-K!HB?Y>^Ap9EooiZHuMwMv$1MO+0nr0?Lw99#=o8fcprGxdMfPqEHu8|R#IrRT=YluRHF$7K&9G{) +`kaQ)r|!8hjpingZBgLU8`z=azS3F4&Rnba6Cw6w8IgRuwJfZwRl5_5g^(RuA|3}pbYH=uqHLzwAutn +vM#F@*y2?c90~)(umS!PpeUL*vbtvqpfy$m=z%-t?v@o_AsycYIyO?H|Kqh#E$~C{&6*oc0@(;b +f-i&JLykAGQ}x56C1ID0+;cM334GW(oPi1)ie!N@(4QSF&kkKAiDp{3mxYPpl%3N-?)>OpeW +z(ppqrxT(*Wec%5eshk)II)Iz!{1eDrS~0T#Iy(TXB9eCThyIN=x+B;1lNr4A*q3YIsBTM-0X|8G1fN +06|ExOZn2GD?X25izSl#6b^0q<}(gp>KSx!oIC=sjLR$7_eig1|3v#BI#Ig=08Kuv!x>=paX(T7jo7F +U;;`m@PirjWl-dza+yYpCO9ccABG-7~V0((h?kzn}$$E`Mq3eH$9Mqlwqf-`&Cn#7U7NC<_SvQZt-Ff +_ls=tJ++>oxKUUTgN6bU3g(nReQ;D#u<8c|R>Rg@UnqE9oBdpw1_M;*WpGoZUk#o0lr1sYwVA~Z@IICzm!f`C8u>xI3e}S@ +8ph}&qNLRxW8Or?`<7Q1s->Lbc^n*x{4ZwAR#mBrpfb6n$*a@N`T6PDZMw`s@+)U~VE!|2py?ZO_p}cDNs>lA)JsK|GQ+`uXkH;9=H>vUDmZZu} +CJxYfTbVb0Io2<0W47ndp6zzKV)u2Sn$@$j7cX8s`$+wR13CXbfWyKJy98!DiL)4L0;S=FmMZWip(`{ +j)cBrQ0896ViAiV5KCOT#g&`G`SX1h=7JTv2yIbtjxgRNVT=faMp +JJ}%8yAU%cI!d%KesuIhGQu(+!kF$0douAljwA7NQ6VLc+kZzi*%$~c#R8b@hul*pI6Q<% +Pw~|LC44$vqljP^r}Ku?dW%{cnF{~W9$)krD}fJ~W#rw!Yn=V +$6jNN_eEt;TKeF!(rir#Rrkpx;5XT-&Pju*M&T~}! +u}3YH4!MPY`gL@~o2W*HO|-e_D&`3ydCg^A-J{IOfnrUb)X80 +gO4ocfdd!s)#VgoN^xNj>V|P<}lz^ZokAj08!~mib&ZkLMJZI07rw<()9+FFYve3@@b`=%8hhb+cW@| +Q4F9q!2*l2T +5_|>TZAN&e{hNdmCP0QYf*ThxgAeosf{HVbc%_giQD33A0=x5a;8UvH{ZOqU2a}p +$9i#Vj}8ZJ3_JXxaQd4?7_3`GH)G4Uu}uf15KKtKc@^0w}n&@|J|F1;mW?yqTH-&tADSQzeh0Yov33C +Pn{XnoPM}rY!~k@oP0}W(8)>aiKOotmi9>e&X%=%sC4&t^!Ud5$j!ve}lEPIpk*&e6kQ-Vmo&%0qg$ +4OmlS?#G!^oaRnsVC4y#U*q9ig)OzDDYa5KZ4Gm5lPMc{4xid;)(ynrJ$KSA`QNvqtOv^nk-b~?My7o +xI@GJj_&2nI&a>GeJ2#vZo5W*+t-q)l2!b@l)ueld60^4r`}Dq#cxXm(OK0wH(Ai~eEo2i-1PNYiY$N +P=ZEVw`2Z$Ok;8iw!CCeZWkVDh(dKGv7@MEJ@I`-g&2U<(`Uwfy7)!th-*Dy{mm1H_!kdL4p!o#|jmr +=Ak8D$8UYw^>`&`bRW$~%}A$tM!s_yk>)DWg<*!GG+t*o?Fv>y?MVqKw{3ztA8SW?0vJD-IkC-CyU1SQ^;4Gq +SdP7V%OXehrv@-&IZ)F>CIv|{4n%~3DTddj5vWF#un%V(K_>%BZ>`-rdpBg<%nKY~Rbe9&7Or@-5bI{ +2gd~?hmfW}5(Z$|z_x9nK!6w_x%vH?Pdg*FWKfgRMu9#5R@IavpP{W44tyszIg2g!5lvKFeks!K82>y +werllo=+MK3EL?ikf1>A1-bI49ly!{Qsc5N#1u>OdM(L*&nm8>Hh1`Js*#K&>KO#SxT177Jtyw3+kO} +r(w{@D0&O3DZvv5{i&vR+*CmG3%=~Dl +r_F2LJ#SApig<0001RX>c!Jc4cm4Z*nhabZu-kY-wUIbaG{7Vs&Y3WMy)5FJy0RE^v9B8fkCaHuSrH1 +*;;6yedN1kHJzPP13E{k`%2wY)AuvvFMbo4o{?W4EynWq)3XSNZE;iCK35AzJu>jS6y49qF8PCrXxjx +XuWPbj_?g@s|_bb|DK_e-cd%|CPSNsF58k673HME6`RdwD?#L;uJRIoD+)DjD7gjhDoLY&fmVcHNenioC~5-gb}b7YJLD6}lz-w5{K5XjPIfg+D +*k>x$H*;h4iA=Z7-{53HjjG}@iX&1HodL&uzVe^AEL_U1cTa)l@!!KNrc3A`v$MygeYNKeE95|7x+)f +TW*f6aVCpln6R!|w=~u0fTM!lspDkd5Ae5m^q{HB0C7+z^`k3>e`8$_Oizo1r^gZODYcIiMYDKB%CuDm& +NvGSbI8?f^*eBQv`g%rTX+ZM9sVuHT5BiC+Q6l8O2c9dB-j4yM)De1r;T5xjzQLcN^-vbyK-8>Rm +909K6vD8bk>-*%2cC2T*`za-%aflmPgT50$k_?tcW)SVl%S?7Ym`YKmma%2_Je7@TWoSrbWA7OD#;O! +q*s2&H3i>P=$hBi+MStfMW#I@ws0RQS9EwXfio=WNpAD|)ijq=f0#I1!Vk#rq1 +_>VohGgfsHXsOg80-WGm2JWt%dO85J9@?i48RdWf31%yoWaFD*49iD!I-E5>Kqq3@w|4Q};;0Ju{gDI +d$BkBVHY6t$5{JsS^H)zznHHN>l2FP1L}rm*;NZmd;hVpsR;es4YXo&w0pns%OpNKo5^S>rnOvqWp2K +(>HH_kjAg8`pA}BSF+Sg-1uH^ZYsL`P!2$P#RFuI3@%0+P_HD`-7n>9Yv_inNv(JY@)&@iP(7V3#2Nb +_)xu>)oD^ +l*v5^l!jztd~i3I5vDZ5GSdqdtU{o*Y=4gaLvhz&bukw+SijTs&~6G2dPeaI(^EXkjD#3bqARy& +m!r-7LJ}ziMjCpcLVsjjo!$_yAC6JZ*y1PK%#56U1Pn*V?Hl=X?*W+wq&y5x`j~?}gKfOHpa(; +HPC>DQzJd^qx+t^ooKZ7gpgDdZ`Bau7z2X9V$cSf(!o4NZP*X +ywr*b#c;tPAn_F*gWihG1r36`JIGg^~o;WzxVjUQoTZG^JXWfi$Ue(oxWZ7!RcQwm0l5e +(E%?Z70s$$1kroJa+nLp%BUX=;imHDDtvaHBCt7*|pR)WMf-=^6EE0fFnzDRncq{u-4y=)MO8MOmb@_!+8YL4LQ&JDwNq<4v{P73_j8cvU~?Uy})^>#SyL_ +P8Z85D}h;CvR_Qt&AwdMXbEIhgcQ9ZvbX~i$JUjy4DZf=& ++5CMu-<2;|$0+kjx-du?WH~WTQmCA2nZ(nur{c*fNp$=(@9JP}|B5*Hf-x{0eX^#hwxBI)qatS{Sk&j +l}orG&FWAk0*)N#EOFUu@-MzS6f!|r`V85S_OSR`nHt8QXcc?v(ot++M<(jpFxyNj#Z4vfoXKWIEFw3 +_=WR2zk{`~*(-t3oJy3?-X5uh(DsH$_60cuVw@57m^VBx*A^&Q<#oe7@K2vUkz>N|S +w;z1|CQDdA*#NrI4F@-xi~QmM3qy$V+;XR602h3CgV-KK)h2&G%t5sG)PxboPt5$buTEF-=*TeiqoIa +|um32@tDgQibt3Y}^OP3M>Gk0I=pCU8Pt<90($t#FRXpv6N=dT6-u_oHEc==VjR5(5bmh%k^OJ+MYbr +xYv-$O=*Rur;XL{)$0~f{5F_VA5?1b%$!>ij~&tJj7}%!N;^#Zo?*E=YrHN2qKB0n<$-^UUgMf@Ki^l +DY5L!wY-lMIP)m&*0fMS3`!=YwZ%|T5&B_7uIkw6xQqyp9$-8|fB_O9P$LCfyiN}B*stf9(CubG>0ZC +tGbA%%(qoz70g}joU`O+@(PeN4ZJZ)1hj;Z(4B^BM1^PHbi^6nzIkbIMDR4YWUux0V)aWWPG*U7;Nb& +yH6O=PxI(i2wT^sc8EeX7HN8PVdxg!N6{9gJ@_9cdaB^2Oy6s@GEk1?Y0=$* +O6k9(MHe4`=UBZ~lILei99JhFZCvNtk9X^wb|iAS0LP7xl-`XV)5iwBG@!^-hiVudfAPD^c|Bcl-E%JY}y4{?2lN_K&~Imom@f)Y+0U=}xr4$)8c{MCXsN +(dV$u*GJ_ES%W!_nuO?)wA|-eRPA_yZ{bF$*-*Z?7dyoEoH~`a94Zsc=LWZTG$R?PNw-Dpfb1@t#1PQ +T(sf;iOY)+Q)}GNkf^xT`ZEQ$fivfy<2oRFb?= +m=cdOo+x;GGTJ6I}NfiPTZI%bFY)m+c2@?Oo`;@8V|QX5>vUs8XZdF6^-u-s>JEis>B(`a5hCIZ~x#S +0x~2snp-jzP22%H$TzmGD`nhQZ-d3!}IoIb;a#3x>e1sB3$v%cMU3hEg +ybx!;v-S1l6~uO*lqZ|h8h>zuO+Lq9_x-hGt~9tRASBAF{2G2_No4Jk;*NM7S6z&dl|M+*>4`}V +$iiJdZOvGFq6&}Fn8XH9(-fkX>Pm`rkZ-<4URTy&(PB)D~?Re2pE~RLJ*jjzL5a1=H$i&?a+Eep)+TS +AP3zQ-HVGOma`$w=?c2x{^}y%r<3nALk6Jy4{9j(OQK$&4(;9!!TXOOf}l?Wyw2bg3$dscv=E!y$;7; +_`m6k70SGwkuLff8uK=c#{{m1;0|XQR000O8^OY7ylb5~DwSC$Uk>O+0TSD}7)a6}aj +#dnK4L|#EXEY6LJ2PAbLGZpzo1BqVSrOiBw`Eml#SN*~jO1T8d +Bp09!ELszXtj&TB|OhkM#-90aK}kql7=%vIoUMHdQz?gYC-Glu0_MQ+miEanX@^$&+2vA)PRPJRu#R; +fd85%w;T{|8A%#mmm9)zwqZp*Dd>g)pEa$?vSRd>ELnZeSV1a)pqz0jRa)K`97H2R1duFKNcTXI7DZV +D!nR@@Y0^AzB_gOH|105JmSn3efpUB^-fY1K!{E>G>Yv}PpU%F8(bHKln@rS_#x<-LzzTxVseBj)l&8Tg0&2h`$tmXqR<^- ++mjEA@%P%acXFpE}Tq#?@>SRS$$8pG6zM6|=pOb9^o|0Uob2M(vHW#VFzzYE*gahWnORN_f6<+FF8$e +S80DapNb&r^?FtKuCWzP>~;RqEcYgnug;8+~qUtLdHx^%l`MS6;_l?4>7F&@zk7#)HqoJBNE3kbDPy= +}o}9g7&CPh0-30u_VUD0*T_bW3cA?k%h8U1$>oP7`EPGhTmYRYvpd->eF4HL5$QH{P$Zg61MW7^cdKR +moZXCd(o2;Dz?$=)!yv8ftOP>s)fu9OpnQg?|?(hL+iiV6t0NPV2hrKm%~pz<^V*eK=)t7Z$H4>xgY#fbz*JP`kT32%UF_#h=)ndT2dYmNFaG{d +A`Ji|TybHq_G&}T}fjk@st|MNU=`q5J3~FPt96}3f0Tc!A}Gf{bpeve|~u`tBlD&jItqJ7k_!_LVHUIy# +b%7{4m`^&WG-fb~{8nPYEBWIXlTmsQh5Sf>ADlYfA1Cqzpf6mmV`JdzzM(Xcq?0?t&4)nfU48UM_dzG +6tef!>OD1)q6|m=`tv9nBkNgnT4XBWS!fux$+NI;~Uoyb!7Sv;U!P*fEiPi0f^>&8)?d@WVD977wq7I +<3CYW>^zoL%zU*h^YEOc`F%aJ6?L(gdd|;=Ly<{LxZSVf7jda^0)|xK9;3nM{>YDx^S6_Qfh%E;&iB< +GMIS0-pub0PSQ4`v8_VExm!3IL3CfEn__Q66exNp{6B6=THj+^-)?If?$%C}=|R4(GxWyk9vPm`I|6z +=Rd*ZwQ3TPKGAqLBuI*P#>4{FK3jIXe#e!Y5F2Y1v&DEk5q9?9PDCi^=95+cBM;hI|z3byU)(3Tt9(e +e-Uk>T3>%#`ndRW8B<@@xGoh#_3$O0L%Z`TnS@&4!%5$nSvuB$^c$mceF*A~zZs9`MBW>6-l=t)cAZe +^8%*HpW9F6yjX(Tz;ihB+FmZN*^dH$SNIK;pPaL0+qZX#&$!HpWOb&iP`n8g;9JS&c^R;X#LNP9nj3;{Vs+!1Cfw5@Ev-%}Q +r~B?wrz54Ae&0?SRcQB~>qgbfEZb})Ia)*Wt$QM4#@e4^^DRx-+spUwl&PVp)HC*M;NfcL&uYZpQ$o$$d(S)1mCO68E!Dy_OKNAs@|djka*-ewe}40nc-A +1i+l_i~$T4#04`eEg?_0JrYfWLXu_nZx3<>PI0sk18n5y<5`16Q=Qx!VkT|K{^JGFIEvMOP%^#s(jYt +P6JukjMz+md+b`)OOY?rvnZzCzm9KwMaD;#phZh&F7^-`Ut>CAD57IKC3*A#3pc?LTb$$J_l;Hka|H^ +SR0#ksj&njXSw3w=wOp--tf#9M0PXI2O|jG7K2Tnk^U!MtsroI3Y+Yden~HU`~0oj`ott5tV$V +Q}-pk@qeA@IM0oHWr4mnH-+{|RA(gh^fH>|F3<~8gpMR|!a&t1;?(cUAi-67 +2LbDX_Xv`g01Bh7gD26Gm>0CX2&0ud~3#>1EDGwkA9PV^YE1JOHuyq2|{sE1I*S>hLKXItEi2K7 +a$IFRW6!%7`F$YtZ}#iQ5{TgI^>+B7&;cBR(;^yMMn--S)Xfh%z*u#Y9X8^((owVg;_^XMy4BkagFcN +rjUB+T_Ls0*cR-%0Ko`cy3mV%b#mSEGgTcP2WS@lfj|!mo+4D9@vecMc{%mE^FdCcM|Vuvek*RxB>nD +8I*#&;y1ZqDVK23xi^o?1{uOj)Gmb|o0R6-OGLA?oApIn`wnh{z! +`mgSmSs&YkD=!)4e3W%f-!NIUd9;Jt+%XlBy*Vc}8oU`30vIK~$vs@hq)Rnyd3- +dtL!>j^gODlNeRxsY|)=p!)O{B--J^>RO-S|uGkbRlO=I?D|kB0c6eum$Ym!p8nO8P}S|*6urs{F(Faqke^V6Ihp=?a&q$gFVn%Z5k8$q&SbW} +Fx4N|1%XElD2)J^9`R`~NNVJ3qCsLB429Rrz>S|?fZ--@RZNfE8FY#hKVzUI%~mTW_A9!#7$9cqi?loPV1n) +!j&`9k+Y2wmx#R2&yFdr?2QVUJHZchCkhin9dgj47YSBU4;@Tk#Xb2iP)h>@6aWAK2mtey7Dt~ +peKm##004#-001li003}la4%nWWo~3|axZ9fZEQ7cX<{#Qa%E+AVQgzbYEXCaCyyGTW{ +Mo6n@vQI8_l;>TF@yV=xye(rnnn+G6#(4yj=<5^b}gMUAAAdPV>H&LMS|>^j@a1SFQpbLV$1bQp#&Ay +rcH)C!e@+Q43ArQ`-SN`tUmGb{2f*qv78b_bc*Y`EsRg*%aF1{ngYIiJCn=MAm8-#0BJ6h +C`uIc*--lJ>UxWl;Ur$1Ftm+f~A5~b7na(Aj$B+<}90oam0DCAn8S3>OREeu75|v~s5c@*%J=xc1 +SGS+gMTpQGiNs6X`or&_DXGfu$ySxeXcn`r6oX=(8LkDBXy!B6b94lCu{(0KQo#%uCGk^lORqZ50?lo +yb4Qg|aYPSBQA&a^41-{!)gIRCO^Hl=y#_QuX%uvef=kQS{`(BWe=iK$IfF76sml0TI@!_$!Fr9pA@2 +fi!Y#M0i{T8yqR=9@^p>eTeQ+|JUeF}769&IBw;@08WwjYV`-DX)CGoC;pt8;!Ol5hJ)D~kXjb#|PdZ +V;LntC_m8&*oYcJc#<9B<+kOA!tW`0_Of0;GbT0}&A}@z`h3oD8GmTD(>{EdMR+C&eogiw7x)RU-uyZU#hAT5uz`qb88|^6{JD>rJpz# +RrN^vDyNT%h?&~+eKNre)z>nm$5BEGIVJ^iTipdec8+AQ|zd`Dn%nrwwnR}-ULM0h0aR|muCjra`&Jei(egG)HkWqk%j@QgbadB;-V +Jaz6D|{O>qv&@$YKKG)u8gF5S=&`Pre$oPy^Wy3)`XngBe)U9Bcs=bvM0!)dDor{$ZFzJ;q^);1a2il +)SUS75R3EDaKPWKM#W57(kfQN}C_S8)eEW^l%+dn9Cxf`i~PgD>9jOBfjGwBTx(d{QEhM)KmXBY`L4* +w^VCsq5egOaHTl9tVDOi+qP_N1V3^C3^t3*=@_7&QL8UN>$pTw5=;RwNu|;!1rT>oIqSp`{U5_&N6M6 +Y)ejG?+bgN_W@|0;z+%9wSS0&N&#&d0$#Xs{e5Ej$)cS;lV-!*ggc7`aWzp#CZ+p0RALIvH{vs&fFC_ +ML1avPGnTp<@sDBOlR6eLqHQ}RRGl(6vo2#d%Z{t8#Ps-jL>@tP7Nfc!FU$+4FN6@DSBRQ9L2+MW1-9 +=N@WbG^8BT!W7Oyr2BI9Ob2So}dHalWcI>WIu-}WUEUnf4knDiSBiiw)I%|I%=^EumQe%_`N_9`PMEx +{Yq-b8UciI7Ip^kH==9s?a0`6KXY1dh*~p5w@Agff^Q`yt+j`1;FuT<*W +$%#67y4DrttrY1m*%Z};-J!Gm)tjs3pKq_p{E#q1|6YW2h9_=l_0#wC42HflkKt&Ydkhy|53mFfS0_% +LMZ!O}+;}Q8rWpQZVE?~iZC#s;!LjNvkpiv16G?E6Mc?!*KBwuOux!GvAsQuM~mK>i9ejW`|6 +l69IsVBG4vM4tmA_mn4KzdD&4Vr4qLpsYmw2fSxicBDynNj*tKIALCpjv#CxjK*IFwbg}>+ZZ#OhbTK +7|(?=9BfXdIir`-C6!YUcGpii3XuP)h>@6aWAK2mtey7Dvs)G_L{%003qi001cf003}la4%nWWo~3|a +xZ9fZEQ7cX<{#Qa%E+AVQgzuOK#;RjUf^Rj7Nh6(DFM2aVD+FoFfW +OWBN9T!BkDaRUGM&hWM5zT_x5=a&e-d3(CV+1n?1jL=|17-#pWG;y;=XczI?k*=Luf*uhTpSb=6 +zz=f7(@x5`Hb~HQ1LVjuvplfrabm>&uH(Vu|)9anML0e>aWaX4G2aCT!QtS@YbS?OHu;uUFGOGh^+Cs +r2_}w)5OO-PgQaRcyy#4EAMD3wC}>B`sh>o21i6*mUus<|6CN%#tK2*_Nm}$8F94 +>$;-iF6Y}^)PkLD|{s7Uy6*#!SF^CuZNkTn{7O +NLJkMf2AMfGC0H^Iotm6Ww?RT*~edb{SP@A)q&8jvnY`kF~jEB={j2t4v7RTO4G?=e8cpxV$I3o7W2> +8LiJb3&Dpu-Uh?IltvqDVaEX4mmEg6#Rr?>QzS^9Y9CE2G3zQ_~}^}xPvjS-qVDPnq{Z*nh`3>=uo)R +HOc1*TKBX%bk&Abwm>xN>5)bjfSycw1u(ErML4X)A=2Da~!0hO}%OUk^cQnj +C_2q4ZXOA}x-kBa4JaMNov1$w#|i +G-o8h}(P|LkBI$By2f+fk%t+Kyn4ZlWY?PqZ9x?u`${1;47UNr%que(YC%ySOuN!O*{g0cpez2*=f;^ +tdmUQwuVwPh!xj9o0ju?`zjt-qN1`H$cN7D+*EAZpclRWQqFuREB|UIY+vwPPN$@W;K1RAS{l~2sUEAm{loK{ +i1&n=}oD4u$EVRKtg=ii$Cjsrh#MAKHdu$&ub|TgQU6>&U20Ywf!zhud7XWNqpNNCR5@hGmyfREJg40 +i!T{eNlXsW{&XU|1Jyr5% +_d`y*LQ`llV}(mW>xuLc!Jc4cm4Z*nhabZu-kY-wUIbaG{7cVTR6WpZ;bWN&RQaCwzf+iu%1 +41M=k=+OoQf53n|1dcldTkRrs+6}`XC^p>+l`oLwph2;JpQI>q9JlGF2Vcm;!y}SXExHB~QV(hnKnP+ +@-wB22PIi1yK#uspM4mX%!vgfj(#av21*;dpI$T6wu63mjw^U5GsqYCenC-CCYP +jE>MaqgjZSZ5+19vZp0%H|sgESNkiRq4AM`cO~VSwnx9U1Z&#c8eQ@LmvA+M9z?*Ss%w0%LvDgyrO(D +@)aZL-B;t?LJLEH!$ur}Xshp|xKXp3EZ$IetWRe{0zlO;Vu|G#=gY0cLo8?#Ue1Dijf5L1Cp6u+hF%# +L_>|2&UW_YSBIKLiln2^fW?fu)q@mYe}Vq&?Sa#b&d4Wh)J{8565gY0LPXQL?fy^WPJei?uL96$z^fk*OSJQdrPjnjo-xa~d#w<^+~0DIv3 +HYZ|m`or8w_Tx2$YhYU)~KDn8()=GQd7NiAI-YZA1J|MCi0;8v6%SMb)f}n=c5CkqnDav%Vh9XxwHR7 +QOW8uNh?51qY(q>|I#|_kDX=R0MQ(URMl5oK@tMsP+KxO!1reOgOB~s9kW@=Rm2~qf0H2w4I?W_1}l) +j3?I0%9q=4=6WJkbC@RYD^9Xe?m`g{2`((SPBjZ0ytQ%p?Aw^}g+yTDezDaMvxZXQGgsJd9JMA2{bsa +$^{o{Kn-yGIK(tSE{&ytkOoTVLKUb*B}hTk2qH_y98EpZADf|u6KxQC^eXdYl5c2soF^(X#uTbe62*z +DkF*o`nu@krU5G$OD-(1I8Dg7VYWgL!@dZ+bOh#Dnd%GrwQ!j#ECx9Z+L4o#P0$o!HBK<_EVlD+{k$l +0cwlPoaBCx^Ad&7Gh^4TG65jEBm$DDcSf1UJCoeKESSF3T*&2RNhI7dmETmEl6a3^thS(AeHTMAuENO +0$iYL)9rt}#q$Xhg$4N=_84-8NZ(9Xq;A|zoqx$Gs*qLaA0n(cdCu2+b84g_E#19G0YD4hzR2N~ktQD +EknazqA+Uz_-pv6t)>JciMtGKgNDGW739 +?N*dM&0V^I`bZ`!?S-*?4rw!~`L9zLlXdL$fbv?VB0?(;nTbrF$hWaxcJ(QQa8dR>@6aWAK2 +mtey7Dp`@u-Cx?008C)001xm003}la4%nWWo~3|axZ9fZEQ7cX<{#Qa%E+AVQgz)XP +WnpbDaCwzgO>f&U487-9aNS|fUKn_`w!+<62Rs-u$6ozWksbE<$EZJQ#?7vU+N37KLn(AUpA|Kz +QNGT~)24R?#rYtZFfoHiY46p~SL}@T==03!{;+iYzLn(QrVhja0STLbyvxG1XDD@*>M5@3JDwAZ=&O|1FQmBuqi5jOxQ`wsWoedc6kqvQuefe&aJ`CKy5*u6X2ou%Lm_T)4 +|-X(rK$<~>GTG_TN@V6^I=Uf(pC2sl+O8c?QCo0jh#Dw2#s|u-&R9m&XYgy&jp3k8CKHeSlv@UoKg6-*?8r*M_=di)uVMpp^Qf) +P4RD^n^QywEm9eU^oZyb2EBf-US{?n8;~8JS9VrF?0B9Eg04)Fj0B~t=FJE?LZe(wAFKBdaY&C +3YVlQ-ZWo36^Y-?q5b1!UoZER(9a%E*MaCzle-EZ4A5P$byLAdBDVTw@iY3P={FCE +DgneSoCW1jGLK-I4krCEDqhr(u3bWZm8Gj`vOPWL=Uh+qJrtEXxQln_6l@x2hJcW|{q-kb>WH#p@~|Z +N>AtV42{WNh;K0hY$^K((Im9MJ-dsA9@_k9(1N38@8});-M5hjcLi4eVwNGyluHCm{h5u3=njmNw#MX +O^1>8lx#~?51bBf`GJDgQY;pWg6#;a6rN0J8L9Zqg20FGh$38(o4R854Spm87gXk@dB+6s!I>+iX_d1 +`CF5!0nV9Ni)ErTz1w)TT%U18seq1JG3D)pjFJrJV7gQ`B@w1_tb}M+E@#6VV>QQM{W~~%)9FL&{TaAa)JtQXvYot{WTcF|F#qjbgc#atoN;Hz)^SV`0j +Cof9mY;hL%v>aZc^oAeHWZ0ZDXSo{L6M(6nC-wb6vRlNT=WDdR{@8k>-u#4!X5*4;@WoyESnLcHw1a+ +l2dhpRh_Ci?`kNlK4YJ%Et`zsj)Y)JCS*vdgmftZ*)=J@L8uGAdG=Wl3>^*se8PYa)Zy7@8T10n@cgV +Go%XPQrZGyZ&EU>!N%z=sOuxcE$35DMPo3s=r5^5+#7vd0WK4Fow2y>W1KK8d{C|65%R4z+Z_HCEv+M +XXbXh`x{ZxK<+&&vf0t5VYd-Q=SsAkvRC%_hduCG2hyy)eyXZWlqRqSEyex|FPhynP8$a3Ux)l +hSlj46d0Znv +&@M2H}Rl^>}vBcdfXGTg7xh-C~91EwO7wPt}QFjkNb4ZLovg1l5q@)99J6=xl|zPeo}Zg1-w&R|^ZEK +k$;Ste&#PIPpMclrL}_jgw}>*PtOZl?*O4PfifAFgZ&QoGTZM`x`u-vfI^Sm|Us#)N|Ja0l(v-Liq}_ +tR7l_|oXciRWuIuK|IapWEwUdQq3C^#tI>`*+4|ZhS0`8GTPFxT>IsKAyk_?6>RBN8s;PZ_ZX5%wD|G +HRQXWT!qs%4mp0{=IRNF+m@^#x+Yr&u7sp4ctzzS>8^C1TuF6)fczh?!l`)`&1|Ck*kAPF%!buB1V5M +*s-Za+Av(nJrF&VojeF||AH_qM?hgIO;)aa$s~FM;XYikYd9QK*vzdEOMa!_lu?bobl;PVH#~&CQhmD +&kH#@MP46eakk{C6r}fxPjB75HzQ9#0JTSWUj$P)+;P6}gf!^c&c(^Pq7gMOwG +S@0V!Qq9i%olfJIWUKNc;EeS0G(QPJAP!pd+pzSZ$S1pyA=NS=O@@|be?xUndj;Ya(jFGhJ0ltrxk{{ +RnQ5^(rlhKMs~y)PoY*!=_Sc)@PKS{m^@6*3*!Ye)SMz#FIn>aK@)}*09y>U+-nMPG49k}%!AFhJI#< +e;i{X&bxJ;7uG60#JqbJx`g$hms0;mmGtEj9&M}Meu7&tP`7Rqjm@Oa6;{TA0jz1?8+s0u>h1k;k3ue +!A1+b|G*_g^9MWP>s6wa|wwHEWn-7ewC}It~>g0IXvye7RjWCRpOR|sx4!W&^9g~edmRC{{*jW;U34(Z;u`UNphg%KiOcNoE!yr_YU6 +PJZJfdQ4+rZ`TRv{5HpaOP*#8kIQ9KAhESAgAYUnOAXiGNcrxeQ +vZuNSH0lNaz1)VjZs+JpTABDgDR{GXWGOL1tsjsZbF@HV6WpOP#9;`d3^>m?M)U|5Th +~)n&=0o91%^OCgXBVIfj_n-fl%ZEZp(da9Oc@{ats;@3iHho0a(BJAHF#0tc<$W#Gbnp9|Z=*h4s5_} +|Ty6Wg@Db8!II@YX=NgxF7qGUJ4_QMS~(W^bXqhV=&GzqM;$W(@soslAXul!1WWilqArj}bkzwXD%)e +2B;`k|3HT8K3)>Cuf(Ut@*LDKd(fO$#Jp0I2y4L@Lu#P)h>@6aWAK2mtey7DuU7-Kd5D007hg +001Qb003}la4%nWWo~3|axZ9fZEQ7cX<{#Qa%p8RUtei%X>?y-E^v8WjWG_wFbqZaoWcjFH~``bO$x_-xwu8v+OOnEXCqI2Z|G;ShYeUh(Xf4o^6Dzo(MD2a7sZ&+ejI +ZB$`2+4CvdNAGp6(DhsyP6;4{PXPFw!xUe5g(-!o=~TMw_yiHDk?zVuh1^0RRA>0{{Rb0001RX>c!Jc4cm4Z*nhabZu-kY-wUIbaH8BFJEF|b7d}Yd4-ZOPs1<}g?ImoQ +&|!bDwTnuQU?ZD5Qw2$RatI&X)GK&@;T7{d+a!&Nt+69w!e4x-r0pU6>wfOuCd5D$f`Ehf!L8zjYA&y +8SLe^Bx!U8jh4CDBUjR)6^a-uLXF%gg}L(x^+n!AT}ypnjO9uY!P-hpy2EtIz^~bC_Pir!MeblH2qBV +%vEV#S{+_kq9t-%w6D5SI$e^}Z$m8n6XzVJ56#!TPH8t8Kowt0-{;p-w=|B<$=~)?;MLz=#gf0onf$$ +DKPp&i?9_LR>&?YcGaOJC&sKZ!@O;p(&+aSK3j@G<^gQWHMERA(CsMJPdJ{aGG@I+>6L6stF|C)sOnKH@N;vd +q_L`V#YG##7nrz`GylMC^fq(Ra!yY|jo4?_Pyhj$tkGsCJKl7(W$;2UIXHU;B!Q&%=yjvN(Xyjl>OGU +p~KImM&5q_xoDSP#X3x1Ep|Ezw;`-`r8NB_U#nS6QS15ir?1QY-O00;o{l@>=!Pj1c~0ssK-1^@sb00 +01RX>c!Jc4cm4Z*nhabZu-kY-wUIbaH8BFK~G-aCyB|%Wm5+5WMRv7Cup^Ahg#2I;2H=?8&zvAZTe7F +G`aFNhQwTcd3U($xiw}QJyT$?r>%~gj;7%AZ6Q!-l3F0r_Qfo*J1IqEcfQFvQlQjkOhHBfO)D+Mu +?Xxygbkvpd8BJqd>FGT41Uv^BUOUXjvIBXn!;Fq!Qezt?yp#v!amM$K5R`}e&tKxtEX!)GydU<(w3** +!z^lQQZIGcLrSPa*maKxB(731tW7(P3f}I#2l&Mjii$!A&t#!cK&Cpx^z*jHwgd#4dSTyXp{Ht@;iQT +={5G&!-d$xq&gCq0gcX@VcjDkuTNue6JH^|UmfoId$i1hGHVXf*T@&R1D+ug!COD04v@v#7nW+2NaDd +Ui8Yl7kdTn5EQB_m#)>xF)?rUMewc0Ckzaq-dDWzJ}~~c^beyP8#{+Bo +vZKG;5r&30OTQJz&V(9syONR9mBKS)+Q9Qf*_WX;IU8$NztlIKb4Z(* +BK5d_6@}@@S_uthZqyS1raAhK^=}gOM@eEY^t*xi#{WEcbpy +YOO!gB{O9KQH000080P~d=NA-WC^;il30Lmi(03ZMW0B~t=FJE?LZe(wAFKlmPYi4O|WiMY}X>MtBUt +cb8dCgkukJ~m9|E|A+aIj}P=T*|82OJjNpy{On7HET9nxG%jK%gah%~%p0l3K6-`_2p>qWoItvIkTMc +30AHUYy5|ql`wQtXAb}A#0JZx9pO=t+`z&-CWAH5^DiJTFZEKCymluhI9-Um^{ngi7%bh!mzhnyHqXv +KK~c%+FBUHwyI-%y{@F{4&|%dB$rb|Xu{7FspTE(J5Z5zK`V=ygQZ0|DR#y +kDyBcF9`BO4YSiXq2~t4V^KgD3oExV80-?QFznUR<0ortZak{Y))JH3k8T&t%1-*Wq#3GX-GE+Yr)Ez +Lxe-tF$LymA5KV3w0NO^j;!HzO>!~04y?p$5aGb#W$Og_)B`3V&3s(5rK&4K&ZUq`ne|Z)obZM%+#M= +|yXUO{Mn<)9=?C)O2^*YyAGX3VBIy`0Y{L!goejA(Sn@{M-^lEg*e{=Vme$R;WM|oFjkV7C2EN0JAEft3E;8+esvMF9Z>`*O`bjw!;h%*K=nH}Ap4sD7QO6v5%@BjT(TG2n*lm9cM2NJqa9e>I)mn)>lBvupeG>lR +F{qyN!lDpCqJ0sq>;;6ZVmBc(g^*t@hO6k`iVj!6wcpanPC-n2Qj)Lj|*V15YQl3Gmh-PgKR(oHrVU@B;5Esz76k&2KF=K497colYSi5 +i`4&mi0nS@e5fwukkPdB}sigPTA=@d4Eb(!O2!J|7Qh?ivu5_Q56`Ye(m}-3j}4#go!;b}E?Tx!}><* +}0I2|F&$1HE)uzJe&=@4Ju>cG`te1xd%@0vJ1WYoH&YdchyhS_!=Wzt^QUcT(Dta;VA|&dqf@&n&UKh +40A%0hz9Hg(>fgE%vzLkAxmGVkN`kyU~iL-fT*q!%Fn1`K_$9=12%i7rJ4o +16EKhZ48Z((bctkw&eMakP}3Y01t$1w_yV~Xv`g23xQH$XsD{5M_+!fc$woxA!*QvM^;pB?lN9=-49Gicz=l2VL^{d?Z_BfAzH +vlgAhhhKxlgV&{r&(O`1QJw!=>(&Nn76QR^%gKX#O(m!`_49_13=RmoA7{;!&6{uIrtkFQIK6;x*oED +G=>1(04}LM^HQ|o(2;OJwG6UY)Uvc}f<=O25gZ$i9y8yopvvQeOL`Amx^E1=nUNx{i6OTK7^T+0PAfP +CY_znYfrkU0xR++QkmR%|B4I(oLe-u@y{HAPnk#?4j>->I9yp{0aPH1nP<@=sLbJoY>DCa`uDM}a471 +EJEq0>evy$z^hr|FppS(sF=ECIogFGAI2fB^q +*1XUmgbJcs*q|i@<^=HjRWXT0shEMjU5wl$93Slej~mskaoAVWzVbiTw#a*yH_zJ)hy~Lk9$Eepub0Z +?{{pA2PAR>UXn9xJPP_$;JJe2AP~nqfb~c0W!o7S1|agjVD|Zh<;4fAFol@1F)FMrV*9oRzPY{!-!H7 +2_ac`M;qymL~wD_tZUIgQ39YglHmp$hw0|j_(#)z=fi9ecmBv;zdH;#@wypkoQz*)yV&hfmF_2NC)9o +~V9x-^xq_)lxm4NzgEM8po5CNHPJ7gLx@Cx|+@@oiP=h~w&U!=@=MYIN(($x{4Kxe@xwPMmeK2Ct)u< +~^)FWWxPgxNeKdQDxft1>V(j&_L2l}+Qr%dO!u-B$r2K7}?FhadNWV`I@l&`hA5Dj3DB +sJ|Vtv3^uiWUz3vH-18iN7oDEM~&$>o$##*a8w37Qwq-Jl7^$Jt%G*bjv>2RsIN3(-YhYtpgb&b3heL*_z7x*FxGfx99ju<3}bayV(+31rGYCB7B&) +k3E&mRjXTWF2~0P5NT}#zfwX~9X*&md_(~Yc8AvN~Al0LdLPU<5;K*6QKjY94Z3Qv$!&96FfZc5=Cb< +6N^H1mporK8~WQ3ZdCFCc5r)2148Xy-ejMT^kpaAju?&?zzRg0GRPucY~`_2!NEyKO;CE?x2Q8?U;J^ +>&4)RP1&#LHwDDK4aNCW^yOI)WbxB}kOl;5GWn7#t2z{SHnPZk98Ly@xQX5M4JAta2`EX}7*By>h3Z& +S1Q;R&0Q(!u`H+(Kic2`*b)PKOqr|5S)1pBr#IMygW^2T9yZnDS7IOB#Tm#Jk8>IOP_YUZf_;)~)541=jHCyb?H@d>H&IRv>Kd_Y4zPn~!+MrwVH=YFHj!n20Z>Z= +1QY-O00;o{l@>=r5E(Zg0{{S73IG5k0001RX>c!Jc4cm4Z*nheZ)0m_X>4ULY-w(5Y;R+0W@&6?E^v9 +3R?BYNFc7@!D;6q(NT{nOIR>zc7HEI~c^n#`M}f9hHW5m6NUDzizDrV)t(TqfVu|JsXJ= +#5g=q@B*h*!9EwvPt!PLJ8K|ODHfz7kjL6F<MeBbjP^BYz9x#*w^~;ac^JziWh>Dm6 +-+59Y2LamhF9190V)Dw1x*>zB*ijZMTYVU2qtNb_UpLg|yU2V35-~s5CFvz>F;T3bsmaQJFo+90Z|7H +*pfU_{CxY!UD{@+gxf{par^&Ke%oNW@Fi7Hos$n2sZruMj7Tr@~z?uBaI@TIZa7~`I9W0Z0s;r1NwewPWocjI1u*_0BS3|h}j}qYdS>y#=brWkLzqYgvjCUJrhZj|0H|Pt^?Hz8NJA( +~Vne&HLgqx(Zeoz-z8=W{m4a?(ZtYcE^j=0O$7wP%WNRd1>>oL!Z%MyH<5`agxUn1=A@*hGbtEIqi!u +86J0Y+(gX%d+zYQxNcVocMiTQ!KK8Z_Z^xEb=R<=Y??nXh@tgja1VDr!MHO%=PZb;o1*tjMAXhY-ZFB%+ZS{+@{9p%zmf?X*NqdfgQTy@QGdjfF-O}Ed_GX6ZRq+y +jl%i?c8nW)0NMl5pE}`5sNo2`W;yk-I~6_|?lRsovzbnHx_Zs<33hIUD7?_NFw9Sa_y6blon`2Xtp(y +XI&&a>zrM1k-BohkYxB|k`pvB?y1FoP{q0)hWHZ!_&|WDD1=4Nk40d#h*bXM9E=8_WFH#hb-3RS0-6( +4VTUEzYLQ%t$zwJK>zH@E#(Bu=_`7eQHJ5hfkEJ(^baA|NaUv_0~WN&gWY;R+0W@&6?FKugNX>x3DV{2w@s;n)~{CN( +!_$!Q1ax!Totf+XqSEk*Web{oXrJ76%GLW{o@fWq;eq@Hvfp+&ylsuoqS7qtgY#;V?@DfjGM%8vcf$s +WHYR>Y#*GeXnb;*o@hixvj14i6nE4g*rQ54Y^DDXd6?O}}wR>Y8E)hQR;hvQk-k{Ys`1EWPA%FwO6 +b@MumXtu4PL2S+mu$@ughMUGbIrZ9WEHANtB$aQO~Z+>Qm>FXSqxH{lsroRC?TDPDMgf +W@aXW8F-Y9GL~#y0Mc0wz7119tEUFpV8e+~#-<{5o +!Al(1)p~9kg6L|^Ox1G2Hw1P&n7=&A~-%+(Ds=y~fueH}D>Au9JhMmkl)iu +o6PS{%&&Cp3-CEdVY*L-K;+vAm;aHhuRI%UYr)vt2NbHnKl7$U3j#tUC@jB7+nd#hvG4h}z>rT-x +5A4m*T*Xbv`7Wj^^o7Rbp28Ce8c%F|8XSi%Oy)K_gH{93z&|U@c1_w|!g3GP)Y#;*hgLLQb;glRFsJAWp_AhlJcP0u`TDfM{&!`Z$}%Bb +zJixvfJRDEWEEyVal(Xr57|SE9y1(gv@(rUd66RM7Z+qB&fce^5&U1QY-O00;o{l@>>&%^(s+2mk<07 +ytkx0001RX>c!Jc4cm4Z*nheZ)0m_X>4ULaA{<0Z)0m_X>4UKaCxOz?{4F`5&v%VAqWSH*gZ$drq|+{ +HbJv#(gw&Si^T0+(H1f-Q8BTS=p(5(F8X2Lp$_i$Ye5 +LdUU{#f=(69olLKlXqjDEbQ)7gXP&8`$|nEJ8D77qJrk0&_2A+Zj!=~y4+cLQBsn(*H6u>Is6K +0a60~dpYQq9%+rS0jM2ackjy~+bm$Agl4f0qowAbP6?9AzK+QDYus6wDX`{OU!MxKH%s +mQ=tKu#OSBO~%`!cgrA9FJxd>FE{E(ahGF==4^V!4UXReqbR%7?!GXA6%(gI@j?`m|6-=!7_nRXFOl= +wL!m6M2i!hgjS?T4y0T^M)juP3Q@1jT~Wt1RVp>w7%)*L!mW{CA?gUFk5T-FVh(3)kQfML>j?1o_^$_ +V|6cE><*JlFRU-Cu_09%p)F=kLh)WAZ^yohb>+%db7{;1yJ8jg78nj+`*8<|atXaoMi!VsklC}{-nmD +JR?2}?DjAb%w4u@b#Dy<>F@-xb#~ZhZEdP)*Rv*z{ynrz6I`=WD +Q%$%R-#J)27#_40THMvpo`8L;aYWrNig@|zF2Tf0vf4gCu=UD87QGpmA+4PRun{S1AQ1+d?kA$#+Mjn6Ugh&~DS7Ku~|2j@cNTTNX{&UUWC?VGiri-AM6 +?yrNlAYtt(eTa6Lw+rYl{;p{c{Bz&ULx1d2`o#Qme@q*japoR2*OF_ID4jN~gBwpaMjEFwP+@@j_JK +B6h0rqTGQyS`hLR4$noG@?U2n8*2`_#9Mr9}ff|J8=gHA3R^l&Fm&#@n_(WA&02B?IB{|~r8 +MJ4q;~D}KwcF|fCDE~65+2Nsu8clC +$0~5RkoS5UR?uBk`@*8n*fXf$Jm_gWD01>OhQ{I%MSVZ!^QRWfhZG&hDt>uVJw|MIm&aja#JY`t71jN +WwPL!Csycamo)FSdepq|vm~0WrH)xpPllBqrok2N$Z~Mxc`iCkKyCU68o=oZLi`&hBN0v9lIJ5IVTcx +B1FLz59-1R)B9}aYSqzdW!Tk@RA=V~%4FSrE01%MMJj}>}-m6Ov$J11zVPICrHM8AM*Q5l|Y49BCk#T +7>j_}fG*=h&3x-{pBva}fEq5_{x;< +73qLoDP8jr&m1qsCYY=ftCv@1d@6aWAK2mtey7Dwk&dG-$l005*F001Tc003}la4%nWWo~3|axZLeV{2wsJsm3`?!5+RZKK*yxs1;-XD}pePD~Bfaquro;(Jc|8BVkBfHA +=J?P<2^i6kZ~gebM=~oZN|I%(TGtY?jIeSeq$YH!1g|w@?sq~8_QVtuRSKcW(oNqpny +k3JBmihm9upw1nTJ6mqai7DQ3 +9taDS=3FRp^C#9^ +0_?>!A_zi$93kGWIcYemi2VB_dCkwC-c34Ed~nI4r<(>66cGd);wQ>laphV>_-wycu*Dv7&}L-Q{+li +-QEr?>cNQ(XQF2~!DeNkeE=wDUr`T>S4Y<*LZcoHt?Dd+8xDk6FGY*F(%&li#*s1$zumxxJ;#q;s9#^ +me7E^y6aeuF*KKi(aI$@jbb@?jmxGI7F3Jbh|b+Y`XoZA+0Pl)&Nr(x2IARznxU;g*niOTTcmE+7T^W +kH<2Zh`R_nKC(&y78`VHz+RLTB?i1xToaW^&A$M_@91|TK9LeOsh~tTgy(FB$_m?# +wn23)8F#EE_VwKp!)<8tXcMj{d;04Izc%x%%omz!bDO;P8M1JUGsP?dza3<0 +SaZIH{+bF>NHxxFCPk8wBSwTw%Bc0*8ex5H~C>Y@)L|67ZH?4Ljwmga3=T9fKlXEcREi+Xw@YZLab~+ +tG}{PZl$i3c6}ZA<^HPQ6@QVpY>dK7Wwwa +ANq;P3I{iRLweT4@Pl$M=JI8*`$pgdoc(5Yuwkr;>i45kwOP)k-;rgvR9=|15yYTwFDHdTAU7-c +eRJfmgiU%-3qy9an*enH>Y%qHd87F6>wktXR0Bg-+^-G5Nypu5rhV*4^SBtwm +_H-mmBWCC|0O66h!fj>&m_!g7yl7fQ&3yrme{%DQJG3%ngU;Mq%y +!VEk$K8_0K`joEyHzb}w}h6r`TCTG6%4SD%>18PM(v;{q2m_%01SHrtz;9=yc8H76@G3t+fD3WaP@d# +yMKa>2BQyLv5nxpJnh<<47t<@Ccaq!VCyj#k=8U{F{&s5CDhKzr@zU7T3Sz^N>-u)*_^n>39yied&EW +|lKBO9Ft4`Ms)aG{)ncf0t$Jjn)b1YJ(~o0gDrFGfI*q?u1*k$+HeSU-7P&jo=3CFJt-YRriAQld9y8 +6{aOyBg}1160(;#jc6r1+HM#=y7R&q_%(GNl;TxKmhBSh#=6bZ*%*2&X!P(+MxVgC2-oNzCN?ac4gycvI +wc|7$Wc7?)%)}1Ks@_EfC5S2hmtv3?|U^B+TmADUZK!<$knY`qS{hD+6@r0NuYZ*kJLv~PPRtcqSy~$ +WNK1UlL))kX(nzIHXGP7ZfHExxby=deAd)-g+6|o2(JHLsO}O>Ln}V0csLX7@&OL6jVL_TL^AV-;A`y +V_>LlUiPHjc6Ez8WdwFpv(-aC^B$uOJ+8f}wgLIWs5xXY(iRTL8K}uKe4{};=O;vZ}UZFsH{kSgQX(5 +Y~!1*@Qsb^{2W1imb9&f27#g5i}G@%%nf2NB&5B~F@^&pz>hRo7PcCs4Qc)*#RWL4P@vYoNjanJ`iV! +@NuU7uVZv9lY=|Cn+e|GQ_vN>i2Y6`ju~H(HM*vuY~`Wlv(C$8bdzhEH4@4QFTW))=JZFrWVbP)h>@6 +aWAK2mtey7DtF|o!UnN001!r001HY003}la4%nWWo~3|axZXUV{2h&X>MmPUteKjZ*_EEUoLQYeN@|S +(?Ae?_g9QuRRYO4Z7DAxBtlw*MU|jBrK%9JHul(AvEE(w64!svtS^uV3BSa%bLPxBv*Vn>O6lJ4X7Aw +Y;_@19lw_iU-1)k8(OGl`cf3Stu>vnEG~o6KOU+99nKB7{Lu0v;aFt%bivWnHRQ&QCG4#qq%X*N?fwx +E$+(OL-0zQ|h9dHSyYPH}@mIxhp`=QN5k`l$!M4@($5tcKZoA%`Smca+#E +9R_R554=E0V6F{h`?pTlzA`Jv!P&@r_oB{A*HPu9>x;^;_0$gGq>@Qw?*f3(9;zxLEv!dQbglng2ZJS +?K6O>F3<{4S*xU+7-5#ZiOk$Vn){m@Z_5e9VTxfR}HxjcF3h%4aI-#2E>0p*1&Z%i_zlA- +@&bYEXCaCv2tO>dh(5QgvkiV?mf62)oMQ==YS+f`8`ECr`gR8?q!0gnW`bU#e|?>n&AbyP0wJ3IT +#JF~lhwdzlrnuCS=yN{n>qoimn$gHbt8!UnaJW`3$U8CY+RmPMkn03(g=T$Usdk0=|{lTObLg>iU+1ED;8>hpEgAi5c-aBUE7pXA92nS=HBhAiUv&wf*Piau +|kKOh#j+n`P^h%=sVgRK)`)*KYXWZ{~0*^{a2v->-SqNWOS&~J}cuDr(ch7rxSv@_i(tWbcVD|*;UAjs3$u4E}4OZzZ +{7BMG1ju9JGWgc((LbA{afDcn^U4t48K{*vWO^*Arjq-TjS~$*qmHO0w*x)uj?8$GhV4~MX{jSC>=gO +0sW_;$>LAZ+XPw48AL}b^K@>){+-L4}#H}A`#759-l9mt1a)bt+5a+oll(YW`Hv#a+VP_9Y=Xu2I^88 +M{#7hg_m<-G>Qw+%L(F_7mSx@w_$YV%q +IQz#io~6{qTX`!Cz2I0|XQR000O8^OY7yXGgu8umS)8VP|P>X +D?r4Z*6d4bS`jtbyVMPn=lZ5=dU;=4^1aVx^xdyraok8r=eBJRMJ(|G$98LV$ImpHlb+R|Gu-KQL-O? +0sB6G_ubtGV_2%X)4beSm|eVi3)f0AkwapeqOid@7{e{kP#VmkkvVFxJA_5eGI|V=5Wb=|TuGQk7cg; +v(GVJ)zbA%HHBhk*q_WT$Bnobz-~s`kGpsFe37M*D!I{huT5fkf%|H?n#p6Jsww4i^5x%Bfaf}1j3*K +2<&!^M2Z6oG|MoO1c(SywNHeTMWlAG5g*2C|mKx07TQ^Pftx$S_}q$OipQYcspN&_o3Qp_r+wbk5mS% +zR#VOyq=SaNQx=G(@eH0nhe)q4z}Rxt^qMFMd$f)9%%PD0{%h&P|s_ZxUv+}$l!oA@Sy^&KqNtLu0Zu +UEAD2#eJte2!PwAt1Gh(%^HgoqiI@T?;XH{Ynr|1Qew-8==+<8wi8jbvOsgYT7q9*|l@BPf+a6dY^F@}x%90vOtca>Y`Y#J;L$#;M5`%aWJIG +!VOej+PYR4(E3rmDJu>yX4xTuCx8?ol|t{+LT+nY7&V5-qconi6G{np=aSuXdnwX<23)CjOM)vz_*2= +!ILZYiTO6P18vxObC)y^rLWJe(L*1t~i3brIBnTJ>{fFAArG8+)XKZp+4jf;mo2l6VqMlPtHP^oQLr9 +*Lm<8P)h>@6aWAK2mtey7DujMmPUvqSFbz^j +Oa%FQaaCzNRO>dh(5WVv&M)t*)2u`D(67@iBM@5aWWSmAhp#=um3h$EL#l-)2cDwPm_Z{lRA5R3zh)`D_7xX?pwe6lxbd!GWE%$i(q +Mc?3|ra2nr%Ty1C2(a;2LsXA>eC@wE-?5mFv3VOr!`cH)XfYp2Q=H=RJi?45MyF{WY!f<33ax8+BNCPLol6((fo?UcI}U%LajmJOT!h7nQVd8q$OnuDXdrvQUNOzQq4%KwN>13QMjOG +Zd#_0STe4S;z?spj5;Wzd5;^&DkfmyM-W5<`07VN9ZEm`AW!!gLYNf>p2xX>|{ +N_zd5JaOMJ%O|%WZ*2?N9k=$B{ne{6|JQ0w~ogiIf%5$F5T%u@Lfl$Z|Dna8wjcU!cJxERRGGeLtnj2 +=iKNmxJPOjt{;y7>q`+DS3E+4vrxu)8)GmTO3)^U448Etjr$fg0${lqVHLy@dSb&hTuydgzOU9* +xNAbIw)$??!|HER~(;+7QG7W#rqIt(d)xXH77F_y&}#L0*iOgD8zzdx52~dI?mw>zPzPn{5wGB{eKap +tACxOb3ginbdLBRa&&Py`h#=<`BReK5_FysO43Da#?CKLO9KQH000080P~d=M~s4+wG|lv0IzKT03!e +Z0B~t=FJE?LZe(wAFK}UFYhh<;Zf7rZaAjj@W@%+|b1ras?LBLA+eVV#^($a%t4u01BKz{?bfz4|arR +V~lT(&At}R*74#5$L2m}}a6vbH1Z@+%b06hbMq7-Lyn+>ayh~S{7r>9@j-P73(US^AR9#3aw@NEC-7s +1zAs**`?S}rdy%bnew-Qe3e(rKY5!7`obJSb;6I9jL({$qX_2H)$vh_f_!7VZaq9MCgA^#=b15Z2i;n +5%V=W@WG}G=PYU;4)5hpl>3*D1$f+qHMlMVwFZZSjFXxrZGT50P%MNA{&`Re5K)e}ILhW{;1bWsGk{%INKu*~r~Pz%5%Qe(g{QL7-!12xSx{8na +&>ne}SIGqlIBD*YCD%SvI5*KA2kC&xGD2o}aR}KJDsWj*vod(CJz2K{()8o@2z<783_P<~M?QQVx=*^ +p>lefpOPJ`EPf|svPzCM0?{Q3mGeG?p={5|-etSg-^)l>)5>{{n3EGJm#d>$9Lkp-YP0Vqj4k4sh3lg6ULoy$C%2NxHY%W|3Piwm4T%gaEGi!6b4U +hwxJEd4r0u)|=H$7u;Kq!9w$*{R-$?4R^omL-LK5SKc49ss#{=I{cUMwND6q;ERCDAx;J42g>_=DJi- +qKd-2acvmYykYou7<{XzDq2@x7b-7cmK}OEI8Lus5>HNUuac#HmFHPLIM@l`)9dx2U|h +|$yN%OJp=L$k@@o?C}!CbL@d{rNYE_!?$vj}7hmj$6(~FLSE|tUtnPyPK(p}ZtC#-^4~8HXKkBF)06G +NZOZ*YGq0CiO!Yi|ELeD4q67~xoUtIJHom?99_rD)UgRfHA57EC)UM(^4h(#yZu%FV;AGE6f*p2Fj^iSGdFUxdv1~pKr7E9*Xex6Z?9g +aAB(%ER1kcNs_JD3X~2b+vT+3D$ofFU4q8y#B|6E*n#k=E`NJ$H}FK1rD$I*s-S!4L%D>}NtSlu{o4MZLF9Yye0ssn+nY_6UL&ch&)$8Rc{I67g&iLC$`hz&;8|5%kGPn+Cn-uz~##PXU1s&pr+gD=Zv +1JmUqi^~DAJm8v*zIXC6e+)e8*mK*6k7oA$fxjs8ymHGtx6vU>lO#2D&-Tx|V93R81o5;J#0Kxx0n;!Vzs}KY +vr9Ba3Z(S_E3rh6rvt&tTcj~Hl>2&-yS49#ydp6~zX^`W2XKOnpTs| +Fc3WX;RYkX8W{+FRH6X+aINRgsnYz{joI-aYFQa8iC(eKTqxUS_@1X}Me5AwCv!3v=a9*phJOLAQZlT +*si{o~&TwsWU;yRK%zGo_cF=dAa)FdOJHES*3*$m?C^_Ti3}jzvRh!?aq|lNuM^OnrG&t;&jE*9#-QogpfL)qMvJrxfLyCYUJ^I=Y^!d<{+=dPg? +YBXn#ep7HYV21WYu2$&CLk9hLj?PrLQbBvpPkn!WU`bc +axxj|O-rm(}&~y-XgJUo?%e;&0hqPpnpOrR25K!f$YEYB3fD_w*I!B}MJqDr{bXX*D +4YfHRws5wm{;uov%76f{dIy*3%dR=1qDbaoZPEODT#?_Yl{EVRTNi6-OXo*RQpetqBX4hJUSTvxlx)< +H2TLX_7$BSQ3X;^nfZv4k8(|CVj`Dk^;nUlVG`UrIc*JDh7s}0uRr$nh=yqW;+!=&SwcjVHbbbU0Qkq +f5+$+lA0h38}Zrzw*_6QFbhRPVB2yXq78`?U7vGv8B+S8`s;nMSN+|8@!fN)`Vae~(e0zr?eo#?A^iL +Ha4_h6$KZVEEa~ir_r>`h5dEDFeq0tN5aY0bImIBURx{v~Vxc17`55zRPJ~c=c3DC75~52_My*obKud +K#eUaTCGYakS)HqurD=}8}p0}^}FESKXAN+yh-@khE)$7w&!7Y9{{_Dx>H?LkEoxb8RgSJ3e4Qez3d) +A}yvH;q9M2~^t-KL +6T33w046doN=}F?2?f$=$NDeYoaVQ9D41YUv0MkWQYWXF3>sJ+T|{bu-U-@0_KCpnXaNStJ{*3dB3l<=jHSstTUC +gqDXX}cab*YWVUjf6x?Rd?vx|e<4YrTHV$8dl?7elIz&7HL$`xyKFTt%U^jyJ8qhPKT62!=nY3SNykkWw*%-e8UXi**8`0LJAJAVD5WzvJQ{U`r +<{@J6!3puG?WFl>9KRguPc^~qhgFPDEb;g8|{-eO0k~`m_d7fOn56_#}5=?bFzKw44=vF0*8GO;Dx&? +sv&vmR<&GY765NRn*Y7JVc)xMsrC^s$$UVLIGc8eruZ2I`#Euejy56mORrMU(`riIV2)Xr!zEY?#Vqb +uOmYdlL6$5-xQ6Hb{;IgbjQPI*|4=umZ^0+$|v&DE9W$JqjFi&TsDZIe;++^i1}a#vb&-7aB!2NmCcc +BY>EY}t@ORZj*8Zns0e@pIey^nLh#kCb3Vykeb}>IMx^cqd;xOlNU9TukK*)_@pK2xPkqkO(Ce=S<>h +T-s1v3p5*lE%X#KQSEx=7gwnS9fqU@tKUtteCDh!=)bd(j^Hyg{}{V~4N^giwETPM9sl!B(nBpU?-uS +2(tUpcIs)g8v&FTcB}aoTz6y%vm;$xHA1m}c+a;&VZ6g}|7C)i23vxy@^M_|Dqp*S&M&*7GtFR8O^hvKF}uOb+S90V7 +ABE_N1FIrCE(1ULo$xjs+Rq5M6T#)glBIhbJ%ggF@|48&%$T;O#lIvb%>9LBl!28IkwAE013xd^qAxn +cwIW57d95bR;P-(7s3;11A-bnE-}FfG`ZGANWLGRiCMktAT^g&z&dbJ8&1f}NUp7I;!tLt-WlCopW7+ +cfbS*fMsmhHmC=+Tji{Bn#D1D$u9DONQd@{#QKdtTDJYSxtSPgl&w(l=xbiWOZr3S98#%I-O +!bq^S77M=`U>f6BXhrAu05Yi*ecawMA;4^-fON|o=S +t{;&6<)SLi5=x!lVt?+7&8Nx@w{Xxsu=s?@;$MfzeX_?b0_POi+9c|*O7~!un{^9US$;+O#PI|9Mx3o +qtA5%nrhv#yM^^~7(0Y?-flj5{;Z*Y4(9l(SCq$VirxZD_tu&TQ5v9Xq`WJ?;#On`R|>AQ^2Z))7;h*_>uO*c>gg0M_LCYVaPcf3N0tcgxM0)-mY2 +vTVfp4jW1dO(~?xThTC{{>^wL)^#(0+(hwd2=&uU)q)$c~GDJlD5bc7=I-yij8Ub9L01!>Vp{U`_Q>q#KLaxtUfaA*x#d^>F{y30eU`D +5)|lOzVYP&_hvhT;Ge7^r_3-(%=jud_&4h3@Lpvq?E{z(+TJP(H&#n=0M370gat80>IQFCN<={Wqd$h +`C$fY+jEX*jrAqPsTCmZ-|&zK!_n7t5sN3v> +7#6@krn*xly$dZFBD+epJf(6-Xx%bSAgZEZAY;t)J8yzC@;SQP!ircjo7&s>tKXEM9OKiiedfLWq1!N +sEfZ)P3%go$FF^A{qm1r1VQ$wxv$2+yEa^ol<`=BnSgT0)f>-!SRA^@ +K!FS*m?!<$^~j>^5!2nDR7%7s-SxN7tK_h_V)y3MV_mDtR!nanO`1%s>}9vIvt&J*tFi +&KgZ@dK(~|IIR*#pD$oi&)N~S0;%kg^i^EGwS7c2JlkWp#!@U|FwW%=>%sq5tpa278j?XItR~JybXHV +l5fY=tc>kZdRqY@K2U!%u{y#aYFcI>%yJig;<_i9Cazd-uqitqkXL3W%Mbx98%IvqmEyJeSPoG7uZ_$ +aLWyLlp=%P62H0TNt2rWFaoij{5A9fW~~AaDKp21Ny7;3g-xZV)1%`d1AlY7v` +&p;tl~RIKU7Nbu>guo9{mR$E?dLaal&AvNY}gW^k}(PzoWu=6FBXYb?32-cpU0@ZFn~H&XKR(uX9e +V9lXg0%^_`4BcbxS~jHScY86cp&VV$uZSl5Qg(Z$RT7C^XNfcVIATL;Dj<*6@I-0bS +jhwOO{)d&!p?xco~y%wQ7Lc%&gZaa>e{{CiDsc>O-dBzNfk*whJifKUk6C+sG+wQMz^c3c;{6FO=ip5 +ZqZ-$q}h!s{mHSd35DPVC=|sE@jd3hsQT{h)e~4)cLNdgqI=ZFA$kdH+bBy+nt-JWR*Y_LyEU&nCuOt +;2aTl%Rl|+i_pAEE$PsApBXAMPM;i)YUWl@0fmGMGCmGUJnysqN +N1`8!8`pc%>B8BBM7?_*+?P5*?$^j)D^$~_eGMnRxbcr@7%O9%jTDV+h2y+D$1DQ_76B@w2WVDO>W#o +PKp!fy=$o&WU@>tw` +;pjxdK042T7J)@cWV1HzolF_&6iHpnr~t?9WkmNiKeo+faZdIyu38kqx+H2&o +}2jCRo~c0sniFYaTYnXr(F5*G+0$>+Oh2CjCvr$=F=|!@P~TFAC3$RHI9N=wjve*Bv!T;AAqo9#xQ1h +xNoXWe93V-A7aqI(GhREtol1t`C$0h*gRmt%@Q(yzu4|m9?ZLc~K +H*dOq$ViV9}&lly|Ua+f8K!fDeg+V1NwJuymZySF}>kr;}JVo}8Vz)ZODu2MnJ&U+H)zzAvF@!dY;l~ +Ib*4^(iOjfRHf+IbECcMh^cpBL~Ho;tqU;<$=>;|?O*i%7GN0Xgsh3q>r!BnTPNYQ+t8DQYoDFl6X?rqNIPMdZEZ3eNuQzc{X +70#gL3BV3hHI~Jfa~hQplaXjL!msni?5EK`Q+j9q;O_Q^4KN6xt@*?^?)DSOs#+ft9VZ!cmeIC)*^|l +Z+qtPnn*E>|h*O#2u94)Zc@sa^eW{yr8n&ehpB8W`$+eoSnUC;BqPOs+IDj;H7;?n1{EGg4gdhHE&u=^0001RX>c!Jc4cm4Z*nhiVPk7yXK8L{F +Lq^eb7^mGE^v9}T5WUNHWL1>UxCs$6S0vQJI&p-zBs9yxINEh9FOg$({X$%L_rd2ieN#?vQziJ-?Mn3 +2vTyKHs4N@i6vt3VBfIVU2u!NQpK&7(^oF*~aklS$Rv>TR(%G8K6##%z&~g=W=Eu!Dl +9_~S+f?48i1R5^Q^?65u&L~baG{{@6wwP168%W_q*MJWIwOE!_2VB#hfMa5*!QZ+9!$@5gOrL1OV83& +R8;%5h;MimD&2YrEGlO`SGmf=}d6?;#fESJlK8%7hQr%y6VR6cog^y={V>~I^*8uB0WOq3_}JN|iy*q5VC8=+}~92dvOCuP`A`3AER9Gg6gh!aOSdBUuSuDV5a^pk=#YGK3-*DXm%hC6Drn%w= +`k>-C01o@HQWpI!7AK2gCn9C5%R=cV-ZjhOQEw(;O7zvh`7H=evZJUxTbhbIT;=ZB}qQSXw#y{GRtc} +{XZ7vpMCWTJ1^9M(YQ_eCTMmCguOi%f9K&sbd3ADGYlQDsGcGnMizx*YUktTz@DX87-4TflhFE)YfL? ++J|=qfF(s$eE*JBKDrGAAR22M2z0v&lWHWr1*#{`aL0|;h +GYe|+IQA}Z93@EDUl9e;H$VlT8+9}G5z7o$bI{XeU;Fq+D#d3y>EIu60csUym`=!VxaYrH=G(*YoO5D +cHd0FLV4VWT(cPHC<6m1c=`i5wLU@#wzIV&-1kCp5>Qz5GOEU5b}Sn=EEfZcDyPCpB`FFLTFMYS(lsQ +G7M_KOy?p1J`%U~^H;)VQ$#b}yaC2+es}(aG!4o9@}5Z!mSNsv{gWVlHx=XT3JhcBz$*Iv%{gx?K?N% ++{g}9Z_VjwRGKK%dT==2WG^+Fixz9usjHcHu?%eRGAIGS;|`9+Gw2wE^H*dyOXDVFu`ZTg1vg=gC)K}hQnN)YhWjVIOX54)*?s!ev%ml2p +I?8|nz{wLv5_%f%!Nh{Yr~u@;h#;yTPbh~6KL`QRYunTdKCu*JYsJRb@XM#9-BFqvn_@c7a1n<8;*=N +D`x!3NL2huikwQ0d4*~Nqay)+kX@7YdQCL*B=SZJ15OyikoF54>3W>1v7oZRq>5D9Z0|AzO_8vJP7(z +!kbh;jn0Spzc8-HXr2_USRp%z#LS4f%N=J4Qc21So5;|dGGNJ7CS^%V2R5r11#-@RTTh1idL4s2n8py +*_fYFID2G>|YPDxnc$kmZRRaA*xSeP8%VsM6+1R{VWP?=4}NE>XwLO(9kBD`cCd6ezByaM +4mNbSlau*cy%1sp_EeM>#xMJwkyqRz+p<1!`5v@pV4M&DRe&$P +g~=XP#g%U#_hxD;lDww5pZ5XCzxl)ep6O&i(*&HQqcd~HN +7H*oBs?0qfZ143gLWwvR7@xZw(7 +MCO*)W#(Q*CK{OP}3DFEO5FHfEumS0@#Y=3k4IQ}Ajxz2XArB>0wBAh&T?&JV~`95)2U&iYYy!(}6O8 +Yy&f_J{SXZa2m=(inSVAhN6;rrzBW$?`553?72emA;H?{s=+g7F;%<2wx9x#KjB9}Jdzy{(2DUkw#fi +-*eukwDMZ$pp=Ad%$77>lY4ry=zbDc>6kOn!G|k^ydz$xYO~cPtTurRYIS5lY)?$e3H#Uzg9n+%mjMK +g#RCARU+SP)!1*M_m7F#)v1&psM^gZWAAD$ +#f7`T>h3Qtm?qeZzk;)oM}nUH2}INw{?bCaq*UgHT-S@B8-HAxs&YgFsUD5Wx7RVC*t;q|I?0q9JhYy +Nn|f74o~feCurM0NO;)s0Fr`DsNM@IY6ZNb1aw$^>H3-jD$9!qctN>Kf)h^z@K8z#F~$CXF|+JI5452 +=7E0HECg7##oM%S;N3rn+$0~!{HS4J6L6EXj|3&+wg@Vfrb~$R9S&D%1l$EXAh9{mJp|4t?<0ZN+&c` +j-8T-E-ZyNt)KSrcnk=8vUb&~$(@6ds<~a4x+x#7v^(S0! +^J;*AY8Hxz2t+BIC@WKB-ikqqXh`ir7F^>*$P??IdZuf+u%<^gO_vh_ed3^8=QLDe*Rv3nVE@mioLRs +|`#le2V~p~U8)ynuEyD;Vr>@}`-3bd2BO#bzoGOce=se8=95Zr#3bHuJs4x< +7mKk7luLA@&R^;( +uUUvD#bJlGm4eux18Rkg>RTSD&OUEu=syW+l9tllwrkTV7@5wXx!+Hbqwg^D4n(7pc2}_`LN~xn^TPI +D5E@Xls8n)l&zW~DWR(PIyWx!jNH=)6F?fG33r$L%2( +3jE%o7Fb^CIoD$h0V0U8`E+h)4B+$ij)#)z~<1w0<5WyQps#nimY0n}BqB50bWTCFsr5&6^6HDC0ex3 +LWR=-pR=e-E=B7?P$yA;hT%OapR?Jt=pFhxT7Ah5lTEaM0kGK;x@2g#N57Ngnx^Y!WP-J-aE}+4J&W+ +ir=ulNTvzfO?I|-8SlHDPq0$UMrHlXTvj-<|;{_N0F&%BUcbj)Wi7dx*irDT-W75&8A?r +WkebolNxkJLLqFD`CwYf^iwQzmWLc4ZgOg*5waKM_HgujuGEQPy3qC(3%gj;{m3=p0Q>NH`K?k;SX!N +Ij!;I=V7PS}|O%p*|KOK-FWq1!N%Ny8crAOlB_a#6NbP ++F9g!!k#NT^Ib1czR`hg2+;ZxR%m|-PmnS*SH3=#@OcBqO9elyD%~u#YI>jai4?^ +{ilA*DRxuZ*+bfcAi2}6)aw;|64WZwS8fwGduH|kbMN&<*iY$IWDfx+8_%Xn!{l=!pj$G +82+AsU{M`(GbN7A^fsw7p%0?f0jc~MzKU6%qG_Q_jL%PBn)_&$@I<&@t?v8PSFmF$p5az%Vc4R`Pxd_ +CrwVtW0o8`6P{6SrdrWcuTSAjEFIdgAinv>f3Mdl1kcTAQK3JbPd=xVU~!NxkMFjwr`^$U8IAy=T6W< +yc)E=*?n?$s`C5Mdua!j6jl3s$9h%W&f3{+1KiY)&lh?h&()?>0-TR|Yq;)X;OVwzK}aWogldavH1B) +21diuRCs3pzD@5qHkK=St4AV9=1hp#{7_aEmM~E6SZNsubJ5Pf$$=}wPI&EyGbeh_$RLMOE2X5Tjwwd +Xn8u0n3Kbk`fWT*w#^PGQ>!m19e5eY)gFBC{7l@)R82K6W-_G<@?hri+BpuXLwz>GD2(p!$^#BFl~0> +vOPd0jpfiy-qRFyv=8GFnJG^71HHUm(B5#Py`QCU}Oq$Hco$vkHxOmz< +Z=1QY-O00;o{l@>>sRHesgZ~y?}p8)_R0001RX>c!Jc4cm4Z*nhiYiD0_Wpi(Ja${w4FJE72ZfSI1Uo +LQY<-Kit8^@6-`klXG46ZK#2^_sSn=BL9t4OrNjV19&vYi}?2N(iFazbDRo&iX~iO+Ap_14|hJv|`hI +D7YbE_P!Pn4aqH>gwux?_RIBcaqJnv&%fG^QPL=vpjiza=dpC`RwgIca4fB$&y8NSsi9qy!@t>D29ivtkEYX6@}R8N50cv}cyN=~_!bNZheL15J21|ofw8=-5@?=mnmnnRlv- +4)92yi=*(A{OGAoPKW&yzLu=Z$J$$4IsmoSp1fdLdHw8gGq9_ij*=M({(^Smi85qt2)ZB<|M;LECB3W +A$$v(A_1{bsb6=9icJWRzs(JlT}^3?R4%FqPwVGRt5w7LCBAm01+af-sbAsiVF0r((tL5G?9^wrSSYG +C4UqNuE7^3h2t_c@5JC945_XwW{hhO>R29%-557w$28_>2zS#RomGD(Uh +y_TIf)nc>GC;WYHPkx6&rp#xM_@hWaX9$Pc$!UBU|4_RTu8&n`A4P-V5 +S4_DWhn{~0U9aYzP>4v&Iuk0fxkE*tB0&QHt;+gNWYOw$+M*4A0ie|ki&dv9HnH38lwz|nJ7+7&{I_v +!7`nJwij8_?+K`O2S{|Ny0*7f#qFM*Fd#YcPj$63BwC&%>DQC(Lxx7kllwyi<1x%f1Yrw;A^nHYXA +vMF_^6FFn)%(6CJvQqamV82Vf@5CSqrH65;_}>y+3>Mk)e4Zu6VN#^@ +<6t;UxWfeDCP9N*8tv`v!)9FJR=|w|4PmpNZ;@Ff4Q#vf>LZMV*S2cx{D|u9at2SA*T76iup5y501C= +QQC?HSAKo6nKbpMz?&Rdn+xIZ+_w^>#K22OOx`+M{GuSLfOJVhccF<0s!dKZ?Tr8hA^-7mgY>M2W +;wH52^PJZ5HU=&7NxH?R}dh@0m(RRIjJ-ae9H&NqajRkhB`bpebJhqS;|AO)QimQ +9Mw-zLp5(q{5(NGuK?!;1h7U=wFg5rxTkob+ZZ+6}$KfcoJdq}pXRg99#y<11_2&lCHzBCg0&K-uf6% +-cIuwtm+VA(>c4xhhuaRh;X)6@KOUPZ7#Na(84(g-KBeV{^JIYeuDu#k8tZX`Pw375Bh@b0Ef;OUp)SSnf2i +9ro>GkUx$njJYVqN@9?C(y#jJ0VS+@H68_r&@erA0iQon05IcKfPRQyOTSNezf(QGLlR=X&E@ZU$sR2M;;s(p>K?gY44){`PVGK3g#af_(Oo +g*mz=7h6rYPY&D`)wDo{kdeVUepwY83Q{N0|J9q1k4Ret+4}X_!1fZ}j=UX7uAD`1z0jlHrek? +cvin+rz*7*I@t4UwinMaqM6IYe@ggUwia%(l7rt$p7ruMt<3W{CtfvjGe=EzHRe0HLz1?aHavE6x3#j +$bNzAm+J`~3U!|1FCgy@>i*!v{9*Es<@aG+(2gYZ#3i@q_>Z}9j3RKNe60?zjASHc1v@Dn4GkhVH#f<*?Uf%I6^(=> +Wgl9F1@@k7nW1_uNDI-(zkt)@V0cP2L8jx3FFKml^F{e(_pFjm#41U+1PMg~OxBCzJ4-vwi*JeM-%Z6oekYTdL> +MDD5p0BevbxEU(9I+>kgP#=TI3ljCD~>4Md<~k1vB?}2l%+}Gq1I)WL6wtK{n<+EeRyN1ipvK44T^Fe!SdJL +4>4jozTCn)z4fsjG!0_YZGTryS^YV#P&Mv8w7Jovr8RvWgKAs;5&SY@nWb>3_iYXsZ#-&tK>PK=eRNj +;KGllM3THUj3C*=!4h1n>(OBj6D*503(HMG4HLDH>GeST4uj%ly_#=PYJ}u25I=&5X=vu!82i3gP`Oe +Viu8WwNXqG;uX(27?|9Fi;yaMktPDQjGBe8&Nr71T?!qb3ZveEhQnE1oHIz^XJwwx)1H4o`TCRp4CXV +tUgS6VV*JECQS_%dQ-r;(Yd+NjZsXXuRiIk3N4GfAQfX6pKGeE!3+}f>i+4fa$#jxP-yT?h1jzG!gxp +92tKH*AHh3EYH_Qk`=Wlm?T;61hVlK^h0Q9F0VE6VWXxoH=!SGNp`k6;N5p|xQ4&W(TzDCJ|2iLbUbk +Xq#!*sL4<8S~^=z)T09?gr{Iz^5P5?=!iM~Ofj4y8X79{D{`W{t@W4_O)$^#_02KKBgGT>~gO4OORNN +OO3gXQ$U^2;sCpY0w7Re|U2?xP%`WmJxulr5RG=hD86GiSHZ;wQLW8`faFRHB{*SYyfZKIN<%xq0opC +iLeq2fhx`52atzX+kwF(^+Ig{*`P?Aj}krl>O7qRC#hxV@Kx4`8|e<&W)bhwUohRZyw%lt1g%Jf*k1` +^EZ~;G$QLn^KFI3J=FnJwurqu?jF3678?mGtl=phQw{l$K8Dt*!n`D`NES8(4wO<1_HQPv35jcI&U=G +9!|3v{^K^I@kVvB-wg;D@A++|S`Ok-K2sa_gb?1h=vlHh5@caj`vEjU56g36?c*wT8yB?1LIkK!EfB9c^$jE@qy7;V6rAHNtL|n`X^!CU0c3O-w|M!#6lL07h>EE +gX&N_ZXr_f+{dieBgI7*i3WnFDngJ(l0ZpumXeYV)-%D8Mk`!rUwuz}*zG@4i7pkRMbfS4u|RA}}Xz# +p>)1a0fz1RR6lMKec=2T^5%%kc<^qTVJe82lO^%upcZjnNm916{ulbUQ)$X0^s|v}5b)rkLk7eCHoDR +8heD=&PJi4-@Layv#o>vz7k?x(CdwWT{ZEHs*nu(S+%XMyGztv!(YFN^|H?XuXbZKM)?h#`#D1vGIN) +=LozkSUoClin=PvS+O9!yslU+?VAIg9MG_r331A{j$gC+e3HRFxFJsmjUg`)i3|etvAKsx8VfRO*ei8 +L8)$;A8~hm$nR2so%7KAGtC3%1pifL@pnv6V_$PI-1mQdJJuWQr=S)_8HAU>^2cE$@p1@n_>{V6*tFi +-s=`B7sBhoQ2j&L1Mm;x*&X$O!emOvon1p%P_fUn7}eo>Vdzy=AD?&x*3{<_+fb2EtVN@RKE5u%EEwK +x-qrt2S!^O;`rd>jf@AUz<{H;jw-4igOt^!W;QK2Mw-=n+TP;wIRQ6zL~r{e)k@M{qgwq^S6JsU*Em??(K^s`}M`2j$Zuv&3EtZ4=<0 +tKl=8~iF`Lb_fCXW^%8P`UBK3aQ_0@~61-98mpD%P>CvL9t~V=;43VK7zslDc23VXp=GQ+qTSEW%HQ> +xNHtTT$_;A0$L@zJBugleXt6}8$gW|Ic<@IK<(5(Q9{`!*lz5eNc7ps#12u~9jEHa#2c%b}b+1KO>Ft +P}qa`Xv#=^fMh2wcd$X2cl7+f6KlqJD?ERf4kH^~2D22H$0C>U=0WLi=lDmNUPoVx)UQ753t^q>Xg?~ix>Ep +Am*8%>WZ$D8U6V^d?F1VR#irhI{4<0Isu!=N35#N=TzPyj~55O6(0fY}gakNJMORqVxMswd~w1JGMfIfA{QR(g%gq?FNInpZhyV*)+P7q@SKy +e8vQ*Zr1Z$@ewVTf_BX6)CImDo$H{7ah83zzxz8N1lCrjNn|>TC$#WWHz@G`+#CKgyL~6G;9l;{F?PV +1SOe{0xY7J6MfX}CsV!TfF@QvqemE999a#hQp$&h1RyM(@>^=mgE4PWYWZq3|-ib4>@}}&sjr~69ktC +a3-cMw#LQe;LL60*p3 +*a!bamCZ=vYKxeIR@VFo0I93MLgVyk)e>^$=Y?0J&sJob(TC}Xb%#$R*sa(f&#;))0W^oozh&0&&pUl +mL6H%Q#DC6K8J&JmQ3?xz>we6AiT6pnJ})_sANnW?>?7-Ar95yU`FW2kf@$UT2^ZB8f7I&Q6%>Usrn) +}kA5~p{)K=%Ta}EFNu9qmr|PvcF)oq`>d*N$FhEU2WQR?z`}#!iyfSRP%hq<>z^EL70oy`*oM)9Mon! +)P(Q1v6GVL`V3Fx6fG`4YVdSkoC`1DM0Ev%M*b~81y)7V-qF{l(l3@m2x14=NQ^Qfy3HN47ZCzWQHpM{4w=Z;SIftGAC{RCWF?uWt%aNadMG2r0eO_rO3W61bbPooYah;&BL9Swl!S( +e0$eW%CmP+YymKZCOe!*Mt*(H??m{kI}cG)BXwB*4HwLKAMF+pxs`3y%Oq$(-7pDbBOX{8gIVQayUMx +pZ147RZ(L)?KQDv_3UaOA;G>2=I{LzjPp2ofe}Tk)eKKq`eg#Ej|nBsm3cxjMh40#G2k5U32oPRc~Hd +2L>^!H^*{n4k}{>yB*MX-Ef@o70^5%G2a&D<|7 +>i#w_h~XO9EfM24s7Z;^j}IewNtwNEKB1egb^t;MCzo3QyB*sLo8+k)`t6os?Lgl*jjfdfI}(_?-Bnk +q$U!9y>kN6i0v8?{^oj-Gv&fY(SU1scJ|-r)HHZ0C!!)P#`rlHMrkO?uHNm7eiJ%+t^32cI`RbVLAQn +wjXFcxE}rIYpn-{*{uRvacXEw47>CBFie4GF|TcnOLy(V +VjoA=108nP7$(J70MTVOAFu8vt~;{K%o#ui8*4SwBB1{yXfi3jD +G}R;?o_DN4q{|;QWdk1P<^H7-kM$02(oMlDhG2v9o>^>XQOJ+^FVQFhm)y3C9*UJ5G(f(lr&Q +?UP|!+@bNh_j;cCcg?>eD;(TmGqdJp& +ug;}fxsp7IsFbWAa@I{=m+y;09kDo((5WB<)4Tl0wSG4VkHP8v2aP1YulO3Fd0;wL4-PhV +}XnP}G_rj8VeBkaxqKK;KsA&+#pMQ~T1CoogG45=o{C!c@Q+HeWWPS7P+j1=?m|anp;5goAM#$`6F5r ++wpO>7U8lUg(wI0$+hYwPDvy3)Q_;%~uU^1aK&4H14a~Gaf3G5-b2G{A-j@e{HLSjn47V$A%LQz|rOd +N}nUX7dJZ~kdc>8t4M0js;KtdkeixE)(I_cy%1oYdBuZ+$59KGHuGsyNLIj+@E*p?uDjk56&%Qo&)pj +Y$sQUI2+FQ!A!Yo5*CC8Uk&)1r8znv^%c4w~I(2wVb&*Wz6}D3mc~40Qp`j~1#Vm{rBu)ltYgBqXj(} +{ij2`uv>?UnRGWSLdFY!=$*j8e@*ubI94WY^XM(YoS0Ja8+0X+A>Ee^qjglIySfj(sH(|C=z`KhC%vG +^DjYjn$vuX0AOvSzZB#{)HZnZU~`=aWDro_^!+S*gCE?S%sDE9)dNDBID^`_}6!kPGEMxBsIcIW!~!_ +^%WWz5_IwsxVOl)VK3RR$kLz!0?Fk5LkN(eVb=hW6O3pE8qVsiPPc +B^!w0SHquhn|)FLCk914vIKExUVLEV+6MZ>Mgy}^=W%|`a6NgLJnC?&oBzCp7QnMrXk4M-ks +ie<6LYC13cDNZIBSY%U_@h~p(M$0SG^9$Gkz@fzVMWGjTN|+;vdXv|affxhFW*kEuvO->G)6~o9v`@A +Z%#3l#F81L$J&8P+iOWYIYIV+ZB}OM-V{_v$WA&4`Snh&ll!pG>991wE!EiwTH31H^m|WM%p_?s;%M2 +aHgW00-k!=4ysj;>e9|+u7V?G`Ubc>UiEwtIXW$2d5Qm6pAx>6Gp3)@U4p(#0P&d1L_)gB{F3J#7-(E +TU~fRqTL2~0!K5jinE`L@w&yG=08y%$M<06ccj>b5a46azh%wq4v0=!vTCfWTB%36bT62?x+a{oc%G* +UGnHLWg8{V#PL24u8aVVIQ}4U#2ldR)Z82FDgmYSb~m|%YH(H&1t38W^D}kjfq^;d_=uxzV(P!( +`9M)_iPz9lm;Y+0Q~sz{@(!wo9JJY<0=pQ&1H$(VrxS!+P%httC|#+CHdMVm;9u1m +-CgQ&*mh!y7Pn7W5uPp1YpIup?C&)UScefkutcEEJnPLtrNj>sSehacq{H=F>5jRU8tfi$aXAcR%L9g +Ek=9y{BS347fV!+=SGz5)HyL+rx>$`-d794_pN=5GDTID$+!Q#A@By<(djIN^ ++qm+DZ1oN?+whK+j~}ICk&uRD;Pm3z1gDLaS(KGdX7^s)VPf+Ub8tjfqS2y}Q}V(!W^{-gOC1zAfUl= +m$ptO?^+-lQ&%p`Kyn_sS^E8UHviek<84 +H$^AR9rQ?n6_G7*<0{0oX(+S`_7-5#%<~k8)bTOQD>Ft^z!zh-;vo%okh8ni)o0^B$^o9GGWjH6+{0+ +Y|a#mbi#6z;-Fm*h+eeoSMe$YUz6#=$NoTVz3pFe8iOxkk>9WT+*Mc6_*4a<(l-*9bvOdM3Smew}>E2 +Q9(aXV@GAdoL6Yel1?ailE;Rp2n`FUV<19>GxyhMN{Q2hW`T&#E`@_wNz_oQ+oNF~kB+GJV!F#$N<~T +Ol=0H-^@od0(HhEt9$~vF8AX3WahzrLgd_g1Oih-2UCd_>rN>)>LLY7eYAXl?&HMP~be8m_`R^;1AX +Qw!jvuM~RzFy3>=C?PS6p-Xv|y_#Gt%hk5S$knNntB7MWV&ya+>5DciD0 +&{V5gp(=l~yzDb;D?=xn(#iuPlpUyLCT1ZZwX*EW-8$-c1MKBvA?hmyoxq~4$;+U+@u)0E5BY^ +AI7MIUe&fr_0~XwGGm3%;g!f^pG!rWw(&5lW*i4IksjXlo7+dv$)=APIOmCb9;j=ZP1|ZTmLXem!4^+$KN#?x*foLxk;H!1U5Z89-NaWuwwXFM5kkRWaxXQE`gn!g9wA(T%{ +9xQCM7}Fw)ItqmT5s2Z=yiwt}#iA!5+%G^KBgJ8=$D_R(-tW$}0h0v<0F-ZHRZ|tSfZU6PS~eowOh+2 +c#v?aU6;jAiqO4P>ok%bR-YMYnFDZ}A0tmQhd&Zebq_&qtlui@lT_qA{$ZYia470F{G97tyXfcYSys5 +4YgCRe#)(FX4ILk_$#yOd0(I}{_8ST_(J-FZFj0I~pFLpZB@gazOSDw{qWQuox=QB``l!%#*STREHdz +e|8n=Es{fg5sQttRQ8lN}`rmqa3(y17AvEm8oHL`oRBvrr@MYt*o9?Z4!W(M1UNNGonR$oX!3yoD_h? +g&oS1IVK~w-zPSeNZJxFBNh%sbHd@1;U!LIO2J?S@A)ICGNE4*5PJM7XE?$ZFqWkc<|&b098>mAbOL@ +7Z-5`xW}H9xKFax!IwUVJkLqdR_)f6DbSJ!ejkhqUagS$s|%lcD>F2Im-z|9#rpRO)TYTVHVcvfI9n3 +oQhEIB98KpoqdyH1M!Dc)eUn8ho1IFM!AR8k$<;J9p2DL?(B+CCpnQIgyKQ}SKp_|br~Q$l;T=FKwfV +TEVPZq}sY4&XHF8h%Dalkf-6*&>uJi{Xjy*?;7VP2~WAt8U>0tBO$D0M5O +DK0;@D(|HAmIkYqYkgGxC0zA=8H{D0kV<884A630MfMaiOA7nW9&mKsJ!-F?G@3V3W1>%2py*Q+r%a$ +i~yvPp*mCe?ziGLzufTxWJ`w5byjEeb+RxRYcH-|hM@Hsd4zD1qIXXuI8?uHPc2$Rb7_w{zD +3G3p(>)W5eEuoBU4n`5w7pwnXDF@OW2sA{_wX6?BEfF=}zva0h#>dao`8Djv^5Mq<@n8TbAyr>sVn1nv#Ae-IJu(eK_B})JEqHgCH4+Db2Ls)=5TomU`)RB!Jw1Dg3z>6b)+#zUq +2*>PJW)n~a25I+Ske)$NDOEP_n~4v75!cM*A0Ig7(i?TkhCkb*IIWzKz;-UVq%(>S1Jd2BD>%pS(n7$5SozRG<<3XIqUV +@oYZU=uZLumxVv;6BXuVwtxMiMk=?Zkw*IN}xv`HpJDgcPd3BmxEHYFd=48Qduxu@fH@CU0q|-{*SmcFdB>{`Y#9cjEDGDNF#C}++I +NPkf;=8o|R$&)V^HlEvn6RvaE&Gu?J)m0ahsj{-;cSYwTHHnywm%)>YH1%q&{|5~3-{%4NZ+Y}YIexg +3^1w4Tj#Waky1xM!j+3YGSzN7b{!vBN@KLBT+=0(T6ZB+kDC||+(lX=gIZ}xb5oizC3Y)&gQ!Rpb_NH +-JiPkz4sp~s51k77))>O_U9%zLcgfgfx$-S0MkEU@ClQCaF-gU30I~$utt7g>TN%fK_i0yIi?|JVrOQ +Fi^EGLSb9K*706T4@?vOWqzIM*j@_nRoi6HX~h~6-%F0=FfbscQ`aI8*sH?)@K!*Ffi5A|D)OQ +?S*^GgnTS^|oPZ0xKywF_7+6#(0o)&q}9_l!?UzEL2!gFuN*T;Ri7g2T2K%y_QdbWSypv)~o{ur$qC$Lxx{e^dv&&9uwTm4 +|v&N5qN=GkF&>*^&c0lYmS?cn2khe4;r^pQIWaQFy`ZL%u|F?T}af>4cn51?Pk^I?I#^XrQ=Ef9SyDXJ(0W$1Q5{K*2HLreA9J^Ee@t+Nlm$N+A!@EFTDQBux_VIv8S8G1<9L10Q&EVG2=x~H(41XGpn_kezw?<%hp7YQ +aCCJFUB?OdMsr7-5Eq7BOjYs6Xu5TAZkYp!9ifyIs@AgdfBE*k)SLII$tvrp^=G$JRI^_B-5D_dy!IF +-mL*+jbg8{P!^FC5YaI3PFu;_IA^U(JQm0APGGO8u|nA)M{(2++A{4!XQ*U{^^*@wPbBwoj +H&|Xdxq;+^UYWc_cew2}C^p@Y+fb3`ilzr+~nDmDS)IYhNoKJKzgAEzL{znP-IZAZWj=Z!Nn*|w3&3x +J|Y_^b^o!`o)4SBQeAQJS~=t-NrEGEPjfg_#}uBoBL1zLbgBkDby4^(j>qE9F*^SpWyuI!^Gc_u7&SIf#7z=@Y +gW{?o^Mb#m5Akvw6knsPPE{FBH39E7O&(PemHe@cilI8W~xhePXa&RI;YjejDWJWeTY4KTDtWr_-VHf9@EIU#%QJcxm1eEpqNM9Mpak&IfSBKf)MK8T^nFFxbb +BoPJwvEV$dEx#B9StKgstsC8CY1W^=Z3C6%4j-uucoeflX0h)I$UJ!9X(X3BS?7%T( +W@NE$(+sWu(PYNaZ59evKuxyCUt)ai_7W9I>Q;uD0f$4)e%ki|uCPu>v;?>Js6^qXpg=h; +bohhEBKc0;*^E6)>4JCPC|5nWT|u#$PGeRvBM-d4A6?>^Wm166nzRvP(^!D?>-v-hn)l%gxa#wqaP8L +j#JCD&SE#gBYy)Rjtev?V*!72IRjtNHuvV&DwXud2#Ji4NiHrzQZssEQE#eWOy$erStf$)xF3R(!8OC%vhOo_DAb^32ECHgIx +QokBR3=pJ9tw8*_JM6$UA +!7`5G{)-yvUOFbSd1AEjyd{$n8MX;x$0ASK%5JQYb(5~*bN&LJJNpD&>0-@_#WHzT8cu@|9*ifw +fza$;R-5@Av5qksv=(PQohihTrG*FX=V7mYW +;_2V0BtQ*yd8s1dWAsq)KrUBW0VqGp9Q;2}4ltl>*tSjPGS2M)Dt{B^bPz&(JPo1E*REL# +9IW8d2TVe6LH~$+B=k3Z2*0$HFsAxAuW=E`ybv~p@h!FwhjUG=73 +R0v`)^y!g82dnGkdc?Q!@8I38MX24oV8JsDwmtw7oVO@%#8T`y^6oDO}T0zK|&~ShSc|4lOg!3s;u-T5Vk1&l@C&Sn?ntU(A*8Zd2+1{D>;T$)3=FI@>P#95?79untA4qD>++1>d5iSgs?u}IHf#DJt6Y}l#*peLhIQ=VAqCrpGleI6d ++{RhrfO{bE<-=Az}boYn@k69H|4rm=HX>sa%rKB^hnIDvBZB&9Wh=4G}K&F$kFKOn#YiHnu^=YWI!;a +>Rg&O07ZQFQsT`s1KGM|@=)?2sI)==g@I6x?Zk`WLpXGBxVS7%nGn$KT3iNE)x~8|W{U|S!UGeDnUS< +3in?-;$Z-erH)!3{mrJUGbr$dZJvJz|a!GM?Lz}@>zOdwc>AKq(%51N;glI*8qdC<^)Nw0bZ8^CeMl@ +>feNxpEPlUKnNxh)r9l`x7VmybB-72Y#n=}Pe6dw&iv=6zq_F3zX%61`hOM!Sda6c#Xx(8VXfd_W41Wbe`>a-M&&P_E +@knC)kh<{-Niuvvm4wD`O~(z;`4MGMI`HQ3clQsk8Kd9G0fh`dqB#|Mjzow*Mr7Y+r&?`m;=9`iA5Lw +;=0$vQvk*Au*S^2PHPe>(E~9yeKC5DUXf$y5f3C0rgs!OE2YPWJ%+ByKYajM +O?06+NmoOpPQKWC!9Sk4Pet7`E}HE4;RfyLP*aR0VkIR~~lYWY?p20Z3n$upSSFalU>|QI{C2%_SF5B +xf9xiC=?K#g-b+hKae>a>0TP@4rwcF7n~x)NNf0$vxo8A4n8Vtx%?Hk|xk=?vKKGn$|{sHD{&1U6{~X +&K4Dyi3IW;u&n~^o)TFfMhm$1KNTwk`k4ySaB)vqfv%SV$X-H8T9Pp?s2SxXdem#}Sjv8fHR)BZEbRwq%e)hQb`2{`4Bk$r+9<_bJ2JV5 +gLNJ`e>mur?9FY^+u_NF*G^W#ePAJ%dzH>(8i$*tq2OM(1LIIaP)&T2ZM7=kG(O&9!X=>AT6*gse=SN +&1)fX2O}Xz%2Fi#MlDxIXU0?uvoxH>`CVF>bU@ICW&O-VKUxIoXs=c7bY%hXQXR;fq?$IaPx?qf2-#y +OGp7_gu>5V(?fo3+v_X8Vn60UMlxk0zl<9Iz@KI*;?Je^tpBm(x1siCQTCyin#6W2({V3MhDV+1WQK2 +In^ph$Ki^@hcFatQ<{6Z@CaCADko~um72e)G-F1E`ACI{R3WcOwgDv6#ZOp}Fx#SSHcfuWH2!h-9wrTCA}AES-<1{ae +g$s{3bwb!;CCK>YyED$H#uTATVV+yw{gZ#kCi^_%zH1M70H0KNPxH`|zz~c$P|ezUm0hjG=Bn<%AXzuXRDrE%3FNg=HzkVuD>&Smj-Sd5G~N>}N1A49H-`GNEDekK}Rno8SCq2z=&o^;`IO5a7kx6*L?;%BR;<@K}4}S{p!k +_P&#fy(BubU`|AC7u#aioqOww#9B@*P%C^);h#Xe#KIkI8h4|3;&3Or;lVN@?&x?O`4K-jnlO0POCO< +-vWRduMK}H62bAzNz2F>eNvP>GblxK~Y9pcw&qlzE3c!|jz!=N@ive^jFbH}iyYPPXg>)P|%!ZY +Xiu)Xi)wpWFJ^o;6b)8;=R%6OWam5!L8_&DwvGssG_In?Da=8hpko{0n|0Sh7H0p<3+*{@E^<6EsMo& +jlq_y{*7+e%N7O`Rd%|&?rQ+4rqH}2$ktgjk+r>cO-}vQAD-mwEUSLa21K9Wzd)py27&9GQOslH)~E?cXn%mi(2qOj!m?Fu89uqY$#_XK64MQ&=ev_m#@+^%0cf=BZEfEN^NomxQNMJZRqb?q}<2m-YJj|E1qSb +TAMflVurD`$+EfC3D5O^(E6@;1A}r|Wu^zx?Gd>RwU*bg|yZmq2M4b)0)zD_hKLjnqB6?m9T_6HXu6! +xCz(>JU~+6)S8M51^pOM%sg;%gd&x4~ng}i1nVYxC%8Q_GPxtddl8Om3}Fqoy1rc<)|MleDZ%ENxc0* +j$QbdhkFJPIjps68BSZucT3{;pYv^ST@hV7Pv4vz_SqOU*;qHE)B=gYUPXOz(D%pM7e2({0&5fac+Sh +U$n9DF88ypRs|j5u2x4D|uD)$?RW11{EJZ#P1j?B_+URF`$u8W{Fc|copPamW{{DG?G?a2)BmMNdcSm +ne-oE+z_}e3DVMgV*`qP_NM=#$Ve-CZw?~~{6|J2{vnp*4z7#q=k@*lr>^dG-_^y)~r{^9ub%j35(a8 +g4+0+LXJCyJz669#*SdbdiA_kQ30sDhc=MRlc=ccIBF7Ef&8dKNzUd8A1cqo9Jy643;C&L{6~Lsfoos +-Hd@e$O97K;-@leYNNN{GLA`KIU~Wi+|AfPJoLxxyXB+z7vl%Iesa((~`N5+|>SEv@bXkpKNROd9fzR +QPSJ^oH4a}ypSXE_7M!sO{q7W=Z_WisYpo)(sW(S9;NQOQWliORyQ|A<>VCWAM|}zB^a&q6!1OhpZ=f +c2md=e`04S%f23y*`y+h8-Dhj(XCmU|UpGto_x@8gq0{`Zn}_bhj6rl?6hHAX(@x=Hm-O0rSJ41wQsT +Z320PTuw%z==1ih-5%Uf;?_P%?YYbQ7!^b_DWX}=YKwi~HtI2x~XD6^&dmrzch-t6C#XzoiglRh&sbG +eg*X;XYV1)kbmlKCgn)W(PV832_s`&xoD4$ZDd0fD_3`f_{q8=ca(YmAa7>biiMt~LkcWGIDhB4^ +)Ug%jLwV9igaS}`U%&3!3joGS)%Dz4e^csVY0}U=kx5)9QE$p>4OwvQ}|Rv +O0P1he6BU0`V%VgBRGPWZ2GM{mM87^+$*M^j#mf6)5B+H8i2Hm^&08Uv|eTyG@k3$@>6?o1r`dlri93 +}{00o*=N$w6u;Yo!g{RclS +?RK5u#1@Z!gu=`A-?pwTPCC-J;@TR_T3TU96?z>Ux>)1BB65Aqh9;}lp%Y}6AL1@p1%s>pB1dXRael& +d0nQb}$%)hIX@{4h)ja8c7cNF-lXYS)>%Io4fn?g>wTN1khkE4|9@ueQ<4i>Hw~u9hkLV{*glP`j`;i +N_c4)8CXJ(C4JbAHDfn!dS3?3h-#4{k|cdhLG0x3n}zD8sRE$*n(eT7FdFg{d~Uj<)1a>q!vkIKPefX +A-+lotD_b% +=t<(zVDo3uJGrPMj8mxA{dNO4ls+d9_ghW6OWDbbY_xPQwj~Lk>w;MJq*@K&hn5u4HdEn;R|}-#nqEp +CCcVUL$zOZH4E^H(mFzQ6TNb!S{L!A#!2`Ysfq&^ezRY7H4Q#cmtiepA0pk-CQaCekLHa?=4=nnr;9Odq$^O8HMS%);Cq)eL`zUC#=nw{G +`f3^aBiI?xr*eRGAN}|nayV0Ls^pp4w^S7er9S-^PZgziEdM~>L^#*5*1_DCxK8>REUm!DsaXX5JHBa +w?FhAup13@4w784Dm98r)J3V-Uaq+v@j1a)0IGY;y1(Cp^_?4??K3H7MXb3jTM(%`xfBS^f3bj+^QRLxn8mxpt +%QWqPiUTDV<`J$NN!YImdWc1ea66+AG$Sl(KECRoVGe+M6p^@Fpbhil5d&F01H`+7YgB99?R=hWmMqA)) +MM@!qq@9(GOQ-TSx4ufGYRH#|3k0m$rJeDSio|wgU$PJ9`=X#YTE1f`@MG4{)Z2im(KJ2yyrrly>)E1{{P9z|ECUzPgrVk_my^)^ +h`-5g3-&jDZ+DveNDhfG-QB(mT$VHgBaHSZ6Mi;9pOs&`f!^eXVFr!(rUwylXiX(x{r*set;RE+Wy~B +v*PX5E)m^)g%Z}B^!Z$m*^-`qo+i6jyf82sPbo_?9jV1DSz}hhmm#F+{lSfnYz0sih_o@a&QjNR%gZF +-Me`X&@e>=LdW`NmNGFir-~MyfBf0=q{f;D`(B4m)dB^?Ffm-?31w@zX~4Y+ +C;##|i4d49?s^Z?nEQ_+2j`YBSUcdPn|CgBWWo6AL$EGJuVe$0Kh^o7JLN4`?Y{6ZD|@vy_%0q8#8hwm +OleV0Gcl$(-hNZY3S@?s;9UkDXyN7Lmwl2P;Y6BU2okwN3iWrZnN>u-Qa>U2j)@T%sM1U*_n4!id81E +dLY6bYY5MViHmJDN|hdkD_ef3sq%!54^VwO+V_l`98K+<1#Wx3s2gW;nWz|@f5g^f!ZPSR%a47PEFH+ +pP2fqErF0<4UE-%fG1FwZuMa?fR{Vhvwih8}t7AjG5*L5Z +>g;95u#vA)8A{Le1tR|~EzbHNqG{Jcfg0emPSnHY!g69e4e(~jso7(Bm628y(R$($d3<+}}V6NBsT4! +`rAktv{5xip;a{+!&(E6BShPOOX9dWJ6N}W=CFO|{{7Md#NVk@VF(a(@v2{&@ +?aSVkg1VIHX{URb>`1dkxo^)aG`MwfCA>4!kYO0%8B?n{N(|Uw{3kzvK0~s@5iHD{SP)#XEGg8gqY?c +S@9#bjECkamc>SL@ +W3be9UsVApr9STu@57@hD3G8FiQ$XrUg2TJ`7=E-GGClC(tkKTB_tBG0$zwEaAgc%x-VbmJYmV-g0WFi0CV3OmPrHV=4^pXX6UX#ckkE)D>%d-s*720P2z1Ny~Y +q-ywNEeqM}E>^Fyvbeyh(nXO$Ud2zv3h9^{BH}sx;{ErEhM_KP8YxBy|>z~wklyT?v|#OFR;+xN0bdEsF2+=2>eF(d+xgH-d35Ptp_@G64?S?K8Hl&QXKM +Sg_V9hy47C-`ZeuMEip^Xjh|m(e#S}=q^~U&xn!!6QGtUi`nnk^_;zb7F~3W5WgLBH@dx`iGBgS@7cd +#u2jUc637W8XGPqWf^i7PjBiJGE3Si8-s{&mvEhMX+A0GV?ryZF> +A(AIl6f}jGLZ`O9o54z58KN3cs!0ciDyKm-16Z1P%b!t5%!*-kN0c>5aPuTFlYk)d4T1*FPjdc#Og)s +dNad}Co^}LSqp=dezJl?W>ps$vk-%&)WiVaVf1><<7fr +yu_Fbx_r_B=MA7I)Sa|*05j=KuuRWM=D@ZV;0?kObu=7Jt`^I+`ESJg043*~BfNvIv-CE`t3UQOd6PG +B0!%wy_HQCyT`Mrh$1|yR&bM;Id;B^JC_SqR8hB6)@#KM&7FE3Z`xisQ#oNpBi?fKR~HqnySPe) +Hz5sSWkkUAW$l>p~KQvO}?2|2N#X6A@WcS$;enAnxWhS*+x$l`nn&|%}c|FPY%yS8I||{MXO+Y442_Q +k)uHuTe~Q-FLrS4)Zgl5ma6`2s@~(+^c5Bty1^U}(*HNbLC572-K8t#9754A{C)C-jr9*rPEBf-oCkxIOPYyXS@!)p5OD$i+jGO4&5?k+%fxI2T3#O|3-F#NxP6NsjXZMFP>8I9w_JfYk>YOI!ayPRJwn} +@gaY&%M}^xwIPMyEbRq_l9{j}McmH*{J~#xvB;v5i1(E#~0Pm>~K9pqUmE43G2g;|I5Bb +mRJAFFSQio-C?8=j$aAm0q(v1=o6tiVUW2x1P%8>HuuBZw#2DpYVABG_vu#>hHg{egP7+4GuguMELod0C<`9v5r%mimJl$ZfXDhqfD0SfFp)X}13Q +kW@DQw{ZS2FXHfvNjsKy~hCtst*b~Wgw|0Yz@!^<-3aYzRi-q0U6w4-XB1BM*+06DfBzRDU6zUn{P5D +Va8j*@|*I{Rk;%q)zqWoq7cWA~8}jm~8XyYpQ!Oks(ec!;j@(-#e02jD=(v*~{Mnw!tQE39^&&yZD_Y +M^{97job9RX)4MdwS2Sn>=nMVrW<*jgYAg5p9G81Q&;8>uSyO1vxKl{Wk!hEPwh#SB**0ig8e%D*P}f +P)Ob};I0+^#Z%;4KAo_#i#U)qlLnMg`Q?L)y2#5p2xP6qeoNH53YEwAyZBBl9f`tMSieJrnzU*!Sv`2 +KE2Sn2S=sxU4PDvm)LS})S6bqqJ~a#^IW&TuWrr5mNBle0QEpLIG54ckomDmU9NFCAJ=+i$IRSCaRB%FbK$*XjHSY|DNxnYRTe(Hf1B)Sc +;Ec@NFghQ$N8#i(P|$Nt*9uQJgpF`r{hyv_aqWbA(BnF?gY9k$@?GJSp8jF>eP>NieYQvH|8Q?CGgyr3aUDI13?|E)+#EWE*aIVYWe{P}K6M|(IwvofPXp9r(S`M{&^RabBV%Jd%EMy~N +@mUz3IkZ2;)QvbxCWAG-S5UfP_n`m}Pr2!tx%ZlZcf!U`+u3eD-Kp?FZ%D?}6D8FR&)NiHR}PvMK^}& +^^K>3{q_^yLEv4Es_DS>D_Kq!h!bZ@zM%3Y%Z;dE4pR`7^3$pLC?}AOfCl5sGf~sR(f*?86!MMJP{s| +GlEmNu==ZS`=9WlTyi^s3i^X>rTs6XBsV^jMVs-4Pi?u_YZY&Qw51JB{??CCb)^$O1Oh4@UkZqWj7EI +#=&2f=Wx2xH_ss;HziE*ph3_WSHT!l^x4SC0%B6B18p;MN^p=i~_{KR?0oQiF`=->^yY>IgiRgl(GmT +JBK7j8(aHk?ZE0y4SHg+*qh(qlsMJPPY`PdxZp9osNNk+G%lRbNlk$y>mT8d^Yp!$1@2!W6{IceFo@6 +4?EIPzy2;Nc?9d*5fKAzRQEVREfa12=;(zn?j4 +mp>6H^9eVAr!hs~ExIuIZ;3DDSNK4s2xBLUlWNjas>Y>-Zr`o^}_;Jeogs2(6vDK2Yx12?&#qhh4)qX +O*wKz95E;5f^RHT<=dEbKY$vfj`x>37x54bDP>}T5FbRA#e1UBZ<=H})!ThKRri-)R2#Y=P~-~}QG|fyew68Sb$zLnVI1K^ZiK+H|9l%;{xL((VQP#t(ZxOW5Q +!>Hq?HudrEa|Cp%9=6j%-B!M(=_N==ZNU*(sTrun8l_ZE%vaYL?+qRs8n|g-zztT|D +mqQYPUv0Z#P+F}d8L}qP)!`qV&G6D&3C>KB7pw=x{yc{imNMD%=>L~}DNl|~oOnqkWt5EWI?X_3aWIj5aoI4QP$7c=JP`1Ub=>y9)96Za6wGLV +@GoOVe}5+#bVO|elma3DPmN2bq+nQUwKu+lJP<8&yOVefhyNtpIMw~(ovF>G~hl6y2z-H*Ax>)u=S4q +ipsKlb2g-P>(}BR_Jri~0H>&ABWIwlW&H0pAYWq};W~V4L*qbPXRXAEh_xCLZjyFHI(|r3E7!HT8AE4{@DfD=01)?7U<=-}W$D9K +SkV(71xrNZ0acpv-GawRj`BQilEiquJD3Fxs?*5o)1d*k)Bk93sO~VM(mi-wQ%$&*Vjq6G^d~iJJCt8 +wr0udV?S|R40gPEEPR{rVu{}~}CJ5cLe2({2k6#{rfAsB}lgZ2DckiRH+T$YcD0#y$oQo=rM@XoPI*@ +$G`_q=(c2i3nLHdLt(A_JbPK{qSr33WzcFoJ#qwbgn8TRncNjnF_8xyr5E0Ed7^adHP*f`XU5~}@96{ +ReY9sUEJJGM%3Jyu}^Qusk3t0*`5PU73K{i&x~y6X0a>>!ohesikCEuzpJM1dbB46As>KJ1za4}4I0U +_6Ty^tfYR(vYM6mt?Ma3V@%qhK%EDdfe)!OMABI{1ee9n=xw6cQ==WOKu)$+AW}=(%othQ@LA>Na2=& +IS?lG^S?*Ujtt6IvKIwi4qG(ZL`t_qbRtFMJi~^`Nb)+9yI%cZeEirLx=g)?sKL-yN(#He6gM9&uPwU +FI+LbF{7h~Vlz0lO%Cfjhg=Qr}k|1T5H3izDmS0c_HvuV^<}C7?tW*YokufdU`;M_wEh@XPX&Hi)uAL +C^PA2Z|L=&lLv^cp#F#mB=+++(1C}Kz{sIZ<%LD7pK0E5DqL$z%ai+oZxc7>G@gM^ +2VKzg#gB+z3>;lRwD+~6gm!p#(DNQU|CH`FF8L=PLdSI +>l<)dVqk9)j>Ni?=ng0bde|E!E%?T%*)l4%$uu-6Ijy~eCGr0CC{^eDuzA45Uis%0egt@cKJT#!e=y3 +teJH_2_)jNA;m5>>Ow56fU!oNkxP@dB24jl&1N{arOvBqRHVcdsjA)OWqtoKw8@S!yFXbQ;b184_zG~ +X%lcjagsqFCO3Y2bOe$X3cJ&3^PMdr}tEliwxhV7N6K4h8ioGal`*x_Un1sV;X4xE03Vr7%oz-#$&Sr&ykS+`;g3uHgpp*y~{Ebe}hHk?|Htn5I9K$)) +vHADd?E8rvoO~mFE(q&4;k4`gV!<~}Nu>}Hn??aJmPodkbGq=2E_Wa0d&cIEw5(ZN&) +qakGk`X5jH+oQ=LXArKWncfY~A>lfPt*)#KqtZZZmH(D#*+=r>~Iv8mrx}1Dk6E%Pi*JUkkBhf>ke#s +p+?QPSEIeEjLVZ%>e5>FJo|M_Uw25XOR(ESU0uQ@PCGZ^5Dk6mZ}g1In8-y*i3P82Y-^1HCu|W(z-2UVAAUzvC +94aU`pf@HI_4WPH+jqxrUdLYj!}zOzdkKsR`jsNj~$3q42!Q``t0aQdv1|sqL7H?hRz@8UxUcGu +Afj+YDz4_zY=P&+z^gf1zQ`_prj#g*3)vGrzzx%e0&D)2A4=Mb2_`snO?{dd$Km5kbKFuZ>e0A~%+^J +ul{-1-hheK7y=>Q)A7TZtg>1vD5Da<@lS|Z{ +8lgc>eBav}a~$1NzYVc>)}2?cY2Nz}~O{6EEq@o4h19A6_m#$66Kz20`)BNOoI(c~^8_sm@9X=tLISj +0Z!x&y4>>k3x8}nV5ih1qTX7wA%FdSa3%aK)I&fShFb2*c(MqennWkmq)FG@8r4q<~O4$p=FGUPtmua +2c9Z4d7G1#K$m6Fr9^{4@8jv`%^4QHz^mdpkd&GaheLVM2PT1}9IN3F4{V@au?YLbY8zuyTfRrAV>F;D +Wo6_{i-or-94DBT!FD0!1uQZ4Xy>27@8aq*BO9R>OkQ_4QQU1F +M$-)H!bJ85$?jBzb|_erm==S@>;0sTq)z*~=H(wAaovekp+A4ElkG)@}ob_w0IsVejLo{!@=?q{B!kt +US59z7#j6dFf;%^HV@J{(>?#sMG@ah*r3U9CTb@h9|QW#1;{Jd@-#VU75+k-8Lei7iE&7;bKEWPfeWfnA(lEReg;@Fi7u~s1OuQR?SnH;W3+SnXL +x;)oeaDS56D|K#hS7T1LbT8f_m0nZEjJMUV91SHs}hIMSBa{mau2w<$;)VS_^y+@KW_iD@(ZDguVl^5 +uuq6vQfO@o(H@*VS&!cBzzIQ_teZJ63qbW~h_^k`|E-C(6ncU`(As^GG$5yT>moj7ws#HP!$*49b4U0 +p3(tlZNneNPpw(lT(`F6Ol)rp6N?T&7cSXWuG~bLM)<0L$J0$b=3cKdPqBOI`!`4nohZ&<_sRN+DXpj +6;)JS#Mwx~m&*yIuoO1{Y_yW-gBrndJDNL$lH~^L!jk2&PboHn1{Ph+(E5bEY~73OK_y@Tcv@J!w{WX +0)62Trtf)e$W;i1I(7kd*8eBc6!2(gIeg3wa7#NR`C*s6HHImYU1UshI +W%5YS=nxD49{ERrK{$m`z^57aJhQ`|9?Qi5fP$>g3PgOeh5hwBkr+cVJU70~0~phUD{CFOQaf@)lYy` +7@2T6Z6B#Unj4g|JR$hBU?x<^0o?cMr#=w8C&V?s(;+jcwH)I?C1x8pS}q7eeYD0;lyKOY$s;arUUsp +kbeW?i<>3d@$HwOk<1#K$e(@#gLY_ONh6rKK@P&OU;IY8*1rv3N2{%O5x@?%?uV)qYd7Ecu8<&Ynidg +NWqtR6T8fcDxuyn31Q@r4AkH3qVPAK>@WpDad~nmiTUorLOHwAt|E+a3tbH1WB)FsqjJ`uoI=gZxn-> +=sIl4}Q2m=z4F%eCSxskERc&KG0Nad4oLqJ&Sji(K;^f~Io%kW>a|Kh&@pohm$@h3 +pMwUJr;P4V|f=I7D>1V>4BM^E+k{!^YVB!Il~OYG<|HtE{=2Ems{@yg_@{Gsm7p2N&$X$iwS=>;D=(r +@XB`jP>D|2{N&MtcjtIpn+FF9B1EY!o-IIQ{f7c!gcB?wysa=8^imJ4q{z*#)nlncC3iXu)}{#k4#m^w +|8L6PR^h-@!@+NA-OZE46T3?K$gL<4Ldv(b!!4~KyUAtNJovKH9upH_MeUQqUmJHrm`OTeM|zb)A(nj +R>9Vs9NI_jz2T_MVQ4W-{na{Fi#67v2=CRc$z+p~=0DQY$`1sWSkfh!UL;z)LQ(*|uxs-+phSEMNsqP +wBVx()WQtRx|<)v2ZTPQF^ +=8G>LJJEsn#R4`L)-}D(7npdW-nUz3hFgRUpYRt}*+Pq>xi6`}c_mA{Dak;&%GP=uYl6@S2rLCc-T}0 +9;rwvt(5-K*>)Xp9g4s}zBepHpCd!j;BuL&>;@%<-(O)c*OH?h%>LUIq1qac{nJEgZz(V-;u53-QrdS +TLQVua)E?-{Ty@YF!h|uv0LeVW~VCfu>|MftdEAZ3*yWW~VCxgEW^q+?mF@B!ophVk5r-ZDyf4G-030 +d8!Qk5outv1BZsKQA#p95fEp#^2t%wbjQHB1>p^u5=QOEL%-vkl&;g@t{kDp|wD9AH4iU;*=G@;H5*! +Xe~Kvkf4I15oB%&wp85*0ea4rAKq^)gq6Lz434{iXT%m;=e +90rU+oP(W=yMue|X5OJbcMk@x4TG+JtyexRHClPR{wU>Jnq+)!c`$U_mDIXZf#rNrHgzBNM^A>QWY^e +{)VUKAgpFtlwQQW;tD-^gOVa<|3_H2XDd7kx_7Py|^M*J@+cn%WHxbCs6AyRB2iLLOlX<=(6XhqZw|V +PR7JR<61vSm^4QC#vQPG+jJf=%%ghB4rO?#OP&&wlckzx;(5#+^+Ob>pCRaBC(eM=Zy?w +y^T_rw-_@UI;g4htd}g%%K_%ULKGB%$GVXgYk{I9a4Ol#je^pdm8d452J$OeA#len=*$sc*?ire~Ym} +)rIyZH6n|<;1n);gKIfuFjLZ6HgNjslT+=PaL2*-pu98wV&(`az*GjdF;byc(@M67CDy=<9ZehZA)or +IF${8^Izx*sX4?S;(PhM-DNN%n@fx|=l@P;4o~2ENB-IW!Lc#I@{Mk{nEhUnnHl8b&#lYwl8u`z@X19y_ihHP7VRmxbqW+6z%aGFf2GA +Lc3Aet8gjCH2Ic-Eg5mRHx89Rfo?lFidyyWGHW!QOFZ6-nT`zEq|lb16wAqDhMW-*Sn1v*%@{`i+$Gt +>>;vBOQ2>ZGN8X6|zq$l<)xlf3=lpLVx#G{{2{$%Z4?=-U+=R{~q6MTABw{WRt>=k*Y%xzKV_urf0~&%6QTv>Y+6oPGGF=xu@9=X +!s}<{=ZkWZIAJ2Lrt`RvpC^c$|9{QF+nuaxi;TNCmU*@Q|tvQo%Q=(RMSyJxSYID9QX7mclh!hx^w#t +hJoC%wI(tZ05Oup>S6Fn&exOD*NMR0x~nZ;cmAG>kLEB`Q#8K3nB8=6vIEH@QZ-*jd_D0 +sT~{;p(;nhd5TqBA)62aMdD;N|4Ijdmoej&sVs^J7p?oJVN%QNd6|_)!Sbm_eNq#RNgmD3NQ(>9SRB2u-} +pbV8PGHB)91pRVUd0iZuLh>53JwuFwDWTOa2WE!SR?`3ZlZLm$;gKyUW$3Th#uND?XinfU@lD+5iesr +uNA*Do*TBwIi<+NVYDGqo#)vKh94?dZ2Bn{1hY1xj{$)-+>CQrSbp8iOWsdW%%AgTHwj9sA7w;)9h#K +C55QVqTGlolR$g8!A9ztdK{f(yUdZC))IR{MZ}-`!%J#|zJwUZau}iR5&!B3o#rcqXaU@L!U&&Fob)F +8w~T`PF&3S>|Zu9F&n#hLiz~Wje<+iMD**z8HoK3g#u66B%v8&<>6*z|faA(0!YEot1J8>t#VnA1WXu +sj#RnE@!+lr3`VU;BW&*97iAcwP3UHJ-L +#XJty5H7g+VTg-e%r>2zLu4Q-fRUW@j(DBHz0Lk1$%(;{+zV`^Tg6?6fD3RA14B|yLh&|Z-51&NM6kU +>b8^dud;|K5HqaIJo)fqDy{3}A6SJ`K6ilFg^GKJ$~9jnu!43RGs6fNg`3QVN1K`zUx<^-Ff%x?-d7A +S8O0y;1qHA!+f*tytcv!YzM*_uRL7(vv;+Nq%H>PfS9nt6x1hP((=cVi@ub-1op6H4WY83F)d1M|L=- +BH$n#D@-3jP8BERm7eVu|7oOSh*mW0W|1)rQOixt=1F20h5ebHlnaEJpEIpw@Z&evi%9EHh +kjph0ge3q<&+~$OAqj3>^aj$p0o|_ay%E(kn|vZZuSnV*7ezy#$*rpZXo`}|*)jWh!?_}S1v+~kshm( +G`wn$f!#+u{6{LX%ScayAFs06JVYDCK*RQ6{GWRtL_(I4fE;STZ--7UjcIcAg2MLw982+DKGIzwbOadN +)P^PIic~e67AT&)+}iRXX}#NB=9V4=_0WFc_Ut +af1)@^a17D4NgZNhG)ZGw=+`|b>yB_J&EVX%o7rNlQ0lGx+nb@90C3*I-x3)-SQ6vuI@H7usx!)aG4b +g)*tJX=7P>|`i^Ew|Ne#D!|%f3f15+N9b0(RXmCdWXDLS&9O%WY$cE+dtd-5s68F1R~`&WV8@TEh1iRa_9R@Mtn!aje}ey(7^< +^^8Qw2b>1Fx~s`WIX=x^ux2>$hM5WYyNa$E(1hyU&Xx)`G=7A4a}?TPuHgEC>g~pp3*StqtP#?oj*hKbRkT9xxcY_V84q_OdxG+eY3=0Cd +QAz+lmkg~;M&=*r?bAV?8-<5EB76fv5IJZ-XZaVloR3jyysKhjdh%4SwO6gR=DF +;QF@Tf-`2qE(&XNVXdJp%|TP_p~{ZVHgg<(dO>&BsZgD=s4*C7ke8eBS8$b@DQWCfOSyJqLk(=vbD6yE-P8ih_`i80CmkT&P7EP=!eo{c>qf413=3hHAM9)RUFjXq9n+VbZvEP6b6X0RRsk(RGX=@0S$YYUQA@P*zu*m^gOe +NW@X`7`iZU=CDfjT<11~Z~qr<@i +@?s?c+!_5`x_WzUV*`HJ&lV?q=tMC@>Q-{?aBVDhLiAB}ig>D>sZ#NA#WjV|QeYPm{_X)Kcg3A{j?oZ +CFT?zL{QGoucovMDsKOl1I*0E86H|En+e|-f-+=|HYuAZ}4ircoM81A{xoqF06n3qj*$Bux$vB4X{-{ +rhr{(;hx;R+yeLufGx(#|FV^rse#R3revM8CCVEjetd?Rrzb|J{#EH7L_-72aB=7N-eGg>a6NF#06T4 +@hr7m{p^9y}Qhf +pSDprx6V&Pe>`XGqj +z~%-^QMp1(5dLM(I{^6sPj8afZ{8;_o`3so^8Qc9?~?CczkKuJyH`iA-ygk9ULC#v)0>ySCrPXwCNlg +?E0rXiY)YH3KMKh)7*jN{Kg_&uN3(Fcoc~~F-W$5FC9VBmEQA;lKVPy9v1ZBN?x(VqzC9fQN~lFEGh}K4Lo4SudZA&99f8OB#^*chMOuZ%_C*I(9Wc@~y%iB4?YOf5v{J8c4>Qr6$LE&AE= +ocsL^6PSSQ{yg8_wT3lqusbzdBm!&o8wiYxD`JeTbhf+%4_#bOMqelererB>NtN+*F>)BTl=~N4x?FXkppk8igCbK*mgAVJHDBL=0R|>$Icb&|UBiUdORfoL(%%#~N}-_+M2IJtz=Bp||*s!Yd!?Sa*Y-nzBI7{Gc#H_3v<4lga6mL&i}1k<7rmmx`|xK)ZZ(uCM*$cv&pZO +zo13jKYaHxUD*$vZZ)xUbj(gWR;m28IE({qPo)>B+nAPEOvuRqbVpzcJVilOz>F$-AX*E(i@&K#J%ilb1&nxb=l0~bjnwwn!owPgY&uzS!xmkvS`@ +?+VG@n8wN?usl|SR#SfCriVb~DPPL5ocHn?H+VUFjPg=Dd2o)?N-n+~!75}221HS>jTh&=z0MRlN0Ii +U?pSJW100K3!pa?k66VNon8d=Xr}oYDsCdy0-KcsFI$^9wna3Vp*zpcI+Ke}iSB(G$pGXYN$k +xCC6r@7^%Dj9lj +q|Wy7x9wqCg%>i`A-Fh;i5UDpkTkj<=DEf%&`DkK9W2Co)|=fN>OH +)$gt=6qBzf4z~?g(?_@q`vKzeMm0*~*V=DTNufO77WY=Gw_9xP&e@50Y`r9%+6E2BonmlV)>LH89&it +{Xn{Bw)sDxwX^cX-xFFY*I38qy2>Z-gF2b#GOb*5Z`H~bbp)%Ds)int;c)bp@G7cG*iL0<_Ot5MPVt+CL2yiea^W;BP>P=>!8F=duz)J>g~G +tQdeit)Pt6-@?hwZ3|)9dHR*bG+b?+lM}RUJ?E*-L7CvhZj9rmYP2O0zkV0vC1*8k93IQ2oZ#2hIvkF +DAg2#<-&;&3HZ^7n5ZSgC$P%xe9w)8Wo=c`VC2M-6!EESkRjR8~N$7G)fY>8iriMC*camn*-Ge_t~ +&+H4d^ztUYM6*m?>XIN_BIIf$sgkP)h>@6aWAK2mtey7DxJ8ag34#007Sm001BW003}la4%nWWo~3|a +xZXlZ)b94b8|0WUukY>bYEXCaCxm(TXUjF6n^(toSHm{S>l*HZf&N9C@NJ5S-?!q6Gfmky#bo-ZjJu? +J>4LpiP@d1^&!H!eCIn?a|L5o?Kxe)NHEd?+>LJUU`82VGXYNo70D|V@W-}({Jt&{nh#S}eCu8HuHcd +If(k)d36jA^5ED|wGofG^UEz09W{^=KIep$p0`djH1Y60sgcDdXjs|i0iF-`lkG(i&J|3D*MkkNV?DSwO#J|n +Ebk|TkM`KHToXwL_Bb*T;qZhWW8VwyKbMGxHZZXk)=bd|v}^OKvYJ~_=ws9Xa|@Slq;i-B{sLS-RJ36 +k+8Dx$Eai;#L&Bknem2qz6l=>OkH?Y3uK}>*Z~${VQJjyX(NWc-iosV;&`=@8&2XFXi+gPadx*<%}isEvOFiLM1g26$ln`MYq +LZWNegmNsppL3GO5)?g2UaYQbO}uD)udukQw2;7N6tvdc8QtEmUNX-aYhhhj)FHrg%Z$CD{C3pS!i=mib>$z&h9LRMgzJQ_1%6$>zNx1MPa~jyhzMkd2%}T6 +kO`Nu6sS?0jlrq9)|^d~0x-NXeVr4qk( +9_G|1My0!&CqYemNDM8IzsN-bxdr&NVx%w(mlQ`Y?4=cJfopvr}6`QIAW>wfNdN(rw97OA-fxOPS#C4Cc5-RSb@>Y2Q>2kKJSD~4MM*L4_9@c*Eamg~W1sK34pGP#I +{Zz(C?4gKLRDEF$V8M4HDF9IE!^f6LFOXJq;&e_+tv=_;>^|%C@?2NWQHyv;jMuUG@>kFg3W|AF7TOo +C~w@f)sLCwA!?G#gww6gsV3nTgd{3oTIHg$t(XP3z?C6$C|UlE&g#!nrO7f5~n=SBPnP)h>@6aWAK2m +tey7Dodn?<7V9005H;000{R003}la4%nWWo~3|axZXlZ)b94b8|0ZVR9~Td9_vBZrer>eb-kEVi=YLN +_E_qB4~oHDM}(hkt#{q2m(W(#ig_@MY2oMwt#$q(<|Bn3HsW8K>sOU(%D^-y3}q{6cJz#cXrO1GsB(b +5%jt}Sfn9Kmd~IpqTXl1(`p@oo@N`)ma78Viw>NfK0SjGOZhU*;ez5u@HNZf^BeW}#d006xW7o(FIq< +ko>IPMdCt-ViWJJ6YM3P3Xt2gq5!xULA!K>M*>zb^C{{?8r%`bma0*e%F<^r{S;@0Br*O-P6`)txv@9 +T^6cDkZoL+BW$%CYzp#~XGZ&*k}S?MIjFm;^^b6^bM3Gs0K1c*J5L1gBS9Tx_sr(49Fct9)*5aklvHw_P|E=_+7t}!AmA{+!E- +Im(ct=Yh|M-pdFrk06Gws>%cNHH;7eT)urZd#`QQYIgozHNA3A1T0gz_>7MAH1=k+0k`wfMt?%%YdQd +A``J+f;TmElUN#xb`9OvkfDA;gzng$@#PHJFa`!>LPkP{E1}g=R5d2P=U`SBYx8E7FKQUN&IByS6S86 +E8JL3jM1Zk>DA>~wXP`V+s3x`$r2D30i+D`zyF{q4jge)J3|lt@)RFPN<6_{3j}sou#~hGGRD1bRM&U@*vJzRb;;onDTVVX` +WZ^6^-$r<@N3*M_imt*d0p{x`=~3hx359cQ>?#r1Pu=_`78xj=^*I^h_?-xDzZXI!;ccBQK+f-HG*an +x7>ix7Pt$6>uH!dB$lK1h2Q=E%Y@gFI{KFW*#vd0THX5_3}t9S2%3*Magp<&FA3rlD4Ejq!E-^ +7!SW+*90`2$23{WQdm;RkiM#|3v!XwbvHPrrh)B1di$KM2C{9BjINi*a@j;-@pXhOu6sbYC!mh +p=}mV}S`*&%Q^r@TgVZrg)XVFCm9nJ$s#2&a%=TSrLZqhh>})Dht)V;osr{>M4^`9D0c(roo#yE2tAH +=@8z7D#{#7q*_dMb0UC^ZHgvZAZo~4J5(t{`I{rzwIXX*Xh`;$h<5S^&Q`=-PXK`!L%NULNW@V)*0kn +fMb@#%~&;t%9|_vZoMyEj`tGg)xD#zqA3ey_4skkcIF+gP?HRQ#mOkIMX@%=gNCr_8s?yiw-nR4=gY7_TBsm2^Qj{yxHUU|3MS2%OQ5af_vWdu|KvKKeW7{Mx&_hw6ZQd_W(xGIpvu +M#n5FI=cXTF~qlRSg-$LFxog{rqNpmpW>bH5S +$lr|uB!1y@4pGo5WJLTudG$N2B)F5GDMN)E`&Wwl^FB7fI?Yk)OG75xE+#NUAo)cNGP?zf;;4CTGMDN +;a0gF;Hr@@st~k!W+@O|6~U$j(5g+MKK&Q%xgt1FD9 ++sytFjJMP*Na|%42iYt;)U>ufNddVhq0*?sC??*tANmoQxVxDF&VLXZnTW}z842a4|A{gaJb;ZOSGCC +s}B2ok)-HAGh;?;yDvku1=%b20a2@mNMDHb$~=D0vESj@!hPJGHlLOCBJ1tclZOPUDab5HY`uL}w>BN +s7+X__GuNnQhA(uk2bMAI3KM2HN>H$+5f!s&M_WWySmkOi4}8(9ZEeEP2DMDP?!v~keZ3Qvt(SIS9~SN2diKIU0nsv2` +4EREh8Y3-q4Co9}>_E>jiuxO#)syYaQO_f`V2d~B5Y=);)cuzNa5dc1Wku`3_=)u`uoQ|{M3h^`|z$0@B8qf55M%`*TLuuyQuHgD_QqV^edzL5{1dVs)xtYb9fr!w +c-xdhi2gMk!v*i&l#PlzgIt;#=F +nWIMt1ONa|3jhEg0001RX>c!Jc4cm4Z*nhia&KpHWpi^cXk~10WpZ;aaCyB}(Qe{66n)QET(u8CH$t6 +C`!ZT)*98O7hNKgRR-+vWh2Vf^LV|3kw12DCM$LaL;if`7RXv_PD$KW4TU5-c8H(C+E_+ggY+RLMc%epi8I}cOgYS7uMxMWcZ&H3s?xHrI=TmgI +*z-Dl@%JB!{e&81Rfdn@Vm<#bGP-3UJi?mz9Q$b3nw3OFn;wrA!LV7cOjM`6w2AfqaR^9}da9eB?-!9 +;zuyEmCe1u&SG5s{5(Uh9?q40ZE=4q~NM+%ZkSoSU8LyNJPP7a2JL5-hd9^f-ro(01^yr5Shl~FoJ={ +`aba{42bUoq9PK+9%V@N;KgHz=!is!2oZ#IN9v&OPX}HwvN&&Y=X)q}#6vhliV2PSV;ms2p6|t9toYE +21IkzzDIf@e-qRokHa0YkylyG@9=Y`?48sVSNbm*N9qoI>cQNUR_G1?r_IHTrhXJFXr^tpeFd!2$GHF +B>T0feq#w2DTszz8FoBFY-VHkxI@Iz+OhAE>cL1JRS*gs5|xrn2fUSzT+fk~(zdtqSWQ8$s(X5-y +6}OPYpD*@o^Yo;FQ$>7f9qWqZv-)U6VpfiYx)$aoWb4USK9R2O41$CdBd%UoJ$~aWYx1VK&PuT}eKhf +mm-!sd1-?LgQ$WYTP-mMOB4J%LSk1LUWnq%5j`A?w47A8ZngaLF?<&hxuQ>-~5`l95xOgPRy)Yh)VNB +DR_{`GZ9asXqWSEJk_0#4&b%IJwHn;sn8)k7@`n&?8Jg+n3X7mp3T~d=NTH1E0rvHFDMH%<<-@9blg( +aMCMWzI--4)a=`#Q-2=}7bA(_(ceWJ^G-(g6591=+%N^+t@%0P>>N}^2vmu$tc~_`J>*sdoCB;6ZQTo +dObJ;~|H#+VDFBZL4%LPN-JBW0gpJB};&%+&a&hkpF+MVMfY)w1s6=*j5j7sNrGt66X)$H?&kQ75yH~ +&_tI_+J|sjBAi3#9KT=dh~lYUwy40jKX*uC@*_1m-g?bY2C({Rk|CA~0DUi^>tsm0DP( +0^)_v)gx;F%FGLb9^c0#aSzOO0D%(+9U1H))`{kUH|H)=c3^6leF{uj8FN%Q2uLIzhh6I>d0HF?>OJi +bb)0Ks_qu +xch*i1fv?)^%J}0Ae>JlC*QLVARGFdnGWZi1JAC8KqgYD +~%^EXgS0|XQR000O8^OY7yiZk0@{sI61Jp}*&9{>OVaA|NaUv_0~WN&gWaB^>Fa%FRKFLQ8dZf<3AE^ +v8`Q_YUsHW0q+DF#^-UKd)o&8Y~Qpj?@@3CNNo(z^(fz|dNhO;i>IQrgV|eTJY-4tbFz1)Ah#@+28jw +s&)j4jgf2zMrAQ6FB?%4A#0(_2vG}qLlkLlL)f8Ii7~GWD3ooDy6Rd9?H0+bF58>jNGP?zhFj!mI@4$ +?;YPJvz^se9YoU}95V4g;UfsgRy{sE9=?3>6^%+d_Tj7KqHa}Feq0Z|!A1fv|OE}57?My +Di0M2aA!yQ5B`csXXt)Z^HE5i=CI!$UejiaE`q879a%iLS#6+AtFi>PMc#wFhaLLeFAPBUGK{*Y2 +niYy83IsL)Avp^@_1I_Rd=EU<(zW)%TASjLA!D>}@ZD-_a1!~u5(?VA(yft!FsaBf2viru-q0Z`3)mY +o7x3a?j%pR(j21|4GO4UIStgGBw;Ek$lX-@A-;gMwcC;)tR(%O6@;V}#bKGAG*D=qF%2WNv21}|Q?^> +4TQG8p=nEnbJ!x-%9p&tnj#lY!3{vV^WF@>ZT&S(SSQ_bBXhsgbG+`3io5O4hz-)XNQzoj!Tv{NArWS +1*UhsTN8e2HVHI($V_!!Pj^HImch$eeA=BKD-~iJkrdyu77~%-yZp<5C8Px?LD4Y)j#0p_5U9E`cof1 +_u=vjs?i30{{R;2LJ#d0001RX>c!Jc4cm4Z*nhkWpQ<7b98erUtei +%X>?y-E^v8uRNHRjHV}R1R}7Q~ORY>_iXw&31lR^{H`p{A#O||}mc}-_lBkkY9Jknh`wl5eb{4H6nB) +v+=A60k3Z~ypp-`o4_8D|`H~q;;7`p<1Ja@}1&lB4F5BmQc@|jymJ%gBb@f6~j|EAz>lQvJhkMNr@7D +W-$_*aL<8hF3iJV7P5TIdt|_rHFOJr9?q0nxlMN#Urawb+1c;OS%!s!3s|G#t8`u5OX&7!JP(BMbO#w +PBqRd(0RkD7Uw_AnR6X3j>@%tl?&q@jcpjaE*W5uS-duX&*wVq%@yMt8^<=NyR3)5rDZ47nAjN{NyXma?$%XFM%#CNHAua4|`Nj>~X +dUZA_=(<&1P5g)f~r6)6U3UW~jD{exR(L<|cV`I%NzFIH*hxvLE#C{V|*6S!6&U%RS;QWafI`4m>FhPmWh_&Lz-OE +?|Pi2f~SEGtxd(sF;W8N@|GMO^#{+Y@}irlIigjMDziSyssc8-p3VYehjYmwcXjAP@IAl3(+=lWsd%m0mV~oiFFt)KhsbI>N5|n{R+Qi-4@xp3yng +$gNl24ac74H=bx_-_cyvtp%$98?mhrI$hD+{V*}Ge!L%wkb>L+wT_W=g;{;dd?9yQ)xZhBXKHZ6gQ@R +vEw{tqwI|gQUQ>CS@x*2GCl)rRo>O@+jT45i1rnfpZ@bc3={{B~jA5*gIC$NwNB6}C9g($Suxpe1*zbuBkUH)vdG$N1r#!n)rK*Us<9c- +0?*z9)a_DE8z7=GCB1VIyl)4$mLY4^AtISwCGHrG6L9=^0Cs71pGFw0tI0xKq>tg>&HrEOAY+MoYAIq +N^-aYQJ~S)A81Qn^Slu?%~irhSq`Bt!zKy)3Q$V}1QY- +O00;o{l@>=)>}^bU5dZ+HK>z?C0001RX>c!Jc4cm4Z*nhkWpQ<7b98erVPs)&bY*gLE^v9}TWxdO#u5 +I`UvZT_5cE)plYHrLOwY)&(rBtkt|X^3bv)3KIEsis0L6=FCX@d5?(V(d4mi+Mnx@m1GjT*_9Hx>7OUXfNz +y}J=GUsehAvf#@{{vfKbDbqArd>s~fo^E&s&q_Vy9X$F@KAN(k%s=fS92~)rAugqwMYH(!?(W^^W^U> +v)%17CM&u1>rP6=i@@BbrD9l-xyLOrIMUgM_O#wPpZ(vNp%Sueyf`fAF5_VM)A{(Qq;O+T0r|&QCqO; +TJ&HJmjm*>&D)4Ok{>_OC#$fP+)MXUvnVe6(N=J^z*C`1-V)p9L1B1%?KCPXY^$%r@g+Gul%!og0L`~ +ja&lvp5Rv#cA?sg~^wB)r!rPvUK|tcO%1J}pH-Hev=#vr&3IFU!0IJ2bm?;`ZyaSk(D4PoFvL1~&KC>FW0OvXxkWdCtVrU+iJaJbz4DI}o1$K$dl+9!GT^{m3(xj>CO4w&BggGJbXDCjg~2|D)t8a;Zy=>kS~6O6-{O&G@#-gz%0IJcLr+}DM2Pufy=QdO0uMmqM# +D#N{z-()fB+gnqbO^A~XXgEfes_xXYmA2~2*K*B6^21q8@y5z8$#!0orC>3yIa~9}aN9rtWl4>ssDetAFfe3qcIY3xNeP-1i#P{Kv% +F?9;7eJ3a)s<-#ddkaFyOKWu(&4WC7ElPr!0SxR)G)VM6QHP#qip$6Hw(=sF}E4#?;Cs&@RRmyT2#+y +Vo{{DkLl6=ug|A^!J3PQ?kHd2$me*Ibts`YQZsQ^Ju +@~T`0u&gEEHi1r0LmPA~qnv+j53L~SY_d8Suj{&)eeuP3%J@X168%4lzz)kQieQotV~Y`xj$vi1*w9T<6&)2-KV$RblwSAL(E9Zc`q7Tksw*weA#@?I;>|7Yg}CD43M +EYcsYgr6PE3kO|V(ECo1wM=U$$Qo`v!vK!mN4^ni>o +m3c>Z6p7Hn%pZBLYcgl}kZ){;4y^RJ!iG{2)NDp~?aOPV<>(CN19UCTCLsm&OK$$v>n6jLC}=FctOk`x4e9)EHwa%U%&(jPhmW6mQIkYRzcWmL$*I4wB@ +l5V;H|Nm4loPVl$Nsu%CYSWB`;vD@Y)WQpZNgZVmjpkkCLF +&j=o;Z8HN)s|scE>4R8V%RNmkcu{sd>5N8j6`_h(=a0NdFG9b7se%#P_2vfkGuDfJb}d!kN*KbrFBThqCaKDL0aI0dgyz +DrP0s3gA621sl0)v?YYBDN&)Qb*}dKZNgnE2%8vo47tP!#Bwwk{BUrCRuO0^UZPJNdU9KPK+eb`voX& +30vu$a5{>OUGx$~`0-1^l(EbNWYE_X +bEVIp+eWqjb$y{M3ThJq}AM$9^T0rI~#&7E_wKaTS6&7nC4rE7LyRt#j>t&akA#E#uM5YCF#g9L9!jN +Oz=5O+TEAO>@)?gWP>MFA(kKzr~$_?7{gJop)&$RQL9a4Uj!q|tY`Grtde}x<$_~1)!y;`laXigll{$ +e-J}kV&WzEo5>Oon!%b?;TWD|2PMz&pG+2U!N0W|f!S+I$6D$Z}aeQ`ugLU#>-e26Dza4vsd4%+oZYW +vzRK^4Rudc7o_w#l)I*|Y}^Jy%puuH_Vr3jG5KBk&@cEt#^N>ZT~@!{o1KOuxOhwe+4uD{;FDOx1N26 +G(g13v|ZpdI|DDqQ$`gS1#LXzbBv92W5CN3ZWSd=T=PKyHDxBvjb>+=NAgrBem|TR^jinLsZ=M{|2u3 +V0)8)#GHZIuAe>I`5Fp`C6tOMg{#Ds=`HOb0RC1>PIz0G&iSDcIV|74`|W_hlCm=L6b(KMFHQ_pRHvFG_yA`4Dqy{yVN^2!Bp_H3B)Tq +$+`wUx@q47-;qYSI=DapT)@3J*#7m_uS?n2gy|ve}IkYi74*!+gjCcx_U6F!24JS)xhoKzvm_;qu^5Z +y83XTtQBW0Z%9F)SUjDRP_#m5H>^cUAe>Fi5em?5)YtIJxWGD(CHC#^B3sC>J`c|%)AX@Qv-c*B(M@c +$o%M9$HehGS&#P1HDc($4HBrrp0daBq(9c`Y4*z#Y7ltJJyf%)>=dnK)NQc`|LybeV|I;(BZW36QG$^ +c2!36GQB5&SY^%(bOhSbuMD3ywUfH{inql#~u8D-7Ib#Qtc$-w{4HeoE&vx<{8jMbLfLpF-O<9VpPIv +0e^v4EpgSb|vA!cq#$zHX3i_#CAPQo&U8eA4bg64lYW6rGB!+AJE-^&3z6KmFrtB +t?dMTPodym_#6aE+8M?F4|AsK=a~mCoZE4Z0DG{@BqcCoj>BVPxEI3!97<)g#Y8vpARxI2-PgF*dhpYqj}@azxk3ane?7S_S?Oj8P}I2pX1AXu +Ou)f4Rl5n#W2u=X3_T;Sb3YSwW>F+uR({UhMEt$qHr=6_+(82NVtD{T&qrpiY&yS$KvmZO-Zj9D&S7% +a*L#0DFCPb$)i&#uthb|HZawa9P#idbcF%wQE!vzAtC(*xt3ui0Ry2{n@iczsOEOb^myK#R-Pl)0ci09~&xb3!TbQ9@T>w%&7^Z#trrVtP9kK?wPN&Q=*UxhGRyCOlus3*5g9Z1ddek?S@miC^OTA&Q(5AlN@e +{T|;&5GW(qnx+@%4Q)0YoaCgYkM-h;~IZEzU}0-G%F82)_nZPrh@mPz@YG*u`!p!}>`fujIzQvxx=%c +BH`*l7k9peKd-RofSSXP!xr{^J#6hiy%(nqARjam&3}%+7hI5+HN12$-^>dlyhj-A{1qBG~O_xJ6=MuubSvd3luOc^Hk +tG|Nfoq83t)-+YL3rrl7n0Nn`KKq1JQ?R(r`UzX%IiueHnD7ybxLc{2o8@fO)RXSbp`#Ti`QC$Mn8LU +zyvE<0sR%0y=KvCx*b4U@oabua^dl2T=q!FIwl-UfQA*U>|X$;?_P=+3P-pQeW=vUXk@v>+E63nLDSK +c)kGXloyHd<3FDR<5=^G&Mzdas@s^@K^l9G4Dq9&oD8O=9`$I`d>h%ck;eU?v$RQntQY2NreV?4YMsF +$7U}y8TBz?+JtjrOmxzGoY=)9KkM#J#q(z#nbu+YM%l_i96K@4uL$Z&}2SAlY3ZB96bQrR_R +PYS)`EEaKfEVPelpo5#TjjF*u*Hf$)7Q_Dlf3W4%ugNt{LGHaLx6$3#;N*C_Cl@{@-$5`U)+i`o$3;^ +^UEFG4{>hr+8>FkfD95$sVmqzAZ^0Jo{{ZDLl1)Up@K!9!%Tc7!N +8z6L{BRlZ&*+z56@pJ(@Oz2h8JhFX@Wi?hU0}o!dsH4wP2`{s~Y^0|XQR000O8^OY7y%AV%vI|Tp$Cl +vqy8vp=2 +YXnD>MYUr&5};LJH_>e?YECSogB+answ-awWuE)**<Q6>{C3`Q_2MY6=BJ{Ux}yf__SO~x=+n&>n_idM+XgtdpkT&o;Hc0p-N7RE?bm>>vJoP+njn-h +;p`%vku4+jUUwa^RGivpk*p`4P1)m1_+iy|eEBBdvYl1vyA#XcT*?H`6Qk+W%33N3P|(IfxYdCF-haJ +>%^gPQ${i4Awn$*Bl#-&}sQp?f!!R8?9ET4X&qlZkuO8z8XR#v)0gV1^u&1z9)(f}{f!GHJeL-Dhl3r +NW9Qi25~6p9$wO!^2Fj(7VgroXv)Krc!cj{yg8WMinhS{=#|juOXKxQq)hUYYykr=?$FM$F?+UNhSI$ +c%sxw;zMvw%BlP92ch?q^3R|-ryue2~;#`_Omi>16NEIPTT=tIDh +-Rts3v9RaE`QzC6SBr3aX`7^3G4myb(8llhV=|mWr49?_&0veoF#?m!)3Fgx+JS%flm2E+ut2Jbb_z7 +?=q}^7jL4AjMn?kM#hsCcM&bdJ>JcJsK5e01S41=r>76JNOv +9zkvzPvi8OHB=b+|qZyD9NL3P;Cm?no8?Ky$Y#XQ>K_b`If(Yuq|tFy~7H8(1%L=+T=aSe>v?qrJXTBII^B7aEu9a(J|HJXw +-Jkl*KEVsdiS>`$AM_9}@kg9dTrM^eNp6T;uH5E^;NB43bPTvI~sw6?DTA^IixSbC_}=^y%*LuXO +J^E8KK?WG=Pm(r7D94e!1Yc#mHA};OPMS^7#AF=yI3H13yMuuI>DcW +F5FEk$TFuo5{3sJ?+O_;cW@I=(EO(bWy2&Z4@U-yJkciHO-IO1;x+>;{WcMPaiJ7V6w(M+>qh31proL1r1?t}&{sUc`Ab~}3wmF@<2wLK +C2-QgSJw@oi#{b#p&YoY7xn(h;uX`}D;&Gh2>YVwIS{_+y<)7jZy^?kN^2YfEo=i|}Y*F3vCyD9p3qB +)aKWw}(wcQ0PgeDC4~{@FIh+s-G>{TJ|`%m1)^_RE1KZ_2@m&Tn3HetV=ys)sf5fx@``-0R|V5V3kp! +w13%n=C&@y3zFX{Hu8Xxp*u~Bj1PgOEE)>&rQMYznfq99NbT1ot=l1?Qc*^0|XQR000O8^OY7yDP{LP +eh2^niW&d_8~^|SaA|NaUv_0~WN&gWa%FLKWpi|MFJX0bXfAMh%~)-38#faEu3teYFm^YQHnEW!fpJF +R+U~_@;{>(~LZ?*J +Ys$E42So!hadLuD@4YuQE9sjTWj{vl-Xo_$_mLv*WiS2l<8DjpxO>ATDl56tV#2ghHAQhRh4v(3Y +ZRZG#4RVLNPgp>AT@B`P}2vaHWCucw4A$A6bnAI>Q&mkRhf;GI>QU& +bQz#t)!;;;5p7zPLWB-$AbI}Jz48Y22AE~CP_jqvc-fc$C_l}5}02X=F0OD>7`PI3Ij6T3StYgr +P2_vAOx`CvrNQ6REz!o?(P#=5$Qv(L?iu~F?_xfmayfOR;HPP@^1;k=RVVzwE{V<(L?6a)OzfV1N?y$0{`>%O6d=P*%I%Cx*-6UVxCT)j#Z>Kr#{zczZcpwjZj0`~GZ)ih9N +We=5S|htJi~3))2IPuM-#P+@w)(vyZh989<$9#&Y>$?6;+m!D9~Dnb!i@(+m +O>~eQ8X8L(Gp~kJ|>Q_u)SE*wvnnyn=xF9=p3PWn+%BLri$GvTy8qwTrNBZwWg)s?XD5kD+*b%USQ~p +2n|dhf!h3QZTL+>+oI6cynKu!cL~@PNsf2IXwOvwGI9}VC}oK8$_@>u{uti7`@!ZdblT +Rb!qeOrwhxb1pEb$X4JxzsCdM +z)IV4Elf*qE;upi#S>r7#KH@ZjZZJ=?6U65 +8dey*+PWqs_IkzcHZxDUOYO=k2B34;PR#t%M0XBz^nRh=~rwQ!`Kg6))n?^~@0Ljk9P-pmnLvl0edHg +Q&La7G~0cV+qqJ8I2bdm^Ay)A5H7h9H`t$3rl8sNAKPCX0+O^(ky#{qy?c&E@&o?PWB)!A+KfC&CbT$ +GVz@0kE>-Pi#=19=2poWCLL`a$6C?S}^6#7>F?FYfi_r4l81)`!r%C?9(?yB}FYJR1AONyB1dZynwf<3BL+`7>P(J$us +L6E95UxLt$%p!O1{x+%p!I!!zN5=Ay>91~;4k$f#k=^cqzQbR63#vGa{eT>YPHj`2d{T_phML!j>4N~Gk7F9jW5gv2G^l2vVg?mw(A +i!f6jE8z`y7=!`Z_(PMHwNcMdXUl?*rh)SUne6J>0|XQR000O8^OY7y(@OVaA|NaUv_0~WN&gWa%FLKWpi|MFJob2WpZ>baAj@ +my;+l^O138Y&aVjTemQOGDlrc-I}gl45=bECmut*o(u_d-`s+>%J2EqJXYQ&xr>pJWZIQ7f9B>>D^nL +4FYx(m3`C=c++sppcU6brZJf+!-a=NxJpzYShRhHae?x&agA$z%J*Y@^u%BNrS(^xi5^s?*Xrc99k`L +ZdK?0C!m_siq&FZkclzrSetOZ1YQ&d-lacAJ+zy1g7v_m{N1-LGZb-Lv$iFYgC%LU{wd02_(57umu5*W{aF$Fyw20I7NTkV?@F8aB6|E3pQQg*aAZrQ3 +U%X;{}Q@5@r!Ii-caJ5gaNQHpVPacEOR0j9TRJg25Jf4u7EO16J%90UPRflH +ANG7Tb^1GUDHIb5=B1IMZQoQokvx1e^K{ZOh~3I2)x7VOJ@*AekBx!EAWBMH?FN)MXwZrgt(@;mV0jL +%1&Y8+%r+RXW(1s7$=9-$TzPS-RxzZI@Vs0GH=x+jrB}@1JxAcfy7G}jXbVPo_(?RsA^Nml`hIEk2x| +w=#hn4iY6OW(7I1|xxx~{EG&F@1g&z@lojZJF#F{pF}8NmZzXxuCH}d!`Q8I<`g>cYV^dotV7hthMKh +4V$W^&txrj5$fi48o9mRvbd%NQ!ISP-YRi@GD`=npJUbK-1>h*DnrVRa+gCs|HOhv(t@c~QK<`EzDn< +h71@FWLq^4tR}B*{r73K)DB1O@;`Uf@Kz$NHN$*nQb$jpyt&rHglBCpKV3o~yFI!WSc#{{ +tdbz-33A{>N5w$;_{d;5Kcv1$DdD+Paf}{oZe5c0K!ITa*!CZQ>9|GOeN!b=x6l2ItZt4dVV;T-2b{6 +jXcpPA6Ky)@&NkYnnVC?U2_L0@RB4D|HSNiFY_{a1 +w?oSpo-gzR6fcZX!#CZ|D_$jBkT8_e#Xq2t<>MB!&=+rC*{c +PCy6)KnA`jY{3CI!xtpBAXx}=F$u8@^pWC=h=5-?1tFG=7i{tqGzHgy>rnuTplcigVHPa_@RJM#NHAJ +FU$FTiA{QvOU?Ygk1Q>9-0FOf^kOv|bLN|bSl3rjLd^7;*BsiKbGVWJs3cv=S>G4_cy(aJl_-FHmP}G +-0U8-Dy4$G#i9u6rO9l-D=IfhMA3X*BdEuxF&=MVXcw*o(bcLDglft?<$(Og=mz)#U|PgOCFzQK0@ +pqd{LfZsj*H{o{$?p5i-D}Fl^psFt??(@7M|H#CBo;TzlnYhpMhWsNF_j%rs-<`N3WP8aBR_jx!9Uh6 +nLsT_+2`K`U2TZc!PXJzxZSAOxHpjv%b>q@|chaM!yF6X4B7QQP`MN?aY#AM5r$|?Oby;v2^2};2$Q? +Ddg-)?*k#;wHaK9UE$dpkr$XlJ5JvyTneMy;LmFqeV9{Z$VFfox=mgpm!S!Tuwe=^TU-b^?!3fWH;5R){?Emd>+q;!?Sng?Vo(Iu8!!KRmMxpScKRUYMWt$ +Q_v`8B~Nhd6K=C`|5TLFDkcEyEt+(qe#@J99Zf>y&be&(@429b9a%tx%YsomS?QIlo!@ll&>+Sj{=+Z8JPENtnFXCMi0D +g(q45QiL%SM~6An%Ud_pWZ4pIt}!b6}-0QU*E$g@QZ7=~C78KeO&`kB2RL*4^+J@^9p0T|yD3GHQ(NJx9049 +N)rFgiyh#n`;~9b6h>r#qFM)DulOn+NVJ-3Phk8OM{6B|nQ$ckF6azU;MhY52UoR}R!6V<8WS3_1`G@ +3C-U&l6-{%D~5Aun6ra#wrlpQ9^RTFy+7VohU{h^!oeD`)o#-~PyA6Cw$f?en3wbkJVWgQn~zIhVWEIQGL;}*9XBY0}H@(6Sb>6ZHZQe*}v +uM7$m)1{P%d@u8Sq}#e6_Y(XQTd2*O%Q?_0Jr7yv(<37vpEmH!g~_*jvG@9>qG=&SrS;|FW9FQ_=c`N +=GQTB>;JG49qLsAlnFb1o9cEdKL1*=PHo@}(>DXn +>gi{^LGNx+~y>4+_X$`0joB+SVAZD>WRWacq~w>h0q6m`TDV1&E`Uf$i3LW&A8>5Jkc$kchgb4Q7l2^EO`uzdhSWm*j5bgfG6VyZ +2nxkW8bkI16vCp=!9!rMh0fp)3=P#2&@6zmfDp>CMGUAZ1zkg3gHGNjKp2oYxCNd-R~Ezmk~TC6(8j5 +Krw!Ri8Fc*N1MC3m5Vl|WNK74Q^*7*JTE2osUU2Jo`EGTWC#e_9~1x@d=~&R_l$ +gtdc$H8VDVG0WZaNsOm`s`%ipvips}~VV>H**2U&t2K8SWFTR`0*^_n*Di(zB)*LV0_$?kx>9e}V|rT +z+H?q^H|zbhC(xJS}9X!ZrTAzz_e@8W}}CR)(ZMO&h|sN$BQmVtO+W_V#eWYQ|NWM}0%og+dfk^q{w# +&#^rvm=M=afmP@7vkL}B*nQ|the(!Du~&5;00?p-#vQCz@)CZT}f-kBgv|ET}t;@bLL0aT#Q6L8D%Wg +*MqgJy2qM}y8v~WA#HNU*i;VB(&aXrD?6eXm|8?$(QPXNs_ctGR`lh>_UW>>&bpfPVI)*1RjvI|NWXs +v;46UqGw%R=1&}Y_0Tb=TS2~sC-jbZUA9UgLYWedfz+zR9M##-Yk8CCFsoMdn+s@!s{09DwmnJI%wgZ +n9^vhS!t^}dzl@ssmx8Z5Ff9!8(-?zA;LNr0x=~QVRIkR7y)5%*w2xLXB+Gtl_(d*j9&^*wd;MU_ds8 +@4G=leGuVk*eH2vI+5kB}2kAU=5T7{g6*E4|ZIU{n+_|AWiRba-U)c`4O)on2Xuqp`7AQwrlLXnd^5m +9MXC83>DLA0KCU-EK2y4!Wa}MY2qtF!q7#YKym=GAO})_h7to12+$fp5CCwerhq|`Lhn7zd`U=vbpX@@cHkzb765-hLV((`c= +AngP=w&|L>4jhWq~`;uUv)ygpe`@#z80=#w{`+K@vDNE?Oknf+OG$bPR__0l5S20ZxeFX(SGhf<_931 +P1gJxG<(5$tfG{)+mJ7NAA_6=C6sF3D4z;gfn +GUlqk4>fwF3UyT;|E5rS2w8(D__fNtJ$RF_pY2_EW(p$vp}9CwyJ9Nht}jt?8%^l8ejYdzX(>MW4v1&JDPdp}W&jscoR&3h$tt`#-`7$T!bbyu}kXcU>+YyNwv|_F&pX6 +f<-FWF53|TnodoE;;so^J!u(oscH((+clz7iFm@Tv_+ZuD9<&+b;vbCDpxOE(bJT&MA&Rcsh1gW`?|6 +^`RxTE8ln~2+wm~Wv)XeTAP+L*4-f1yPSXWJu{4t>hyF~ood%Pb)NHioIa0wjc?m7w*iQUJXZgAVe8A +^UQ~SkAIblE!8ne6`L4Ua!HD)t^m_7`r7ztrdpRAO=luP|m)D4^k=^^#wf@&4^}l><|0M2D_4UnoSyEieTs9K0qVnKLLN1fEN?V0>hy!0Ym^a62-wzf#d*u# +9~m>fD_Oh`ms2`F~lUCA~=*JSx^~NFQ5_4Ch}rn;Dlu%&9U(>)d&xR&g~6=KM~H0e0LFOLS8n<8J(>R +J@_8{6$t)CB2T^;T`+^9O9|P->?%!q0cZV~&e%PIN)?14UTS?q1C#SGlY`Nq1il*6zINp)Sd5h|-mF%|j_Bh-7e +xJ0rAnXytIUaao2CFaXhWfmXbXS9XIZH90u(Y4+lPDN<^UpokV$U+cQTRwZ`@NIz- +{-kyy60jfUY&$*Xu~4Z?Lxdv4NZri9OUywpejgssm3a$4bO6fU{n4u`yE{Y=0=r4&tZicgKl$KP%dWT +CgC-zO*i^~*ofkAArHo3taA0FsHo8Nd!4gEBPDp(ur;B7rwdVn9eVRrAefGOVVH;kC$gv9fx+JqmR5lwS(~O^|vX9$)h(FxjRQNnI2oRYF%JI$P(D$54`b6V1-ra +xPzPo7R=hJ;$m$i)_<&9L97U?%H}r8)ZNPYpUhL=y67dC%S*qx5QrZ%ae_+bscppXHF97UUvX6GnfQy +WQLe;n>~A0I8r5C!xp!GZH#QaJR_KQt!}59cB`6<`+zOgCSKQsa>n*#tR3}sUbD~6=gQpK?^Y|axyMP +W(zc~8tqS~v+>Xxn&=p~Mcki*`lFHdD>7-b1w~yyaFm?&Hw`J0yRi@93jkghkCzX=jfDdd@N4FK?;Iu +g&Z$!FjdW(`v$J4zmqK9iOx1wHzYfe!wb>)TP)h|YSz7elNEHu)-$P|h*ScEH;6EnL$oijJDDQWi})i +x{eO1=8fQt36QEyGt`sQBIF$+9Nj5>Qq)FTuEjE}*X`7p5l&R*~UBWSO}CJT>NqK;_ZipXT$C+yCgTb +fC9V1RoL}JMNCT%;Bhp&za4od{nlwmeyFl8*WFjzdp=1a~SUGUryG36F1^|J0i~tJJ_kAim^WHX{ibT +O|aMN<7yudCR3BAS@0;!fMICCbRS1me4yl*n43gVorWr8gkX)lF&y`4S;A4b($q6uDd${$`&6qrYcS6 +z6`(PGd5rl(J#w4FN()!lqRGXUdA2)*k7f66_URdDr;S?InLv-{VHkprSwC0VO~LSW|2QlUEqNJ~U}# +d|SO(5@<~>{AiBd#bUqouvScESUI2Le0W?e{k^tcDf5%p3RXsU9qobAlbE1l%r{gH`2>F-Ueii=p6k) +`hBXH9r0duc@!Pfa`!UfB5MT&`B@eRwAM-wmUDOFQ4t4NQOik&*uPV&OmMt>5q9=gc*o@l*PuS)64ln +qo1W`ij0d5^4}2F_;We1W*Hc3KOdc6ox8DKujpig9U5=6Kv71eOlBaL!n;@@COE{g__jJBy>;`Dj1+c +(sYtF?8HV4^myUmR@qPJ3nqHu@EUUReZlKdnAi*WD&}D70FW#&V#2{RvN(sqd%&0x2FDBp6r{BT=AzL +#ba9c8vLLI1OTbYs`z3vKP}W@5KhT#%1}#;fU(%N?$p9V5x2W)-`|s(kZ>H=A=4&EaIF&ZQ%$Rp-6F; +#N0_f?}LH(P9;MkOBrAq-|B^jG^!bh5wJhdSojg_G5d%j=3GtZEIFwA!ZQ*8Fa9$X9~rXPXr^*4|3cJ +M8*|J^Y#UwiFiUXagOOn{npJaiJ8ClUNC@auTD;_2C@Wlyc+io^Og)7*V5a>o3ylxX?7+aM1z&4=SmM +H#L4jhMUU3PWstGFSzx`XFJbvdd<~eU^~r%{d*I{Uu)SqcFRyGu=C=ERvlz*T-o*-{_~eGBbaFt}nuK +hAxlUyewuIf9&JtS}C10w-(~kO&o-uT3Uj}1F38<(vQn~dk7c2Yt5S~Fm9b~`MQ#q1or~lqxgDN +&_vR7A;Uu>5DL>kceB7+mwWV#w6cIT;9Cyddsy|&5YN;Nr?)KClCvq*J8%o^RdDk0<2d?@T1(4@6u(q +1Nniq9{wi@yrA>(Cs#q#VTM(5&@j-k(S&x^;~e!&Y*=SuHr`y%xEfj`mWv)G9($-V`?x55!fA*8im4W +p&WPIUAhT=_{vJbgWvl$FAC+L^XQTs%pZH{l}Osqnr!-3hJ_4<*?f#neGAh-?odbl~}m6&W9wxw{FgwjF3e-VvuNm<`y9qpw+$u +tlb?3i*C(Ol`Q#mz21bg<5`OS&^ys=C@M}0JXiXTj~4$?~kY{lk9r`dva>$(6>k|Kj_6_#D5#%>8wy8x52o3z-l|wJ3$zVL&$lHUcURriM{42@b|ta+oZZeZ4XzqoCd +btVbk}P=Vr0Na%OuSm>oo6WBeQK;Ixe2}23b-oRWLY|{AGlQf|+g&4?m}0I|Sp~u#))lJ=aRb!b7Y!lQ +#;{lHA-j(4-`J-1r!?(aUMh$SbqjI;%GpO%x^ +d5derufTVeho=aI_+>umsYB5%dQ#jNq71*3I+1_GN +Kz;^K!`7a9rK8))4=7J<$fw3XovfeD74o~2^|QG`es{8dHdn~+PS(%n3i+6<-&$BB1zxbC%eeHqOYi_ +A3y{qvb(VbCaodZr-}FNx>QqSuNukVs}R?r_h@zU}2 +=v?Mx~AqjlM#<9r~5S}metOG?-DsThiA#;rt1(ySI+satu1$p(m>1DSqTM%UjP>2X~wLp1FTbe{ZdVa +li&C0E?KONX2-`}HjKR-W*d$)?yA?4}g#zQprb +}HDp;5@2Kq8w~%za^~$@2Oy@E3!<}<%;YhH850M4c{^v%KOJ`InuU*{9 +RJhKQo3V}dka+o?m5R;0dpd3mF7{mwA4VVZJ1`uB9v}7`eA*i3Q1t2iE(1(Evj+?xG>6G*U_y7p97=z +Bih=y)NKm&l@h-vW<5P&SRU|IgZTUW86$ +K1g78)s}WBjgaTY0qJ5t>h2Tjcl|!zF;*Tfb(CbxJygK; +%sB1mV*;eAA$2p3iA(Ct^}k>X={^S&|3IA8KHPg6xfQt0Z0&2iOC}b1a2;lqGIj+mYnzSAi(5O!Pu_B +N$V?IIX035Wm!UM;9ijztc#>AD_0E>7CU%`_$2o>OYrS5g^hTfS_uB=J#(k;kRP5+_MVhzUa66^XsFi +yW@#ed27t&2qQ0x21veY3w%{I(Em7lD~x#bewrT;B#LHswd#jo!3&KB05e{T`ZWaJfnztSoAJP@lmp>dG09V`g)ij{ +7Z*j`^>ZLQ&M+*4Vl2whG-xBSFC$ejt$IpPh#2U +$0-7Vq7O$ZvEQN{9K;yg;3
-f -t ' + + + +def main(argv): + print "start script with ", len(sys.argv), 'arguments.' + print "==============================================" + + try: + opts, args = getopt.getopt(argv, "h:o:a:n:f:t:", ["operation","address","indexName","file","toIndex"]) + except getopt.GetoptError: + usage() + sys.exit(2) + + host = None + for opt, arg in opts: + print opt, arg + if opt == '-h': + usage() + sys.exit(2) + elif opt in ('-f', '--file'): + mapping=readFileToJson(arg) + elif opt in ('-a', '--address'): + host=arg + elif opt in ('-o', '--operation'): + operation=arg + elif opt in ('-n', '--indexName'): + indexName=arg + elif opt in ('-t', '--toIndex'): + destIndexName=arg + + if (operation == None): + usage() + sys.exit(2) + elif (host == None): + print "address is mandatory argument" + usage() + sys.exit(2) + elif operation == 'create': + print "create new index ", indexName + client = Elasticsearch([{'host': host, 'timeout':5}] ) + res = createIndex(client, indexName, mapping) + + elif operation == 'delete': + print "delete index ", indexName + client = Elasticsearch([{'host': host, 'timeout':5}] ) + res = deleteIndex(client, indexName) + + elif operation == 'move': + print "move index ", indexName, " to ", destIndexName + client = Elasticsearch([{'host': host, 'timeout':5}] ) + res = copyIndex(client, indexName, destIndexName) + else: + usage() + exit(2) + if res != 0: + print "ERROR: operation Failed" + exit(1) + + + +if __name__ == "__main__": + main(sys.argv[1:]) + + diff --git a/asdctool/src/main/resources/es-resources/types/auditinggetuebclusterevent.txt b/asdctool/src/main/resources/es-resources/types/auditinggetuebclusterevent.txt new file mode 100644 index 0000000000..b7e9435f97 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/auditinggetuebclusterevent.txt @@ -0,0 +1,8 @@ +{ "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "consumerId": "CONSUMER_ID" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/distributiondeployevent.txt b/asdctool/src/main/resources/es-resources/types/distributiondeployevent.txt new file mode 100644 index 0000000000..a74f0370e6 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/distributiondeployevent.txt @@ -0,0 +1,14 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "currVersion": "CURR_VERSION", + "distributionId": "DID", + "modifierName": "MODIFIER_NAME", + "modifierUid": "MODIFIER_UID", + "resourceName": "RESOURCE_NAME", + "resourceType": "RESOURCE_TYPE" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/distributiondownloadevent.txt b/asdctool/src/main/resources/es-resources/types/distributiondownloadevent.txt new file mode 100644 index 0000000000..879c4c4231 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/distributiondownloadevent.txt @@ -0,0 +1,9 @@ +{ "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "resourceUrl": "RESOURCE_URL", + "consumerId": "CONSUMER_ID" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/distributionengineevent.txt b/asdctool/src/main/resources/es-resources/types/distributionengineevent.txt new file mode 100644 index 0000000000..a261042720 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/distributionengineevent.txt @@ -0,0 +1,13 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "consumerId": "CONSUMER_ID", + "role": "ROLE", + "topicName": "TOPIC_NAME", + "apiKey": "API_KEY", + "environmentName": "D_ENV" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/distributionnotificationevent.txt b/asdctool/src/main/resources/es-resources/types/distributionnotificationevent.txt new file mode 100644 index 0000000000..6375ead9bb --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/distributionnotificationevent.txt @@ -0,0 +1,16 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "currVersion": "CURR_VERSION", + "currState": "CURR_STATE", + "distributionId": "DID", + "modifierName": "MODIFIER_NAME", + "modifierUid": "MODIFIER_UID", + "resourceName": "RESOURCE_NAME", + "resourceType": "RESOURCE_TYPE", + "topicName": "TOPIC_NAME" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/distributionstatusevent.txt b/asdctool/src/main/resources/es-resources/types/distributionstatusevent.txt new file mode 100644 index 0000000000..8fed9dd0c0 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/distributionstatusevent.txt @@ -0,0 +1,12 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "resourceUrl": "RESOURCE_URL", + "consumerId": "CONSUMER_ID", + "distributionId": "DID", + "topicName": "TOPIC_NAME" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/resourceadminevent.txt b/asdctool/src/main/resources/es-resources/types/resourceadminevent.txt new file mode 100644 index 0000000000..4631aa3367 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/resourceadminevent.txt @@ -0,0 +1,21 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "currVersion": "CURR_VERSION", + "currState": "CURR_STATE", + "distributionId": "DID", + "modifierName": "MODIFIER_NAME", + "modifierUid": "MODIFIER_UID", + "prevVersion": "PREV_VERSION", + "prevState": "PREV_STATE", + "resourceName": "RESOURCE_NAME", + "resourceType": "RESOURCE_TYPE", + "dPrevStatus": "DPREV_STATUS", + "dCurrStatus": "DCURR_STATUS", + "comment": "COMMENT", + "artifactName": "ARTIFACT_NAME" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/useraccessevent.txt b/asdctool/src/main/resources/es-resources/types/useraccessevent.txt new file mode 100644 index 0000000000..ebd27b55e3 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/useraccessevent.txt @@ -0,0 +1,10 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "userUid": "USER_UID", + "userName": "USER_NAME" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/es-resources/types/useradminevent.txt b/asdctool/src/main/resources/es-resources/types/useradminevent.txt new file mode 100644 index 0000000000..15e0d9bdca --- /dev/null +++ b/asdctool/src/main/resources/es-resources/types/useradminevent.txt @@ -0,0 +1,20 @@ +{ + "action": "ACTION", + "timestamp": "TIMESTAMP", + "requestId": "REQUEST_ID", + "serviceInstanceId": "SERVICE_INSTANCE_ID", + "desc": "DESC", + "status": "STATUS", + "modifierName": "MODIFIER_NAME", + "modifierUid": "MODIFIER_UID", + "userUid": "USER_UID", + "userName": "USER_NAME", + "userEmail": "USER_EMAIL", + "userRole": "USER_ROLE", + "userBeforeName": "USER_BEFORE_NAME", + "userBeforeEmail": "USER_BEFORE_EMAIL", + "userBeforeRole": "USER_BEFORE_ROLE", + "userAfterName": "USER_AFTER_NAME", + "userAfterEmail": "USER_AFTER_EMAIL", + "userAfterRole": "USER_AFTER_ROLE" +} \ No newline at end of file diff --git a/asdctool/src/main/resources/scripts/baseOperation.sh b/asdctool/src/main/resources/scripts/baseOperation.sh new file mode 100644 index 0000000000..b27b734276 --- /dev/null +++ b/asdctool/src/main/resources/scripts/baseOperation.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +#echo $FULL_PATH + +LIB_DIR=$FULL_PATH/.. +BIN_DIR=$FULL_PATH/../bin +CONFIG_DIR=$FULL_PATH/../config + +JVM_VERBOSE=-Dverbose + +JVM_LOG_FILE="-Dlogback.configurationFile=${CONFIG_DIR}/logback.xml" + +###################################################### + +#BINS=`find $BIN_DIR -name "*.jar" | tr "\\n" ":"` + +LIBS=`find $LIB_DIR -name "*.jar" | tr "\\n" ":"` + +JARS=$JARS:$BINS:$LIBS + + +export JARS +export JVM_LOG_FILE diff --git a/asdctool/src/main/resources/scripts/cleanCsar.sh b/asdctool/src/main/resources/scripts/cleanCsar.sh new file mode 100644 index 0000000000..c11cdef8f8 --- /dev/null +++ b/asdctool/src/main/resources/scripts/cleanCsar.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass clean-csar $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/dataMigration.sh b/asdctool/src/main/resources/scripts/dataMigration.sh new file mode 100644 index 0000000000..b05c6dc355 --- /dev/null +++ b/asdctool/src/main/resources/scripts/dataMigration.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass migrate-1602-1604 $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/dataMigration1607.sh b/asdctool/src/main/resources/scripts/dataMigration1607.sh new file mode 100644 index 0000000000..027852d882 --- /dev/null +++ b/asdctool/src/main/resources/scripts/dataMigration1607.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration 1607 +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass migrate-1604-1607 $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/dataMigration1610.sh b/asdctool/src/main/resources/scripts/dataMigration1610.sh new file mode 100644 index 0000000000..45d61adeee --- /dev/null +++ b/asdctool/src/main/resources/scripts/dataMigration1610.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +############################## +# Data Migration 1610 +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass fix-properties $@" +echo $command + +$command +result=$? + +if [ $result -eq 0 ] +then + command="java $JVM_LOG_FILE -cp $JARS $mainClass align-tosca-artifacts $@" + echo $command + $command + result=$? +fi + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/deleteAllProducts.sh b/asdctool/src/main/resources/scripts/deleteAllProducts.sh new file mode 100644 index 0000000000..38e468d5f7 --- /dev/null +++ b/asdctool/src/main/resources/scripts/deleteAllProducts.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# delete all products from titan +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.RemoveUtils" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass remove-products $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/derivedFromAlignment.sh b/asdctool/src/main/resources/scripts/derivedFromAlignment.sh new file mode 100644 index 0000000000..05025a01c0 --- /dev/null +++ b/asdctool/src/main/resources/scripts/derivedFromAlignment.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass align-derived-from-1604 $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/esToCassandraMigration.sh b/asdctool/src/main/resources/scripts/esToCassandraMigration.sh new file mode 100644 index 0000000000..383904c661 --- /dev/null +++ b/asdctool/src/main/resources/scripts/esToCassandraMigration.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.EsToCassandraDataMigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass es-to-cassndra-migration $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/esToCassandraMigrationExportOnly.sh b/asdctool/src/main/resources/scripts/esToCassandraMigrationExportOnly.sh new file mode 100644 index 0000000000..2c8e346f30 --- /dev/null +++ b/asdctool/src/main/resources/scripts/esToCassandraMigrationExportOnly.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.EsToCassandraDataMigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass es-to-cassndra-migration-export-only $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/esToCassandraMigrationImportOnly.sh b/asdctool/src/main/resources/scripts/esToCassandraMigrationImportOnly.sh new file mode 100644 index 0000000000..9ce3ca8aae --- /dev/null +++ b/asdctool/src/main/resources/scripts/esToCassandraMigrationImportOnly.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.EsToCassandraDataMigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass es-to-cassndra-migration-import-only $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/exportGraph.sh b/asdctool/src/main/resources/scripts/exportGraph.sh new file mode 100644 index 0000000000..648cb50669 --- /dev/null +++ b/asdctool/src/main/resources/scripts/exportGraph.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.ExportImportMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass export $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/exportGraphAsGraphMl.sh b/asdctool/src/main/resources/scripts/exportGraphAsGraphMl.sh new file mode 100644 index 0000000000..17d660ce4e --- /dev/null +++ b/asdctool/src/main/resources/scripts/exportGraphAsGraphMl.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.ExportImportMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass export-as-graph-ml $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/exportUsers.sh b/asdctool/src/main/resources/scripts/exportUsers.sh new file mode 100644 index 0000000000..d701c57f92 --- /dev/null +++ b/asdctool/src/main/resources/scripts/exportUsers.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# export all users from titan +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.ExportImportMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass exportusers $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/fix_icons.sh b/asdctool/src/main/resources/scripts/fix_icons.sh new file mode 100644 index 0000000000..230dea7218 --- /dev/null +++ b/asdctool/src/main/resources/scripts/fix_icons.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass fix-icons $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result \ No newline at end of file diff --git a/asdctool/src/main/resources/scripts/fix_issue.sh b/asdctool/src/main/resources/scripts/fix_issue.sh new file mode 100644 index 0000000000..af63ec525d --- /dev/null +++ b/asdctool/src/main/resources/scripts/fix_issue.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass fix-properties $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/groupsAlignment.sh b/asdctool/src/main/resources/scripts/groupsAlignment.sh new file mode 100644 index 0000000000..742b246a48 --- /dev/null +++ b/asdctool/src/main/resources/scripts/groupsAlignment.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Groups Alignment +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass align-groups $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/importGraph.sh b/asdctool/src/main/resources/scripts/importGraph.sh new file mode 100644 index 0000000000..ffdd2fddb0 --- /dev/null +++ b/asdctool/src/main/resources/scripts/importGraph.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.ExportImportMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass import $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/populateComponentCache.sh b/asdctool/src/main/resources/scripts/populateComponentCache.sh new file mode 100644 index 0000000000..79ddbf822e --- /dev/null +++ b/asdctool/src/main/resources/scripts/populateComponentCache.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Groups Alignment +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass populate-component-cache $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/python/duplicates.py b/asdctool/src/main/resources/scripts/python/duplicates.py new file mode 100644 index 0000000000..be60b05909 --- /dev/null +++ b/asdctool/src/main/resources/scripts/python/duplicates.py @@ -0,0 +1,47 @@ +import json +import sys + +dict = {} +dupliacteUid = {} +#debugFlag = True +debugFlag = False + +def debug(str1, str2=""): + 'print only if debug enabled' + if (debugFlag == True): print str1, str2 + +print 'Number of arguments:', len(sys.argv), 'arguments.' + + +with open(sys.argv[1]) as json_file: + json_data = json.load(json_file) + for x in json_data['vertices']: + uid = None + nodeLabel=x.get('nodeLabel') + debug(nodeLabel) + if ( nodeLabel == 'user' ): + uid = x['userId'] + elif ( nodeLabel == 'tag' ): + uid = x['name'] + elif ( nodeLabel == None ): + pass + elif ( nodeLabel == 'lockNode' ): + uid = x.get('uid') + else: uid = x['uid'] + + debug(nodeLabel, uid) + + existId = dict.get(uid) + if (existId == None): + dict[uid] = x.get('_id') + else: + dupliacteUid[uid] = existId + + print dupliacteUid + +# with open('data.txt', 'w') as outfile: +# json.dump(json_data, outfile) + + + +# print x['uid'] diff --git a/asdctool/src/main/resources/scripts/python/duplicatesAndRemove.py b/asdctool/src/main/resources/scripts/python/duplicatesAndRemove.py new file mode 100644 index 0000000000..a4bd35dd2b --- /dev/null +++ b/asdctool/src/main/resources/scripts/python/duplicatesAndRemove.py @@ -0,0 +1,136 @@ +import json +import sys, getopt +from collections import OrderedDict + +dict = {} +dupliacteUid = {} +#debugFlag = True +debugFlag = False + +def join_strings(lst): + concat = "" + for string in lst: + if (string != None): + if (type(string) == int): + string = str(string) + concat += (string + " ") + return concat + +def debug(desc, *args): + 'print only if debug enabled' + if (debugFlag == True): + print desc, join_strings(args) + +def log(desc, arg): + 'print log info' + print desc, arg + +def getUid(vertex): + uid = None + nodeLabel=vertex.get('nodeLabel') + debug(nodeLabel) + if ( nodeLabel == 'user' ): + uid = vertex['userId'] + elif ( nodeLabel == 'tag' ): + uid = vertex['name'] + elif ( nodeLabel == None ): + pass + elif ( nodeLabel == 'lockNode' ): + uid = vertex.get('uid') + else: uid = vertex['uid'] + + debug(nodeLabel, uid) + + return uid + +def generateFile(inputFile, outputFile): + + with open(inputFile) as json_file: + dupliacteUid = {} + json_data = json.load(json_file) + for x in json_data['vertices']: + uid = getUid(x) + + existId = dict.get(uid) + if (existId == None): + dict[uid] = x.get('_id') + else: + dupliacteUid[uid] = existId + + log("duplicate ids", dupliacteUid) + + json_data_vertices = json_data['vertices'] + log("number of vertices is", len(json_data_vertices)) + + ids = {} + deleteIndexes = [] + + for i in xrange(len(json_data_vertices)): + #print "****** ", i, " *************" + #print json_data_vertices[i] + id = json_data_vertices[i]["_id"] + uid = getUid(json_data_vertices[i]) + isDuplicateId = dupliacteUid.get(uid) + if (isDuplicateId != None): + debug("uid to id pair", uid if uid != None else 'None', id) + value = ids.get(uid) + if (value == None): + list = [id,] + ids[uid] = list + else: + value.append(id) + deleteIndexes.append(id) + + log("ids", ids) + log("deleteIndexes", deleteIndexes) + log("deleteIndexes size", len(deleteIndexes)) + + filter_vertex = [ x for x in json_data_vertices if x.get('_id') not in deleteIndexes ] + json_data['vertices'] = filter_vertex + + log("number of vertexes after filter", len(filter_vertex)) + + json_data_edges = json_data['edges'] + + log("number of edges", len(json_data_edges)) + + filter_edge = [ x for x in json_data_edges if x['_outV'] not in (deleteIndexes) and x['_inV'] not in (deleteIndexes) ] + json_data['edges'] = filter_edge + + log("number of edges after filter", len(json_data['edges'])) + + json_data = OrderedDict(sorted(json_data.items(), key=lambda t: t[0], reverse=True)) + + with open(outputFile, 'w') as outfile: + #json.dump(json_data, outfile) + json.dump(json_data, outfile) + log("output file is", outputFile); + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + inputfile = None + outputfile = '' + try: + opts, args = getopt.getopt(argv,"h:i:o:",["ifile=","ofile="]) + except getopt.GetoptError: + print sys.argv[0], '-i ' + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print sys.argv[0], '-i ' + sys.exit(3) + elif opt in ("-i", "--ifile"): + inputfile = arg + + if ( inputfile == None ): + print sys.argv[0] ,'-i ' + sys.exit(3) + + print 'Input file is "', inputfile + generateFile(inputfile, inputfile + '.noduplicates') + + +if __name__ == "__main__": + main(sys.argv[1:]) + +# print x['uid'] diff --git a/asdctool/src/main/resources/scripts/python/graphSize.py b/asdctool/src/main/resources/scripts/python/graphSize.py new file mode 100644 index 0000000000..6c36ec6844 --- /dev/null +++ b/asdctool/src/main/resources/scripts/python/graphSize.py @@ -0,0 +1,56 @@ +import json +import sys, getopt + +dict = {} +dupliacteUid = {} +#debugFlag = True +debugFlag = False + +def debug(desc, *args): + 'print only if debug enabled' + if (debugFlag == True): + print desc, join_strings(args) + +def log(desc, arg): + 'print log info' + print desc, arg + +def graphSize(inputFile): + + with open(inputFile) as json_file: + json_data = json.load(json_file) + + json_data_vertices = json_data['vertices'] + log("number of vertices is", len(json_data_vertices)) + + json_data_edges = json_data['edges'] + log("number of edges is", len(json_data_edges)) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + inputfile = None + outputfile = '' + try: + opts, args = getopt.getopt(argv,"h:i:o:",["ifile=","ofile="]) + except getopt.GetoptError: + print sys.argv[0], '-i ' + sys.exit(2) + for opt, arg in opts: + if opt == '-h': + print sys.argv[0], '-i ' + sys.exit(3) + elif opt in ("-i", "--ifile"): + inputfile = arg + + if ( inputfile == None ): + print sys.argv[0], '-i ' + sys.exit(3) + + print 'Input file is ', inputfile + graphSize(inputfile) + + +if __name__ == "__main__": + main(sys.argv[1:]) + +# print x['uid'] diff --git a/asdctool/src/main/resources/scripts/python/user/exportUsers.py b/asdctool/src/main/resources/scripts/python/user/exportUsers.py new file mode 100644 index 0000000000..e32a3b0a21 --- /dev/null +++ b/asdctool/src/main/resources/scripts/python/user/exportUsers.py @@ -0,0 +1,122 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json + + +################################################################################################################################################ +# # +# Export all active users to file - for 1602+ # +# # +# activation : # +# python exportUsers.py [-i | --ip=] [-p | --port= ] [-f | --ofile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python exportUsers.py [-f | --ofile= ] # +# # +################################################################################################################################################ + +ALL_USERS_SUFFIX = '/sdc2/rest/v1/user/users' + +def errorAndExit(errorCode, errorDesc): + if ( errorCode > 0 ): + print("status=" + str(errorCode) + ". " + errorDesc) + else: + print("status=" + str(errorCode)) + sys.exit(errorCode) + +def getUsers(beHost, bePort, adminUser): + + try: + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + ALL_USERS_SUFFIX + print(url) + c.setopt(c.URL, url) + c.setopt(c.WRITEFUNCTION, buffer.write) + #c.setopt(c.WRITEFUNCTION, lambda x: None) + adminHeader = 'USER_ID: ' + adminUser + c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + res = c.perform() + #print(res) + + #print('Status: %d' % c.getinfo(c.RESPONSE_CODE)) + + c.close() + + body = buffer.getvalue() + + #print(body) + + return (body, None) + + except Exception as inst: + print inst + #print type(inst) # the exception instance + #print inst.args # arguments stored in .args + #print inst # __str__ allows args to be printed directly + #x, y = inst.args + #print 'x =', x + + return (None, inst) + + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-f | --ofile= ]' + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + adminHeader = 'jh0003' + beHost = 'localhost' + bePort = '8080' + outputfile = None + + try: + opts, args = getopt.getopt(argv,"i:p:f:h:",["ip=","port=","ofile="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-f", "--ofile"): + outputfile = arg + + print 'be host =',beHost,', be port =', bePort,', output file =',outputfile + + if ( outputfile == None ): + usage() + sys.exit(3) + + users = getUsers(beHost, bePort, adminHeader) + error = users[1] + body = users[0] + + if ( error != None ): + errorAndExit(5, str(error)) + + #print body + + io = StringIO(body) + usersAsJson = json.load(io) + + writeFile = open(outputfile, 'w') + + json.dump(usersAsJson, writeFile) + + writeFile.close() + + print("-------------------------------------------") + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/asdctool/src/main/resources/scripts/python/user/importUsers.py b/asdctool/src/main/resources/scripts/python/user/importUsers.py new file mode 100644 index 0000000000..669cbbe6f2 --- /dev/null +++ b/asdctool/src/main/resources/scripts/python/user/importUsers.py @@ -0,0 +1,215 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy + +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + + +def importUsers(beHost, bePort, users, adminUser): + + result = [] + + for user in users: + + #print("Going to add user " + user['userId']) + + getRes = getUser(beHost, bePort, user) + userId = getRes[0] + error = getRes[1] + #print error + if ( error != None and error == 404 ): + res = createUser(beHost, bePort, user ,adminUser) + result.append(res) + else: + if ( error == 200 ): + curResult = (userId, 409) + result.append(curResult) + else: + result.append(getRes) + + return result + + +def convertUsersToCreationObject(users): + + cloneUsers = copy.deepcopy(users) + for user in cloneUsers: + #print user + if (user.get('fullName') != None): + del user['fullName'] + #user['userId'] = user['userId'] + '1' + #print user + + return cloneUsers + +def getUser(beHost, bePort, user): + + userId = user['userId'] + try: + buffer = StringIO() + c = pycurl.Curl() + + #print type(userId) + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/user/' + str(userId) + c.setopt(c.URL, url) + + #adminHeader = 'USER_ID: ' + adminUser + c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json']) + c.setopt(c.WRITEFUNCTION, lambda x: None) + res = c.perform() + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + #print("After get response code") + responseCode = c.getinfo(c.RESPONSE_CODE) + + #print('Status: ' + str(responseCode)) + + c.close() + + return (userId, httpRes) + + except Exception as inst: + print(inst) + return (userId, None) + + + +def createUser(beHost, bePort, user, adminUser): + + userId = user['userId'] + try: + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/user' + c.setopt(c.URL, url) + c.setopt(c.POST, 1) + + adminHeader = 'USER_ID: ' + adminUser + c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + + data = json.dumps(user) + c.setopt(c.POSTFIELDS, data) + + c.setopt(c.WRITEFUNCTION, lambda x: None) + #print("before perform") + res = c.perform() + #print(res) + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + #print("After get response code") + responseCode = c.getinfo(c.RESPONSE_CODE) + + #print('Status: ' + str(responseCode)) + + c.close() + + return (userId, httpRes) + + except Exception as inst: + print(inst) + return (userId, None) + + +def errorAndExit(errorCode, errorDesc): + if ( errorCode > 0 ): + print("status=" + str(errorCode) + ". " + errorDesc) + else: + print("status=" + str(errorCode)) + sys.exit(errorCode) + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-f | --ifile= ]' + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + inputfile = None + + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:f:h:",["ip=","port=","ifile="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-f", "--ifile"): + inputfile = arg + + print 'be host =',beHost,', be port =', bePort,', users file =',inputfile + + if ( inputfile == None ): + usage() + sys.exit(3) + + print 'Input file is ', inputfile + + usersFile = open(inputfile) + + json_data = json.load(usersFile) + + #print json_data + + cloneUsers = convertUsersToCreationObject(json_data) + + activeUsers = filter(lambda x: x['status'] == 'ACTIVE', cloneUsers) + + #print activeUsers + + resultTable = importUsers(beHost, bePort, activeUsers, adminUser) + + g = lambda x: x[1] != 201 and x[1] != 409 + + result = filter(g, resultTable) + + if ( len(result) > 0 ): + #print("ERROR: Failed to load the users " + ', '.join(map(lambda x: x[0],result))) + errorAndExit(3, "Failed to load the users " + ', '.join(map(lambda x: x[0],result))) + + g = lambda x: x[1] == 409 + result = filter(g, resultTable) + + print("-------------------------------------------") + print("Existing users: " + ', '.join(map(lambda x: x[0],result))) + + result = filter(lambda x: x[1] == 201, resultTable) + if ( len(result) == 0 ): + print("-------------------------------------------") + print("No NEW user was loaded. All users are already exist") + print("-------------------------------------------") + else: + print("-------------------------------------------") + print("Loaded users: " + ', '.join(map(lambda x: x[0],result))) + print("-------------------------------------------") + + errorAndExit(0, None) + + +if __name__ == "__main__": + main(sys.argv[1:]) diff --git a/asdctool/src/main/resources/scripts/schemaCreation.sh b/asdctool/src/main/resources/scripts/schemaCreation.sh new file mode 100644 index 0000000000..657db5e6f1 --- /dev/null +++ b/asdctool/src/main/resources/scripts/schemaCreation.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.DataSchemaMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass create-cassandra-structures $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/updateIsVnf.sh b/asdctool/src/main/resources/scripts/updateIsVnf.sh new file mode 100644 index 0000000000..62bfb9cd66 --- /dev/null +++ b/asdctool/src/main/resources/scripts/updateIsVnf.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +######################################################################## +# +# Example: +# ./updateIsVnf.sh ../config/titan.properties Bservice,Myservice +# +######################################################################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.UpdateIsVnfMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass updateIsVnfTrue $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/src/main/resources/scripts/vfcNameAlignment.sh b/asdctool/src/main/resources/scripts/vfcNameAlignment.sh new file mode 100644 index 0000000000..10fbb257ef --- /dev/null +++ b/asdctool/src/main/resources/scripts/vfcNameAlignment.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +############################## +# Data Migration +############################## + +CURRENT_DIR=`pwd` +BASEDIR=$(dirname $0) + +if [ ${BASEDIR:0:1} = "/" ] +then + FULL_PATH=$BASEDIR +else + FULL_PATH=$CURRENT_DIR/$BASEDIR +fi + +source ${FULL_PATH}/baseOperation.sh + +mainClass="org.openecomp.sdc.asdctool.main.MigrationMenu" + +command="java $JVM_LOG_FILE -cp $JARS $mainClass align-vfc-names-1604 $@" +echo $command + +$command +result=$? + +echo "***********************************" +echo "***** $result *********************" +echo "***********************************" + +exit $result + + diff --git a/asdctool/tarball.xml b/asdctool/tarball.xml new file mode 100644 index 0000000000..62deb75e10 --- /dev/null +++ b/asdctool/tarball.xml @@ -0,0 +1,26 @@ + + bin + + tar + + + + ${project.build.directory}/${project.artifactId}-${project.version}-jar-with-dependencies.jar + ./ + ${project.artifactId}-${project.version}-jar-with-dependencies.jar + + + + + + src/main/resources/scripts + scripts + + + src/main/resources/config + config + + + diff --git a/catalog-be/.gitignore b/catalog-be/.gitignore new file mode 100644 index 0000000000..fbfe5d3901 --- /dev/null +++ b/catalog-be/.gitignore @@ -0,0 +1,8 @@ +/target +/target +/target + +/target +/target +/target +/build diff --git a/catalog-be/.pydevproject b/catalog-be/.pydevproject new file mode 100644 index 0000000000..7ff1370cd2 --- /dev/null +++ b/catalog-be/.pydevproject @@ -0,0 +1,5 @@ + + +python 2.7 +Default + diff --git a/catalog-be/README.txt b/catalog-be/README.txt new file mode 100644 index 0000000000..575484081f --- /dev/null +++ b/catalog-be/README.txt @@ -0,0 +1,41 @@ +#open rpm +#install jetty +#run installJettyBase.sh +#copy jvm.properties to base +#export variables +#run startJetty.sh + +#Properties: + + STOP.PORT=[number] + The port to use to stop the running Jetty server. + Required along with STOP.KEY if you want to use the --stop option above. + + STOP.KEY=[alphanumeric] + The passphrase defined to stop the server. + Requried along with STOP.PORT if you want to use the --stop option above. + + STOP.WAIT=[number] + The time (in seconds) to wait for confirmation that the running + Jetty server has stopped. If not specified, the stopper will wait + indefinitely. Use in conjunction with the --stop option. + + +#Upload Normative types: +# 1. create zip file containing the yaml +# 2. create json string (payloadName should be the yml file name): { +# "payloadName":"normative-types-new-root.yml", +# "userId":"adminid", +# "resourceName":"tosca.nodes.Root", +# "description":"Represents a generic software component that can be managed and run by a Compute Node Type.", +# "resourceIconPath":"defaulticon", +# "category":"Abstract", +# "tags":["Root"] +# } +# +# +# 3. run curl command: curl -v -F resourceMetadata= -F resourceZip=@ /sdc2/rest/v1/catalog/upload/multipart +# e.g.: +# curl -v -F resourceMetadata='{"payloadName":"normative-types-new-root.yml","userId":"adminid","resourceName":"tosca.nodes.Root","description":"Represents a generic software component that can be managed and run by a Compute Node Type.","resourceIconPath":"defaulticon","category":"Abstract","tags":["Root"]}' -F resourceZip=@/var/tmp/normative-types-new-root.zip localhost:8080/sdc2/rest/v1/catalog/upload/multipart + +# diff --git a/catalog-be/normatives.xml b/catalog-be/normatives.xml new file mode 100644 index 0000000000..059867224e --- /dev/null +++ b/catalog-be/normatives.xml @@ -0,0 +1,18 @@ + + bin + + tar.gz + + + + src/main/resources/import + import + + + src/main/resources/scripts + scripts + + + diff --git a/catalog-be/pom.xml b/catalog-be/pom.xml new file mode 100644 index 0000000000..ddf421a046 --- /dev/null +++ b/catalog-be/pom.xml @@ -0,0 +1,790 @@ + + + 4.0.0 + + catalog-be + war + + + org.openecomp.sdc + sdc-main + 1.0.0-SNAPSHOT + + + + + 2.1.0-M2 + + + + + + + + + + + com.fasterxml.jackson.dataformat + jackson-dataformat-yaml + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-core + ${jackson.version} + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.annotations.version} + + + + com.sun.jersey.contribs + jersey-multipart + 2.14 + + + + + + + + + + org.openecomp.sdc + security-utils + ${security-utils.version} + compile + + + + com.tinkerpop.blueprints + blueprints-sail-graph + 2.6.0 + true + + + org.slf4j + slf4j-log4j12 + + + + + + com.tinkerpop.blueprints + blueprints-graph-sail + 2.5.0 + true + + + + + com.wordnik + swagger-jersey2-jaxrs + compile + 1.5.1-M2 + + + + org.glassfish.jersey.containers + jersey-container-servlet-core + + + + + org.openecomp.sdc + common-app-api + ${common-app-api.version} + compile + + + + org.openecomp.sdc.be + common-be + ${common-be.version} + compile + + + org.openecomp.sdc.be + catalog-dao + ${catalog-dao.version} + compile + + + + org.openecomp.sdc.be + catalog-model + ${catalog-model.version} + compile + + + + + org.slf4j + slf4j-api + compile + + + + ch.qos.logback + logback-classic + compile + + + + ch.qos.logback + logback-core + compile + + + + + org.yaml + snakeyaml + compile + + + + + + org.apache.commons + commons-jci-core + compile + + + + + + com.google.code.gson + gson + compile + + + + + + + + + + org.glassfish.jersey.media + jersey-media-json-jackson + compile + + + + + + org.apache.httpcomponents + httpclient + compile + + + + org.apache.httpcomponents + httpcore + compile + + + + commons-logging + commons-logging + compile + + + + commons-codec + commons-codec + compile + + + + + javax.servlet + servlet-api + provided + + + + + org.eclipse.jgit + org.eclipse.jgit + 3.4.1.201406201815-r + + + + + + + org.springframework + spring-core + compile + + + + org.springframework + spring-context + compile + + + + org.springframework + spring-web + compile + + + + org.springframework + spring-webmvc + compile + + + + org.springframework + spring-aop + compile + + + + org.springframework + spring-beans + compile + + + + org.springframework + spring-expression + compile + + + + org.codehaus.groovy + groovy-all + compile + + + + org.codehaus.janino + janino + compile + + + + org.codehaus.janino + commons-compiler + 3.0.6 + compile + + + + + com.google.guava + guava + + + + + com.thinkaurelius.titan + titan-core + ${titan.version} + compile + + + org.json + json + + + slf4j-log4j12 + org.slf4j + + + + + + com.thinkaurelius.titan + titan-cassandra + + ${titan.version} + + compile + + + org.slf4j + slf4j-log4j12 + + + io.netty + netty-all + + + + + + org.apache.commons + commons-lang3 + compile + + + + + com.googlecode.json-simple + json-simple + compile + + + + + org.elasticsearch + elasticsearch + compile + + + + + org.elasticsearch.plugin + shield + ${elastic-search.version} + compile + + + + org.functionaljava + functionaljava + compile + + + + + com.jcabi + jcabi-aspects + compile + + + + org.aspectj + aspectjrt + compile + + + + + com.att.nsa + cambriaClient + 0.0.1 + compile + + + + com.att.nsa + saClientLibrary + 0.0.1 + compile + + + org.slf4j + slf4j-log4j12 + + + + + + org.json + json + 20131018 + compile + + + org.apache.tinkerpop + tinkergraph-gremlin + 3.0.1-incubating + compile + + + + org.apache.tinkerpop + gremlin-groovy + 3.0.1-incubating + compile + + + + + com.datastax.cassandra + cassandra-driver-core + ${cassandra.driver.version} + compile + + + com.datastax.cassandra + cassandra-driver-mapping + ${cassandra.driver.version} + compile + + + + + + org.openecomp.ecompsdkos + ecompFW + ${ecomp.version} + compile + + + com.att.nsa + cambriaClient + + + slf4j-log4j12 + org.slf4j + + + + + + + org.openecomp.sdc.sdc_common + openecomp-sdc-artifact-generator-api + ${artefact-gen-api.version} + compile + + + + org.openecomp.sdc.sdc_common + openecomp-sdc-artifact-generator-core + ${artefact-gen-core.version} + compile + + + + org.openecomp.sdc.sdc_common + openecomp-common-lib + ${dox-common-lib.version} + pom + + + + + + org.eclipse.jetty + jetty-proxy + ${jetty.version} + compile + + + + + + org.eclipse.jetty + jetty-servlets + ${jetty.servlets.version} + compile + + + + + org.glassfish.jersey.test-framework.providers + jersey-test-framework-provider-bundle + pom + test + + + + org.eclipse.jetty + jetty-servlet + test + + + + org.eclipse.jetty + jetty-webapp + test + + + + junit + junit + test + + + + org.mockito + mockito-all + test + + + + org.springframework + spring-test + test + + + + org.springframework + spring-tx + ${spring.version} + test + + + + + + + + ${project.artifactId}-${project.version} + + + + + maven-surefire-plugin + + + src/test/resources/logback-test.xml + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.6 + + WEB-INF\lib\slf4j-log4j*.jar, + WEB-INF/classes/elasticsearch.yml, + WEB-INF/classes/portal.properties + + + ${parent.version} + + + + true + true + + + + + + src/main/resources + + src/main/resources/swagger + + + true + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + package + + copy-dependencies + + + compile + + + + copy-installed + install + + copy + + + + + ${project.groupId} + ${project.artifactId} + ${project.version} + ${project.packaging} + + + ${project.parent.basedir}/sdc-os-chef/sdc-backend/ + + + + + + + + com.jcabi + jcabi-maven-plugin + ${jcabi.plugin.version} + + + + ajc + + + + + + + + + + com.googlecode.maven-download-plugin + download-maven-plugin + 1.2.1 + + + swagger-ui + + wget + + + https://github.com/swagger-api/swagger-ui/archive/v${swagger-ui-version}.tar.gz + true + ${project.build.directory} + + + + + + + + + maven-resources-plugin + 2.6 + + + + copy-resources + process-resources + + copy-resources + + + target/${project.artifactId}-${project.version} + + + ${project.build.directory}/swagger-ui-${swagger-ui-version}/dist + true + + index.html + + + + + + + + copy-normatives-backend + install + + copy-resources + + + ${project.parent.basedir}/sdc-os-chef/sdc-backend/chef-repo/cookbooks/sdc-normatives/files/default + + + ./target + + normatives.tar.gz + + + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + 2.6 + + + normatives + package + + single + + + normatives + false + ${project.basedir}/normatives.xml + + + + + + + + + + + + + + + org.eclipse.m2e + lifecycle-mapping + 1.0.0 + + + + + + com.googlecode.maven-download-plugin + download-maven-plugin + [1.2.1,) + + wget + + + + + + + + + + com.jcabi + jcabi-maven-plugin + [0.0,) + + ajc + + + + + + + + + + + + + org.apache.maven.plugins + maven-deploy-plugin + 2.7 + + + + + + + + + + diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/api/IAuditingManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/api/IAuditingManager.java new file mode 100644 index 0000000000..36b79c2d9c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/api/IAuditingManager.java @@ -0,0 +1,31 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.auditing.api; + +import java.util.EnumMap; + +import javax.servlet.ServletContext; + +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; + +public interface IAuditingManager { + void auditEvent(EnumMap auditingFields); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatConstants.java b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatConstants.java new file mode 100644 index 0000000000..eb14b5afe7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatConstants.java @@ -0,0 +1,258 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.auditing.impl; + +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; + +public interface AuditingLogFormatConstants { + + static AuditingFieldsKeysEnum[] DISTRIBUTION_REGISTRATION_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_NOTIFICATION_TOPIC_NAME, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TOPIC_NAME}; + + static AuditingFieldsKeysEnum[] DISTRIBUTION_DOWNLOAD_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] GET_UEB_CLUSTER_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_DESC + }; + + static AuditingFieldsKeysEnum[] DISTRIBUTION_DEPLOY_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] DISTRIBUTION_STATUS_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TOPIC_NAME, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] DISTRIBUTION_NOTIFY_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] ADD_REMOVE_TOPIC_KEY_ACL_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ROLE, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, + AuditingFieldsKeysEnum.AUDIT_STATUS + }; + + static AuditingFieldsKeysEnum[] CREATE_TOPIC_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, + AuditingFieldsKeysEnum.AUDIT_STATUS + }; + + static AuditingFieldsKeysEnum[] ACTIVATE_DISTRIBUTION_ARRAY ={ + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] CHANGE_DISTRIBUTION_STATUS_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT + }; + + static AuditingFieldsKeysEnum[] CREATE_RESOURCE_TEMPLATE_SUFFIX_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] CREATE_RESOURCE_TEMPLATE_PREFIX_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE + }; + + static AuditingFieldsKeysEnum[] USER_ACCESS_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_USER_UID, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] USER_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_USER_UID, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] AUTH_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_AUTH_URL, + AuditingFieldsKeysEnum.AUDIT_AUTH_USER, + AuditingFieldsKeysEnum.AUDIT_AUTH_STATUS, + AuditingFieldsKeysEnum.AUDIT_AUTH_REALM + }; + + static AuditingFieldsKeysEnum[] ECOMP_USER_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_ECOMP_USER, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] CATEGORY_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_CATEGORY_NAME, + AuditingFieldsKeysEnum.AUDIT_SUB_CATEGORY_NAME, + AuditingFieldsKeysEnum.AUDIT_GROUPING_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] GET_USERS_LIST_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_USER_DETAILS, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + + static AuditingFieldsKeysEnum[] GET_CATEGORY_HIERARCHY_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_DETAILS, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + static AuditingFieldsKeysEnum[] USER_ADMIN_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_USER_BEFORE, + AuditingFieldsKeysEnum.AUDIT_USER_AFTER, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + static AuditingFieldsKeysEnum[] EXTERNAL_GET_ASSET_LIST_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + static AuditingFieldsKeysEnum[] EXTERNAL_GET_ASSET_TEMPLATE_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + static AuditingFieldsKeysEnum[] EXTERNAL_DOWNLOAD_ARTIFACT_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; + static AuditingFieldsKeysEnum[] EXTERNAL_CRUD_API_ARTIFACT_ARRAY = { + AuditingFieldsKeysEnum.AUDIT_ACTION, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, + AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, + AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, + AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, + AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, + AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, + AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, + AuditingFieldsKeysEnum.AUDIT_STATUS, + AuditingFieldsKeysEnum.AUDIT_DESC + }; +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatUtil.java b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatUtil.java new file mode 100644 index 0000000000..5fec39bbdb --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingLogFormatUtil.java @@ -0,0 +1,268 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.auditing.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.Formatter; +import java.util.Locale; + +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +public class AuditingLogFormatUtil { + + // When adding any new fields here, please keep the convention = + // , with the space between them. + private static Logger log = LoggerFactory.getLogger(AuditingLogFormatUtil.class.getName()); + + // This is the key by which audit marker is recognized in logback.xml + private static String AUDIT_MARKER_STR = "AUDIT_MARKER"; + + public static Marker auditMarker = MarkerFactory.getMarker(AUDIT_MARKER_STR); + + protected static void logAuditEvent(EnumMap auditingFields) { + + StringBuilder sb = new StringBuilder(); + Formatter formatter = new Formatter(sb, Locale.US); + log.trace("logAuditEvent - start"); + + try { + + // Common fields + String modifier = getModifier((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME), (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID)); + Object statusObj = auditingFields.get(AuditingFieldsKeysEnum.AUDIT_STATUS); + String status = null; + if (statusObj != null) { + status = String.valueOf(statusObj); + } + String desc = (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_DESC); + String action = (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_ACTION); + + AuditingActionEnum auditEventType = AuditingActionEnum.getActionByName(action); + StringBuilder formattedEvent = getFormattedEvent(auditingFields, modifier, status, desc, action, auditEventType); + String formattedString = formattedEvent.toString(); + + // This is the only way to fix DE166225 without major refactoring, + // after it was previously agreed with Ella that activity type will + // be the method name. + + if (auditEventType.equals(AuditingActionEnum.AUTH_REQUEST)) { + HttpRequestAuthentication(formattedString); + } else { + log.info(auditMarker, formattedString); + } + } catch (Exception e) { + log.debug("unexpected error occurred: {} {}", e.getMessage(), e); + + } finally { + formatter.close(); + log.trace("logAuditEvent - end"); + } + + } + + private static void HttpRequestAuthentication(String formattedString) { + log.info(auditMarker, formattedString); + } + + private static StringBuilder getFormattedEvent(EnumMap auditingFields, String modifier, String status, String desc, String action, AuditingActionEnum auditEventType) { + + StringBuilder formattedString = new StringBuilder(); + + switch (auditEventType) { + case ADD_USER: + case DELETE_USER: + case UPDATE_USER: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.USER_ADMIN_TEMPLATE_ARRAY, auditingFields); + + break; + case USER_ACCESS: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.USER_ACCESS_TEMPLATE_ARRAY, auditingFields); + break; + case DISTRIBUTION_REGISTER: + case DISTRIBUTION_UN_REGISTER: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.DISTRIBUTION_REGISTRATION_TEMPLATE_ARRAY, auditingFields); + break; + case UPDATE_RESOURCE_METADATA: + case CREATE_RESOURCE: + case IMPORT_RESOURCE: + ArrayList createResourceList = new ArrayList(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_PREFIX_ARRAY)); + createResourceList.addAll(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_SUFFIX_ARRAY)); + if (auditEventType == AuditingActionEnum.IMPORT_RESOURCE) { + createResourceList.add(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TOSCA_NODE_TYPE); + } + AuditingFieldsKeysEnum[] createResourceArray = new AuditingFieldsKeysEnum[100]; + createResourceArray = createResourceList.toArray(createResourceArray); + formattedString = buildStringAccrodingToArray(createResourceArray, auditingFields); + break; + case CHECKIN_RESOURCE: + case CHECKOUT_RESOURCE: + case UNDO_CHECKOUT_RESOURCE: + case CERTIFICATION_REQUEST_RESOURCE: + case START_CERTIFICATION_RESOURCE: + case CERTIFICATION_SUCCESS_RESOURCE: + case FAIL_CERTIFICATION_RESOURCE: + case CANCEL_CERTIFICATION_RESOURCE: + ArrayList checkinFieldsList = new ArrayList(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_PREFIX_ARRAY)); + checkinFieldsList.add(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT); + checkinFieldsList.addAll(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_SUFFIX_ARRAY)); + AuditingFieldsKeysEnum[] checkinFieldsArray = new AuditingFieldsKeysEnum[100]; + checkinFieldsArray = checkinFieldsList.toArray(checkinFieldsArray); + String comment = (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT); + if (comment == null || comment.equals(Constants.NULL_STRING)) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, Constants.EMPTY_STRING); + } + formattedString = buildStringAccrodingToArray(checkinFieldsArray, auditingFields); + break; + case ARTIFACT_UPLOAD: + case ARTIFACT_DELETE: + case ARTIFACT_METADATA_UPDATE: + case ARTIFACT_PAYLOAD_UPDATE: + case ARTIFACT_DOWNLOAD: + ArrayList artifactFieldsList = new ArrayList(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_PREFIX_ARRAY)); + artifactFieldsList.add(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID); + artifactFieldsList.add(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID); + artifactFieldsList.add(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA); + artifactFieldsList.addAll(Arrays.asList(AuditingLogFormatConstants.CREATE_RESOURCE_TEMPLATE_SUFFIX_ARRAY)); + artifactFieldsList.addAll(Arrays.asList(AuditingLogFormatConstants.EXTERNAL_DOWNLOAD_ARTIFACT_ARRAY)); + AuditingFieldsKeysEnum[] artifactFieldsArray = new AuditingFieldsKeysEnum[100]; + artifactFieldsArray = artifactFieldsList.toArray(artifactFieldsArray); + formattedString = buildStringAccrodingToArray(artifactFieldsArray, auditingFields); + break; + case DOWNLOAD_ARTIFACT: + ArrayList downloadArtifactFieldsList = new ArrayList(Arrays.asList(AuditingLogFormatConstants.EXTERNAL_DOWNLOAD_ARTIFACT_ARRAY)); + AuditingFieldsKeysEnum[] downloadArtifactFieldsArray = new AuditingFieldsKeysEnum[100]; + artifactFieldsArray = downloadArtifactFieldsList.toArray(downloadArtifactFieldsArray); + formattedString = buildStringAccrodingToArray(artifactFieldsArray, auditingFields); + break; + case DISTRIBUTION_STATE_CHANGE_REQUEST: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.ACTIVATE_DISTRIBUTION_ARRAY, auditingFields); + break; + case DISTRIBUTION_STATE_CHANGE_APPROV: + case DISTRIBUTION_STATE_CHANGE_REJECT: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.CHANGE_DISTRIBUTION_STATUS_ARRAY, auditingFields); + break; + case CREATE_DISTRIBUTION_TOPIC: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.CREATE_TOPIC_TEMPLATE_ARRAY, auditingFields); + break; + case ADD_KEY_TO_TOPIC_ACL: + case REMOVE_KEY_FROM_TOPIC_ACL: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.ADD_REMOVE_TOPIC_KEY_ACL_TEMPLATE_ARRAY, auditingFields); + break; + case DISTRIBUTION_STATUS: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.DISTRIBUTION_STATUS_TEMPLATE_ARRAY, auditingFields); + break; + case DISTRIBUTION_NOTIFY: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.DISTRIBUTION_NOTIFY_ARRAY, auditingFields); + break; + case DISTRIBUTION_DEPLOY: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.DISTRIBUTION_DEPLOY_ARRAY, auditingFields); + break; + case GET_UEB_CLUSTER: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.GET_UEB_CLUSTER_ARRAY, auditingFields); + break; + case DISTRIBUTION_ARTIFACT_DOWNLOAD: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.DISTRIBUTION_DOWNLOAD_TEMPLATE_ARRAY, auditingFields); + break; + case AUTH_REQUEST: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.AUTH_TEMPLATE_ARRAY, auditingFields); + break; + case ADD_ECOMP_USER_CREDENTIALS: + case GET_ECOMP_USER_CREDENTIALS: + case DELETE_ECOMP_USER_CREDENTIALS: + case UPDATE_ECOMP_USER_CREDENTIALS: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.ECOMP_USER_TEMPLATE_ARRAY, auditingFields); + break; + case ADD_CATEGORY: + case ADD_SUB_CATEGORY: + case ADD_GROUPING: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.CATEGORY_TEMPLATE_ARRAY, auditingFields); + break; + case GET_USERS_LIST: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.GET_USERS_LIST_TEMPLATE_ARRAY, auditingFields); + break; + case GET_CATEGORY_HIERARCHY: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.GET_CATEGORY_HIERARCHY_TEMPLATE_ARRAY, auditingFields); + break; + case GET_ASSET_LIST: + case GET_FILTERED_ASSET_LIST: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.EXTERNAL_GET_ASSET_LIST_TEMPLATE_ARRAY, auditingFields); + break; + case GET_ASSET_METADATA: + case GET_TOSCA_MODEL: + formattedString = buildStringAccrodingToArray(AuditingLogFormatConstants.EXTERNAL_GET_ASSET_TEMPLATE_ARRAY, auditingFields); + break; + case ARTIFACT_UPLOAD_BY_API: + case ARTIFACT_DELETE_BY_API: + case ARTIFACT_UPDATE_BY_API: + ArrayList uploadArtifactFieldsList = new ArrayList(Arrays.asList(AuditingLogFormatConstants.EXTERNAL_CRUD_API_ARTIFACT_ARRAY)); + AuditingFieldsKeysEnum[] uploadArtifactFieldsArray = new AuditingFieldsKeysEnum[100]; + artifactFieldsArray = uploadArtifactFieldsList.toArray(uploadArtifactFieldsArray); + formattedString = buildStringAccrodingToArray(artifactFieldsArray, auditingFields); + break; + default: + break; + } + + return formattedString; + } + + private static StringBuilder buildStringAccrodingToArray(AuditingFieldsKeysEnum[] sortedFieldsArray, EnumMap auditingFields) { + StringBuilder formattedString = new StringBuilder(); + for (int i = 0; i < sortedFieldsArray.length; i++) { + AuditingFieldsKeysEnum key = sortedFieldsArray[i]; + + Object fieldVal = auditingFields.get(key); + if (fieldVal != null) { + formattedString.append(key.getDisplayName()).append(" = \"").append(fieldVal).append("\""); + if (i < sortedFieldsArray.length - 1) { + formattedString.append(" "); + } + } + } + return formattedString; + } + + protected static String getModifier(String modifierName, String modifierUid) { + if (modifierUid == null || modifierUid.equals(Constants.EMPTY_STRING)) { + return Constants.EMPTY_STRING; + } + StringBuilder sb = new StringBuilder(); + if (modifierName != null) { + sb.append(modifierName); + } + sb.append("(").append(modifierUid).append(")"); + return sb.toString(); + } + + protected static String getUser(String userData) { + StringBuilder sb = new StringBuilder(); + sb.append(userData); + return sb.toString(); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingManager.java new file mode 100644 index 0000000000..aa5afa4a8e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/auditing/impl/AuditingManager.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.auditing.impl; + +import java.util.EnumMap; +import java.util.Map.Entry; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.auditing.api.IAuditingManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.impl.AuditingDao; +import org.openecomp.sdc.be.resources.data.auditing.AuditRecordFactory; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component("auditingManager") +public class AuditingManager implements IAuditingManager { + + private static Logger log = LoggerFactory.getLogger(AuditingManager.class.getName()); + + @Resource + private AuditingDao auditingDao; + @Autowired + private AuditCassandraDao cassandraDao; + + @Override + public void auditEvent(EnumMap auditingFields) { + try { + boolean disableAudit = ConfigurationManager.getConfigurationManager().getConfiguration().isDisableAudit(); + if (disableAudit) { + return; + } + // Adding UUID from thread local + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, ThreadLocalsHolder.getUuid()); + + Object status = auditingFields.get(AuditingFieldsKeysEnum.AUDIT_STATUS); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, String.valueOf(status)); + + // normalizing empty string values - US471661 + normalizeEmptyAuditStringValues(auditingFields); + + // Format modifier + formatModifier(auditingFields); + + // Format user + formatUser(auditingFields); + + // Logging the event + AuditingLogFormatUtil.logAuditEvent(auditingFields); + + // Determining the type of the auditing data object + AuditingActionEnum actionEnum = AuditingActionEnum.getActionByName((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_ACTION)); + log.info("audit event {} of type {}", actionEnum.getName(), actionEnum.getAuditingEsType()); + ActionStatus addRecordStatus = auditingDao.addRecord(auditingFields, actionEnum.getAuditingEsType()); + if (!addRecordStatus.equals(ActionStatus.OK)) { + log.warn("Failed to persist auditing event: {}", addRecordStatus.name()); + } + + AuditingGenericEvent recordForCassandra = AuditRecordFactory.createAuditRecord(auditingFields); + if (recordForCassandra != null) { + CassandraOperationStatus result = cassandraDao.saveRecord(recordForCassandra); + if (!result.equals(CassandraOperationStatus.OK)) { + log.warn("Failed to persist to cassandra auditing event: {}", addRecordStatus.name()); + } + } + + } catch (Exception e) { + // Error during auditing shouldn't terminate flow + log.warn("Error during auditEvent: {}", e); + } + } + + private void formatUser(EnumMap auditingFields) { + if (auditingFields.get(AuditingFieldsKeysEnum.AUDIT_USER_UID) != null) { + String userDetails = (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_USER_UID); + + String user = AuditingLogFormatUtil.getUser(userDetails); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_UID, user); + } + } + + private void formatModifier(EnumMap auditingFields) { + String modifier = AuditingLogFormatUtil.getModifier((String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME), (String) auditingFields.get(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID)); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier); + auditingFields.remove(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME); + } + + private void normalizeEmptyAuditStringValues(EnumMap auditingFields) { + for (Entry auditingEntry : auditingFields.entrySet()) { + if (auditingEntry.getKey().getValueClass().equals(String.class)) { + String auditingValue = (String) auditingEntry.getValue(); + boolean isEmpty = false; + if (auditingValue != null) { + String trimmedValue = auditingValue.trim(); + if ((trimmedValue.equals(Constants.EMPTY_STRING)) || trimmedValue.equals(Constants.NULL_STRING) || trimmedValue.equals(Constants.DOUBLE_NULL_STRING)) { + isEmpty = true; + } + } else {// is null + isEmpty = true; + } + // Normalizing to "" + if (isEmpty) { + auditingEntry.setValue(Constants.EMPTY_STRING); + } + } + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/AsdcComponentsCleanerTask.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/AsdcComponentsCleanerTask.java new file mode 100644 index 0000000000..b3b842b9e4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/AsdcComponentsCleanerTask.java @@ -0,0 +1,175 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.clean; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.CleanComponentsConfiguration; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("asdcComponentsCleaner") +public class AsdcComponentsCleanerTask implements Runnable { + + private static Logger log = LoggerFactory.getLogger(AsdcComponentsCleanerTask.class.getName()); + + @javax.annotation.Resource + private ComponentsCleanBusinessLogic componentsCleanBusinessLogic = null; + + private List componentsToClean; + private long cleaningIntervalInMinutes; + + private ScheduledExecutorService scheduledService = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("ComponentsCleanThread-%d").build()); + ScheduledFuture scheduledFuture = null; + + @PostConstruct + public void init() { + log.trace("Enter init method of AsdcComponentsCleaner"); + Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); + CleanComponentsConfiguration cleanComponentsConfiguration = configuration.getCleanComponentsConfiguration(); + + if (cleanComponentsConfiguration == null) { + log.info("ERROR - configuration is not valid!!! missing cleanComponentsConfiguration"); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeComponentCleanerSystemError, "AsdcComponentsCleanerTask.init()", "AsdcComponentsCleanerTask.init()"); + BeEcompErrorManager.getInstance().logBeComponentCleanerSystemError("AsdcComponentsCleanerTask-init", "fecth configuration"); + return; + + } + componentsToClean = new ArrayList(); + List components = cleanComponentsConfiguration.getComponentsToClean(); + if (components == null) { + log.info("no component were configured for cleaning"); + } + for (String component : components) { + NodeTypeEnum typeEnum = NodeTypeEnum.getByNameIgnoreCase(component); + if (typeEnum != null) + componentsToClean.add(typeEnum); + } + + long intervalInMinutes = cleanComponentsConfiguration.getCleanIntervalInMinutes(); + + if (intervalInMinutes < 1) { + log.warn("cleaningIntervalInMinutes value should be greater than or equal to 1 minute. use default"); + intervalInMinutes = 60; + } + cleaningIntervalInMinutes = intervalInMinutes; + + startTask(); + + log.trace("End init method of AsdcComponentsCleaner"); + } + + @PreDestroy + public void destroy() { + this.stopTask(); + shutdownExecutor(); + } + + public void startTask() { + + log.debug("start task for cleaning components"); + + try { + + if (scheduledService != null) { + log.debug("Start Cleaning components task. interval {} minutes", cleaningIntervalInMinutes); + scheduledFuture = scheduledService.scheduleAtFixedRate(this, 5, cleaningIntervalInMinutes, TimeUnit.MINUTES); + + } + } catch (Exception e) { + log.debug("unexpected error occured", e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeComponentCleanerSystemError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeComponentCleanerSystemError("AsdcComponentsCleanerTask-startTask", e.getMessage()); + + } + } + + public void stopTask() { + if (scheduledFuture != null) { + boolean result = scheduledFuture.cancel(true); + log.debug("Stop cleaning task. result = {}", result); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + if (false == result) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeComponentCleanerSystemError, methodName, "try to stop the polling task"); + BeEcompErrorManager.getInstance().logBeComponentCleanerSystemError("AsdcComponentsCleanerTask-stopTask", "try to stop the polling task"); + } + scheduledFuture = null; + } + + } + + private void shutdownExecutor() { + if (scheduledService == null) + return; + + scheduledService.shutdown(); // Disable new tasks from being submitted + try { + // Wait a while for existing tasks to terminate + if (!scheduledService.awaitTermination(60, TimeUnit.SECONDS)) { + scheduledService.shutdownNow(); // Cancel currently executing + // tasks + // Wait a while for tasks to respond to being cancelled + if (!scheduledService.awaitTermination(60, TimeUnit.SECONDS)) + log.debug("Pool did not terminate"); + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + scheduledService.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + + @Override + public void run() { + try { + componentsCleanBusinessLogic.cleanComponents(componentsToClean); + } catch (Throwable e) { + log.error("unexpected error occured", e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeComponentCleanerSystemError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeComponentCleanerSystemError("AsdcComponentsCleanerTask-run", e.getMessage()); + } + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/ComponentsCleanBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/ComponentsCleanBusinessLogic.java new file mode 100644 index 0000000000..b12b55ba8b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/clean/ComponentsCleanBusinessLogic.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.clean; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.components.impl.BaseBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("componentsCleanBusinessLogic") +public class ComponentsCleanBusinessLogic extends BaseBusinessLogic { + + @Autowired + private ResourceBusinessLogic resourceBusinessLogic; + + @Autowired + private ServiceBusinessLogic serviceBusinessLogic; + + private static Logger log = LoggerFactory.getLogger(ComponentsCleanBusinessLogic.class.getName()); + + public Map, ResponseFormat>> cleanComponents(List componentsToClean) { + + Map, ResponseFormat>> cleanedComponents = new HashMap, ResponseFormat>>(); + + log.trace("start cleanComponents"); + for (NodeTypeEnum type : componentsToClean) { + switch (type) { + case Resource: + processDeletionForType(cleanedComponents, NodeTypeEnum.Resource, resourceBusinessLogic); + break; + case Service: + processDeletionForType(cleanedComponents, NodeTypeEnum.Service, serviceBusinessLogic); + break; + default: + log.debug("{} component type does not have cleaning method defined", type); + break; + } + } + + log.trace("end cleanComponents"); + return cleanedComponents; + } + + private void processDeletionForType(Map, ResponseFormat>> cleanedComponents, NodeTypeEnum type, ComponentBusinessLogic componentBusinessLogic) { + Either, ResponseFormat> deleteMarkedResources = componentBusinessLogic.deleteMarkedComponents(); + if (deleteMarkedResources.isRight()) { + log.debug("failed to clean deleted components of type {}. error: {}", type, deleteMarkedResources.right().value().getFormattedMessage()); + } else { + if (log.isDebugEnabled()) { + StringBuilder sb = new StringBuilder("list of deleted components - type " + type + ": "); + for (String id : deleteMarkedResources.left().value()) { + sb.append(id).append(", "); + } + log.debug(sb.toString()); + } + } + cleanedComponents.put(type, deleteMarkedResources); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ArtifactInfoImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ArtifactInfoImpl.java new file mode 100644 index 0000000000..e1a1270fe3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ArtifactInfoImpl.java @@ -0,0 +1,196 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; + +public class ArtifactInfoImpl implements IArtifactInfo { + + private String artifactName; + private ArtifactTypeEnum artifactType; + private String artifactURL; + private String artifactChecksum; + private String artifactDescription; + private Integer artifactTimeout; + private String artifactUUID; + private String artifactVersion; + private String generatedFromUUID; + private List relatedArtifacts; + + public ArtifactInfoImpl() { + } + + private ArtifactInfoImpl(ArtifactDefinition artifactDef, String generatedFromUUID, List relatedArtifacts) { + artifactName = artifactDef.getArtifactName(); + artifactType = ArtifactTypeEnum.findType(artifactDef.getArtifactType()); + artifactChecksum = artifactDef.getArtifactChecksum(); + artifactDescription = artifactDef.getDescription(); + artifactTimeout = artifactDef.getTimeout(); + artifactUUID = artifactDef.getArtifactUUID(); + artifactVersion = artifactDef.getArtifactVersion(); + this.relatedArtifacts = relatedArtifacts; + this.generatedFromUUID = generatedFromUUID; + } + + public static List convertToArtifactInfoImpl(Service service, ComponentInstance resourceInstance, Collection list) { + List ret = new ArrayList(); + Map> artifactIdToDef = list.stream().collect(Collectors.groupingBy(ArtifactDefinition::getUniqueId)); + if (list != null) { + for (ArtifactDefinition artifactDef : list) { + String generatedFromUUID = null; + if (artifactDef.getGeneratedFromId() != null && !artifactDef.getGeneratedFromId().isEmpty()) { + ArtifactDefinition artifactFrom = artifactIdToDef.get(artifactDef.getGeneratedFromId()).get(0); + generatedFromUUID = artifactFrom.getArtifactUUID(); + } + ArtifactInfoImpl artifactInfoImpl = new ArtifactInfoImpl(artifactDef, generatedFromUUID, getUpdatedRequiredArtifactsFromNamesToUuids(artifactDef, resourceInstance.getDeploymentArtifacts())); + String artifactURL = ServiceDistributionArtifactsBuilder.buildResourceInstanceArtifactUrl(service, resourceInstance, artifactDef.getArtifactName()); + artifactInfoImpl.setArtifactURL(artifactURL); + ret.add(artifactInfoImpl); + } + } + return ret; + + } + + public static List convertServiceArtifactToArtifactInfoImpl(Service service, Collection list) { + List ret = new ArrayList(); + Map> artifactIdToDef = list.stream().collect(Collectors.groupingBy(ArtifactDefinition::getUniqueId)); + if (list != null) { + for (ArtifactDefinition artifactDef : list) { + String generatedFromUUID = null; + if (artifactDef.getGeneratedFromId() != null && !artifactDef.getGeneratedFromId().isEmpty()) { + ArtifactDefinition artifactFrom = artifactIdToDef.get(artifactDef.getGeneratedFromId()).get(0); + generatedFromUUID = artifactFrom.getArtifactUUID(); + } + ArtifactInfoImpl artifactInfoImpl = new ArtifactInfoImpl(artifactDef, generatedFromUUID, getUpdatedRequiredArtifactsFromNamesToUuids(artifactDef, service.getDeploymentArtifacts())); + String artifactURL = ServiceDistributionArtifactsBuilder.buildServiceArtifactUrl(service, artifactDef.getArtifactName()); + artifactInfoImpl.setArtifactURL(artifactURL); + ret.add(artifactInfoImpl); + } + } + return ret; + + } + + private static List getUpdatedRequiredArtifactsFromNamesToUuids(ArtifactDefinition artifactDefinition, Map artifacts) { + List requiredArtifacts = null; + if (artifactDefinition != null && artifactDefinition.getRequiredArtifacts() != null && !artifactDefinition.getRequiredArtifacts().isEmpty() && artifacts != null && !artifacts.isEmpty()) { + requiredArtifacts = artifacts.values().stream().filter(art -> artifactDefinition.getRequiredArtifacts().contains(art.getArtifactName())).map(art -> art.getArtifactUUID()).collect(Collectors.toList()); + } + return requiredArtifacts; + } + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public ArtifactTypeEnum getArtifactType() { + return artifactType; + } + + public void setArtifactType(ArtifactTypeEnum artifactType) { + this.artifactType = artifactType; + } + + public String getArtifactURL() { + return artifactURL; + } + + public void setArtifactURL(String artifactURL) { + this.artifactURL = artifactURL; + } + + public String getArtifactChecksum() { + return artifactChecksum; + } + + public void setArtifactChecksum(String artifactChecksum) { + this.artifactChecksum = artifactChecksum; + } + + public String getArtifactDescription() { + return artifactDescription; + } + + public void setArtifactDescription(String artifactDescription) { + this.artifactDescription = artifactDescription; + } + + public Integer getArtifactTimeout() { + return artifactTimeout; + } + + public void setArtifactTimeout(Integer artifactTimeout) { + this.artifactTimeout = artifactTimeout; + } + + public List getRelatedArtifacts() { + return relatedArtifacts; + } + + public void setRelatedArtifacts(List relatedArtifacts) { + this.relatedArtifacts = relatedArtifacts; + } + + @Override + public String toString() { + return "ArtifactInfoImpl [artifactName=" + artifactName + ", artifactType=" + artifactType + ", artifactURL=" + artifactURL + ", artifactChecksum=" + artifactChecksum + ", artifactDescription=" + artifactDescription + ", artifactTimeout=" + + artifactTimeout + ", artifactUUID=" + artifactUUID + ", artifactVersion=" + artifactVersion + ", generatedFromUUID=" + generatedFromUUID + ", relatedArtifacts=" + relatedArtifacts + "]"; + } + + public String getArtifactUUID() { + return artifactUUID; + } + + public void setArtifactUUID(String artifactUUID) { + this.artifactUUID = artifactUUID; + } + + public String getArtifactVersion() { + return artifactVersion; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public String getGeneratedFromUUID() { + return generatedFromUUID; + } + + public void setGeneratedFromUUID(String generatedFromUUID) { + this.generatedFromUUID = generatedFromUUID; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaErrorResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaErrorResponse.java new file mode 100644 index 0000000000..149ea2286a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaErrorResponse.java @@ -0,0 +1,86 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.distribution.api.client.CambriaOperationStatus; + +public class CambriaErrorResponse { + + public static final int HTTP_OK = 200; + + public static final int HTTP_INTERNAL_SERVER_ERROR = 500; + + CambriaOperationStatus operationStatus; + Integer httpCode; + List variables = new ArrayList(); + + public CambriaErrorResponse() { + super(); + } + + public CambriaErrorResponse(CambriaOperationStatus operationStatus) { + super(); + this.operationStatus = operationStatus; + } + + public CambriaErrorResponse(CambriaOperationStatus operationStatus, Integer httpCode) { + super(); + this.operationStatus = operationStatus; + this.httpCode = httpCode; + } + + public CambriaOperationStatus getOperationStatus() { + return operationStatus; + } + + public void setOperationStatus(CambriaOperationStatus operationStatus) { + this.operationStatus = operationStatus; + } + + public Integer getHttpCode() { + return httpCode; + } + + public void setHttpCode(Integer httpCode) { + this.httpCode = httpCode; + } + + public void addVariable(String variable) { + variables.add(variable); + } + + public List getVariables() { + return variables; + } + + public void setVariables(List variables) { + this.variables = variables; + } + + @Override + public String toString() { + return "CambriaErrorResponse [operationStatus=" + operationStatus + ", httpCode=" + httpCode + ", variables=" + variables + "]"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaHandler.java new file mode 100644 index 0000000000..3528ed9be3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/CambriaHandler.java @@ -0,0 +1,610 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.security.GeneralSecurityException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.distribution.api.client.CambriaOperationStatus; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.att.nsa.apiClient.http.HttpException; +import com.att.nsa.apiClient.http.HttpObjectNotFoundException; +import com.att.nsa.cambria.client.CambriaBatchingPublisher; +import com.att.nsa.cambria.client.CambriaClient.CambriaApiException; +import com.att.nsa.cambria.client.CambriaClientBuilders.TopicManagerBuilder; +import com.att.nsa.cambria.client.CambriaClientBuilders.PublisherBuilder; +import com.att.nsa.cambria.client.CambriaClientBuilders.ConsumerBuilder; +import com.att.nsa.cambria.client.CambriaClientBuilders.IdentityManagerBuilder; +import com.att.nsa.cambria.client.CambriaConsumer; +import com.att.nsa.cambria.client.CambriaIdentityManager; +import com.att.nsa.cambria.client.CambriaPublisher.message; +import com.att.nsa.cambria.client.CambriaTopicManager; +import com.google.gson.Gson; + +import fj.data.Either; + +public class CambriaHandler { + + private static Logger logger = LoggerFactory.getLogger(CambriaHandler.class.getName()); + + public static String PARTITION_KEY = "asdc" + "aa"; + + private Gson gson = new Gson(); + + /** + * process the response error from Cambria client + * + * @param message + * @return + */ + private Integer processMessageException(String message) { + + String[] patterns = { "(HTTP Status )(\\d\\d\\d)", "(HTTP/\\d.\\d )(\\d\\d\\d)" }; + + Integer result = checkPattern(patterns[0], message, 2); + if (result != null) { + return result; + } + result = checkPattern(patterns[1], message, 2); + + return result; + + } + + /** + * check whether the message has a match with a given pattern inside it + * + * @param patternStr + * @param message + * @param groupIndex + * @return + */ + private Integer checkPattern(String patternStr, String message, int groupIndex) { + Integer result = null; + + Pattern pattern = Pattern.compile(patternStr); + Matcher matcher = pattern.matcher(message); + boolean find = matcher.find(); + if (find) { + String httpCode = matcher.group(groupIndex); + if (httpCode != null) { + try { + result = Integer.valueOf(httpCode); + } catch (NumberFormatException e) { + logger.debug("Failed to parse http code {}", httpCode); + } + } + } + return result; + } + + /** + * retrieve all topics from U-EB server + * + * @param hostSet + * @return + */ + public Either, CambriaErrorResponse> getTopics(List hostSet) { + + CambriaTopicManager createTopicManager = null; + try { + + createTopicManager = new TopicManagerBuilder().usingHosts(hostSet).build(); + Set topics = createTopicManager.getTopics(); + + if (topics == null || true == topics.isEmpty()) { + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.NOT_FOUND, null); + return Either.right(cambriaErrorResponse); + } + + return Either.left(topics); + + } catch (IOException | GeneralSecurityException e) { + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + logger.debug("Failed to fetch topics from U-EB server", e); + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "get topics"); + + return Either.right(cambriaErrorResponse); + } finally { + if (createTopicManager != null) { + createTopicManager.close(); + } + } + + } + + /** + * process the error message from Cambria client. + * + * set Cambria status and http code in case we succeed to fetch it + * + * @param errorMessage + * @return + */ + private CambriaErrorResponse processError(Exception e) { + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(); + + Integer httpCode = processMessageException(e.getMessage()); + + if (httpCode != null) { + cambriaErrorResponse.setHttpCode(httpCode); + switch (httpCode.intValue()) { + + case 401: + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.AUTHENTICATION_ERROR); + break; + case 409: + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.TOPIC_ALREADY_EXIST); + break; + case 500: + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.INTERNAL_SERVER_ERROR); + break; + default: + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.CONNNECTION_ERROR); + } + } else { + + boolean found = false; + Throwable throwable = e.getCause(); + if (throwable != null) { + String message = throwable.getMessage(); + + Throwable cause = throwable.getCause(); + + if (cause != null) { + Class clazz = cause.getClass(); + String className = clazz.getName(); + if (className.endsWith("UnknownHostException")) { + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.UNKNOWN_HOST_ERROR); + cambriaErrorResponse.addVariable(message); + found = true; + } + } + } + + if (false == found) { + cambriaErrorResponse.setOperationStatus(CambriaOperationStatus.CONNNECTION_ERROR); + cambriaErrorResponse.setHttpCode(HttpStatus.SC_INTERNAL_SERVER_ERROR); + } + } + + return cambriaErrorResponse; + } + + /** + * write the error to the log + * + * @param cambriaErrorResponse + * @param errorMessage + * @param methodName + * @param operationDesc + */ + private void writeErrorToLog(CambriaErrorResponse cambriaErrorResponse, String errorMessage, String methodName, String operationDesc) { + + String httpCode = (cambriaErrorResponse.getHttpCode() == null ? "" : String.valueOf(cambriaErrorResponse.getHttpCode())); + + switch (cambriaErrorResponse.getOperationStatus()) { + case UNKNOWN_HOST_ERROR: + String hostname = cambriaErrorResponse.getVariables().get(0); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebUnkownHostError, methodName, hostname); + BeEcompErrorManager.getInstance().logBeUebUnkownHostError(methodName, httpCode); + break; + case AUTHENTICATION_ERROR: + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebAuthenticationError, methodName, httpCode); + BeEcompErrorManager.getInstance().logBeUebAuthenticationError(methodName, httpCode); + break; + case CONNNECTION_ERROR: + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebConnectionError, methodName, httpCode); + BeEcompErrorManager.getInstance().logBeUebConnectionError(methodName, httpCode); + break; + + case INTERNAL_SERVER_ERROR: + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, methodName, operationDesc); + BeEcompErrorManager.getInstance().logBeUebSystemError(methodName, operationDesc); + break; + + } + + } + + /** + * create a topic if it does not exists in the topicsList + * + * @param hostSet + * - list of U-EB servers + * @param apiKey + * @param secretKey + * @param topicsList + * - list of exists topics + * @param topicName + * - topic to create + * @param partitionCount + * @param replicationCount + * @return + */ + public CambriaErrorResponse createTopic(Collection hostSet, String apiKey, String secretKey, String topicName, int partitionCount, int replicationCount) { + + CambriaTopicManager createTopicManager = null; + try { + createTopicManager = new TopicManagerBuilder().usingHosts(hostSet).authenticatedBy(apiKey, secretKey).build(); + createTopicManager.createTopic(topicName, "ASDC distribution notification topic", partitionCount, replicationCount); + + } catch (GeneralSecurityException | HttpException | IOException e) { + logger.debug("Failed to create topic {}", topicName, e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + if (cambriaErrorResponse.getOperationStatus() != CambriaOperationStatus.TOPIC_ALREADY_EXIST) { + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "create topic"); + } + + return cambriaErrorResponse; + + } finally { + if (createTopicManager != null) { + createTopicManager.close(); + } + } + return new CambriaErrorResponse(CambriaOperationStatus.OK); + } + + public CambriaErrorResponse unRegisterFromTopic(Collection hostSet, String topicName, String managerApiKey, String managerSecretKey, String subscriberApiKey, SubscriberTypeEnum subscriberTypeEnum) { + CambriaTopicManager createTopicManager = null; + try { + createTopicManager = new TopicManagerBuilder().usingHosts(hostSet).authenticatedBy(managerApiKey, managerSecretKey).build(); + + if (subscriberTypeEnum == SubscriberTypeEnum.PRODUCER) { + createTopicManager.revokeProducer(topicName, subscriberApiKey); + } else { + createTopicManager.revokeConsumer(topicName, subscriberApiKey); + } + + } catch (HttpObjectNotFoundException | GeneralSecurityException e) { + logger.debug("Failed to unregister {} from topic {} as {}", managerApiKey, topicName, subscriberTypeEnum.toString().toLowerCase(), e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebObjectNotFoundError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeUebObjectNotFoundError(methodName, e.getMessage()); + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.OBJECT_NOT_FOUND, HttpStatus.SC_NOT_FOUND); + return cambriaErrorResponse; + + } catch (HttpException | IOException e) { + logger.debug("Failed to unregister {} from topic {} as producer", managerApiKey, topicName, e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "unregister from topic as " + subscriberTypeEnum.toString().toLowerCase()); + + return cambriaErrorResponse; + } finally { + if (createTopicManager != null) { + createTopicManager.close(); + } + } + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.OK, HttpStatus.SC_OK); + return cambriaErrorResponse; + } + + /** + * + * register a public key (subscriberId) to a given topic as a CONSUMER or PRODUCER + * + * @param hostSet + * @param topicName + * @param managerApiKey + * @param managerSecretKey + * @param subscriberApiKey + * @param subscriberTypeEnum + * @return + */ + public CambriaErrorResponse registerToTopic(Collection hostSet, String topicName, String managerApiKey, String managerSecretKey, String subscriberApiKey, SubscriberTypeEnum subscriberTypeEnum) { + + CambriaTopicManager createTopicManager = null; + try { + createTopicManager = new TopicManagerBuilder().usingHosts(hostSet).authenticatedBy(managerApiKey, managerSecretKey).build(); + + if (subscriberTypeEnum == SubscriberTypeEnum.PRODUCER) { + createTopicManager.allowProducer(topicName, subscriberApiKey); + } else { + createTopicManager.allowConsumer(topicName, subscriberApiKey); + } + + } catch (HttpObjectNotFoundException | GeneralSecurityException e) { + logger.debug("Failed to register {} to topic {} as {}", managerApiKey, topicName, subscriberTypeEnum.toString().toLowerCase(), e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebObjectNotFoundError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeUebObjectNotFoundError(methodName, e.getMessage()); + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.OBJECT_NOT_FOUND, HttpStatus.SC_NOT_FOUND); + return cambriaErrorResponse; + + } catch (HttpException | IOException e) { + logger.debug("Failed to register {} to topic {} as {}", managerApiKey, topicName, subscriberTypeEnum.toString().toLowerCase(), e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "register to topic as " + subscriberTypeEnum.toString().toLowerCase()); + + return cambriaErrorResponse; + } finally { + if (createTopicManager != null) { + createTopicManager.close(); + } + } + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.OK, HttpStatus.SC_OK); + return cambriaErrorResponse; + } + + /** + * create and retrieve a Cambria Consumer for a specific topic + * + * @param hostSet + * @param topicName + * @param apiKey + * @param secretKey + * @param consumerId + * @param consumerGroup + * @param timeoutMS + * @return + * @throws Exception + */ + public CambriaConsumer createConsumer(Collection hostSet, String topicName, String apiKey, String secretKey, String consumerId, String consumerGroup, int timeoutMS) throws Exception { + + CambriaConsumer consumer = new ConsumerBuilder().authenticatedBy(apiKey, secretKey).knownAs(consumerGroup, consumerId).onTopic(topicName).usingHosts(hostSet).withSocketTimeout(timeoutMS).build(); + consumer.setApiCredentials(apiKey, secretKey); + return consumer; + } + + public void closeConsumer(CambriaConsumer consumer) { + + if (consumer != null) { + consumer.close(); + } + + } + + /** + * use the topicConsumer to fetch messages from topic. in case no messages were fetched, empty ArrayList will be returned (not error) + * + * @param topicConsumer + * @return + */ + public Either, CambriaErrorResponse> fetchFromTopic(CambriaConsumer topicConsumer) { + + try { + Iterable messages = topicConsumer.fetch(); + if (messages == null) { + messages = new ArrayList(); + } + return Either.left(messages); + + } catch (IOException e) { + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + logger.debug("Failed to fetch from U-EB topic. error={}", e.getMessage()); + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "get messages from topic"); + + return Either.right(cambriaErrorResponse); + + } catch (Exception e) { + logger.debug("Failed to fetch from U-EB topic", e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(methodName, e.getMessage()); + + CambriaErrorResponse cambriaErrorResponse = new CambriaErrorResponse(CambriaOperationStatus.INTERNAL_SERVER_ERROR, HttpStatus.SC_INTERNAL_SERVER_ERROR); + return Either.right(cambriaErrorResponse); + } + } + + /** + * Publish notification message to a given queue + * + * @param topicName + * @param uebPublicKey + * @param uebSecretKey + * @param uebServers + * @param data + * @return + */ + public CambriaErrorResponse sendNotification(String topicName, String uebPublicKey, String uebSecretKey, List uebServers, INotificationData data) { + + CambriaBatchingPublisher createSimplePublisher = null; + + try { + + String json = gson.toJson(data); + logger.trace("Before sending notification data {} to topic {}", json, topicName); + + createSimplePublisher = new PublisherBuilder().onTopic(topicName).usingHosts(uebServers).build(); + createSimplePublisher.setApiCredentials(uebPublicKey, uebSecretKey); + + int result = createSimplePublisher.send(PARTITION_KEY, json); + + try { + Thread.sleep(1 * 1000); + } catch (InterruptedException e) { + logger.debug("Failed during sleep after sending the message.", e); + } + + logger.debug("After sending notification data to topic {}. result is {}", topicName, result); + + CambriaErrorResponse response = new CambriaErrorResponse(CambriaOperationStatus.OK, 200); + + return response; + + } catch (IOException | GeneralSecurityException e) { + logger.debug("Failed to send notification {} to topic {} ", data, topicName, e); + + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + CambriaErrorResponse cambriaErrorResponse = processError(e); + + writeErrorToLog(cambriaErrorResponse, e.getMessage(), methodName, "send notification"); + + return cambriaErrorResponse; + } finally { + if (createSimplePublisher != null) { + logger.debug("Before closing publisher"); + createSimplePublisher.close(); + logger.debug("After closing publisher"); + } + } + } + + private String convertListToString(List list) { + StringBuilder builder = new StringBuilder(); + + if (list != null) { + for (int i = 0; i < list.size(); i++) { + builder.append(list.get(i)); + if (i < list.size() - 1) { + builder.append(","); + } + } + } + + return builder.toString(); + } + + public CambriaErrorResponse sendNotificationAndClose(String topicName, String uebPublicKey, String uebSecretKey, List uebServers, INotificationData data, long waitBeforeCloseTimeout) { + + CambriaBatchingPublisher createSimplePublisher = null; + + CambriaErrorResponse response = null; + try { + + String json = gson.toJson(data); + logger.debug("Before sending notification data {} to topic {}", json, topicName); + + createSimplePublisher = new PublisherBuilder().onTopic(topicName).usingHosts(uebServers).build(); + createSimplePublisher.setApiCredentials(uebPublicKey, uebSecretKey); + + int result = createSimplePublisher.send(PARTITION_KEY, json); + + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logger.debug("Failed during sleep after sending the message.", e); + } + + logger.debug("After sending notification data to topic {}. result is {}", topicName, result); + + } catch (IOException | GeneralSecurityException e) { + logger.debug("Failed to send notification {} to topic {} ", data, topicName, e); + + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + response = processError(e); + + writeErrorToLog(response, e.getMessage(), methodName, "send notification"); + + return response; + + } + + logger.debug("Before closing publisher. Maximum timeout is {} seconds.", waitBeforeCloseTimeout); + try { + List messagesInQ = createSimplePublisher.close(waitBeforeCloseTimeout, TimeUnit.SECONDS); + if (messagesInQ != null && false == messagesInQ.isEmpty()) { + logger.debug("Cambria client returned {} non sent messages.", messagesInQ.size()); + response = new CambriaErrorResponse(CambriaOperationStatus.INTERNAL_SERVER_ERROR, 500); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + writeErrorToLog(response, "closing publisher returned non sent messages", methodName, "send notification"); + } else { + logger.debug("No message left in the queue after closing cambria publisher"); + response = new CambriaErrorResponse(CambriaOperationStatus.OK, 200); + } + } catch (IOException | InterruptedException e) { + logger.debug("Failed to close cambria publisher", e); + response = new CambriaErrorResponse(CambriaOperationStatus.INTERNAL_SERVER_ERROR, 500); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + writeErrorToLog(response, "closing publisher returned non sent messages", methodName, "send notification"); + } + logger.debug("After closing publisher"); + + return response; + + } + + public CambriaErrorResponse getApiKey(String server, String apiKey) { + + CambriaErrorResponse response = null; + + List hostSet = new ArrayList<>(); + hostSet.add(server); + CambriaIdentityManager createIdentityManager = null; + try { + createIdentityManager = new IdentityManagerBuilder().usingHosts(hostSet).build(); + createIdentityManager.getApiKey(apiKey); + response = new CambriaErrorResponse(CambriaOperationStatus.OK, 200); + + } catch (HttpException | IOException | CambriaApiException | GeneralSecurityException e) { + logger.debug("Failed to fetch api key {} from server ", apiKey, server, e); + + response = processError(e); + + } + + return response; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DeConfigurationStatus.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DeConfigurationStatus.java new file mode 100644 index 0000000000..5e4c08275f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DeConfigurationStatus.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public enum DeConfigurationStatus { + + OK(""), MISSING_CONFIGURATION(""); + + private String description; + + DeConfigurationStatus(String description) { + this.description = description; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngine.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngine.java new file mode 100644 index 0000000000..6cb31c8cf2 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngine.java @@ -0,0 +1,367 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("distributionEngine") +public class DistributionEngine implements IDistributionEngine { + + public static final Pattern FQDN_PATTERN = Pattern.compile("^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])(\\.([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9]))*(:[0-9]{2,4})*$", Pattern.CASE_INSENSITIVE); + + @javax.annotation.Resource + private ComponentsUtils componentUtils; + + @javax.annotation.Resource + private DistributionNotificationSender distributionNotificationSender; + + @javax.annotation.Resource + private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder; + + @javax.annotation.Resource + private DistributionEngineClusterHealth distributionEngineClusterHealth; + + private static Logger logger = LoggerFactory.getLogger(DistributionEngine.class.getName()); + + private Map envNamePerInitTask = new HashMap(); + private Map envNamePerPollingTask = new HashMap(); + + private Map envNamePerStatus = new HashMap(); + + @Override + public boolean isActive() { + + if (true == envNamePerInitTask.isEmpty()) { + return false; + } + + for (DistributionEngineInitTask task : envNamePerInitTask.values()) { + boolean active = task.isActive(); + if (active == false) { + return false; + } + } + return true; + } + + @PostConstruct + private void init() { + + logger.trace("Enter init method of DistributionEngine"); + + DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + + boolean startDistributionEngine = distributionEngineConfiguration.isStartDistributionEngine(); + logger.debug("Distribution engine activation parameter is {}", startDistributionEngine); + if (false == startDistributionEngine) { + logger.info("The disribution engine is disabled"); + + this.distributionEngineClusterHealth.setHealthCheckUebIsDisabled(); + + return; + } + + boolean isValidConfig = validateConfiguration(distributionEngineConfiguration); + + if (false == isValidConfig) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DistributionEngineInitTask.INIT_DISTRIBUTION_ENGINE_FLOW, "validate distribution configuration in init phase"); + BeEcompErrorManager.getInstance().logBeUebSystemError(DistributionEngineInitTask.INIT_DISTRIBUTION_ENGINE_FLOW, "validate distribution configuration in init phase"); + + this.distributionEngineClusterHealth.setHealthCheckUebConfigurationError(); + return; + } + + List environments = distributionEngineConfiguration.getEnvironments(); + + for (String envName : environments) { + + DistributionEnginePollingTask distributionEnginePollingTask = new DistributionEnginePollingTask(distributionEngineConfiguration, envName, componentUtils, distributionEngineClusterHealth); + + logger.debug("Init task for environment {}", envName); + + AtomicBoolean status = new AtomicBoolean(false); + envNamePerStatus.put(envName, status); + DistributionEngineInitTask distributionEngineInitTask = new DistributionEngineInitTask(0l, distributionEngineConfiguration, envName, status, componentUtils, distributionEnginePollingTask); + distributionEngineInitTask.startTask(); + envNamePerInitTask.put(envName, distributionEngineInitTask); + envNamePerPollingTask.put(envName, distributionEnginePollingTask); + } + + logger.debug("Init UEB health check"); + distributionEngineClusterHealth.startHealthCheckTask(envNamePerStatus); + + logger.trace("Exit init method of DistributionEngine"); + + } + + @PreDestroy + public void shutdown() { + logger.info("distribution engine shutdown - start"); + if (envNamePerInitTask != null) { + for (DistributionEngineInitTask task : envNamePerInitTask.values()) { + task.destroy(); + } + } + if (envNamePerPollingTask != null) { + for (DistributionEnginePollingTask task : envNamePerPollingTask.values()) { + task.destroy(); + } + } + + } + + /** + * validate mandatory configuration parameters received + * + * @param deConfiguration + * @return + */ + protected boolean validateConfiguration(DistributionEngineConfiguration deConfiguration) { + + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + boolean result = true; + result = isValidServers(deConfiguration.getUebServers(), methodName, "uebServers") && result; + result = isValidParam(deConfiguration.getEnvironments(), methodName, "environments") && result; + result = isValidParam(deConfiguration.getUebPublicKey(), methodName, "uebPublicKey") && result; + result = isValidParam(deConfiguration.getUebSecretKey(), methodName, "uebSecretKey") && result; + result = isValidParam(deConfiguration.getDistributionNotifTopicName(), methodName, "distributionNotifTopicName") && result; + result = isValidParam(deConfiguration.getDistributionStatusTopicName(), methodName, "distributionStatusTopicName") && result; + result = isValidObject(deConfiguration.getCreateTopic(), methodName, "createTopic") && result; + result = isValidObject(deConfiguration.getDistributionStatusTopic(), methodName, "distributionStatusTopic") && result; + result = isValidObject(deConfiguration.getInitMaxIntervalSec(), methodName, "initMaxIntervalSec") && result; + result = isValidObject(deConfiguration.getInitRetryIntervalSec(), methodName, "initRetryIntervalSec") && result; + result = isValidParam(deConfiguration.getDistributionStatusTopic().getConsumerId(), methodName, "consumerId") && result; + result = isValidParam(deConfiguration.getDistributionStatusTopic().getConsumerGroup(), methodName, "consumerGroup") && result; + result = isValidObject(deConfiguration.getDistributionStatusTopic().getFetchTimeSec(), methodName, "fetchTimeSec") && result; + result = isValidObject(deConfiguration.getDistributionStatusTopic().getPollingIntervalSec(), methodName, "pollingIntervalSec") && result; + + return result; + } + + private boolean isValidServers(List uebServers, String methodName, String paramName) { + + if (uebServers == null || uebServers.size() == 0) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName); + BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName); + return false; + } + + if (uebServers.size() < 2) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeConfigurationInvalidListSizeError, methodName, paramName, "2"); + BeEcompErrorManager.getInstance().logBeConfigurationInvalidListSizeError(methodName, paramName, 2); + return false; + } + + for (String serverFqdn : uebServers) { + if (false == isValidFqdn(serverFqdn)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidConfigurationError, methodName, paramName, serverFqdn); + BeEcompErrorManager.getInstance().logBeInvalidConfigurationError(methodName, paramName, serverFqdn); + return false; + } + } + + return true; + } + + private boolean isValidFqdn(String serverFqdn) { + + try { + Matcher matcher = FQDN_PATTERN.matcher(serverFqdn); + return matcher.matches(); + + } catch (Exception e) { + logger.debug("Failed to match value of address {}", serverFqdn, e); + return false; + } + + } + + private boolean isEmptyParam(String param) { + + if (param == null || true == param.isEmpty()) { + return true; + } + + return false; + } + + private boolean isValidParam(String paramValue, String methodName, String paramName) { + + if (isEmptyParam(paramValue)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName); + BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName); + return false; + } + return true; + + } + + private boolean isValidParam(List paramValue, String methodName, String paramName) { + + if (isEmptyList(paramValue)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName); + BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName); + return false; + } + return true; + + } + + private boolean isValidObject(Object paramValue, String methodName, String paramName) { + + if (paramValue == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingConfigurationError, methodName, paramName); + BeEcompErrorManager.getInstance().logBeMissingConfigurationError(methodName, paramName); + return false; + } + return true; + + } + + private boolean isEmptyList(List list) { + if (list == null || true == list.isEmpty()) { + return true; + } + return false; + } + + private String getEnvironmentErrorDescription(StorageOperationStatus status) { + + switch (status) { + case DISTR_ENVIRONMENT_NOT_AVAILABLE: + return "environment is unavailable"; + case DISTR_ENVIRONMENT_NOT_FOUND: + return "environment is not configured in our system"; + case DISTR_ENVIRONMENT_SENT_IS_INVALID: + return "environment name is invalid"; + + default: + return "unkhown"; + + } + } + + public StorageOperationStatus isEnvironmentAvailable(String envName) { + + if (envName == null || true == envName.isEmpty()) { + + return StorageOperationStatus.DISTR_ENVIRONMENT_SENT_IS_INVALID; + } + + AtomicBoolean status = envNamePerStatus.get(envName); + if (status == null) { + return StorageOperationStatus.DISTR_ENVIRONMENT_NOT_FOUND; + } + + if (false == status.get()) { + return StorageOperationStatus.DISTR_ENVIRONMENT_NOT_AVAILABLE; + } + return StorageOperationStatus.OK; + } + + public StorageOperationStatus isEnvironmentAvailable() { + + String envName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0); + + return isEnvironmentAvailable(envName); + } + + @Override + public void disableEnvironment(String envName) { + // TODO disable tasks + AtomicBoolean status = envNamePerStatus.get(envName); + status.set(false); + } + + @Override + public StorageOperationStatus notifyService(String distributionId, Service service, INotificationData notificationData, String envName, String userId, String modifierName) { + + if (logger.isDebugEnabled()) { + logger.debug("Received notify service request. distributionId = {}, serviceUuid = {}, serviceUid = {}, envName = {}, userId = {}, modifierName {}", distributionId, service.getUUID(), service.getUniqueId(), envName, userId, modifierName); + } + + DistributionEngineConfiguration deConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + + String distributionNotifTopicName = deConfiguration.getDistributionNotifTopicName(); + String topicName = DistributionEngineInitTask.buildTopicName(distributionNotifTopicName, envName); + + StorageOperationStatus sendNotification = distributionNotificationSender.sendNotification(topicName, distributionId, deConfiguration, envName, notificationData, service, userId, modifierName); + + logger.debug("Finish notifyService. status is {}", sendNotification); + + return sendNotification; + } + + @Override + public Either isReadyForDistribution(Service service, String distributionId, String envName) { + StorageOperationStatus status = isEnvironmentAvailable(envName); + if (status != StorageOperationStatus.OK) { + String envErrorDec = getEnvironmentErrorDescription(status); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, DistributionNotificationSender.DISTRIBUTION_NOTIFICATION_SENDING, + "Environment name " + envName + " is not available. Reason : " + envErrorDec); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionNotificationSender.DISTRIBUTION_NOTIFICATION_SENDING, "Environment name " + envName + " is not available. Reason : " + envErrorDec); + return Either.right(status); + } + + Either isServiceContainsDeploymentArtifactsStatus = serviceDistributionArtifactsBuilder.isServiceContainsDeploymentArtifacts(service); + if (isServiceContainsDeploymentArtifactsStatus.isRight()) { + StorageOperationStatus operationStatus = isServiceContainsDeploymentArtifactsStatus.right().value(); + return Either.right(operationStatus); + } else { + Boolean isDeploymentArtifactExists = isServiceContainsDeploymentArtifactsStatus.left().value(); + if (isDeploymentArtifactExists == null || isDeploymentArtifactExists.booleanValue() == false) { + return Either.right(StorageOperationStatus.DISTR_ARTIFACT_NOT_FOUND); + } + } + + INotificationData value = serviceDistributionArtifactsBuilder.buildResourceInstanceForDistribution(service, distributionId); + value = serviceDistributionArtifactsBuilder.buildServiceForDistribution(value, service); + + return Either.left(value); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineClusterHealth.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineClusterHealth.java new file mode 100644 index 0000000000..a3d0362c61 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineClusterHealth.java @@ -0,0 +1,356 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckComponent; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("distribution-engine-cluster-health") +public class DistributionEngineClusterHealth { + + protected static String UEB_HEALTH_LOG_CONTEXT = "ueb.healthcheck"; + + private static Logger healthLogger = LoggerFactory.getLogger(UEB_HEALTH_LOG_CONTEXT); + + private static final String UEB_HEALTH_CHECK_STR = "uebHealthCheck"; + + boolean lastHealthState = false; + + Object lockOject = new Object(); + + private long reconnectInterval = 5; + + private long healthCheckReadTimeout = 20; + + private static Logger logger = LoggerFactory.getLogger(DistributionEngineClusterHealth.class.getName()); + + private List uebServers = null; + + private String publicApiKey = null; + + public enum HealthCheckInfoResult { + + OK(new HealthCheckInfo(HealthCheckComponent.DE, HealthCheckStatus.UP, null, ClusterStatusDescription.OK.getDescription())), UNAVAILABLE( + new HealthCheckInfo(HealthCheckComponent.DE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.UNAVAILABLE.getDescription())), NOT_CONFIGURED( + new HealthCheckInfo(HealthCheckComponent.DE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.NOT_CONFIGURED.getDescription())), DISABLED( + new HealthCheckInfo(HealthCheckComponent.DE, HealthCheckStatus.DOWN, null, ClusterStatusDescription.DISABLED.getDescription())); + + private HealthCheckInfo healthCheckInfo; + + HealthCheckInfoResult(HealthCheckInfo healthCheckInfo) { + this.healthCheckInfo = healthCheckInfo; + } + + public HealthCheckInfo getHealthCheckInfo() { + return healthCheckInfo; + } + + } + + private HealthCheckInfo healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo(); + + private Map envNamePerStatus = null; + + private ScheduledFuture scheduledFuture = null; + + ScheduledExecutorService healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "UEB-Health-Check-Task"); + } + }); + + HealthCheckScheduledTask healthCheckScheduledTask = null; + + public enum ClusterStatusDescription { + + OK("OK"), UNAVAILABLE("U-EB cluster is not available"), NOT_CONFIGURED("U-EB cluster is not configured"), DISABLED("DE is disabled in configuration"); + + private String desc; + + ClusterStatusDescription(String desc) { + this.desc = desc; + } + + public String getDescription() { + return desc; + } + + } + + /** + * Health Check Task Scheduler. + * + * It schedules a task which send a apiKey get query towards the UEB servers. In case a query to the first UEB server is failed, then a second query is sent to the next UEB server. + * + * + * @author esofer + * + */ + public class HealthCheckScheduledTask implements Runnable { + + List healthCheckCalls = new ArrayList<>(); + + public HealthCheckScheduledTask(List uebServers) { + + logger.debug("Create health check calls for servers {}", uebServers); + if (uebServers != null) { + for (String server : uebServers) { + healthCheckCalls.add(new UebHealthCheckCall(server, publicApiKey)); + } + } + } + + @Override + public void run() { + + healthLogger.trace("Executing UEB Health Check Task - Start"); + + boolean healthStatus = verifyAtLeastOneEnvIsUp(); + + if (true == healthStatus) { + boolean queryUebStatus = queryUeb(); + if (queryUebStatus == lastHealthState) { + return; + } + + synchronized (lockOject) { + if (queryUebStatus != lastHealthState) { + logger.trace("UEB Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus); + lastHealthState = queryUebStatus; + logAlarm(lastHealthState); + if (true == queryUebStatus) { + healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo(); + } else { + healthCheckInfo = HealthCheckInfoResult.UNAVAILABLE.getHealthCheckInfo(); + } + } + } + } else { + healthLogger.trace("Not all UEB Environments are up"); + } + + } + + /** + * verify that at least one environment is up. + * + */ + private boolean verifyAtLeastOneEnvIsUp() { + + boolean healthStatus = false; + + if (envNamePerStatus != null) { + Collection values = envNamePerStatus.values(); + if (values != null) { + for (AtomicBoolean status : values) { + if (true == status.get()) { + healthStatus = true; + break; + } + } + } + } + + return healthStatus; + } + + /** + * executor for the query itself + */ + ExecutorService healthCheckExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "UEB-Health-Check-Thread"); + } + }); + + /** + * go all UEB servers and send a get apiKeys query. In case a query is succeed, no query is sent to the rest of UEB servers. + * + * + * @return + */ + private boolean queryUeb() { + + Boolean result = false; + int retryNumber = 1; + for (UebHealthCheckCall healthCheckCall : healthCheckCalls) { + try { + + healthLogger.debug("Before running Health Check retry query number {} towards UEB server {}", retryNumber, healthCheckCall.getServer()); + + Future future = healthCheckExecutor.submit(healthCheckCall); + result = future.get(healthCheckReadTimeout, TimeUnit.SECONDS); + + healthLogger.debug("After running Health Check retry query number {} towards UEB server {}. Result is {}", retryNumber, healthCheckCall.getServer(), result); + + if (result != null && true == result.booleanValue()) { + break; + } + + } catch (Exception e) { + String message = e.getMessage(); + if (message == null) { + message = e.getClass().getName(); + } + healthLogger.debug("Error occured during running Health Check retry query towards UEB server {}. Result is {}", healthCheckCall.getServer(), message); + } + retryNumber++; + + } + + return result; + + } + + public List getHealthCheckCalls() { + return healthCheckCalls; + } + + } + + @PostConstruct + private void init() { + + logger.trace("Enter init method of DistributionEngineClusterHealth"); + + Long reconnectIntervalConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getUebHealthCheckReconnectIntervalInSeconds(); + if (reconnectIntervalConfig != null) { + reconnectInterval = reconnectIntervalConfig.longValue(); + } + Long healthCheckReadTimeoutConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getUebHealthCheckReadTimeout(); + if (healthCheckReadTimeoutConfig != null) { + healthCheckReadTimeout = healthCheckReadTimeoutConfig.longValue(); + } + + DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + + this.uebServers = distributionEngineConfiguration.getUebServers(); + this.publicApiKey = distributionEngineConfiguration.getUebPublicKey(); + + this.healthCheckScheduledTask = new HealthCheckScheduledTask(this.uebServers); + + logger.trace("Exit init method of DistributionEngineClusterHealth"); + + } + + @PreDestroy + private void destroy() { + + if (scheduledFuture != null) { + scheduledFuture.cancel(true); + scheduledFuture = null; + } + + if (healthCheckScheduler != null) { + healthCheckScheduler.shutdown(); + } + + } + + /** + * Start health check task. + * + * @param envNamePerStatus + * @param startTask + */ + public void startHealthCheckTask(Map envNamePerStatus, boolean startTask) { + this.envNamePerStatus = envNamePerStatus; + + if (startTask == true && this.scheduledFuture == null) { + this.scheduledFuture = this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, reconnectInterval, TimeUnit.SECONDS); + } + } + + public void startHealthCheckTask(Map envNamePerStatus) { + startHealthCheckTask(envNamePerStatus, true); + } + + private void logAlarm(boolean lastHealthState) { + if (lastHealthState == true) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeHealthCheckRecovery, UEB_HEALTH_CHECK_STR); + BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterRecovery(UEB_HEALTH_CHECK_STR); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeHealthCheckError, UEB_HEALTH_CHECK_STR); + BeEcompErrorManager.getInstance().logBeHealthCheckUebClusterError(UEB_HEALTH_CHECK_STR); + } + } + + public HealthCheckInfo getHealthCheckInfo() { + return healthCheckInfo; + } + + /** + * change the health check to DISABLE + */ + public void setHealthCheckUebIsDisabled() { + healthCheckInfo = HealthCheckInfoResult.DISABLED.getHealthCheckInfo(); + } + + /** + * change the health check to NOT CONFGIURED + */ + public void setHealthCheckUebConfigurationError() { + healthCheckInfo = HealthCheckInfoResult.NOT_CONFIGURED.getHealthCheckInfo(); + } + + public void setHealthCheckOkAndReportInCaseLastStateIsDown() { + + if (lastHealthState == true) { + return; + } + synchronized (lockOject) { + if (lastHealthState == false) { + logger.debug("Going to update health check state to available"); + lastHealthState = true; + healthCheckInfo = HealthCheckInfoResult.OK.getHealthCheckInfo(); + logAlarm(lastHealthState); + } + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineInitTask.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineInitTask.java new file mode 100644 index 0000000000..1eeaa1229e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEngineInitTask.java @@ -0,0 +1,293 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.distribution.api.client.CambriaOperationStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class DistributionEngineInitTask implements Runnable { + + public static final String INIT_DISTRIBUTION_ENGINE_FLOW = "initDistributionEngine"; + public static final String ALREADY_EXISTS = "ALREADY_EXISTS"; + public static final String CONSUMER = "CONSUMER"; + public static final String PRODUCER = "PRODUCER"; + public static final String CREATED = "CREATED"; + public static final String FAILED = "FAILED"; + public static final Integer HTTP_OK = 200; + + private Long delayBeforeStartFlow = 0l; + private DistributionEngineConfiguration deConfiguration; + private String envName; + private long retryInterval; + private long currentRetryInterval; + private long maxInterval; + // private boolean active = false; + boolean maximumRetryInterval = false; + private AtomicBoolean status = null; + ComponentsUtils componentsUtils = null; + DistributionEnginePollingTask distributionEnginePollingTask = null; + + private CambriaHandler cambriaHandler = new CambriaHandler(); + + public DistributionEngineInitTask(Long delayBeforeStartFlow, DistributionEngineConfiguration deConfiguration, String envName, AtomicBoolean status, ComponentsUtils componentsUtils, DistributionEnginePollingTask distributionEnginePollingTask) { + super(); + this.delayBeforeStartFlow = delayBeforeStartFlow; + this.deConfiguration = deConfiguration; + this.envName = envName; + this.retryInterval = deConfiguration.getInitRetryIntervalSec(); + this.currentRetryInterval = retryInterval; + this.maxInterval = deConfiguration.getInitMaxIntervalSec(); + this.status = status; + this.componentsUtils = componentsUtils; + this.distributionEnginePollingTask = distributionEnginePollingTask; + } + + private ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1); + + private static Logger logger = LoggerFactory.getLogger(DistributionEngineInitTask.class.getName()); + + ScheduledFuture scheduledFuture = null; + + public void startTask() { + if (scheduledExecutorService != null) { + Integer retryInterval = deConfiguration.getInitRetryIntervalSec(); + logger.debug("Start Distribution Engine init task. retry interval {} seconds, delay before first run {} seconds", retryInterval, delayBeforeStartFlow); + this.scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(this, delayBeforeStartFlow, retryInterval, TimeUnit.SECONDS); + + } + } + + public void restartTask() { + + this.stopTask(); + + logger.debug("Start Distribution Engine init task. next run in {} seconds", this.currentRetryInterval); + + long lastCurrentInterval = currentRetryInterval; + incrementRetryInterval(); + + this.scheduledFuture = scheduledExecutorService.scheduleAtFixedRate(this, lastCurrentInterval, this.currentRetryInterval, TimeUnit.SECONDS); + + } + + protected void incrementRetryInterval() { + if (currentRetryInterval < maxInterval) { + currentRetryInterval *= 2; + if (currentRetryInterval > maxInterval) { + setMaxRetryInterval(); + } + } else { + setMaxRetryInterval(); + } + } + + private void setMaxRetryInterval() { + currentRetryInterval = maxInterval; + maximumRetryInterval = true; + logger.debug("Set next retry init interval to {}", maxInterval); + } + + public void stopTask() { + if (scheduledFuture != null) { + boolean result = scheduledFuture.cancel(true); + logger.debug("Stop reinit task. result = {}", result); + if (false == result) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, INIT_DISTRIBUTION_ENGINE_FLOW, "try to stop the reinit task"); + BeEcompErrorManager.getInstance().logBeUebSystemError(INIT_DISTRIBUTION_ENGINE_FLOW, "try to stop the reinit task"); + } + scheduledFuture = null; + } + } + + public void destroy() { + this.stopTask(); + if (scheduledExecutorService != null) { + scheduledExecutorService.shutdown(); + } + } + + @Override + public void run() { + + boolean result = false; + result = initFlow(); + + if (true == result) { + this.stopTask(); + this.status.set(true); + if (this.distributionEnginePollingTask != null) { + String topicName = buildTopicName(deConfiguration.getDistributionStatusTopicName(), envName); + logger.debug("start polling distribution status topic {}", topicName); + this.distributionEnginePollingTask.startTask(topicName); + } + } else { + if (false == maximumRetryInterval) { + this.restartTask(); + } + } + } + + /** + * run initialization flow + * + * @return + */ + public boolean initFlow() { + + logger.trace("Start init flow for environment {}", this.envName); + + Set topicsList = null; + Either, CambriaErrorResponse> getTopicsRes = null; + + getTopicsRes = cambriaHandler.getTopics(deConfiguration.getUebServers()); + if (getTopicsRes.isRight()) { + CambriaErrorResponse status = getTopicsRes.right().value(); + if (status.getOperationStatus() == CambriaOperationStatus.NOT_FOUND) { + topicsList = new HashSet<>(); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, INIT_DISTRIBUTION_ENGINE_FLOW, "try retrieve list of topics from U-EB server"); + + BeEcompErrorManager.getInstance().logBeUebSystemError(INIT_DISTRIBUTION_ENGINE_FLOW, "try retrieve list of topics from U-EB server"); + + return false; + } + } else { + topicsList = getTopicsRes.left().value(); + } + + String notificationTopic = buildTopicName(deConfiguration.getDistributionNotifTopicName(), this.envName); + logger.debug("Going to handle topic {}", notificationTopic); + + boolean status = createTopicIfNotExists(topicsList, notificationTopic); + if (false == status) { + return false; + } + + CambriaErrorResponse registerProducerStatus = registerToTopic(notificationTopic, SubscriberTypeEnum.PRODUCER); + + CambriaOperationStatus createStatus = registerProducerStatus.getOperationStatus(); + + if (createStatus != CambriaOperationStatus.OK) { + return false; + } + + String statusTopic = buildTopicName(deConfiguration.getDistributionStatusTopicName(), this.envName); + logger.debug("Going to handle topic {}", statusTopic); + status = createTopicIfNotExists(topicsList, statusTopic); + if (false == status) { + return false; + } + + CambriaErrorResponse registerConcumerStatus = registerToTopic(statusTopic, SubscriberTypeEnum.CONSUMER); + + if (registerConcumerStatus.getOperationStatus() != CambriaOperationStatus.OK) { + return false; + } + + return true; + } + + private CambriaErrorResponse registerToTopic(String topicName, SubscriberTypeEnum subscriberType) { + CambriaErrorResponse registerStatus = cambriaHandler.registerToTopic(deConfiguration.getUebServers(), topicName, deConfiguration.getUebPublicKey(), deConfiguration.getUebSecretKey(), deConfiguration.getUebPublicKey(), subscriberType); + + String role = CONSUMER; + if (subscriberType == SubscriberTypeEnum.PRODUCER) { + role = PRODUCER; + } + auditRegistration(topicName, registerStatus, role); + return registerStatus; + } + + private void auditRegistration(String notificationTopic, CambriaErrorResponse registerProducerStatus, String role) { + if (componentsUtils != null) { + Integer httpCode = registerProducerStatus.getHttpCode(); + String httpCodeStr = String.valueOf(httpCode); + this.componentsUtils.auditDistributionEngine(AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL, this.envName, notificationTopic, role, deConfiguration.getUebPublicKey(), httpCodeStr); + } + } + + private boolean createTopicIfNotExists(Set topicsList, String topicName) { + + if (topicsList.contains(topicName)) { + if (componentsUtils != null) { + this.componentsUtils.auditDistributionEngine(AuditingActionEnum.CREATE_DISTRIBUTION_TOPIC, this.envName, topicName, null, null, ALREADY_EXISTS); + } + return true; + } + + CambriaErrorResponse createDistribTopicStatus = cambriaHandler.createTopic(deConfiguration.getUebServers(), deConfiguration.getUebPublicKey(), deConfiguration.getUebSecretKey(), topicName, deConfiguration.getCreateTopic().getPartitionCount(), + deConfiguration.getCreateTopic().getReplicationCount()); + + CambriaOperationStatus status = createDistribTopicStatus.getOperationStatus(); + if (status == CambriaOperationStatus.TOPIC_ALREADY_EXIST) { + if (componentsUtils != null) { + this.componentsUtils.auditDistributionEngine(AuditingActionEnum.CREATE_DISTRIBUTION_TOPIC, this.envName, topicName, null, null, ALREADY_EXISTS); + } + } else if (status == CambriaOperationStatus.OK) { + if (componentsUtils != null) { + this.componentsUtils.auditDistributionEngine(AuditingActionEnum.CREATE_DISTRIBUTION_TOPIC, this.envName, topicName, null, null, CREATED); + } + } else { + if (componentsUtils != null) { + this.componentsUtils.auditDistributionEngine(AuditingActionEnum.CREATE_DISTRIBUTION_TOPIC, this.envName, topicName, null, null, FAILED); + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, INIT_DISTRIBUTION_ENGINE_FLOW, "try to create topic " + topicName); + + BeEcompErrorManager.getInstance().logBeUebSystemError(INIT_DISTRIBUTION_ENGINE_FLOW, "try to create topic " + topicName); + + return false; + } + + return true; + } + + public static String buildTopicName(String topicName, String environment) { + return topicName + "-" + environment.toUpperCase(); + } + + public boolean isActive() { + return this.status.get(); + } + + public long getCurrentRetryInterval() { + return currentRetryInterval; + } + + protected void setCambriaHandler(CambriaHandler cambriaHandler) { + this.cambriaHandler = cambriaHandler; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEnginePollingTask.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEnginePollingTask.java new file mode 100644 index 0000000000..fc7c473d6b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionEnginePollingTask.java @@ -0,0 +1,207 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +import org.apache.commons.lang3.concurrent.BasicThreadFactory; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration.DistributionStatusTopicConfig; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.att.nsa.cambria.client.CambriaConsumer; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +public class DistributionEnginePollingTask implements Runnable { + + public static final String DISTRIBUTION_STATUS_POLLING = "distributionEngineStatusPolling"; + + private String topicName; + private ComponentsUtils componentUtils; + private int fetchTimeoutInSec = 15; + private int pollingIntervalInSec; + private String consumerId; + private String consumerGroup; + private DistributionEngineConfiguration distributionEngineConfiguration; + + private CambriaHandler cambriaHandler = new CambriaHandler(); + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + private ScheduledExecutorService scheduledPollingService = Executors.newScheduledThreadPool(1, new BasicThreadFactory.Builder().namingPattern("TopicPollingThread-%d").build()); + + private static Logger logger = LoggerFactory.getLogger(DistributionEnginePollingTask.class.getName()); + + ScheduledFuture scheduledFuture = null; + private CambriaConsumer cambriaConsumer = null; + + private DistributionEngineClusterHealth distributionEngineClusterHealth = null; + + public DistributionEnginePollingTask(DistributionEngineConfiguration distributionEngineConfiguration, String envName, ComponentsUtils componentUtils, DistributionEngineClusterHealth distributionEngineClusterHealth) { + + this.componentUtils = componentUtils; + this.distributionEngineConfiguration = distributionEngineConfiguration; + DistributionStatusTopicConfig statusConfig = distributionEngineConfiguration.getDistributionStatusTopic(); + this.pollingIntervalInSec = statusConfig.getPollingIntervalSec(); + this.fetchTimeoutInSec = statusConfig.getFetchTimeSec(); + this.consumerGroup = statusConfig.getConsumerGroup(); + this.consumerId = statusConfig.getConsumerId(); + this.distributionEngineClusterHealth = distributionEngineClusterHealth; + } + + public void startTask(String topicName) { + + this.topicName = topicName; + logger.debug("start task for polling topic {}", topicName); + if (fetchTimeoutInSec < 15) { + logger.warn("fetchTimeout value should be greater or equal to 15 sec. use default"); + fetchTimeoutInSec = 15; + } + try { + cambriaConsumer = cambriaHandler.createConsumer(distributionEngineConfiguration.getUebServers(), topicName, distributionEngineConfiguration.getUebPublicKey(), distributionEngineConfiguration.getUebSecretKey(), consumerId, consumerGroup, + fetchTimeoutInSec * 1000); + + if (scheduledPollingService != null) { + logger.debug("Start Distribution Engine polling task. polling interval {} seconds", pollingIntervalInSec); + scheduledFuture = scheduledPollingService.scheduleAtFixedRate(this, 0, pollingIntervalInSec, TimeUnit.SECONDS); + + } + } catch (Exception e) { + logger.debug("unexpected error occured", e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(methodName, e.getMessage()); + } + } + + public void stopTask() { + if (scheduledFuture != null) { + boolean result = scheduledFuture.cancel(true); + logger.debug("Stop polling task. result = {}", result); + if (false == result) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DISTRIBUTION_STATUS_POLLING, "try to stop the polling task"); + BeEcompErrorManager.getInstance().logBeUebSystemError(DISTRIBUTION_STATUS_POLLING, "try to stop the polling task"); + } + scheduledFuture = null; + } + if (cambriaConsumer != null) { + logger.debug("close consumer"); + cambriaHandler.closeConsumer(cambriaConsumer); + } + + } + + public void destroy() { + this.stopTask(); + shutdownExecutor(); + } + + @Override + public void run() { + logger.trace("run() method. polling queue {}", topicName); + + try { + // init error + if (cambriaConsumer == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DISTRIBUTION_STATUS_POLLING, "polling task was not initialized properly"); + BeEcompErrorManager.getInstance().logBeUebSystemError(DISTRIBUTION_STATUS_POLLING, "polling task was not initialized properly"); + stopTask(); + return; + } + + Either, CambriaErrorResponse> fetchResult = cambriaHandler.fetchFromTopic(cambriaConsumer); + // fetch error + if (fetchResult.isRight()) { + CambriaErrorResponse errorResponse = fetchResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DISTRIBUTION_STATUS_POLLING, "failed to fetch messages from topic " + topicName + " error: " + fetchResult.right().value()); + BeEcompErrorManager.getInstance().logBeUebSystemError(DISTRIBUTION_STATUS_POLLING, "failed to fetch messages from topic " + topicName + " error: " + fetchResult.right().value()); + + // TODO: if status== internal error (connection problem) change + // state to inactive + // in next try, if succeed - change to active + return; + } + + // success + Iterable messages = fetchResult.left().value(); + for (String message : messages) { + logger.trace("received message {}", message); + try { + DistributionStatusNotification notification = gson.fromJson(message, DistributionStatusNotification.class); + componentUtils.auditDistributionStatusNotification(AuditingActionEnum.DISTRIBUTION_STATUS, notification.getDistributionID(), notification.getConsumerID(), topicName, notification.getArtifactURL(), + String.valueOf(notification.getTimestamp()), notification.getStatus().name(), notification.getErrorReason()); + + distributionEngineClusterHealth.setHealthCheckOkAndReportInCaseLastStateIsDown(); + + } catch (Exception e) { + logger.debug("failed to convert message to object", e); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUebSystemError, DISTRIBUTION_STATUS_POLLING, "failed to parse message " + message + " from topic " + topicName + " error: " + fetchResult.right().value()); + BeEcompErrorManager.getInstance().logBeUebSystemError(DISTRIBUTION_STATUS_POLLING, "failed to parse message " + message + " from topic " + topicName + " error: " + fetchResult.right().value()); + } + + } + } catch (Exception e) { + logger.debug("unexpected error occured", e); + String methodName = new Object() { + }.getClass().getEnclosingMethod().getName(); + + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, methodName, e.getMessage()); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(methodName, e.getMessage()); + } + + } + + private void shutdownExecutor() { + if (scheduledPollingService == null) + return; + + scheduledPollingService.shutdown(); // Disable new tasks from being + // submitted + try { + // Wait a while for existing tasks to terminate + if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) { + scheduledPollingService.shutdownNow(); // Cancel currently + // executing tasks + // Wait a while for tasks to respond to being cancelled + if (!scheduledPollingService.awaitTermination(60, TimeUnit.SECONDS)) + logger.debug("Pool did not terminate"); + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + scheduledPollingService.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionNotificationSender.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionNotificationSender.java new file mode 100644 index 0000000000..667276db2c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionNotificationSender.java @@ -0,0 +1,127 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.RejectedExecutionException; + +import javax.annotation.PreDestroy; + +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration.DistributionNotificationTopicConfig; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("distributionNotificationSender") +public class DistributionNotificationSender { + + protected static final String DISTRIBUTION_NOTIFICATION_SENDING = "distributionNotificationSending"; + + private static Logger logger = LoggerFactory.getLogger(DistributionNotificationSender.class.getName()); + + // final String BASE_ARTIFACT_URL = "/asdc/v1/catalog/services/%s/%s/"; + // final String RESOURCE_ARTIFACT_URL = BASE_ARTIFACT_URL + // + "resources/%s/%s/artifacts/%s"; + // final String SERVICE_ARTIFACT_URL = BASE_ARTIFACT_URL + "artifacts/%s"; + + @javax.annotation.Resource + InterfaceLifecycleOperation interfaceLifecycleOperation; + + @javax.annotation.Resource + protected IServiceOperation serviceOperation; + + @javax.annotation.Resource + protected ResourceOperation resourceOperation; + + @javax.annotation.Resource + protected ComponentsUtils componentUtils; + + ExecutorService executorService = null; + + CambriaHandler cambriaHandler = new CambriaHandler(); + + NotificationExecutorService notificationExecutorService = new NotificationExecutorService(); + + public DistributionNotificationSender() { + super(); + + DistributionNotificationTopicConfig distributionNotificationTopic = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getDistributionNotificationTopic(); + + executorService = notificationExecutorService.createExcecutorService(distributionNotificationTopic); + } + + @PreDestroy + public void shutdown() { + logger.debug("Going to close notificationExecutorService"); + if (executorService != null) { + + long maxWaitingTime = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getDistributionNotificationTopic().getMaxWaitingAfterSendingSeconds(); + + notificationExecutorService.shutdownAndAwaitTermination(executorService, maxWaitingTime + 1); + } + } + + public StorageOperationStatus sendNotification(String topicName, String distributionId, DistributionEngineConfiguration deConfiguration, String envName, INotificationData notificationData, Service service, String userId, String modifierName) { + + Runnable task = new PublishNotificationRunnable(envName, distributionId, service, notificationData, deConfiguration, topicName, userId, modifierName, cambriaHandler, componentUtils, ThreadLocalsHolder.getUuid()); + try { + executorService.submit(task); + } catch (RejectedExecutionException e) { + logger.warn("Failed to submit task. Number of threads exceeeds", e); + return StorageOperationStatus.OVERLOAD; + } + + return StorageOperationStatus.OK; + } + + /** + * Audit the publishing notification in case of internal server error. + * + * @param topicName + * @param status + * @param distributionId + * @param envName + */ + private void auditDistributionNotificationInternalServerError(String topicName, StorageOperationStatus status, String distributionId, String envName) { + + if (this.componentUtils != null) { + this.componentUtils.auditDistributionNotification(AuditingActionEnum.DISTRIBUTION_NOTIFY, "", " ", "Service", " ", " ", " ", envName, " ", topicName, distributionId, "Error: Internal Server Error. " + status, " "); + } + } + + protected CambriaErrorResponse publishNotification(INotificationData data, DistributionEngineConfiguration deConfiguration, String topicName) { + + CambriaErrorResponse status = cambriaHandler.sendNotification(topicName, deConfiguration.getUebPublicKey(), deConfiguration.getUebSecretKey(), deConfiguration.getUebServers(), data); + + return status; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotification.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotification.java new file mode 100644 index 0000000000..73a0336361 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotification.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public class DistributionStatusNotification { + + String distributionID; + String consumerID; + long timestamp; + String artifactURL; + DistributionStatusNotificationEnum status; + String errorReason; + + public String getDistributionID() { + return distributionID; + } + + public void setDistributionID(String distributionId) { + this.distributionID = distributionId; + } + + public String getConsumerID() { + return consumerID; + } + + public void setConsumerID(String consumerId) { + this.consumerID = consumerId; + } + + public long getTimestamp() { + return timestamp; + } + + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + public String getArtifactURL() { + return artifactURL; + } + + public void setArtifactURL(String artifactURL) { + this.artifactURL = artifactURL; + } + + public DistributionStatusNotificationEnum getStatus() { + return status; + } + + public void setStatus(DistributionStatusNotificationEnum status) { + this.status = status; + } + + public String getErrorReason() { + return errorReason; + } + + public void setErrorReason(String errorReason) { + this.errorReason = errorReason; + } + + @Override + public String toString() { + return "DistributionStatusNotification [distributionId=" + distributionID + ", consumerId=" + consumerID + ", timestamp=" + timestamp + ", artifactURL=" + artifactURL + ", status=" + status + ", errorReason=" + errorReason + "]"; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotificationEnum.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotificationEnum.java new file mode 100644 index 0000000000..bd77f3915a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/DistributionStatusNotificationEnum.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public enum DistributionStatusNotificationEnum { + + DOWNLOAD_OK, DOWNLOAD_ERROR, ALREADY_DOWNLOADED, DEPLOY_OK, DEPLOY_ERROR, ALREADY_DEPLOYED, NOTIFIED, NOT_NOTIFIED +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IArtifactInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IArtifactInfo.java new file mode 100644 index 0000000000..169f4f3efa --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IArtifactInfo.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import org.openecomp.sdc.common.api.ArtifactTypeEnum; + +public interface IArtifactInfo { + + /** Artifact File name */ + String getArtifactName(); + + /** + * Artifact Type.
+ * Following are valid values : HEAT , DG_XML.
+ * List of values will be extended in post-1510 releases. + */ + ArtifactTypeEnum getArtifactType(); + + /** + * Relative artifact's URL. Should be used in REST GET API to download the artifact's payload.
+ * The full artifact URL will be in the following format :
+ * https://{serverBaseURL}/{resourcePath}
+ * serverBaseURL - Hostname ( ASDC LB FQDN) + optional port
+ * resourcePath - "artifactURL"
+ * Ex : https://asdc.sdc.com/v1/catalog/services/srv1/2.0/resources/aaa/1.0/artifacts/aaa.yml + */ + String getArtifactURL(); + + /** + * Base-64 encoded MD5 checksum of the artifact's payload.
+ * Should be used for data integrity validation when an artifact's payload is downloaded.
+ */ + String getArtifactChecksum(); + + /** + * Installation timeout. Used by the orchestrator. + */ + Integer getArtifactTimeout(); + + /** + * Artifact description + */ + String getArtifactDescription(); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IDistributionEngine.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IDistributionEngine.java new file mode 100644 index 0000000000..a27156616b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IDistributionEngine.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; + +import fj.data.Either; + +public interface IDistributionEngine { + + public boolean isActive(); + + public StorageOperationStatus notifyService(String distributionId, Service service, INotificationData notificationData, String envName, String userId, String modifierName); + + public StorageOperationStatus isEnvironmentAvailable(String envName); + + /** + * Currently, it used for tests. For real implementation we need cancel the initialization task and the polling task. + * + * @param envName + */ + public void disableEnvironment(String envName); + + public Either isReadyForDistribution(Service service, String distributionId, String envName); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/INotificationData.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/INotificationData.java new file mode 100644 index 0000000000..48f6c42823 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/INotificationData.java @@ -0,0 +1,102 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.List; + +public interface INotificationData { + /** + * Global Distribution Identifier: UUID generated by ASDC per each distribution activation.
+ * Generated UUID is compliant with RFC 4122.
+ * It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").
+ * Ex.: AA97B177-9383-4934-8543-0F91A7A02836 + */ + String getDistributionID(); + + /** Logical Service Name. */ + String getServiceName(); + + /** + * Service Version.
+ * Two dot (".") separated digit blocks.
+ * Ex. : "2.0" + */ + String getServiceVersion(); + + /** + * Global UUID generated by ASDC per each service version. Generated UUID is compliant with RFC 4122.
+ * It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").
+ * Ex. : AA97B177-9383-4934-8543-0F91A7A02836 + */ + String getServiceUUID(); + + /** + * Service description + */ + String getServiceDescription(); + + /** + * ServiceInvariant UUID + */ + String getServiceInvariantUUID(); + + /** List of the resource instances */ + List getResources(); + + /** List of the artifacts */ + List getServiceArtifacts(); + + void setDistributionID(String distributionId); + + /** Logical Service Name. */ + void setServiceName(String serviceName); + + /** + * Service Version.
+ * Two dot (".") separated digit blocks.
+ * Ex. : "2.0" + */ + void setServiceVersion(String serviceVersion); + + /** + * Global UUID generated by ASDC per each service version. Generated UUID is compliant with RFC 4122.
+ * It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").
+ * Ex. : AA97B177-9383-4934-8543-0F91A7A02836 + */ + void setServiceUUID(String serviceUUID); + + /** + * Service Description + */ + void setServiceDescription(String serviceDescription); + + /** + * ServiceInvariant UUID + */ + void setServiceInvariantUUID(String serviceInvariantUuid); + + /** List of the Resource Instances */ + void setResources(List resource); + + /** List of the Resource Instances */ + void setServiceArtifacts(List artifacts); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IResourceArtifactInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IResourceArtifactInfo.java new file mode 100644 index 0000000000..9a77b9f94f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IResourceArtifactInfo.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public interface IResourceArtifactInfo extends IArtifactInfo { + + /** resource name */ + String getResourceName(); + + /** resource version */ + String getResourceVersion(); + + /** + * Global UUID of the resource that specific artifact belongs to.
+ * It is generated by ASDC per each resource version.
+ * Generated UUID is compliant with RFC 4122. It is a 128-bit value formatted into blocks of hexadecimal digits separated by a hyphen ("-").
+ * Ex.: AA97B177-9383-4934-8543-0F91A7A02836 + */ + String getResourceUUID(); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IServiceArtifactInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IServiceArtifactInfo.java new file mode 100644 index 0000000000..e102f742ac --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/IServiceArtifactInfo.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public interface IServiceArtifactInfo extends IArtifactInfo { + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/JsonContainerResourceInstance.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/JsonContainerResourceInstance.java new file mode 100644 index 0000000000..25a6f46c90 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/JsonContainerResourceInstance.java @@ -0,0 +1,108 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.List; + +import org.openecomp.sdc.be.model.ComponentInstance; + +public class JsonContainerResourceInstance { + private String resourceInstanceName, resourceName, resourceVersion, resoucreType, resourceUUID, resourceInvariantUUID; + private List artifacts; + + public JsonContainerResourceInstance(ComponentInstance resourceInstance, String resourceType, List artifacts) { + super(); + this.resourceInstanceName = resourceInstance.getName(); + this.resourceName = resourceInstance.getComponentName(); + this.resourceVersion = resourceInstance.getComponentVersion(); + this.resoucreType = resourceType; + this.resourceUUID = resourceInstance.getComponentUid(); + this.artifacts = artifacts; + } + + public JsonContainerResourceInstance(ComponentInstance resourceInstance, String resourceInvariantUUID, String resourceType, List artifacts) { + super(); + this.resourceInstanceName = resourceInstance.getName(); + this.resourceName = resourceInstance.getComponentName(); + this.resourceVersion = resourceInstance.getComponentVersion(); + this.resoucreType = resourceType; + this.resourceUUID = resourceInstance.getComponentUid(); + this.resourceInvariantUUID = resourceInvariantUUID; + this.artifacts = artifacts; + } + + public String getResourceInstanceName() { + return resourceInstanceName; + } + + public void setResourceInstanceName(String resourceInstanceName) { + this.resourceInstanceName = resourceInstanceName; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public String getResoucreType() { + return resoucreType; + } + + public void setResoucreType(String resoucreType) { + this.resoucreType = resoucreType; + } + + public String getResourceUUID() { + return resourceUUID; + } + + public void setResourceUUID(String resourceUUID) { + this.resourceUUID = resourceUUID; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + public String getResourceInvariantUUID() { + return resourceInvariantUUID; + } + + public void setResourceInvariantUUID(String resourceInvariantUUID) { + this.resourceInvariantUUID = resourceInvariantUUID; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationDataImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationDataImpl.java new file mode 100644 index 0000000000..8a2ef8e63b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationDataImpl.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.List; + +public class NotificationDataImpl implements INotificationData { + + private String distributionID; + private String serviceName; + private String serviceVersion; + private String serviceUUID; + private String serviceDescription; + private String serviceInvariantUUID; + private List resources; + private List serviceArtifacts; + + @Override + public String getDistributionID() { + return distributionID; + } + + @Override + public String getServiceName() { + return serviceName; + } + + @Override + public String getServiceVersion() { + return serviceVersion; + } + + @Override + public String getServiceUUID() { + return serviceUUID; + } + + public void setDistributionID(String distributionID) { + this.distributionID = distributionID; + } + + public void setServiceName(String serviceName) { + this.serviceName = serviceName; + } + + public void setServiceVersion(String serviceVersion) { + this.serviceVersion = serviceVersion; + } + + public void setServiceUUID(String serviceUUID) { + this.serviceUUID = serviceUUID; + } + + public String getServiceDescription() { + return serviceDescription; + } + + public void setServiceDescription(String serviceDescription) { + this.serviceDescription = serviceDescription; + } + + @Override + public String toString() { + return "NotificationDataImpl [distributionID=" + distributionID + ", serviceName=" + serviceName + ", serviceVersion=" + serviceVersion + ", serviceUUID=" + serviceUUID + ", serviceInvariantUUID=" + serviceInvariantUUID + "]"; + } + + @Override + public List getResources() { + return resources; + } + + @Override + public void setResources(List resources) { + this.resources = resources; + + } + + @Override + public List getServiceArtifacts() { + // TODO Auto-generated method stub + return serviceArtifacts; + } + + @Override + public void setServiceArtifacts(List serviceArtifacts) { + this.serviceArtifacts = serviceArtifacts; + + } + + @Override + public String getServiceInvariantUUID() { + return serviceInvariantUUID; + } + + @Override + public void setServiceInvariantUUID(String serviceInvariantUUID) { + this.serviceInvariantUUID = serviceInvariantUUID; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationExecutorService.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationExecutorService.java new file mode 100644 index 0000000000..74fbb2c660 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/NotificationExecutorService.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.concurrent.ExecutorService; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +import org.openecomp.sdc.be.config.DistributionEngineConfiguration.DistributionNotificationTopicConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +public class NotificationExecutorService { + + private static Logger logger = LoggerFactory.getLogger(NotificationExecutorService.class.getName()); + + public ExecutorService createExcecutorService(DistributionNotificationTopicConfig distributionNotificationTopic) { + + Integer minThreadPoolSize = distributionNotificationTopic.getMinThreadPoolSize(); + if (minThreadPoolSize == null) { + minThreadPoolSize = 0; + } + + Integer maxThreadPoolSize = distributionNotificationTopic.getMaxThreadPoolSize(); + if (maxThreadPoolSize == null) { + maxThreadPoolSize = 10; + } + + ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder(); + threadFactoryBuilder.setNameFormat("distribution-notification-thread-%d"); + ThreadFactory threadFactory = threadFactoryBuilder.build(); + + ExecutorService executorService = new ThreadPoolExecutor(minThreadPoolSize, maxThreadPoolSize, 60L, TimeUnit.SECONDS, new SynchronousQueue(), threadFactory); + + return executorService; + } + + public void shutdownAndAwaitTermination(ExecutorService pool, long maxTimeToWait) { + + logger.debug("shutdown NotificationExecutorService"); + pool.shutdown(); // Disable new tasks from being submitted + try { + // Wait a while for existing tasks to terminate + if (!pool.awaitTermination(maxTimeToWait, TimeUnit.SECONDS)) { + pool.shutdownNow(); // Cancel currently executing tasks + // Wait a while for tasks to respond to being cancelled + if (!pool.awaitTermination(maxTimeToWait, TimeUnit.SECONDS)) { + logger.debug("Failed to close executor service"); + } + } + } catch (InterruptedException ie) { + // (Re-)Cancel if current thread also interrupted + pool.shutdownNow(); + // Preserve interrupt status + Thread.currentThread().interrupt(); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/PublishNotificationRunnable.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/PublishNotificationRunnable.java new file mode 100644 index 0000000000..362f3948ed --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/PublishNotificationRunnable.java @@ -0,0 +1,156 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.distribution.api.client.CambriaOperationStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class PublishNotificationRunnable implements Runnable { + + private String envName; + private String distributionId; + private Service service; + private INotificationData data; + private DistributionEngineConfiguration deConfiguration; + private String topicName; + private CambriaHandler cambriaHandler; + private ComponentsUtils componentUtils; + private String userId; + private String modifierName; + private String requestId; + + private static Logger logger = LoggerFactory.getLogger(PublishNotificationRunnable.class.getName()); + + public PublishNotificationRunnable(String envName, String distributionId, Service service, INotificationData data, DistributionEngineConfiguration deConfiguration, String topicName, String userId, String modifierName, + CambriaHandler cambriaHandler, ComponentsUtils componentUtils, String requestId) { + super(); + this.envName = envName; + this.distributionId = distributionId; + this.service = service; + this.data = data; + this.deConfiguration = deConfiguration; + this.topicName = topicName; + this.cambriaHandler = cambriaHandler; + this.componentUtils = componentUtils; + this.userId = userId; + this.modifierName = modifierName; + this.requestId = requestId; + } + + public INotificationData getData() { + return data; + } + + public void setData(INotificationData data) { + this.data = data; + } + + public DistributionEngineConfiguration getDeConfiguration() { + return deConfiguration; + } + + public void setDeConfiguration(DistributionEngineConfiguration deConfiguration) { + this.deConfiguration = deConfiguration; + } + + public String getTopicName() { + return topicName; + } + + public void setTopicName(String topicName) { + this.topicName = topicName; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getModifierName() { + return modifierName; + } + + public void setModifierName(String modifierName) { + this.modifierName = modifierName; + } + + @Override + public void run() { + + long startTime = System.currentTimeMillis(); + ThreadLocalsHolder.setUuid(this.requestId); + + CambriaErrorResponse status = cambriaHandler.sendNotificationAndClose(topicName, deConfiguration.getUebPublicKey(), deConfiguration.getUebSecretKey(), deConfiguration.getUebServers(), data, + deConfiguration.getDistributionNotificationTopic().getMaxWaitingAfterSendingSeconds().longValue()); + + logger.info("After publishing service {} of version {}. Status is {}", service.getName(), service.getVersion(), status.getHttpCode()); + auditDistributionNotification(topicName, status, service, distributionId, envName, userId, modifierName); + + long endTime = System.currentTimeMillis(); + logger.debug("After building and publishing artifacts object. Total took {} milliseconds.", (endTime - startTime)); + + } + + private void auditDistributionNotification(String topicName, CambriaErrorResponse status, Service service, String distributionId, String envName, String userId, String modifierName) { + if (this.componentUtils != null) { + Integer httpCode = status.getHttpCode(); + String httpCodeStr = String.valueOf(httpCode); + + String desc = getDescriptionFromErrorResponse(status); + + this.componentUtils.auditDistributionNotification(AuditingActionEnum.DISTRIBUTION_NOTIFY, service.getUUID(), service.getName(), "Service", service.getVersion(), userId, modifierName, envName, service.getLifecycleState().name(), topicName, + distributionId, desc, httpCodeStr); + } + } + + private String getDescriptionFromErrorResponse(CambriaErrorResponse status) { + + CambriaOperationStatus operationStatus = status.getOperationStatus(); + + switch (operationStatus) { + case OK: + return "OK"; + case AUTHENTICATION_ERROR: + return "Error: Authentication problem towards U-EB server"; + case INTERNAL_SERVER_ERROR: + return "Error: Internal U-EB server error"; + case UNKNOWN_HOST_ERROR: + return "Error: Cannot reach U-EB server host"; + case CONNNECTION_ERROR: + return "Error: Cannot connect to U-EB server"; + case OBJECT_NOT_FOUND: + return "Error: object not found in U-EB server"; + default: + return "Error: Internal Cambria server problem"; + + } + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ResourceArtifactInfoImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ResourceArtifactInfoImpl.java new file mode 100644 index 0000000000..31f3cb6fda --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ResourceArtifactInfoImpl.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public class ResourceArtifactInfoImpl extends ArtifactInfoImpl implements IResourceArtifactInfo { + + private String resourceName; + private String resourceVersion; + private String resourceUUID; + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public String getResourceUUID() { + return resourceUUID; + } + + public void setResourceUUID(String resourceUUID) { + this.resourceUUID = resourceUUID; + } + + @Override + public String toString() { + return "ResourceArtifactInfoImpl [resourceName=" + resourceName + ", resourceVersion=" + resourceVersion + ", resourceUUID=" + resourceUUID + super.toString() + "]"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceArtifactInfoImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceArtifactInfoImpl.java new file mode 100644 index 0000000000..50d1700f37 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceArtifactInfoImpl.java @@ -0,0 +1,30 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public class ServiceArtifactInfoImpl extends ArtifactInfoImpl implements IServiceArtifactInfo { + + @Override + public String toString() { + return "ServiceArtifactInfoImpl [" + super.toString() + "]"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceDistributionArtifactsBuilder.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceDistributionArtifactsBuilder.java new file mode 100644 index 0000000000..da148ee80a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/ServiceDistributionArtifactsBuilder.java @@ -0,0 +1,268 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.InterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("serviceDistributionArtifactsBuilder") +public class ServiceDistributionArtifactsBuilder { + + private int defaultArtifactInstallTimeout = 60; + + private static Logger logger = LoggerFactory.getLogger(ServiceDistributionArtifactsBuilder.class.getName()); + + final static String BASE_ARTIFACT_URL = "/asdc/v1/catalog/services/%s/%s/"; + final static String RESOURCE_ARTIFACT_URL = BASE_ARTIFACT_URL + "resources/%s/%s/artifacts/%s"; + final static String SERVICE_ARTIFACT_URL = BASE_ARTIFACT_URL + "artifacts/%s"; + + final static String RESOURCE_INSTANCE_ARTIFACT_URL = BASE_ARTIFACT_URL + "resourceInstances/%s/artifacts/%s"; + + @javax.annotation.Resource + ServiceOperation serviceOperation; + + @javax.annotation.Resource + ResourceOperation resourceOperation; + + @javax.annotation.Resource + InterfaceLifecycleOperation interfaceLifecycleOperation; + + @javax.annotation.Resource + IArtifactOperation artifactOperation; + + /* + * @javax.annotation.Resource private InformationDeployedArtifactsBusinessLogic informationDeployedArtifactsBusinessLogic; + */ + + @PostConstruct + private void init() { + defaultArtifactInstallTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes(); + } + + public ServiceOperation getServiceOperation() { + return serviceOperation; + } + + public void setServiceOperation(ServiceOperation serviceOperation) { + this.serviceOperation = serviceOperation; + } + + public ResourceOperation getResourceOperation() { + return resourceOperation; + } + + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + public InterfaceLifecycleOperation getInterfaceLifecycleOperation() { + return interfaceLifecycleOperation; + } + + public void setInterfaceLifecycleOperation(InterfaceLifecycleOperation interfaceLifecycleOperation) { + this.interfaceLifecycleOperation = interfaceLifecycleOperation; + } + + public INotificationData buildResourceInstanceForDistribution(Service service, String distributionId) { + INotificationData notificationData = new NotificationDataImpl(); + + notificationData.setResources(convertRIToJsonContanier(service)); + notificationData.setServiceName(service.getName()); + notificationData.setServiceVersion(service.getVersion()); + notificationData.setDistributionID(distributionId); + notificationData.setServiceUUID(service.getUUID()); + notificationData.setServiceDescription(service.getDescription()); + notificationData.setServiceInvariantUUID(service.getInvariantUUID()); + + logger.debug("Before returning notification data object {}", notificationData); + + return notificationData; + + } + + public INotificationData buildServiceForDistribution(INotificationData notificationData, Service service) { + + notificationData.setServiceArtifacts(convertServiceArtifactsToArtifactInfo(service)); + + logger.debug("Before returning notification data object {}", notificationData); + + return notificationData; + + } + + private List convertServiceArtifactsToArtifactInfo(Service service) { + + Map serviceArtifactsMap = service.getDeploymentArtifacts(); + List ret = new ArrayList(); + + for (ArtifactDefinition artifactDef : serviceArtifactsMap.values()) { + if (artifactDef.checkEsIdExist()) { + ret.add(artifactDef); + } + } + List artifacts = ArtifactInfoImpl.convertServiceArtifactToArtifactInfoImpl(service, ret); + return artifacts; + } + + private List convertRIToJsonContanier(Service service) { + List ret = new ArrayList(); + if (service.getComponentInstances() != null) { + for (ComponentInstance resourceInstance : service.getComponentInstances()) { + String resoucreType = "VF"; + List artifactsDefList = getArtifactsWithPayload(resourceInstance); + List artifacts = ArtifactInfoImpl.convertToArtifactInfoImpl(service, resourceInstance, artifactsDefList); + Either responseResult = resourceOperation.getInvariantUUID(NodeTypeEnum.Resource, resourceInstance.getComponentUid(), false); + String resourceInvariantUUID = null; + if (responseResult.isRight()) { + logger.debug("Resource {} Invariant UUID retrieving failed", resourceInstance.getComponentUid()); + } else { + resourceInvariantUUID = responseResult.left().value(); + } + JsonContainerResourceInstance jsonContainer = new JsonContainerResourceInstance(resourceInstance, resourceInvariantUUID, resoucreType, artifacts); + ret.add(jsonContainer); + } + + } + return ret; + } + + private List getArtifactsWithPayload(ComponentInstance resourceInstance) { + List ret = new ArrayList(); + + // List informationDeployedArtifacts = + // informationDeployedArtifactsBusinessLogic.getInformationalDeployedArtifactsForResourceInstance(resourceInstance); + List deployableArtifacts = new ArrayList(); + // deployableArtifacts.addAll(informationDeployedArtifacts); + if (resourceInstance.getDeploymentArtifacts() != null) { + deployableArtifacts.addAll(resourceInstance.getDeploymentArtifacts().values()); + } + + for (ArtifactDefinition artifactDef : deployableArtifacts) { + if (artifactDef.checkEsIdExist()) { + ret.add(artifactDef); + } + } + + return ret; + } + + /** + * build the url for resource intance artifact + * + * @param service + * @param resourceData + * @param artifactName + * @return + */ + public static String buildResourceInstanceArtifactUrl(Service service, ComponentInstance resourceInstance, String artifactName) { + + String url = String.format(RESOURCE_INSTANCE_ARTIFACT_URL, service.getSystemName(), service.getVersion(), resourceInstance.getNormalizedName(), artifactName); + + logger.debug("After building artifact url {}", url); + + return url; + } + + /** + * build the url for resource intance artifact + * + * @param service + * @param resourceData + * @param artifactName + * @return + */ + public static String buildServiceArtifactUrl(Service service, String artifactName) { + + String url = String.format(SERVICE_ARTIFACT_URL, service.getSystemName(), service.getVersion(), artifactName); + + logger.debug("After building artifact url {}", url); + + return url; + + } + + /** + * Retrieve all deployment artifacts of all resources under a given service + * + * @param resourceArtifactsResult + * @param service + * @param deConfiguration + * @return + */ + public Either isServiceContainsDeploymentArtifacts(Service service) { + + Either result = Either.left(false); + Map serviseArtifactsMap = service.getDeploymentArtifacts(); + if (serviseArtifactsMap != null && !serviseArtifactsMap.isEmpty()) { + result = Either.left(true); + return result; + } + + List resourceInstances = service.getComponentInstances(); + + if (resourceInstances != null) { + for (ComponentInstance resourceInstance : resourceInstances) { + + Map deploymentArtifactsMapper = resourceInstance.getDeploymentArtifacts(); + // List informationDeployedArtifacts = + // informationDeployedArtifactsBusinessLogic.getInformationalDeployedArtifactsForResourceInstance(resourceInstance); + + boolean isDeployableArtifactFound = isContainsPayload(deploymentArtifactsMapper.values());// || + // isContainsPayload(informationDeployedArtifacts); + if (isDeployableArtifactFound) { + result = Either.left(true); + break; + } + + } + + } + + return result; + } + + private boolean isContainsPayload(Collection collection) { + boolean payLoadFound = collection != null && collection.stream().anyMatch(p -> p.checkEsIdExist()); + return payLoadFound; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/SubscriberTypeEnum.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/SubscriberTypeEnum.java new file mode 100644 index 0000000000..f8c0e3f593 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/SubscriberTypeEnum.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +public enum SubscriberTypeEnum { + + CONSUMER, PRODUCER; +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/TestQueue.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/TestQueue.java new file mode 100644 index 0000000000..c9e3c4e34d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/TestQueue.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.ArrayList; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.RejectedExecutionException; +import java.util.concurrent.SynchronousQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import com.google.common.util.concurrent.ThreadFactoryBuilder; + +public class TestQueue { + + public static void main(String[] args) { + ThreadFactoryBuilder threadFactoryBuilder = new ThreadFactoryBuilder(); + threadFactoryBuilder.setNameFormat("distribution-notification-thread"); + ThreadFactory threadFactory = threadFactoryBuilder.build(); + // TODO: add the package of google to the pom + + ExecutorService executorService = new ThreadPoolExecutor(0, 10, 60L, TimeUnit.SECONDS, new SynchronousQueue(), threadFactory); + // ExecutorService executorService = new ThreadPoolExecutor(0, 2, 60L, + // TimeUnit.SECONDS, new ArrayBlockingQueue(20)); + + // 2 threads are always up and they handle the tasks. in case core size + // is 0, only one is handles the tasks. + // ExecutorService executorService = new ThreadPoolExecutor(0, 2, 60L, + // TimeUnit.SECONDS, new ArrayBlockingQueue(20)); + + // TODO : check what happen when the number of threads are full. Throw + // RejectedExecutionException + // TODO : check what happen whether the pool is full and the size of + // pool + + ExecutorService newCachedThreadPool = Executors.newCachedThreadPool(threadFactory); + Runnable task = new Runnable() { + + @Override + public void run() { + // TODO Auto-generated method stub + try { + System.out.println("iN SLEEP" + Thread.currentThread()); + Thread.sleep(10 * 1000); + System.out.println("OUT SLEEP"); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + }; + + for (int i = 0; i < 4; i++) { + try { + executorService.submit(task); + } catch (RejectedExecutionException e) { + e.printStackTrace(); + } + } + + newCachedThreadPool.submit(task); + System.out.println("After submitting the task"); + + MyWorker[] watchThreads = new MyWorker[1]; + BlockingQueue queue = new ArrayBlockingQueue<>(5); + for (int i = 0; i < watchThreads.length; i++) { + MyWorker myWorker = new MyWorker(queue); + myWorker.start(); + } + + for (int i = 0; i < 1; i++) { + try { + queue.put("message " + i); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + } + + public static class MyTimerTask extends TimerTask { + + AtomicBoolean state; + Thread thread; + + public MyTimerTask(AtomicBoolean state, Thread thread) { + super(); + this.state = state; + this.thread = thread; + + System.out.println("After create timer"); + } + + @Override + public void run() { + System.out.println("In running of Timer task"); + if (state.get() == false) { + System.out.println("In running of Timer task. Going to interrupt thread"); + // thread.interrupt(); + } else { + System.out.println("In running of Timer task. Finished."); + } + } + + } + + public static class MyWorker extends Thread { + + boolean active = true; + private final BlockingQueue queue; + + public MyWorker(BlockingQueue queue) { + this.queue = queue; + } + + Timer timer = new Timer(); + + public void run() { + try { + while (active) { + String s = queue.take(); + System.out.println("Thread " + Thread.currentThread() + " fecthed a message " + s); + + AtomicBoolean atomicBoolean = new AtomicBoolean(false); + MyTimerTask myTimerTask = new MyTimerTask(atomicBoolean, this); + timer.schedule(myTimerTask, 10 * 1000); + doWork(s); + atomicBoolean.set(true); + + } + } catch (InterruptedException ie) { + + System.out.println("Interrupted our thread"); + ie.printStackTrace(); + } + } + + private void doWork(String s) { + // TODO Auto-generated method stub + + CambriaHandler cambriaHandler = new CambriaHandler(); + INotificationData data = new NotificationDataImpl(); + List servers = new ArrayList<>(); + servers.add("aaaaaaa"); + cambriaHandler.sendNotification("topicName", "uebPublicKey", "uebSecretKey", servers, data); + + System.out.println("IN WORK " + s); + try { + Thread.sleep(1 * 1000); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + + for (int i = 0; i < 10; i++) { + System.out.println("*************************************************"); + } + e.printStackTrace(); + } + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/UebHealthCheckCall.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/UebHealthCheckCall.java new file mode 100644 index 0000000000..c522ca91b5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/UebHealthCheckCall.java @@ -0,0 +1,77 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.concurrent.Callable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class UebHealthCheckCall implements Callable { + + CambriaHandler cambriaHandler = new CambriaHandler(); + + String server; + String publicApiKey; + + private static Logger healthLogger = LoggerFactory.getLogger(DistributionEngineClusterHealth.UEB_HEALTH_LOG_CONTEXT); + + private static Logger logger = LoggerFactory.getLogger(UebHealthCheckCall.class.getName()); + + public UebHealthCheckCall(String server, String publicApiKey) { + super(); + this.server = server; + this.publicApiKey = publicApiKey; + } + + @Override + public Boolean call() { + + healthLogger.trace("Going to run health check towards ueb server {}", server); + + boolean result = false; + CambriaErrorResponse cambriaErrorResponse = cambriaHandler.getApiKey(server, publicApiKey); + + logger.debug("After running Health check towards ueb server {}. Result is {}", server, cambriaErrorResponse); + + if (cambriaErrorResponse.httpCode < CambriaErrorResponse.HTTP_INTERNAL_SERVER_ERROR) { + logger.debug("After running Health check towards ueb server {}. Error code is {}. Set result to true", server, cambriaErrorResponse.httpCode); + result = true; + } + + healthLogger.trace("Result after running health check towards ueb server {} is {}. Returned result is {} ", server, cambriaErrorResponse, result); + + return result; + } + + public String getServer() { + return server; + } + + public CambriaHandler getCambriaHandler() { + return cambriaHandler; + } + + public void setCambriaHandler(CambriaHandler cambriaHandler) { + this.cambriaHandler = cambriaHandler; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/VfModuleArtifactPayload.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/VfModuleArtifactPayload.java new file mode 100644 index 0000000000..89cb6d91ee --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/distribution/engine/VfModuleArtifactPayload.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.distribution.engine; + +import java.util.List; +import java.util.Optional; + +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.common.api.Constants; + +public class VfModuleArtifactPayload { + public VfModuleArtifactPayload(GroupDefinition group) { + vfModuleModelName = group.getName(); + vfModuleModelInvariantUUID = group.getInvariantUUID(); + vfModuleModelVersion = group.getVersion(); + vfModuleModelUUID = group.getGroupUUID(); + vfModuleModelDescription = group.getDescription(); + + artifacts = group.getArtifactsUuid(); + // Base Value is set from properties + setBaseValue(group); + + } + + private void setBaseValue(GroupDefinition group) { + if (group.getProperties() != null) { + Optional findBaseProperty = group.getProperties().stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny(); + if (findBaseProperty.isPresent()) { + isBase = Boolean.valueOf(findBaseProperty.get().getValue()); + } + + } + } + + private String vfModuleModelName, vfModuleModelInvariantUUID, vfModuleModelVersion, vfModuleModelUUID, vfModuleModelDescription; + private Boolean isBase; + private List artifacts; + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + public static int compareByGroupName(VfModuleArtifactPayload art1, VfModuleArtifactPayload art2) { + Integer thisCounter = Integer.parseInt(art1.vfModuleModelName.split(Constants.MODULE_NAME_DELIMITER)[1]); + Integer otherCounter = Integer.parseInt(art2.vfModuleModelName.split(Constants.MODULE_NAME_DELIMITER)[1]); + return thisCounter.compareTo(otherCounter); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AdditionalInformationBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AdditionalInformationBusinessLogic.java new file mode 100644 index 0000000000..e01d4c238c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AdditionalInformationBusinessLogic.java @@ -0,0 +1,573 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.List; + +import javax.servlet.ServletContext; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IAdditionalInformationOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.model.tosca.converters.StringConvertor; +import org.openecomp.sdc.be.model.tosca.validators.StringValidator; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +import fj.data.Either; + +@Component("additionalInformationBusinessLogic") +public class AdditionalInformationBusinessLogic extends BaseBusinessLogic { + + private static final String CREATE_ADDITIONAL_INFORMATION = "CreateAdditionalInformation"; + + private static final String UPDATE_ADDITIONAL_INFORMATION = "UpdateAdditionalInformation"; + + private static final String DELETE_ADDITIONAL_INFORMATION = "DeleteAdditionalInformation"; + + private static final String GET_ADDITIONAL_INFORMATION = "GetAdditionalInformation"; + + private static Logger log = LoggerFactory.getLogger(AdditionalInformationBusinessLogic.class.getName()); + + @javax.annotation.Resource + private IAdditionalInformationOperation additionalInformationOperation = null; + + @javax.annotation.Resource + private IResourceOperation resourceOperation; + + @javax.annotation.Resource + private IServiceOperation serviceOperation; + + @javax.annotation.Resource + private IGraphLockOperation graphLockOperation; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + protected static IElementOperation getElementDao(Class class1, ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + + return webApplicationContext.getBean(class1); + } + + /** + * Create new additional information on resource/service on graph + * + * @param resourceId + * @param propertyName + * @param newPropertyDefinition + * @param userId + * @return Either + */ + public Either createAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) { + + Either resp = validateUserExists(userId, "create Additional Information", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either result = null; + + ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + // lock component + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, CREATE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId); + log.info("Failed to lock component {} error - {}", resourceId, lockResult); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + try { + responseFormat = validateMaxSizeNotReached(nodeType, resourceId, additionalInfoParameterInfo); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + // validate label + responseFormat = validateAndConvertKey(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + // validate value + responseFormat = validateAndConvertValue(additionalInfoParameterInfo, CREATE_ADDITIONAL_INFORMATION); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + Either addResult = additionalInformationOperation.createAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getKey(), + additionalInfoParameterInfo.getValue(), true); + + if (addResult.isRight()) { + StorageOperationStatus status = addResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, CREATE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeSystemError(CREATE_ADDITIONAL_INFORMATION); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.Label)); + return result; + + } else { + AdditionalInformationDefinition informationDefinition = addResult.left().value(); + + AdditionalInfoParameterInfo createdAI = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey()); + result = Either.left(createdAI); + return result; + } + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, nodeType); + } + + } + + /** + * Validate the value format. Format the value. + * + * @param additionalInfoParameterInfo + * @return null in case of success. Otherwise response format. + */ + private ResponseFormat validateAndConvertValue(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) { + ResponseFormat result = null; + + String value = additionalInfoParameterInfo.getValue(); + log.debug("Going to validate additional information value {}", value); + + Either valueValidRes = validateValue(value); + if (valueValidRes.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidValueError, context, additionalInfoParameterInfo.getValue(), "additional information value", "string"); + BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getValue(), "additional information value", "string"); + result = valueValidRes.right().value(); + } else { + String newValue = valueValidRes.left().value(); + if (log.isTraceEnabled()) { + if (value != null && false == value.equals(newValue)) { + log.trace("The additional information value was normalized from {} to {}", value, newValue); + } + } + additionalInfoParameterInfo.setValue(newValue); + } + return result; + } + + /** + * @param additionalInfoParameterInfo + * @return + */ + private ResponseFormat validateAndConvertKey(AdditionalInfoParameterInfo additionalInfoParameterInfo, String context) { + + String key = additionalInfoParameterInfo.getKey(); + log.debug("Going to validate additional information key {}", key); + + ResponseFormat result = null; + ResponseFormat responseFormat; + Either validateKeyRes = validateAndNormalizeKey(key); + if (validateKeyRes.isRight()) { + responseFormat = validateKeyRes.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidValueError, context, additionalInfoParameterInfo.getKey(), "additional information label", "string"); + BeEcompErrorManager.getInstance().logBeInvalidValueError(context, additionalInfoParameterInfo.getKey(), "additional information label", "string"); + result = responseFormat; + + } else { + String convertedKey = validateKeyRes.left().value(); + + if (log.isTraceEnabled()) { + if (key != null && false == key.equals(convertedKey)) { + log.trace("The additional information key {} was normalized to {}", key, convertedKey); + } + } + additionalInfoParameterInfo.setKey(convertedKey); + } + return result; + } + + /** + * verify that the maximal number of additional information properties has not been reached. + * + * @param nodeType + * @param componentId + * @param additionalInfoParameterInfo + * @return response format in case the maximal number has been reached. + */ + private ResponseFormat validateMaxSizeNotReached(NodeTypeEnum nodeType, String componentId, AdditionalInfoParameterInfo additionalInfoParameterInfo) { + + ResponseFormat result; + Integer additionalInformationMaxNumberOfKeys = ConfigurationManager.getConfigurationManager().getConfiguration().getAdditionalInformationMaxNumberOfKeys(); + + Either checkRes = additionalInformationOperation.getNumberOfAdditionalInformationParameters(nodeType, componentId, true); + if (checkRes.isRight()) { + StorageOperationStatus status = checkRes.right().value(); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None); + return result; + } + Integer currentNumberOfProperties = checkRes.left().value(); + if (currentNumberOfProperties >= additionalInformationMaxNumberOfKeys) { + log.info("The current number of additional information properties is {}. The maximum allowed additional information properties is {}", currentNumberOfProperties, currentNumberOfProperties); + result = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None); + return result; + } + + return null; + } + + /** + * validate additional information value + * + * @param value + * @return + */ + private Either validateValue(String value) { + + boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(value); + if (false == isNonEmptyString) { + return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED)); + } + + boolean valid = StringValidator.getInstance().isValid(value, null); + if (false == valid) { + return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS, new AdditionalInfoParameterInfo(null, value), null, AdditionalInformationEnum.Value)); + } + + String converted = StringConvertor.getInstance().convert(value, null, null); + + return Either.left(converted); + } + + private AdditionalInfoParameterInfo findAdditionInformationKey(List parameters, String key) { + + for (AdditionalInfoParameterInfo infoParameterInfo : parameters) { + if (infoParameterInfo.getKey().equals(key)) { + return infoParameterInfo; + } + } + return null; + } + + /** + * validate and normalize the key + * + * @param additionalInfoParameterInfo + * @return + */ + private Either validateAndNormalizeKey(String key) { + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + additionalInfoParameterInfo.setKey(key); + + key = ValidationUtils.normalizeAdditionalInformation(key); + boolean isNonEmptyString = ValidationUtils.validateStringNotEmpty(key); + if (false == isNonEmptyString) { + return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED, null, null, AdditionalInformationEnum.Label)); + } + boolean isValidString = ValidationUtils.validateAdditionalInformationKeyName(key); + if (false == isValidString) { + if (false == ValidationUtils.validateLength(key, ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH)) { + return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_EXCEEDS_LIMIT, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label)); + } + return Either.right(componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS, additionalInfoParameterInfo, null, AdditionalInformationEnum.Label)); + } + + return Either.left(key); + } + + /** + * update key and value of a given additional information. + * + * @param nodeType + * @param resourceId + * @param additionalInfoParameterInfo + * @param additionalInformationUid + * - Future use + * @param userId + * @return + */ + public Either updateAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) { + + Either resp = validateUserExists(userId, "create Additional Information", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either result = null; + + ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + // lock component + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, UPDATE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId); + log.info("Failed to lock component {} error - {}", resourceId, lockResult); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + try { + + // validate input + responseFormat = validateAndConvertKey(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + responseFormat = validateAndConvertValue(additionalInfoParameterInfo, UPDATE_ADDITIONAL_INFORMATION); + if (responseFormat != null) { + result = Either.right(responseFormat); + return result; + } + + Either addResult = additionalInformationOperation.updateAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), + additionalInfoParameterInfo.getKey(), additionalInfoParameterInfo.getValue(), true); + + if (addResult.isRight()) { + StorageOperationStatus status = addResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, UPDATE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeSystemError(UPDATE_ADDITIONAL_INFORMATION); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None)); + return result; + } else { + AdditionalInformationDefinition informationDefinition = addResult.left().value(); + AdditionalInfoParameterInfo parameterInfo = findAdditionInformationKey(informationDefinition.getParameters(), additionalInfoParameterInfo.getKey()); + result = Either.left(parameterInfo); + return result; + } + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, nodeType); + } + + } + + /** + * Delete an additional information label + * + * @param nodeType + * @param resourceId + * @param additionalInfoParameterInfo + * @param additionalInformationUid + * - Null. Future use. + * @param userId + * @return + */ + public Either deleteAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) { + + Either resp = validateUserExists(userId, "delete Additional Information", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either result = null; + + ResponseFormat responseFormat = verifyCanWorkOnComponent(nodeType, resourceId, userId); + if (responseFormat != null) { + return Either.right(responseFormat); + } + // lock component + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, nodeType); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, DELETE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ADDITIONAL_INFORMATION, nodeType.getName(), resourceId); + log.info("Failed to lock component {} error - {}", resourceId, lockResult); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + + try { + + Either findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true); + if (findIdRes.isRight()) { + StorageOperationStatus status = findIdRes.right().value(); + if (status != StorageOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, GET_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeSystemError(GET_ADDITIONAL_INFORMATION); + } + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None)); + return result; + } + + AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value(); + + Either addResult = additionalInformationOperation.deleteAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true); + + if (addResult.isRight()) { + StorageOperationStatus status = addResult.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, DELETE_ADDITIONAL_INFORMATION); + BeEcompErrorManager.getInstance().logBeDaoSystemError(DELETE_ADDITIONAL_INFORMATION); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None)); + return result; + } else { + result = Either.left(foundAdditionalInfo); + return result; + } + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, nodeType); + } + + } + + /** + * @param nodeType + * @param resourceId + * @param additionalInfoParameterInfo + * @param additionalInformationUid + * @param userId + * @return + */ + public Either getAdditionalInformation(NodeTypeEnum nodeType, String resourceId, AdditionalInfoParameterInfo additionalInfoParameterInfo, String additionalInformationUid, String userId) { + + Either resp = validateUserExists(userId, "get Additional Information", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either result = null; + + try { + + Either findIdRes = additionalInformationOperation.getAdditionalInformationParameter(nodeType, resourceId, additionalInfoParameterInfo.getUniqueId(), true); + + if (findIdRes.isRight()) { + StorageOperationStatus status = findIdRes.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus, additionalInfoParameterInfo, nodeType, AdditionalInformationEnum.None)); + } + + AdditionalInfoParameterInfo foundAdditionalInfo = findIdRes.left().value(); + + result = Either.left(foundAdditionalInfo); + + return result; + + } finally { + commitOrRollback(result); + } + + } + + /** + * Get all additional information properties of a given resource/service + * + * @param nodeType + * @param resourceId + * @param additionalInformationUid + * - Future use + * @param userId + * @return + */ + public Either getAllAdditionalInformation(NodeTypeEnum nodeType, String resourceId, String additionalInformationUid, String userId) { + + Either resp = validateUserExists(userId, "get All Additional Information", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either result = null; + + try { + + Either findIdRes = additionalInformationOperation.getAllAdditionalInformationParameters(nodeType, resourceId, false); + if (findIdRes.isRight()) { + StorageOperationStatus status = DaoStatusConverter.convertTitanStatusToStorageStatus(findIdRes.right().value()); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForAdditionalInformation(status); + result = Either.right(componentsUtils.getResponseFormatAdditionalProperty(actionStatus)); + } else { + AdditionalInformationDefinition informationDefinition = findIdRes.left().value(); + result = Either.left(informationDefinition); + } + + return result; + + } finally { + commitOrRollback(result); + } + + } + + private ResponseFormat verifyCanWorkOnComponent(NodeTypeEnum nodeType, String resourceId, String userId) { + + switch (nodeType) { + case Resource: + + // verify that resource is checked-out and the user is the last + // updater + if (!ComponentValidationUtils.canWorkOnResource(resourceId, resourceOperation, userId)) { + return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } + break; + case Service: + + // verify that resource is checked-out and the user is the last + // updater + if (!ComponentValidationUtils.canWorkOnService(resourceId, serviceOperation, userId)) { + return componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } + break; + default: + return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT, nodeType.getName()); + } + + return null; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java new file mode 100644 index 0000000000..16ed4a1868 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ArtifactsBusinessLogic.java @@ -0,0 +1,4127 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.math.BigDecimal; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Predicate; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.validation.DeploymentArtifactHeatConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.ArtifactDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.ArtifactData; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingTypesConstants; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.be.tosca.CsarUtils; +import org.openecomp.sdc.be.tosca.ToscaError; +import org.openecomp.sdc.be.tosca.ToscaExportHandler; +import org.openecomp.sdc.be.tosca.ToscaRepresentation; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; +import org.yaml.snakeyaml.Yaml; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.sun.org.apache.xerces.internal.parsers.SAXParser; + +import fj.data.Either; + +@org.springframework.stereotype.Component("artifactBusinessLogic") +public class ArtifactsBusinessLogic extends BaseBusinessLogic { + private static final String ARTIFACT_TYPE_OTHER = "OTHER"; + private static final String ARTIFACT_DESCRIPTION = "artifact description"; + private static final String ARTIFACT_LABEL = "artifact label"; + private static final String ARTIFACT_URL = "artifact url"; + private static final String ARTIFACT_NAME = "artifact name"; + private static final String ARTIFACT_PAYLOAD = "artifact payload"; + + private static final String ARTIFACT_PLACEHOLDER_TYPE = "type"; + private static final String ARTIFACT_PLACEHOLDER_DISPLAY_NAME = "displayName"; + private static final Object ARTIFACT_PLACEHOLDER_DESCRIPTION = "description"; + + private static Integer defaultHeatTimeout; + private static final Integer NON_HEAT_TIMEOUT = 0; + private static Logger log = LoggerFactory.getLogger(ArtifactsBusinessLogic.class.getName()); + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + @javax.annotation.Resource + private IArtifactOperation artifactOperation; + + // @javax.annotation.Resource + // private IResourceUploader daoUploader; + + @javax.annotation.Resource + private IInterfaceLifecycleOperation interfaceLifecycleOperation; + @javax.annotation.Resource + private IUserAdminOperation userOperaton; + + // @javax.annotation.Resource + // private ESCatalogDAO esCatalogDao; + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private ResourceBusinessLogic resourceBusinessLogic; + + @javax.annotation.Resource + private ServiceBusinessLogic serviceBusinessLogic; + + @javax.annotation.Resource + private UserBusinessLogic userAdminManager; + + @javax.annotation.Resource + private IHeatParametersOperation heatParametersOperation; + + @javax.annotation.Resource + private IComponentInstanceOperation resourceInstanceOperation; + + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + + @Autowired + private ToscaExportHandler toscaExportUtils; + + @Autowired + private CsarUtils csarUtils; + + @Autowired + private LifecycleBusinessLogic lifecycleBusinessLogic; + + @Autowired + private IUserBusinessLogic userBusinessLogic; + + public ArtifactsBusinessLogic() { + defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes(); + if ((defaultHeatTimeout == null) || (defaultHeatTimeout < 1)) { + defaultHeatTimeout = 60; + } + } + + public static enum ArtifactOperation { + + Create(false), Update(false), Delete(false), Download(false); + + private boolean isExternalApi; + + ArtifactOperation(boolean isExternalApi) { + this.isExternalApi = isExternalApi; + } + + public boolean isExternalApi() { + return isExternalApi; + } + + public void setExternalApi(boolean isExternalApi) { + this.isExternalApi = isExternalApi; + } + } + + // new flow US556184 + public Either, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, + String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType) { + return handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, containerComponentType, true, false); + } + + public Either, ResponseFormat> handleArtifactRequest(String componentId, String userId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, + String origMd5, String originData, String interfaceName, String operationName, String parentId, String containerComponentType, boolean shouldLock, boolean inTransaction) { + // step 1 + // detect auditing type + AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5); + Wrapper errorWrapper = new Wrapper<>(); + // step 2 + // check header + if (userId == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + log.debug("handleArtifactRequest - no HTTP_CSP_HEADER , component id {}", componentId); + handleAuditing(auditingAction, null, componentId, null, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + // step 3 + // check user existence + // step 4 + // check user's role + Either userResult = validateUserExists(userId, auditingAction, componentId, artifactId, componentType, inTransaction); + if (userResult.isRight()) { + return Either.right(userResult.right().value()); + } + + User user = userResult.left().value(); + Either validateUserRole = validateUserRole(user, auditingAction, componentId, artifactId, componentType, operation); + if (validateUserRole.isRight()) { + return Either.right(validateUserRole.right().value()); + } + + // steps 5 - 6 - 7 + // 5. check service/resource existence + // 6. check service/resource check out + // 7. user is owner of checkout state + org.openecomp.sdc.be.model.Component component = null; + // ComponentInstance resourceInstance = null; + String realComponentId = componentType == ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId; + Either validateComponent = validateComponentExists(realComponentId, userId, auditingAction, user, artifactId, componentType, containerComponentType, inTransaction); + if (validateComponent.isRight()) { + return Either.right(validateComponent.right().value()); + } + component = validateComponent.left().value(); + Either validateWorkOnResource = validateWorkOnComponent(component, userId, auditingAction, user, artifactId, operation, componentType); + if (validateWorkOnResource.isRight()) { + return Either.right(validateWorkOnResource.right().value()); + } + // step 8 + Either, ResponseFormat> result = validateAndHandleArtifact(componentId, componentType, operation, artifactId, artifactInfo, origMd5, originData, interfaceName, operationName, parentId, user, component, + shouldLock, inTransaction); + + return result; + } + + /** + * This Method validates only the Artifact and does not validate user / role / component ect...
+ * For regular usage use
+ * {@link #handleArtifactRequest(String, String, ComponentTypeEnum, ArtifactOperation, String, ArtifactDefinition, String, String, String, String, String, String)} + * + * @return + */ + public Either, ResponseFormat> validateAndHandleArtifact(String componentUniqueId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactUniqueId, ArtifactDefinition artifactDefinition, + String origMd5, String originData, String interfaceName, String operationName, String parentId, User user, Component component, boolean shouldLock, boolean inTransaction) { + Component parent = component; + Wrapper errorWrapper = new Wrapper<>(); + + AuditingActionEnum auditingAction = detectAuditingType(operation, origMd5); + artifactDefinition = validateArtifact(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, parentId, auditingAction, user, component, parent, shouldLock, errorWrapper); + + Either, ResponseFormat> result; + if (errorWrapper.isEmpty()) { + // step 10 + result = doAction(componentUniqueId, componentType, operation, artifactUniqueId, artifactDefinition, origMd5, originData, interfaceName, operationName, auditingAction, user, parent, shouldLock, inTransaction); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + private ArtifactDefinition validateArtifact(String componentId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String parentId, AuditingActionEnum auditingAction, User user, + org.openecomp.sdc.be.model.Component component, org.openecomp.sdc.be.model.Component parent, boolean shouldLock, Wrapper errorWrapper) { + if (operation == ArtifactOperation.Update || operation == ArtifactOperation.Delete || operation == ArtifactOperation.Download) { + Either validateArtifact = validateArtifact(componentId, componentType, artifactId, component, auditingAction, parentId); + if (validateArtifact.isRight()) { + ResponseFormat responseFormat = validateArtifact.right().value(); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + errorWrapper.setInnerElement(validateArtifact.right().value()); + } else if (operation == ArtifactOperation.Download) { + artifactInfo = validateArtifact.left().value(); + handleHeatEnvDownload(componentId, user, component, validateArtifact, shouldLock, errorWrapper); + } + } + return artifactInfo; + } + + private void handleHeatEnvDownload(String componentId, User user, org.openecomp.sdc.be.model.Component component, Either validateArtifact, boolean shouldLock, Wrapper errorWrapper) { + ArtifactDefinition validatedArtifact = validateArtifact.left().value(); + + if (validatedArtifact.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ENV.getType())) { + ComponentInstance componentInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findAny().get(); + ArtifactDefinition heatEnvWithHeatParams = componentInstance.getDeploymentArtifacts().values().stream().filter(p -> p.getUniqueId().equals(validatedArtifact.getUniqueId())).findAny().get(); + Either eitherGenerated = generateHeatEnvArtifact(heatEnvWithHeatParams, component, componentInstance.getName(), user, shouldLock); + if (eitherGenerated.isRight()) { + errorWrapper.setInnerElement(eitherGenerated.right().value()); + } + } + } + + private boolean artifactGenerationRequired(org.openecomp.sdc.be.model.Component component, ArtifactDefinition artifactInfo) { + return artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && (component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || component.getLifecycleState() == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + } + + public Either, ResponseFormat> generateAndSaveToscaArtifact(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, + boolean shouldLock, boolean inTransaction, boolean fetchTemplatesFromDB) { + + Either, ResponseFormat> generated = generateToscaArtifact(component, artifactDefinition, isInCertificationRequest, fetchTemplatesFromDB, shouldLock, inTransaction); + if (generated.isRight()) { + return generated; + } + byte[] decodedPayload = artifactDefinition.getPayloadData(); + artifactDefinition.setEsId(artifactDefinition.getUniqueId()); + artifactDefinition.setArtifactChecksum(GeneralUtility.calculateMD5ByByteArray(decodedPayload)); + return lockComponentAndUpdateArtifact(component.getUniqueId(), artifactDefinition, AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, artifactDefinition.getUniqueId(), user, component.getComponentType(), component, decodedPayload, null, null, + shouldLock, inTransaction); + + } + + private Either, ResponseFormat> generateToscaArtifact(Component parent, ArtifactDefinition artifactInfo, boolean isInCertificationRequest, boolean fetchTemplatesFromDB, boolean shouldLock, + boolean inTransaction) { + log.debug("tosca artifact generation"); + if (artifactInfo.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())) { + Either generated = csarUtils.createCsar(parent, fetchTemplatesFromDB, isInCertificationRequest, shouldLock, inTransaction); + + if (generated.isRight()) { + log.debug("Failed to export tosca csar for component {} error {}", parent.getUniqueId(), generated.right().value()); + + return Either.right(generated.right().value()); + } + byte[] value = generated.left().value(); + artifactInfo.setPayload(value); + + } else { + Either exportComponent = toscaExportUtils.exportComponent(parent); + if (exportComponent.isRight()) { + log.debug("Failed export tosca yaml for component {} error {}", parent.getUniqueId(), exportComponent.right().value()); + ActionStatus status = componentsUtils.convertFromToscaError(exportComponent.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status); + return Either.right(responseFormat); + } + log.debug("Tosca yaml exported for component {} ", parent.getUniqueId()); + String payload = exportComponent.left().value().getMainYaml(); + artifactInfo.setPayloadData(payload); + } + return Either.left(Either.left(artifactInfo)); + } + + private Either, ResponseFormat> doAction(String componentId, ComponentTypeEnum componentType, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String origMd5, + String originData, String interfaceName, String operationName, AuditingActionEnum auditingAction, User user, org.openecomp.sdc.be.model.Component parent, boolean shouldLock, boolean inTransaction) { + if (interfaceName != null && operationName != null) { + interfaceName = interfaceName.toLowerCase(); + operationName = operationName.toLowerCase(); + } + switch (operation) { + case Download: + if (artifactGenerationRequired(parent, artifactInfo)) { + return generateToscaArtifact(parent, artifactInfo, false, false, shouldLock, inTransaction); + } + return handleDownload(componentId, artifactId, user, auditingAction, componentType, parent, shouldLock, inTransaction); + case Delete: + return handleDelete(componentId, artifactId, user, auditingAction, componentType, parent, interfaceName, operationName, shouldLock, inTransaction); + case Update: + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + if (componentType.equals(ComponentTypeEnum.RESOURCE_INSTANCE) + && (artifactType == ArtifactTypeEnum.HEAT || artifactType == ArtifactTypeEnum.HEAT_VOL || artifactType == ArtifactTypeEnum.HEAT_NET || artifactType == ArtifactTypeEnum.HEAT_ENV)) { + return handleUpdateHeatEnv(componentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, originData, origMd5, operation, shouldLock, inTransaction); + } + return handleUpdate(componentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceName, operationName, shouldLock, inTransaction); + case Create: + return handleCreate(componentId, artifactInfo, operation, auditingAction, user, componentType, parent, origMd5, originData, interfaceName, operationName, shouldLock, inTransaction); + } + return null; + } + + /** + * + * @param componentId + * @param artifactId + * @param userId + * @param componentType + * @param parentId + * TODO + * @return + */ + + public Either, ResponseFormat> handleDownloadToscaModelRequest(Component component, ArtifactDefinition csarArtifact, boolean shouldLock, boolean inTransaction) { + if (artifactGenerationRequired(component, csarArtifact)) { + Either generated = csarUtils.createCsar(component, false, false, shouldLock, inTransaction); + + if (generated.isRight()) { + log.debug("Failed to export tosca csar for component {} error {}", component.getUniqueId(), generated.right().value()); + + return Either.right(generated.right().value()); + } + return Either.left(new ImmutablePair(csarArtifact.getArtifactName(), generated.left().value())); + } + return downloadArtifact(csarArtifact); + } + + public Either, ResponseFormat> handleDownloadRequestById(String componentId, String artifactId, String userId, ComponentTypeEnum componentType, String parentId, String containerComponentType) { + // perform all validation in common flow + Either, ResponseFormat> result = handleArtifactRequest(componentId, userId, componentType, ArtifactOperation.Download, artifactId, null, null, null, null, null, parentId, containerComponentType); + if (result.isRight()) { + return Either.right(result.right().value()); + } + ArtifactDefinition artifactDefinition; + Either insideValue = result.left().value(); + if (insideValue.isLeft()) { + artifactDefinition = insideValue.left().value(); + } else { + artifactDefinition = insideValue.right().value().getImplementation(); + } + // for tosca artifacts generated on download without saving + if (artifactDefinition.getArtifactGroupType() == ArtifactGroupTypeEnum.TOSCA && artifactDefinition.getPayloadData() != null) { + return Either.left(new ImmutablePair(artifactDefinition.getArtifactName(), artifactDefinition.getPayloadData())); + } + return downloadArtifact(artifactDefinition); + } + + private Either validateArtifact(String componentId, ComponentTypeEnum componentType, String artifactId, org.openecomp.sdc.be.model.Component component, AuditingActionEnum auditingAction, String parentId) { + // step 9 + // check artifact existence + Either artifactResult = artifactOperation.getArtifactById(artifactId, false); + if (artifactResult.isRight()) { + if (artifactResult.right().value().equals(StorageOperationStatus.ARTIFACT_NOT_FOUND)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""); + log.debug("addArtifact - artifact {} not found", artifactId); + return Either.right(responseFormat); + + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactResult.right().value())); + log.debug("addArtifact - failed to fetch artifact {}, error {}", artifactId, artifactResult.right().value()); + return Either.right(responseFormat); + } + } + // step 9.1 + // check artifact belong to component + boolean found = false; + switch (componentType) { + case RESOURCE: + case SERVICE: + found = checkArtifactInComponent(component, artifactId); + break; + case RESOURCE_INSTANCE: + found = checkArtifactInResourceInstance(component, componentId, artifactId); + break; + default: + + } + if (!found) { + // String component = + // componentType.equals(ComponentTypeEnum.RESOURCE) ? "resource" : + // "service"; + String componentName = componentType.name().toLowerCase(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ARTIFACT_NOT_FOUND, componentName); + log.debug("addArtifact - Component artifact not found component Id {}, artifact id {}", componentId, artifactId); + return Either.right(responseFormat); + } + return Either.left(artifactResult.left().value()); + } + + private Either, ResponseFormat> handleCreate(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + String artifactId = null; + + // step 11 + Either payloadEither = validateInput(parentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceType, operationName, inTransaction); + if (payloadEither.isRight()) { + return Either.right(payloadEither.right().value()); + } + byte[] decodedPayload = payloadEither.left().value(); + NodeTypeEnum parentType = convertParentType(componentType); + // lock resource + + if (shouldLock) { + Either lockComponent = lockComponent(parent, "Upload Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, null, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either, ResponseFormat> resultOp = null; + + try { + resultOp = createArtifact(parent, parentId, artifactInfo, decodedPayload, user, componentType, auditingAction, interfaceType, operationName); + return resultOp; + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + + } + + } + + private Either, ResponseFormat> lockComponentAndUpdateArtifact(String parentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, + ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, byte[] decodedPayload, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + NodeTypeEnum parentType = convertParentType(componentType); + + // lock resource + if (shouldLock) { + Either lockComponent = lockComponent(parent, "Update Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + + Either, ResponseFormat> resultOp = null; + try { + resultOp = updateArtifactFlow(parent, parentId, artifactId, artifactInfo, user, decodedPayload, componentType, auditingAction, interfaceType, operationName); + return resultOp; + + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + } + } + + private Either, ResponseFormat> handleUpdate(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, String artifactId, User user, + ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + + Either payloadEither = validateInput(parentId, artifactInfo, operation, auditingAction, artifactId, user, componentType, parent, origMd5, originData, interfaceType, operationName, inTransaction); + + if (payloadEither.isRight()) { + return Either.right(payloadEither.right().value()); + } + byte[] decodedPayload = payloadEither.left().value(); + + return lockComponentAndUpdateArtifact(parentId, artifactInfo, auditingAction, artifactId, user, componentType, parent, decodedPayload, interfaceType, operationName, shouldLock, inTransaction); + } + + private Either validateInput(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String origMd5, String originData, String interfaceType, String operationName, boolean inTransaction) { + // Md5 validations + Either validateMd5 = validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation); + if (validateMd5.isRight()) { + ResponseFormat responseFormat = validateMd5.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + // step 11 + Either validateResult = validateInput(parentId, artifactInfo, operation, artifactId, user, interfaceType, operationName, componentType, parent, inTransaction); + if (validateResult.isRight()) { + ResponseFormat responseFormat = validateResult.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(validateResult.right().value()); + } + + Either payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction)); + if (payloadEither.isRight()) { + ResponseFormat responseFormat = payloadEither.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + log.debug("Error during handle payload"); + return Either.right(responseFormat); + } + + // validate heat parameters. this part must be after the parameters are + // extracted in "handlePayload" + Either validateAndConvertHeatParamers = validateAndConvertHeatParamers(artifactInfo, artifactInfo.getArtifactType()); + if (validateAndConvertHeatParamers.isRight()) { + ResponseFormat responseFormat = validateAndConvertHeatParamers.right().value(); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, null, artifactId, responseFormat, componentType, null); + log.debug("Error during handle payload"); + return Either.right(responseFormat); + } + return payloadEither; + } + + public void handleAuditing(AuditingActionEnum auditingActionEnum, Component component, String componentId, User user, ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid, ResponseFormat responseFormat, + ComponentTypeEnum componentTypeEnum, String resourceInstanceName) { + + if (auditingActionEnum.getAuditingEsType().equals(AuditingTypesConstants.EXTERNAL_API_EVENT_TYPE)) { + return; + } + + EnumMap auditingFields = createArtifactAuditingFields(artifactDefinition, prevArtifactUuid, currentArtifactUuid); + + if (user == null) { + user = new User(); + user.setUserId("UNKNOWN"); + } + switch (componentTypeEnum) { + + case RESOURCE: + Resource resource = (Resource) component; + if (resource == null) { + // In that case, component ID should be instead of name + resource = new Resource(); + resource.setName(componentId); + } + componentsUtils.auditResource(responseFormat, user, resource, null, null, auditingActionEnum, auditingFields); + break; + + case SERVICE: + Service service = (Service) component; + if (service == null) { + // In that case, component ID should be instead of name + service = new Service(); + service.setName(componentId); + } + componentsUtils.auditComponent(responseFormat, user, service, null, null, auditingActionEnum, ComponentTypeEnum.SERVICE, auditingFields); + break; + + case RESOURCE_INSTANCE: + if (resourceInstanceName == null) { + resourceInstanceName = getResourceInstanceNameFromComponent(component, componentId); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + componentsUtils.auditComponent(responseFormat, user, component, null, null, auditingActionEnum, ComponentTypeEnum.RESOURCE_INSTANCE, auditingFields); + + break; + default: + break; + } + } + + private String getResourceInstanceNameFromComponent(Component component, String componentId) { + ComponentInstance resourceInstance = component.getComponentInstances().stream().filter(p -> p.getUniqueId().equals(componentId)).findFirst().orElse(null); + String resourceInstanceName = null; + if (resourceInstance != null) { + resourceInstanceName = resourceInstance.getName(); + } + return resourceInstanceName; + } + + public EnumMap createArtifactAuditingFields(ArtifactDefinition artifactDefinition, String prevArtifactUuid, String currentArtifactUuid) { + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + // Putting together artifact info + String artifactData = buildAuditingArtifactData(artifactDefinition); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, artifactData); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, prevArtifactUuid); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, currentArtifactUuid); + return auditingFields; + } + + // ----- + + private String buildAuditingArtifactData(ArtifactDefinition artifactDefinition) { + StringBuilder sb = new StringBuilder(); + if (artifactDefinition != null) { + sb.append(artifactDefinition.getArtifactGroupType().getType()).append(",").append("'").append(artifactDefinition.getArtifactLabel()).append("'").append(",").append(artifactDefinition.getArtifactType()).append(",") + .append(artifactDefinition.getArtifactName()).append(",").append(artifactDefinition.getTimeout()).append(",").append(artifactDefinition.getEsId()); + + sb.append(","); + if (artifactDefinition.getArtifactVersion() != null) { + + sb.append(artifactDefinition.getArtifactVersion()); + } else { + sb.append(" "); + } + sb.append(","); + if (artifactDefinition.getArtifactUUID() != null) { + sb.append(artifactDefinition.getArtifactUUID()); + } else { + sb.append(" "); + } + } + return sb.toString(); + } + + private Either validateMd5(String origMd5, String originData, byte[] payload, ArtifactOperation operation) { + + if (origMd5 != null) { + String encodeBase64Str = GeneralUtility.calculateMD5ByString(originData); + + if (false == encodeBase64Str.equals(origMd5)) { + log.debug("The calculated md5 is different then the received one"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_MD5)); + } + } else { + if (operation == ArtifactOperation.Create) { + log.debug("Missing md5 header during artifact create"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_MD5)); + } + // Update metadata + if (payload != null && payload.length != 0) { + log.debug("Cannot have payload while md5 header is missing"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + return Either.left(true); + } + + private Either validateInput(String parentId, ArtifactDefinition artifactInfo, ArtifactOperation operation, String artifactId, User user, String interfaceName, String operationName, + ComponentTypeEnum componentType, Component parentComponent, boolean inTransaction) { + + Either validateAndSetArtifactname = validateAndSetArtifactname(artifactInfo); + if (validateAndSetArtifactname.isRight()) { + return Either.right(validateAndSetArtifactname.right().value()); + } + Either artifactById = fetchCurrentArtifact(operation, artifactId); + if (artifactById.isRight()) { + return Either.right(artifactById.right().value()); + } + ArtifactDefinition currentArtifactInfo = artifactById.left().value(); + if (operationName != null && interfaceName != null) { + operationName = operationName.toLowerCase(); + interfaceName = interfaceName.toLowerCase(); + } + Either logicalNameStatus = handleArtifactLabel(parentId, operation, artifactId, artifactInfo, interfaceName, operationName, currentArtifactInfo, componentType, inTransaction); + if (logicalNameStatus.isRight()) { + return Either.right(logicalNameStatus.right().value()); + } + // This is a patch to block possibility of updating service api fields + // through other artifacts flow + + if (!operation.equals(ArtifactOperation.Create)) { + checkAndSetUnUpdatableFields(user, artifactInfo, currentArtifactInfo, (operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL)); + } else { + checkCreateFields(user, artifactInfo, (operationName != null ? ArtifactGroupTypeEnum.LIFE_CYCLE : ArtifactGroupTypeEnum.INFORMATIONAL)); + } + + composeArtifactId(parentId, artifactId, artifactInfo, interfaceName, operationName); + if (currentArtifactInfo != null) { + artifactInfo.setMandatory(currentArtifactInfo.getMandatory()); + } + + // artifactGroupType is not allowed to be updated + if (!operation.equals(ArtifactOperation.Create)) { + Either validateGroupType = validateOrSetArtifactGroupType(artifactInfo, currentArtifactInfo); + if (validateGroupType.isRight()) { + return Either.right(validateGroupType.right().value()); + } + } + // TODO TEMP !!! + NodeTypeEnum parentType = convertParentType(componentType); + + // TODO TEMP !!! + boolean isCreate = operation.equals(ArtifactOperation.Create); + + if (isDeploymentArtifact(artifactInfo)) { + Either deploymentValidationResult = validateDeploymentArtifact(parentComponent, parentId, user.getUserId(), isCreate, artifactInfo, currentArtifactInfo, parentType); + if (deploymentValidationResult.isRight()) { + return Either.right(deploymentValidationResult.right().value()); + } + } else { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + + /* + * if (informationDeployedArtifactsBusinessLogic. isInformationDeployedArtifact(artifactInfo)) { Either validationResult = informationDeployedArtifactsBusinessLogic.validateArtifact( isCreate, artifactInfo, + * parentComponent, parentType); if (validationResult.isRight()) { return Either.right(validationResult.right().value()); } } + */ + } + + Either descriptionResult = validateAndCleanDescription(artifactInfo); + if (descriptionResult.isRight()) { + return Either.right(descriptionResult.right().value()); + } + + if (currentArtifactInfo != null && currentArtifactInfo.getArtifactGroupType().equals(ArtifactGroupTypeEnum.SERVICE_API)) { + Either validateServiceApiType = validateArtifactType(user.getUserId(), artifactInfo, parentType); + if (validateServiceApiType.isRight()) { + return Either.right(validateServiceApiType.right().value()); + } + // Change of type is not allowed and should be ignored + + artifactInfo.setArtifactType(ARTIFACT_TYPE_OTHER); + + Either validateUrl = validateAndServiceApiUrl(artifactInfo); + if (validateUrl.isRight()) { + return Either.right(validateUrl.right().value()); + } + + Either validateUpdate = validateFirstUpdateHasPayload(artifactInfo, currentArtifactInfo); + if (validateUpdate.isRight()) { + log.debug("serviceApi first update cnnot be without payload."); + return Either.right(validateUpdate.right().value()); + } + } else { + Either validateArtifactType = validateArtifactType(user.getUserId(), artifactInfo, parentType); + if (validateArtifactType.isRight()) { + return Either.right(validateArtifactType.right().value()); + } + if (artifactInfo.getApiUrl() != null) { + artifactInfo.setApiUrl(null); + log.error("Artifact URL cannot be set through this API - ignoring"); + } + + if (artifactInfo.getServiceApi() != null) { + if (artifactInfo.getServiceApi()) { + artifactInfo.setServiceApi(false); + log.error("Artifact service API flag cannot be changed - ignoring"); + } + } + } + + return Either.left(artifactInfo); + } + + private NodeTypeEnum convertParentType(ComponentTypeEnum componentType) { + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + return NodeTypeEnum.Resource; + } else if (componentType.equals(ComponentTypeEnum.RESOURCE_INSTANCE)) { + return NodeTypeEnum.ResourceInstance; + } else { + return NodeTypeEnum.Service; + } + } + + public Either, ResponseFormat> handleDelete(String parentId, String artifactId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, org.openecomp.sdc.be.model.Component parent, + String interfaceType, String operationName, boolean shouldLock, boolean inTransaction) { + NodeTypeEnum parentType = convertParentType(componentType); + // lock resource + if (shouldLock) { + Either lockComponent = lockComponent(parent, "Delete Artifact - lock resource: "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either, ResponseFormat> resultOp = null; + Either insideEither = null; + StorageOperationStatus error = null; + boolean isLeft = false; + ArtifactDefinition artifactDefinition = null; + Integer artifactParentsCount = 1; + try { + if (interfaceType != null && operationName != null) { + log.debug("Try to delete inteface lifecycle artifact {}", artifactId); + + Either result = interfaceLifecycleOperation.deleteInterfaceOperation(parentId, interfaceType, UniqueIdBuilder.buildOperationByInterfaceUniqueId(parentId, interfaceType, operationName), + inTransaction); + isLeft = result.isLeft(); + if (isLeft) { + artifactDefinition = result.left().value().getImplementation(); + insideEither = Either.right(result.left().value()); + } + } else { + log.debug("Try to delete artifact, get parents {}", artifactId); + + Either parentsOfArtifact = artifactOperation.getParentsOfArtifact(artifactId, parentType); + if (parentsOfArtifact.isRight()) { + log.debug("Failed to delete entry on graph for artifact {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(parentsOfArtifact.right().value()), ""); + resultOp = Either.right(responseFormat); + } else { + + artifactParentsCount = parentsOfArtifact.left().value(); + log.debug("Number of parents nodes on graph for artifact {} is {}", artifactId, artifactParentsCount); + + Either result = artifactOperation.removeArifactFromResource(parentId, artifactId, parentType, false, true); + isLeft = result.isLeft(); + if (isLeft) { + log.debug("Artifact removed from graph {}", artifactId); + + artifactDefinition = result.left().value(); + insideEither = Either.left(result.left().value()); + } else { + error = result.right().value(); + } + } + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + if (isLeft) { + StorageOperationStatus deleteIfNotOnGraph = StorageOperationStatus.OK; + if (artifactParentsCount < 2) { + log.debug("Number of parent nodes is 1. Need to delete from ES {}", artifactId); + deleteIfNotOnGraph = deleteIfNotOnGraph(artifactId, artifactDefinition.getEsId(), true); + } + if (deleteIfNotOnGraph.equals(StorageOperationStatus.OK)) { + if (artifactDefinition.getMandatory() || artifactDefinition.getServiceApi()) { + log.debug("Artifact is mandatory or service API. Clean all fields for {}", artifactId); + artifactDefinition.setEsId(""); + artifactDefinition.setArtifactName(""); + artifactDefinition.setDescription(""); + artifactDefinition.setApiUrl(""); + artifactDefinition.setArtifactChecksum(""); + setDefaultArtifactTimeout(artifactDefinition.getArtifactGroupType(), artifactDefinition); + artifactDefinition.setArtifactUUID(""); + long time = System.currentTimeMillis(); + artifactDefinition.setPayloadUpdateDate(time); + artifactDefinition.setHeatParameters(null); + artifactDefinition.setHeatParamsUpdateDate(null); + Either resStatus = null; + if (artifactParentsCount < 2) { + log.debug("Only one parent , clean existing placeholder for {}", artifactId); + resStatus = artifactOperation.updateArifactOnResource(artifactDefinition, parentId, artifactId, parentType, true); + } else { + log.debug("more than one parent , create new placeholder for {}", artifactId); + artifactDefinition.setUniqueId(null); + resStatus = artifactOperation.addArifactToComponent(artifactDefinition, parentId, parentType, true, true); + } + if (resStatus.isRight()) { + log.debug("Failed to clean placeholder for {}", artifactId); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(resStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + resultOp = Either.right(responseFormat); + } else { + log.debug("Placeholder was cleaned for {}", artifactId); + + ArtifactDefinition artifactUfterChange = resStatus.left().value(); + + insideEither = Either.left(artifactUfterChange); + resultOp = Either.left(insideEither); + } + } else { + log.debug("Artifact isn't mandatory/service API. Removed. {}", artifactId); + resultOp = Either.left(insideEither); + } + + } else { + log.debug("failed to delete artifact from ES {} status {}", artifactId, deleteIfNotOnGraph); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(deleteIfNotOnGraph), artifactDefinition.getArtifactDisplayName()); + resultOp = Either.right(responseFormat); + } + } else { + log.debug("Failed to delete entry on graph for artifact {}", artifactId); + responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), ""); + resultOp = Either.right(responseFormat); + } + handleAuditing(auditingAction, parent, parentId, user, artifactDefinition, null, artifactId, responseFormat, componentType, null); + return resultOp; + } finally { + if (shouldLock) { + unlockComponent(resultOp, parent, inTransaction); + } + } + + } + + private Either, ResponseFormat> handleDownload(String componentId, String artifactId, User user, AuditingActionEnum auditingAction, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, boolean shouldLock, boolean inTransaction) { + Either artifactById = artifactOperation.getArtifactById(artifactId, false); + if (artifactById.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value()); + log.debug("Error when getting artifact info by id{}, error: {}", artifactId, actionStatus.name()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(actionStatus, ""); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + ArtifactDefinition artifactDefinition = artifactById.left().value(); + if (artifactDefinition == null) { + log.debug("Empty artifact definition returned from DB by artifact id {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ""); + handleAuditing(auditingAction, parent, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + Either insideEither = Either.left(artifactDefinition); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, componentId, user, artifactDefinition, null, artifactId, responseFormat, componentType, null); + return Either.left(insideEither); + } + + private Either fetchCurrentArtifact(ArtifactOperation operation, String artifactId) { + Either artifactById = artifactOperation.getArtifactById(artifactId, true); + if (!operation.equals(ArtifactOperation.Create) && artifactById.isRight()) { + // in case of update artifact must be + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeArtifactMissingError, "Artifact Update / Upload", artifactId); + BeEcompErrorManager.getInstance().logBeArtifactMissingError("Artifact Update / Upload", artifactId); + log.debug("Failed to fetch artifact {}. error: {}", artifactId, artifactById.right().value()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactById.right().value()), artifactId)); + } + if (operation.equals(ArtifactOperation.Create) && artifactById.isLeft()) { + log.debug("Artifact {} already exist", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactById.left().value().getArtifactLabel())); + } + ArtifactDefinition currentArtifactInfo = null; + if (artifactById.isLeft()) { + // get previous value + currentArtifactInfo = artifactById.left().value(); + } + return Either.left(currentArtifactInfo); + } + + private Either handleArtifactLabel(String componentId, ArtifactOperation operation, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName, + ArtifactDefinition currentArtifactInfo, ComponentTypeEnum componentType, boolean inTransaction) { + String artifactLabel = artifactInfo.getArtifactLabel(); + + if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Update / Upload", "artifactLabel"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("missing artifact logical name for component {}", componentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + if (operation.equals(ArtifactOperation.Create) && !artifactInfo.getMandatory()) { + + if (operationName != null) { + if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) { + log.debug("artifact label cannot be set {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } else { + artifactLabel = operationName; + } + } + String displayName = artifactInfo.getArtifactDisplayName(); + if (displayName == null || displayName.isEmpty()) + displayName = artifactLabel; + displayName = ValidationUtils.cleanArtifactDisplayName(displayName); + artifactInfo.setArtifactDisplayName(displayName); + + if (!ValidationUtils.validateArtifactLabel(artifactLabel)) { + log.debug("Invalid format form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel); + + if (artifactLabel.isEmpty()) { + log.debug("missing normalized artifact logical name for component {}", componentId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + + if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) { + log.debug("Invalid lenght form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH))); + } + if (!validateLabelUniqueness(componentId, artifactLabel, componentType, inTransaction)) { + log.debug("Non unique Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel)); + } + } + artifactInfo.setArtifactLabel(artifactLabel); + + if (currentArtifactInfo != null && !currentArtifactInfo.getArtifactLabel().equals(artifactInfo.getArtifactLabel())) { + log.info("Logical artifact's name cannot be changed {}", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } + return Either.left(ActionStatus.OK); + } + + private boolean validateLabelUniqueness(String parentId, String artifactLabel, ComponentTypeEnum componentType, boolean inTransaction) { + boolean isUnique = true; + NodeTypeEnum parentType; + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + parentType = NodeTypeEnum.Resource; + } else { + parentType = NodeTypeEnum.Service; + } + Either, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(parentId, parentType, inTransaction); + if (artifacts.isLeft()) { + for (String label : artifacts.left().value().keySet()) { + if (label.equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + Either, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(parentId, true, inTransaction); + if (allInterfacesOfResource.isLeft()) { + for (InterfaceDefinition interace : allInterfacesOfResource.left().value().values()) { + for (Operation operation : interace.getOperations().values()) { + if (operation.getImplementation() != null && operation.getImplementation().getArtifactLabel().equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + } + } + return isUnique; + } + + // *************************************************************** + + private Either, ResponseFormat> createArtifact(org.openecomp.sdc.be.model.Component parent, String parentId, ArtifactDefinition artifactInfo, byte[] decodedPayload, User user, + ComponentTypeEnum componentTypeEnum, AuditingActionEnum auditingActionEnum, String interfaceType, String operationName) { + + ESArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload); + Either, ResponseFormat> resultOp = null; + Either insideEither = null; + + if (artifactData == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Upload Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact"); + log.debug("Failed to create artifact object for ES."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, null, responseFormat, componentTypeEnum, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } + // set on graph object id of artifact in ES! + artifactInfo.setEsId(artifactData.getId()); + + boolean isLeft = false; + String artifactUniqueId = null; + ArtifactDefinition artifactDefinition = null; + StorageOperationStatus error = null; + if (interfaceType != null && operationName != null) { + // lifecycle artifact + Operation operation = convertToOperation(artifactInfo, operationName); + + Either result = interfaceLifecycleOperation.updateInterfaceOperation(parentId, interfaceType, operationName, operation); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getImplementation().getUniqueId(); + artifactDefinition = result.left().value().getImplementation(); + + insideEither = Either.right(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } else { + // information/deployment/api aritfacts + log.debug("Try to create entry on graph"); + NodeTypeEnum nodeType = convertParentType(componentTypeEnum); + Either result = artifactOperation.addArifactToComponent(artifactInfo, parentId, nodeType, true, true); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value(); + + insideEither = Either.left(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } + if (isLeft) { + boolean res = saveArtifacts(artifactData, parentId, false); + // String uniqueId = artifactDefinition.getUniqueId(); + + if (res) { + log.debug("Artifact saved into ES - {}", artifactUniqueId); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, artifactUniqueId, artifactUniqueId, responseFormat, componentTypeEnum, null); + return resultOp; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Upload Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Upload Artifact"); + log.debug("Failed to save the artifact."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, artifactUniqueId, responseFormat, componentTypeEnum, null); + + resultOp = Either.right(responseFormat); + return resultOp; + } + } else { + log.debug("Failed to create entry on graph for artifact {}", artifactInfo.getArtifactName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), artifactInfo.getArtifactDisplayName()); + handleAuditing(auditingActionEnum, parent, parentId, user, artifactInfo, null, null, responseFormat, componentTypeEnum, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + + } + + private Either validateDeploymentArtifact(Component parentComponent, String parentId, String userId, boolean isCreate, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, NodeTypeEnum parentType) { + + Either result = Either.left(true); + Wrapper responseWrapper = new Wrapper(); + + validateArtifactTypeExists(responseWrapper, artifactInfo); + + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + + Map resourceDeploymentArtifacts = fillDeploymentArtifactTypeConf(parentType); + + if (responseWrapper.isEmpty()) { + validateDeploymentArtifactConf(artifactInfo, responseWrapper, artifactType, resourceDeploymentArtifacts); + } + + if (responseWrapper.isEmpty()) { + // Common code for all types + // not allowed to change artifactType + if (!isCreate) { + Either validateServiceApiType = validateArtifactTypeNotChanged(artifactInfo, currentArtifact); + if (validateServiceApiType.isRight()) { + responseWrapper.setInnerElement(validateServiceApiType.right().value()); + } + } + } + if (responseWrapper.isEmpty()) { + if (parentType.equals(NodeTypeEnum.Resource)) { + // if (parentComponent instanceof Resource) { + Resource resource = (Resource) parentComponent; + ResourceTypeEnum resourceType = resource.getResourceType(); + DeploymentArtifactTypeConfig config = resourceDeploymentArtifacts.get(artifactType.getType()); + if (config == null) { + responseWrapper.setInnerElement(ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + } else { + List myList = config.getValidForResourceTypes(); + Either either = validateResourceType(resourceType, artifactInfo, myList); + if (either.isRight()) { + responseWrapper.setInnerElement(either.right().value()); + } + } + } + } + if (responseWrapper.isEmpty()) { + validateFileExtension(responseWrapper, () -> getDeploymentArtifactTypeConfig(parentType, artifactType), artifactInfo, parentType, artifactType); + } + + if (responseWrapper.isEmpty() && !NodeTypeEnum.ResourceInstance.equals(parentType)) { + String artifactName = artifactInfo.getArtifactName(); + if (isCreate || !artifactName.equalsIgnoreCase(currentArtifact.getArtifactName())) { + validateSingleDeploymentArtifactName(responseWrapper, artifactName, parentComponent, parentType); + } + } + + if (responseWrapper.isEmpty()) { + switch (artifactType) { + case HEAT: + case HEAT_VOL: + case HEAT_NET: { + result = validateHeatDeploymentArtifact(parentComponent, userId, isCreate, artifactInfo, currentArtifact, parentType); + break; + } + case HEAT_ENV: { + result = validateHeatEnvDeploymentArtifact(parentComponent, parentId, userId, isCreate, artifactInfo, parentType); + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + break; + } + case DCAE_INVENTORY_TOSCA: + case DCAE_INVENTORY_JSON: + case DCAE_INVENTORY_POLICY: + // Validation is done in handle payload. + case DCAE_INVENTORY_DOC: + case DCAE_INVENTORY_BLUEPRINT: + case DCAE_INVENTORY_EVENT: + // No specific validation + default: { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + } + } + + } + + if (!responseWrapper.isEmpty()) { + result = Either.right(responseWrapper.getInnerElement()); + } + return result; + } + + private void validateDeploymentArtifactConf(ArtifactDefinition artifactInfo, Wrapper responseWrapper, ArtifactTypeEnum artifactType, Map resourceDeploymentArtifacts) { + if ((resourceDeploymentArtifacts == null) || !resourceDeploymentArtifacts.containsKey(artifactType.name())) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType()); + responseWrapper.setInnerElement(responseFormat); + log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType()); + } + } + + private Map fillDeploymentArtifactTypeConf(NodeTypeEnum parentType) { + Map resourceDeploymentArtifacts = null; + if (parentType.equals(NodeTypeEnum.Resource)) { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts(); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + } else { + resourceDeploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts(); + } + return resourceDeploymentArtifacts; + } + + public void validateArtifactTypeExists(Wrapper responseWrapper, ArtifactDefinition artifactInfo) { + ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + if (artifactType == null) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.GENERAL_ERROR); + responseWrapper.setInnerElement(responseFormat); + log.debug("Artifact Type: {} Not found !", artifactInfo.getArtifactType()); + } + } + + private DeploymentArtifactTypeConfig getDeploymentArtifactTypeConfig(NodeTypeEnum parentType, ArtifactTypeEnum artifactType) { + DeploymentArtifactTypeConfig retConfig = null; + String fileType = artifactType.getType(); + if (parentType.equals(NodeTypeEnum.Resource)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts().get(fileType); + } else if (parentType.equals(NodeTypeEnum.Service)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts().get(fileType); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + retConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts().get(fileType); + } + return retConfig; + } + + private Either extractHeatParameters(ArtifactDefinition artifactInfo) { + // extract heat parameters + if (artifactInfo.getPayloadData() != null) { + String heatDecodedPayload = GeneralUtility.isBase64Encoded(artifactInfo.getPayloadData()) ? new String(Base64.decodeBase64(artifactInfo.getPayloadData())) : new String(artifactInfo.getPayloadData()); + Either, ResultStatusEnum> heatParameters = ImportUtils.getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactInfo.getArtifactType()); + if (heatParameters.isRight() && (!heatParameters.right().value().equals(ResultStatusEnum.ELEMENT_NOT_FOUND))) { + log.info("failed to parse heat parameters "); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactType()); + return Either.right(responseFormat); + } else if (heatParameters.isLeft() && heatParameters.left().value() != null) { + artifactInfo.setHeatParameters(heatParameters.left().value()); + } + } + return Either.left(true); + + } + + // Valid extension + public void validateFileExtension(Wrapper responseWrapper, IDeploymentArtifactTypeConfigGetter deploymentConfigGetter, ArtifactDefinition artifactInfo, NodeTypeEnum parentType, ArtifactTypeEnum artifactType) { + String fileType = artifactType.getType(); + List acceptedTypes = null; + DeploymentArtifactTypeConfig deploymentAcceptedTypes = deploymentConfigGetter.getDeploymentArtifactConfig(); + if (!parentType.equals(NodeTypeEnum.Resource) && !parentType.equals(NodeTypeEnum.Service) && !parentType.equals(NodeTypeEnum.ResourceInstance)) { + log.debug("parent type of artifact can be either resource or service"); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return; + } + + if (deploymentAcceptedTypes == null) { + log.debug("parent type of artifact can be either resource or service"); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + return; + } else { + acceptedTypes = deploymentAcceptedTypes.getAcceptedTypes(); + } + /* + * No need to check specific types. In case there are no acceptedTypes in configuration, then any type is accepted. + * + * if ((!artifactType.equals(ArtifactTypeEnum.OTHER) && !artifactType.equals(ArtifactTypeEnum.HEAT_ARTIFACT )) && (acceptedTypes == null || acceptedTypes.isEmpty()) ) { log.debug( "No accepted types found for type {}, parent type {}", + * fileType, parentType.getName()); String methodName = new Object() { }.getClass().getEnclosingMethod().getName(); String configEntryMissing = (parentType.equals(NodeTypeEnum.Resource)) ? "resourceDeploymentArtifacts:" + fileType : + * "serviceDeploymentArtifacts:" + fileType; BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeMissingConfigurationError, methodName, configEntryMissing); BeEcompErrorManager.getInstance().logBeMissingConfigurationError( + * methodName, configEntryMissing); responseWrapper.setInnerElement(componentsUtils.getResponseFormat( ActionStatus.GENERAL_ERROR)); return; } + */ + + String artifactName = artifactInfo.getArtifactName(); + String fileExtension = GeneralUtility.getFilenameExtension(artifactName); + // Pavel - File extension validation is case-insensitive - Ella, + // 21/02/2016 + if (acceptedTypes != null && !acceptedTypes.isEmpty() && !acceptedTypes.contains(fileExtension.toLowerCase())) { + log.debug("File extension \"{}\" is not allowed for {} which is of type:{}", fileExtension, artifactName, fileType); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.WRONG_ARTIFACT_FILE_EXTENSION, fileType)); + return; + } + } + + private Either validateHeatEnvDeploymentArtifact(Component parentComponent, String parentId, String userId, boolean isCreate, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + + Wrapper errorWrapper = new Wrapper(); + Wrapper heatMDWrapper = new Wrapper(); + Wrapper payloadWrapper = new Wrapper<>(); + + if (errorWrapper.isEmpty()) { + validateValidYaml(errorWrapper, artifactInfo); + } + + if (errorWrapper.isEmpty()) { + // Validate Heat Exist + validateHeatExist(artifactInfo.getUniqueId(), errorWrapper, heatMDWrapper, getDeploymentArtifacts(parentComponent, parentType, parentId)); + } + + if (errorWrapper.isEmpty() && isCreate) { + // Validate Only Single HeatEnv Artifact + validateSingleArtifactType(errorWrapper, ArtifactTypeEnum.HEAT_ENV, parentComponent, parentType, parentId); + } + + if (errorWrapper.isEmpty() && !heatMDWrapper.isEmpty()) { + fillArtifactPayloadValidation(errorWrapper, payloadWrapper, heatMDWrapper.getInnerElement()); + } + + if (errorWrapper.isEmpty() && !heatMDWrapper.isEmpty()) { + validateEnvVsHeat(errorWrapper, artifactInfo, heatMDWrapper.getInnerElement(), payloadWrapper.getInnerElement()); + } + + // Init Response + Either eitherResponse; + if (errorWrapper.isEmpty()) { + eitherResponse = Either.left(true); + } else { + eitherResponse = Either.right(errorWrapper.getInnerElement()); + } + return eitherResponse; + } + + public void fillArtifactPayloadValidation(Wrapper errorWrapper, Wrapper payloadWrapper, ArtifactDefinition artifactDefinition) { + if (artifactDefinition.getPayloadData() == null || artifactDefinition.getPayloadData().length == 0) { + Either fillArtifactPayload = fillArtifactPayload(payloadWrapper, artifactDefinition); + if (fillArtifactPayload.isRight()) { + errorWrapper.setInnerElement(fillArtifactPayload.right().value()); + log.debug("Error getting payload for artifact:{}", artifactDefinition.getArtifactName()); + } + } else { + payloadWrapper.setInnerElement(artifactDefinition.getPayloadData()); + } + } + + public Either fillArtifactPayload(Wrapper payloadWrapper, ArtifactDefinition artifactMD) { + Either result = Either.left(true); + Either eitherArtifactData = artifactCassandraDao.getArtifact(artifactMD.getEsId()); + // Either eitherArtifactData = + // esCatalogDao.getArtifact(artifactMD.getEsId()); + if (eitherArtifactData.isLeft()) { + byte[] data = eitherArtifactData.left().value().getDataAsArray(); + if (!GeneralUtility.isBase64Encoded(data)) { + data = Base64.encodeBase64(data); + } + payloadWrapper.setInnerElement(data); + } else { + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(eitherArtifactData.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus)); + result = Either.right(responseFormat); + } + return result; + + } + + @SuppressWarnings("unchecked") + private void validateEnvVsHeat(Wrapper errorWrapper, ArtifactDefinition envArtifact, ArtifactDefinition heatArtifact, byte[] heatPayloadData) { + + String envPayload = (GeneralUtility.isBase64Encoded(envArtifact.getPayloadData())) ? new String(Base64.decodeBase64(envArtifact.getPayloadData())) : new String(envArtifact.getPayloadData()); + Map heatEnvToscaJson = (Map) new Yaml().load(envPayload); + + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(heatPayloadData)) ? new String(Base64.decodeBase64(heatPayloadData)) : new String(heatPayloadData); + Map heatToscaJson = (Map) new Yaml().load(heatDecodedPayload); + + Either, ResultStatusEnum> eitherHeatEnvProperties = ImportUtils.findFirstToscaMapElement(heatEnvToscaJson, ToscaTagNamesEnum.PARAMETERS); + Either, ResultStatusEnum> eitherHeatProperties = ImportUtils.findFirstToscaMapElement(heatToscaJson, ToscaTagNamesEnum.PARAMETERS); + if (eitherHeatEnvProperties.isRight()) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.CORRUPTED_FORMAT, "Heat Env"); + errorWrapper.setInnerElement(responseFormat); + log.debug("Invalid heat env format for file:{}", envArtifact.getArtifactName()); + } else if (eitherHeatProperties.isRight()) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + errorWrapper.setInnerElement(responseFormat); + log.debug("Validation of heat_env for artifact:{} vs heat artifact for artifact :{} failed", envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + } else { + Set heatPropertiesKeys = eitherHeatProperties.left().value().keySet(); + Set heatEnvPropertiesKeys = eitherHeatEnvProperties.left().value().keySet(); + heatEnvPropertiesKeys.removeAll(heatPropertiesKeys); + if (heatEnvPropertiesKeys.size() > 0) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, envArtifact.getArtifactName(), heatArtifact.getArtifactName()); + errorWrapper.setInnerElement(responseFormat); + } + } + } + + private void validateValidYaml(Wrapper errorWrapper, ArtifactDefinition artifactInfo) { + YamlToObjectConverter yamlConvertor = new YamlToObjectConverter(); + boolean isYamlValid = yamlConvertor.isValidYaml(artifactInfo.getPayloadData()); + if (!isYamlValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_YAML, artifactInfo.getArtifactType()); + errorWrapper.setInnerElement(responseFormat); + log.debug("Yaml is not valid for artifact : {}", artifactInfo.getArtifactName()); + } + } + + public boolean isValidXml(byte[] xmlToParse) { + XMLReader parser = new SAXParser(); + boolean isXmlValid = true; + try { + parser.parse(new InputSource(new ByteArrayInputStream(xmlToParse))); + } catch (IOException | SAXException e) { + isXmlValid = false; + } + return isXmlValid; + } + + public boolean isValidJson(byte[] jsonToParse) { + String parsed = new String(jsonToParse); + try { + gson.fromJson(parsed, Object.class); + } catch (Exception e) { + return false; + } + return true; + } + + public void validateSingleArtifactType(Wrapper errorWrapper, ArtifactTypeEnum allowedArtifactType, Component parentComponent, NodeTypeEnum parentType, String parentRiId) { + boolean typeArtifactFound = false; + // Iterator parentDeploymentArtifactsItr = + // (parentType == NodeTypeEnum.Resource) ? + // informationDeployedArtifactsBusinessLogic.getAllDeployableArtifacts((Resource) + // parentComponent).iterator() + // : getDeploymentArtifacts(parentComponent, parentType).iterator(); + + Iterator parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, parentType, parentRiId).iterator(); + + while (!typeArtifactFound && parentDeploymentArtifactsItr.hasNext()) { + ArtifactTypeEnum foundArtifactType = ArtifactTypeEnum.findType(parentDeploymentArtifactsItr.next().getArtifactType()); + typeArtifactFound = (foundArtifactType == allowedArtifactType); + } + if (typeArtifactFound) { + String parentName = parentComponent.getName(); + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS, parentType.name(), parentName, allowedArtifactType.getType(), allowedArtifactType.getType()); + + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't upload artifact of type: {}, because another artifact of this type already exist.", allowedArtifactType.getType()); + + } + } + + public void validateSingleDeploymentArtifactName(Wrapper errorWrapper, String artifactName, Component parentComponent, NodeTypeEnum parentType) { + boolean artifactNameFound = false; + // Iterator parentDeploymentArtifactsItr = + // (parentType == NodeTypeEnum.Resource) ? + // informationDeployedArtifactsBusinessLogic.getAllDeployableArtifacts((Resource) + // parentComponent).iterator() + // : getDeploymentArtifacts(parentComponent, parentType).iterator(); + + Iterator parentDeploymentArtifactsItr = getDeploymentArtifacts(parentComponent, parentType, null).iterator(); + + while (!artifactNameFound && parentDeploymentArtifactsItr.hasNext()) { + artifactNameFound = (artifactName.equalsIgnoreCase(parentDeploymentArtifactsItr.next().getArtifactName())); + } + if (artifactNameFound) { + String parentName = parentComponent.getName(); + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS, parentType.name(), parentName, artifactName); + + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't upload artifact: {}, because another artifact with this name already exist.", artifactName); + + } + } + + private void validateHeatExist(String heatEnvId, Wrapper errorWrapper, Wrapper heatArtifactMDWrapper, Collection parentDeploymentArtifacts) { + boolean heatFound = false; + Either res = artifactOperation.getHeatArtifactByHeatEnvId(heatEnvId, true); + if (res.isRight()) { + return; + } + ArtifactDefinition heatArtifact = res.left().value(); + Iterator parentArtifactsItr = parentDeploymentArtifacts.iterator(); + while (!heatFound && parentArtifactsItr.hasNext()) { + ArtifactDefinition currArtifact = parentArtifactsItr.next(); + if (heatArtifact.getUniqueId().equals(currArtifact.getUniqueId())) { + heatFound = true; + heatArtifactMDWrapper.setInnerElement(currArtifact); + log.trace("In validateHeatExist found artifact {}", currArtifact); + /* + * ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(currArtifact.getArtifactType()); if(artifactType == ArtifactTypeEnum.HEAT || artifactType == ArtifactTypeEnum.HEAT_VOL || artifactType == ArtifactTypeEnum.HEAT_NET){ + * heatFound = true; } if (heatFound) { heatArtifactMDWrapper.setInnerElement(currArtifact); } + */ + } + } + if (!heatFound) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISSING_HEAT); + errorWrapper.setInnerElement(responseFormat); + log.debug("Can't create heat env artifact because No heat Artifact exist."); + } + + } + + private Either validateHeatDeploymentArtifact(Component parentComponent, String userId, boolean isCreate, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, NodeTypeEnum parentType) { + log.trace("Started HEAT pre-payload validation for artifact {}", artifactInfo.getArtifactLabel()); + // timeout > 0 for HEAT artifacts + Integer timeout = artifactInfo.getTimeout(); + Integer defaultTimeout = (isCreate) ? defaultHeatTimeout : currentArtifact.getTimeout(); + if (timeout == null) { + artifactInfo.setTimeout(defaultTimeout); + // HEAT artifact but timeout is invalid + } else if (timeout < 1) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_INVALID_TIMEOUT)); + } + + // US649856 - Allow several HEAT files on Resource + /* + * if (isCreate) { Wrapper errorWrapper = new Wrapper<>(); validateSingleArtifactType(errorWrapper, ArtifactTypeEnum.findType(artifactInfo.getArtifactType()), parentComponent, parentType); if (!errorWrapper.isEmpty()) { return + * Either.right(errorWrapper.getInnerElement()); } } + */ + + log.trace("Ended HEAT validation for artifact {}", artifactInfo.getArtifactLabel()); + return Either.left(true); + } + + private Either validateResourceType(ResourceTypeEnum resourceType, ArtifactDefinition artifactInfo, List typeList) { + String listToString = (typeList != null) ? typeList.toString() : ""; + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE, artifactInfo.getArtifactName(), listToString, resourceType.getValue()); + Either either = Either.right(responseFormat); + String resourceTypeName = resourceType.name(); + if (typeList != null && typeList.contains(resourceTypeName)) { + either = Either.left(true); + } + return either; + } + + private Either validateAndConvertHeatParamers(ArtifactDefinition artifactInfo, String artifactType) { + if (artifactInfo.getHeatParameters() != null) { + for (HeatParameterDefinition heatParam : artifactInfo.getHeatParameters()) { + String parameterType = heatParam.getType(); + HeatParameterType heatParameterType = HeatParameterType.isValidType(parameterType); + String artifactTypeStr = artifactType != null ? artifactType : ArtifactTypeEnum.HEAT.getType(); + if (heatParameterType == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_HEAT_PARAMETER_TYPE, artifactTypeStr, heatParam.getType()); + return Either.right(responseFormat); + } + + StorageOperationStatus validateAndUpdateProperty = heatParametersOperation.validateAndUpdateProperty(heatParam); + if (validateAndUpdateProperty != StorageOperationStatus.OK) { + log.debug("Heat parameter {} is invalid. Status is: {}", heatParam.getName(), validateAndUpdateProperty); + ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE; + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, artifactTypeStr, heatParam.getType(), heatParam.getName()); + return Either.right(responseFormat); + } + } + } + return Either.left(artifactInfo); + } + + public List getDeploymentArtifacts(Component parentComponent, NodeTypeEnum parentType, String ciId) { + List deploymentArtifacts = new ArrayList<>(); + if (parentComponent.getDeploymentArtifacts() != null && ciId != null) { + if (NodeTypeEnum.ResourceInstance == parentType) { + Either getRI = getRIFromComponent(parentComponent, ciId, null, null, null); + if (getRI.isRight()) { + return deploymentArtifacts; + } + ComponentInstance ri = getRI.left().value(); + deploymentArtifacts.addAll(ri.getDeploymentArtifacts().values()); + } else { + deploymentArtifacts.addAll(parentComponent.getDeploymentArtifacts().values()); + } + } + return deploymentArtifacts; + } + + private void checkCreateFields(User user, ArtifactDefinition artifactInfo, ArtifactGroupTypeEnum type) { + // on create if null add informational to current + if (artifactInfo.getArtifactGroupType() == null) { + artifactInfo.setArtifactGroupType(type); + } + if (artifactInfo.getUniqueId() != null) { + log.error("artifact uniqid cannot be set ignoring"); + } + artifactInfo.setUniqueId(null); + + if (artifactInfo.getArtifactRef() != null) { + log.error("artifact ref cannot be set ignoring"); + } + artifactInfo.setArtifactRef(null); + + if (artifactInfo.getArtifactRepository() != null) { + log.error("artifact repository cannot be set ignoring"); + } + artifactInfo.setArtifactRepository(null); + + if (artifactInfo.getUserIdCreator() != null) { + log.error("creator uuid cannot be set ignoring"); + } + artifactInfo.setArtifactCreator(user.getUserId()); + + if (artifactInfo.getUserIdLastUpdater() != null) { + log.error("userId of last updater cannot be set ignoring"); + } + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + if (artifactInfo.getCreatorFullName() != null) { + log.error("creator Full name cannot be set ignoring"); + } + String fullName = user.getFirstName() + " " + user.getLastName(); + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getUpdaterFullName() != null) { + log.error("updater Full name cannot be set ignoring"); + } + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getCreationDate() != null) { + log.error("Creation Date cannot be set ignoring"); + } + long time = System.currentTimeMillis(); + artifactInfo.setCreationDate(time); + + if (artifactInfo.getLastUpdateDate() != null) { + log.error("Last Update Date cannot be set ignoring"); + } + artifactInfo.setLastUpdateDate(time); + + if (artifactInfo.getEsId() != null) { + log.error("es id cannot be set ignoring"); + } + artifactInfo.setEsId(null); + + } + + private Either fetchCurrentArtifact(boolean isCreate, String artifactId) { + Either artifactById = artifactOperation.getArtifactById(artifactId, true); + if (isCreate == false && artifactById.isRight()) { + // in case of update artifact must be + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeArtifactMissingError, "Artifact Update / Upload", artifactId); + BeEcompErrorManager.getInstance().logBeArtifactMissingError("Artifact Update / Upload", artifactId); + log.debug("Failed to fetch artifact {}. error: {}", artifactId, artifactById.right().value()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(artifactById.right().value()), artifactId)); + } + if (isCreate && artifactById.isLeft()) { + log.debug("Artifact {} already exist", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactById.left().value().getArtifactLabel())); + } + ArtifactDefinition currentArtifactInfo = null; + if (artifactById.isLeft()) { + // get previous value + currentArtifactInfo = artifactById.left().value(); + } + return Either.left(currentArtifactInfo); + } + + private Either handleArtifactLabel(String resourceId, boolean isCreate, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName, ArtifactDefinition currentArtifactInfo, + NodeTypeEnum parentType) { + String artifactLabel = artifactInfo.getArtifactLabel(); + + if (operationName == null && (artifactInfo.getArtifactLabel() == null || artifactInfo.getArtifactLabel().isEmpty())) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Update / Upload", "artifactLabel"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("missing artifact logical name for component {}", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + if (isCreate && !artifactInfo.getMandatory()) { + + if (operationName != null) { + if (artifactInfo.getArtifactLabel() != null && !operationName.equals(artifactInfo.getArtifactLabel())) { + log.debug("artifact label cannot be set {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } else { + artifactLabel = operationName; + } + } + String displayName = ValidationUtils.cleanArtifactDisplayName(artifactLabel); + artifactInfo.setArtifactDisplayName(displayName); + + if (!ValidationUtils.validateArtifactLabel(artifactLabel)) { + log.debug("Invalid format form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + artifactLabel = ValidationUtils.normalizeArtifactLabel(artifactLabel); + + if (artifactLabel.isEmpty()) { + log.debug("missing normalized artifact logical name for component {}", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_LABEL)); + } + + if (!ValidationUtils.validateArtifactLabelLength(artifactLabel)) { + log.debug("Invalid lenght form Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_LABEL, String.valueOf(ValidationUtils.ARTIFACT_LABEL_LENGTH))); + } + if (!validateLabelUniqueness(resourceId, artifactLabel, parentType)) { + log.debug("Non unique Artifact label : {}", artifactLabel); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_EXIST, artifactLabel)); + } + } + artifactInfo.setArtifactLabel(artifactLabel); + + if (currentArtifactInfo != null && !currentArtifactInfo.getArtifactLabel().equals(artifactInfo.getArtifactLabel())) { + log.info("Logical artifact's name cannot be changed {}", artifactId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED)); + } + return Either.left(ActionStatus.OK); + } + + private boolean validateLabelUniqueness(String parentId, String artifactLabel, NodeTypeEnum parentType) { + boolean isUnique = true; + Either, StorageOperationStatus> artifacts = artifactOperation.getArtifacts(parentId, parentType, true); + if (artifacts.isLeft()) { + for (String label : artifacts.left().value().keySet()) { + if (label.equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + if (parentType.equals(NodeTypeEnum.Resource)) { + Either, StorageOperationStatus> allInterfacesOfResource = interfaceLifecycleOperation.getAllInterfacesOfResource(parentId, true); + if (allInterfacesOfResource.isLeft()) { + for (InterfaceDefinition interace : allInterfacesOfResource.left().value().values()) { + for (Operation operation : interace.getOperations().values()) { + if (operation.getImplementation() != null && operation.getImplementation().getArtifactLabel().equals(artifactLabel)) { + isUnique = false; + break; + } + } + } + } + } + return isUnique; + } + + private String composeArtifactId(String resourceId, String artifactId, ArtifactDefinition artifactInfo, String interfaceName, String operationName) { + String id = artifactId; + if (artifactId == null || artifactId.isEmpty()) { + String uniqueId = null; + if (interfaceName != null && operationName != null) { + uniqueId = UniqueIdBuilder.buildArtifactByInterfaceUniqueId(resourceId, interfaceName, operationName, artifactInfo.getArtifactLabel()); + } else { + uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId, artifactInfo.getArtifactLabel()); + } + artifactInfo.setUniqueId(uniqueId); + artifactInfo.setEsId(uniqueId); + id = uniqueId; + } else { + artifactInfo.setUniqueId(artifactId); + artifactInfo.setEsId(artifactId); + } + return id; + } + + private Either validateArtifactType(String userId, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + if (artifactInfo.getArtifactType() == null || artifactInfo.getArtifactType().isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeMissingArtifactInformationError, "Artifact Upload / Update"); + BeEcompErrorManager.getInstance().logBeMissingArtifactInformationError("Artifact Update / Upload", "artifactLabel"); + log.debug("Missing artifact type for artifact {}", artifactInfo.getArtifactName()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE)); + } + + boolean artifactTypeExist = false; + Either, ActionStatus> allArtifactTypes = null; + ArtifactGroupTypeEnum artifactGroupType = artifactInfo.getArtifactGroupType(); + + if ((artifactGroupType != null) && artifactGroupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) { + allArtifactTypes = getDeploymentArtifactTypes(userId, artifactInfo, parentType); + } else { + + allArtifactTypes = elementOperation.getAllArtifactTypes(); + } + if (allArtifactTypes.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidConfigurationError, "Artifact Upload / Update", "artifactTypes", allArtifactTypes.right().value().name()); + BeEcompErrorManager.getInstance().logBeInvalidConfigurationError("Artifact Upload / Update", "artifactTypes", allArtifactTypes.right().value().name()); + log.debug("Failed to retrieve list of suported artifact types. error: {}", allArtifactTypes.right().value()); + return Either.right(componentsUtils.getResponseFormatByUserId(allArtifactTypes.right().value(), userId)); + } + + for (ArtifactType type : allArtifactTypes.left().value()) { + if (type.getName().equalsIgnoreCase(artifactInfo.getArtifactType())) { + artifactInfo.setArtifactType(artifactInfo.getArtifactType().toUpperCase()); + artifactTypeExist = true; + break; + } + } + + if (!artifactTypeExist) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidTypeError, "Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(), "Artifact " + artifactInfo.getArtifactName()); + BeEcompErrorManager.getInstance().logBeInvalidTypeError("Artifact Upload / Delete / Update - Not supported artifact type", artifactInfo.getArtifactType(), "Artifact " + artifactInfo.getArtifactName()); + log.debug("Not supported artifact type = {}", artifactInfo.getArtifactType()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, artifactInfo.getArtifactType())); + } + + return Either.left(ActionStatus.OK); + } + + private Either, ActionStatus> getDeploymentArtifactTypes(String userId, ArtifactDefinition artifactInfo, NodeTypeEnum parentType) { + + Map deploymentArtifacts = null; + List artifactTypes = new ArrayList(); + + if (parentType.equals(NodeTypeEnum.Service)) { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts(); + } else if (parentType.equals(NodeTypeEnum.ResourceInstance)) { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceInstanceDeploymentArtifacts(); + } else { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts(); + } + if (deploymentArtifacts != null) { + for (String artifactType : deploymentArtifacts.keySet()) { + ArtifactType artifactT = new ArtifactType(); + artifactT.setName(artifactType); + artifactTypes.add(artifactT); + } + return Either.left(artifactTypes); + } else { + return Either.right(ActionStatus.GENERAL_ERROR); + } + + } + + private Either validateFirstUpdateHasPayload(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (currentArtifact.getEsId() == null && (artifactInfo.getPayloadData() == null || artifactInfo.getPayloadData().length == 0)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD)); + } + return Either.left(true); + + } + + private Either validateAndSetArtifactname(ArtifactDefinition artifactInfo) { + if (artifactInfo.getArtifactName() == null || artifactInfo.getArtifactName().isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME)); + } + + String normalizeFileName = ValidationUtils.normalizeFileName(artifactInfo.getArtifactName()); + if (normalizeFileName == null || normalizeFileName.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_NAME)); + } + artifactInfo.setArtifactName(normalizeFileName); + + if (!ValidationUtils.validateArtifactNameLength(artifactInfo.getArtifactName())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_NAME, String.valueOf(ValidationUtils.ARTIFACT_NAME_LENGTH))); + } + + return Either.left(true); + } + + private Either validateArtifactTypeNotChanged(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (artifactInfo.getArtifactType() == null || artifactInfo.getArtifactType().isEmpty()) { + log.info("artifact type is missing operation ignored"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_ARTIFACT_TYPE)); + } + + if (!currentArtifact.getArtifactType().equalsIgnoreCase(artifactInfo.getArtifactType())) { + log.info("artifact type cannot be changed operation ignored"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(true); + } + + private Either validateOrSetArtifactGroupType(ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact) { + if (artifactInfo.getArtifactGroupType() == null) { + artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType()); + } + + else if (!currentArtifact.getArtifactGroupType().getType().equalsIgnoreCase(artifactInfo.getArtifactGroupType().getType())) { + log.info("artifact group type cannot be changed. operation failed"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(artifactInfo); + } + + private void checkAndSetUnUpdatableFields(User user, ArtifactDefinition artifactInfo, ArtifactDefinition currentArtifact, ArtifactGroupTypeEnum type) { + + // on update if null add informational to current + if (currentArtifact.getArtifactGroupType() == null && type != null) { + currentArtifact.setArtifactGroupType(type); + } + + if (artifactInfo.getUniqueId() != null && !currentArtifact.getUniqueId().equals(artifactInfo.getUniqueId())) { + log.error("artifact uniqid cannot be set ignoring"); + } + artifactInfo.setUniqueId(currentArtifact.getUniqueId()); + + if (artifactInfo.getArtifactRef() != null && !currentArtifact.getArtifactRef().equals(artifactInfo.getArtifactRef())) { + log.error("artifact ref cannot be set ignoring"); + } + artifactInfo.setArtifactRef(currentArtifact.getArtifactRef()); + + if (artifactInfo.getArtifactRepository() != null && !currentArtifact.getArtifactRepository().equals(artifactInfo.getArtifactRepository())) { + log.error("artifact repository cannot be set ignoring"); + } + artifactInfo.setArtifactRepository(currentArtifact.getArtifactRepository()); + + if (artifactInfo.getUserIdCreator() != null && !currentArtifact.getUserIdCreator().equals(artifactInfo.getUserIdCreator())) { + log.error("creator uuid cannot be set ignoring"); + } + artifactInfo.setUserIdCreator(currentArtifact.getUserIdCreator()); + + if (artifactInfo.getArtifactCreator() != null && !currentArtifact.getArtifactCreator().equals(artifactInfo.getArtifactCreator())) { + log.error("artifact creator cannot be set ignoring"); + } + artifactInfo.setArtifactCreator(currentArtifact.getArtifactCreator()); + + if (artifactInfo.getUserIdLastUpdater() != null && !currentArtifact.getUserIdLastUpdater().equals(artifactInfo.getUserIdLastUpdater())) { + log.error("userId of last updater cannot be set ignoring"); + } + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + if (artifactInfo.getCreatorFullName() != null && !currentArtifact.getCreatorFullName().equals(artifactInfo.getCreatorFullName())) { + log.error("creator Full name cannot be set ignoring"); + } + artifactInfo.setCreatorFullName(currentArtifact.getCreatorFullName()); + + if (artifactInfo.getUpdaterFullName() != null && !currentArtifact.getUpdaterFullName().equals(artifactInfo.getUpdaterFullName())) { + log.error("updater Full name cannot be set ignoring"); + } + String fullName = user.getFirstName() + " " + user.getLastName(); + artifactInfo.setUpdaterFullName(fullName); + + if (artifactInfo.getCreationDate() != null && !currentArtifact.getCreationDate().equals(artifactInfo.getCreationDate())) { + log.error("Creation Date cannot be set ignoring"); + } + artifactInfo.setCreationDate(currentArtifact.getCreationDate()); + + if (artifactInfo.getLastUpdateDate() != null && !currentArtifact.getLastUpdateDate().equals(artifactInfo.getLastUpdateDate())) { + log.error("Last Update Date cannot be set ignoring"); + } + long time = System.currentTimeMillis(); + artifactInfo.setLastUpdateDate(time); + + if (artifactInfo.getEsId() != null && !currentArtifact.getEsId().equals(artifactInfo.getEsId())) { + log.error("es id cannot be set ignoring"); + } + artifactInfo.setEsId(currentArtifact.getUniqueId()); + + if (artifactInfo.getArtifactDisplayName() != null && !currentArtifact.getArtifactDisplayName().equals(artifactInfo.getArtifactDisplayName())) { + log.error(" Artifact Display Name cannot be set ignoring"); + } + artifactInfo.setArtifactDisplayName(currentArtifact.getArtifactDisplayName()); + + if (artifactInfo.getServiceApi() != null && !currentArtifact.getServiceApi().equals(artifactInfo.getServiceApi())) { + log.debug("serviceApi cannot be set. ignoring."); + } + artifactInfo.setServiceApi(currentArtifact.getServiceApi()); + + if (artifactInfo.getArtifactGroupType() != null && !currentArtifact.getArtifactGroupType().equals(artifactInfo.getArtifactGroupType())) { + log.debug("artifact group cannot be set. ignoring."); + } + artifactInfo.setArtifactGroupType(currentArtifact.getArtifactGroupType()); + + artifactInfo.setArtifactVersion(currentArtifact.getArtifactVersion()); + + if (artifactInfo.getArtifactUUID() != null && !artifactInfo.getArtifactUUID().isEmpty() && !currentArtifact.getArtifactUUID().equals(artifactInfo.getArtifactUUID())) { + log.debug("artifact UUID cannot be set. ignoring."); + } + artifactInfo.setArtifactUUID(currentArtifact.getArtifactUUID()); + + if ((artifactInfo.getHeatParameters() != null) && (currentArtifact.getHeatParameters() != null) && !artifactInfo.getHeatParameters().isEmpty() && !currentArtifact.getHeatParameters().isEmpty()) { + checkAndSetUnupdatableHeatParams(artifactInfo.getHeatParameters(), currentArtifact.getHeatParameters()); + } + } + + private void checkAndSetUnupdatableHeatParams(List heatParameters, List currentParameters) { + + Map currentParametersMap = getMapOfParameters(currentParameters); + for (HeatParameterDefinition parameter : heatParameters) { + HeatParameterDefinition currentParam = currentParametersMap.get(parameter.getUniqueId()); + + if (currentParam != null) { + + if (parameter.getName() != null && !parameter.getName().equalsIgnoreCase(currentParam.getName())) { + log.debug("heat parameter name cannot be updated ({}). ignoring.", parameter.getName()); + parameter.setName(currentParam.getName()); + } + if (parameter.getDefaultValue() != null && !parameter.getDefaultValue().equalsIgnoreCase(currentParam.getDefaultValue())) { + log.debug("heat parameter defaultValue cannot be updated ({}). ignoring.", parameter.getDefaultValue()); + parameter.setDefaultValue(currentParam.getDefaultValue()); + } + if (parameter.getType() != null && !parameter.getType().equalsIgnoreCase(currentParam.getType())) { + log.debug("heat parameter type cannot be updated ({}). ignoring.", parameter.getType()); + parameter.setType(currentParam.getType()); + } + if (parameter.getDescription() != null && !parameter.getDescription().equalsIgnoreCase(currentParam.getDescription())) { + log.debug("heat parameter description cannot be updated ({}). ignoring.", parameter.getDescription()); + parameter.setDescription(currentParam.getDescription()); + } + + // check and set current value + if ((parameter.getCurrentValue() == null) && (currentParam.getDefaultValue() != null)) { + log.debug("heat parameter current value is null. set it to default value {}). ignoring.", parameter.getDefaultValue()); + parameter.setCurrentValue(currentParam.getDefaultValue()); + } + } + } + } + + private Map getMapOfParameters(List currentParameters) { + + Map currentParamsMap = new HashMap(); + for (HeatParameterDefinition param : currentParameters) { + currentParamsMap.put(param.getUniqueId(), param); + } + return currentParamsMap; + } + + private Either validateAndServiceApiUrl(ArtifactDefinition artifactInfo) { + if (!ValidationUtils.validateStringNotEmpty(artifactInfo.getApiUrl())) { + log.debug("Artifact url cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_URL)); + } + artifactInfo.setApiUrl(artifactInfo.getApiUrl().toLowerCase()); + + if (!ValidationUtils.validateUrl(artifactInfo.getApiUrl())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_SERVICE_API_URL)); + } + if (!ValidationUtils.validateUrlLength(artifactInfo.getApiUrl())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_URL, String.valueOf(ValidationUtils.API_URL_LENGTH))); + } + + return Either.left(true); + } + + private Either validateAndCleanDescription(ArtifactDefinition artifactInfo) { + if (artifactInfo.getDescription() == null || artifactInfo.getDescription().isEmpty()) { + log.debug("Artifact description cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_DESCRIPTION)); + } + String description = artifactInfo.getDescription(); + description = ValidationUtils.removeNoneUtf8Chars(description); + description = ValidationUtils.normaliseWhitespace(description); + description = ValidationUtils.stripOctets(description); + description = ValidationUtils.removeHtmlTagsOnly(description); + if (!ValidationUtils.validateIsEnglish(description)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + if (!ValidationUtils.validateLength(description, ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, ARTIFACT_DESCRIPTION, String.valueOf(ValidationUtils.ARTIFACT_DESCRIPTION_MAX_LENGTH))); + } + artifactInfo.setDescription(description); + return Either.left(true); + } + + private Either, ResponseFormat> updateArtifactFlow(org.openecomp.sdc.be.model.Component parent, String parentId, String artifactId, ArtifactDefinition artifactInfo, User user, byte[] decodedPayload, + ComponentTypeEnum componentType, AuditingActionEnum auditingAction, String interfaceType, String operationName) { + ESArtifactData artifactData = createEsArtifactData(artifactInfo, decodedPayload); + String prevArtifactId = null; + String currArtifactId = artifactId; + + Either, ResponseFormat> resultOp = null; + Either insideEither = null; + + if (artifactData == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Update Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); + log.debug("Failed to create artifact object for ES."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + log.debug("Try to update entry on graph"); + String artifactUniqueId = null; + ArtifactDefinition artifactDefinition = null; + StorageOperationStatus error = null; + + boolean isLeft = false; + if (interfaceType != null && operationName != null) { + // lifecycle artifact + Operation operation = convertToOperation(artifactInfo, operationName); + + Either result = interfaceLifecycleOperation.updateInterfaceOperation(parentId, interfaceType, operationName, operation); + + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value().getImplementation(); + + insideEither = Either.right(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } else { + + NodeTypeEnum convertParentType = convertParentType(componentType); + Either result = artifactOperation.updateArifactOnResource(artifactInfo, parentId, artifactId, convertParentType, true); + isLeft = result.isLeft(); + if (isLeft) { + artifactUniqueId = result.left().value().getUniqueId(); + artifactDefinition = result.left().value(); + + insideEither = Either.left(result.left().value()); + resultOp = Either.left(insideEither); + } else { + error = result.right().value(); + } + } + if (isLeft) { + log.debug("Enty on graph is updated. Update artifact in ES"); + boolean res; + // Changing previous and current artifactId for auditing + prevArtifactId = currArtifactId; + currArtifactId = artifactDefinition.getUniqueId(); + + if (!artifactDefinition.getUniqueId().equals(artifactId)) { + // different ids ==> artifact node was cloned . + // if no data in request get from ES + if (decodedPayload == null) { + if (!artifactDefinition.getMandatory() || artifactDefinition.getEsId() != null) { + Either artifactFromCassandra = artifactCassandraDao.getArtifact(artifactId); + // Either + // artifactfromES = daoUploader.getArtifact(artifactId); + if (artifactFromCassandra.isRight()) { + log.debug("Failed to get artifact data from ES for artifact id {}", artifactId); + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactFromCassandra.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus)); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + } + // clone data to new artifact + artifactData.setData(artifactFromCassandra.left().value().getData()); + } + } + artifactData.setId(artifactDefinition.getUniqueId()); + // create new entry in ES + res = true; + if (artifactData.getData() != null) { + res = saveArtifacts(artifactData, parentId, false); + // set on graph object id of artifact in ES! + if (res) { + artifactInfo.setEsId(artifactData.getId()); + Either updateArifactRes = artifactOperation.updateArifactDefinition(artifactInfo, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value())); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } else { + insideEither = Either.left(updateArifactRes.left().value()); + resultOp = Either.left(insideEither); + } + } + } + } else { + res = true; + if (artifactData.getData() != null) { + // override artifact in ES + res = saveArtifacts(artifactData, parentId, true); + if (res && artifactDefinition.getMandatory()) { + artifactInfo.setEsId(artifactData.getId()); + Either updateArifactRes = artifactOperation.updateArifactDefinition(artifactInfo, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value()), artifactId); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + return resultOp; + + } + } + } + } + if (res) { + log.debug("Artifact saved into ES - {}", artifactUniqueId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + // resultOp = Either.left(result.left().value()); + // return resultOp; + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Update Artifact"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Update Artifact"); + log.debug("Failed to save the artifact."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + // return resultOp; + } + } else { + log.debug("Failed to create entry on graph for artifact {}", artifactInfo.getArtifactDisplayName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(error), artifactInfo.getArtifactDisplayName()); + handleAuditing(auditingAction, parent, parentId, user, artifactInfo, prevArtifactId, currArtifactId, responseFormat, componentType, null); + resultOp = Either.right(responseFormat); + // return resultOp; + } + + return resultOp; + } + + private Either handlePayload(ArtifactDefinition artifactInfo, boolean isArtifactMetadataUpdate) { + log.trace("Starting payload handling"); + byte[] payload = artifactInfo.getPayloadData(); + byte[] decodedPayload = null; + + if (payload != null && payload.length != 0) { + + decodedPayload = Base64.decodeBase64(payload); + if (decodedPayload.length == 0) { + log.debug("Failed to decode the payload."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(responseFormat); + } + + String checkSum = GeneralUtility.calculateMD5ByByteArray(decodedPayload); + artifactInfo.setArtifactChecksum(checkSum); + log.trace("Calculated checksum, base64 payload: {}, checksum: {}", payload, checkSum); + + // Specific payload validations of different types + Either isValidPayload = Either.left(true); + if (isDeploymentArtifact(artifactInfo)) { + log.trace("Starting deployment artifacts payload validation"); + String artifactType = artifactInfo.getArtifactType(); + if (ArtifactTypeEnum.HEAT.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_VOL.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.HEAT_NET.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { + isValidPayload = validateDeploymentHeatPayload(decodedPayload, artifactType); + if (isValidPayload.isLeft()) { + isValidPayload = extractHeatParameters(artifactInfo); + } + } else if (ArtifactTypeEnum.YANG_XML.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VNF_CATALOG.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.VF_LICENSE.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.VENDOR_LICENSE.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.MODEL_INVENTORY_PROFILE.getType().equalsIgnoreCase(artifactType) + || ArtifactTypeEnum.MODEL_QUERY_SPEC.getType().equalsIgnoreCase(artifactType)) { + isValidPayload = validateYangPayload(decodedPayload, artifactType); + // else + // if(ArtifactTypeEnum.APPC_CONFIG.getType().equalsIgnoreCase(artifactType) + // || ){ + } else if (ArtifactTypeEnum.DCAE_INVENTORY_JSON.getType().equalsIgnoreCase(artifactType) || ArtifactTypeEnum.DCAE_INVENTORY_TOSCA.getType().equalsIgnoreCase(artifactType)) { + String artifactFileName = artifactInfo.getArtifactName(); + String fileExtension = GeneralUtility.getFilenameExtension(artifactFileName).toLowerCase(); + switch (fileExtension) { + case "xml": + isValidPayload = validateYangPayload(decodedPayload, artifactType); + break; + case "json": + isValidPayload = validateJsonPayload(decodedPayload, artifactType); + break; + case "yml": + case "yaml": + isValidPayload = validateYmlPayload(decodedPayload, artifactType); + break; + } + } + } + if (isValidPayload.isRight()) { + ResponseFormat responseFormat = isValidPayload.right().value(); + return Either.right(responseFormat); + } + + } // null/empty payload is normal if called from metadata update ONLY. + // The validation of whether this is metadata/payload update case is + // currently done separately + else { + if (!isArtifactMetadataUpdate) { + log.debug("Payload is missing."); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD); + return Either.right(responseFormat); + } + } + log.trace("Ended payload handling"); + return Either.left(decodedPayload); + } + + private Either validateDeploymentHeatPayload(byte[] payload, String artifactType) { + // Basic YAML validation + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (!yamlToObjectConverter.isValidYaml(payload)) { + log.debug("Invalid YAML format"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); + return Either.right(responseFormat); + } + if (!ArtifactTypeEnum.HEAT_ENV.getType().equalsIgnoreCase(artifactType)) { + // HEAT specific YAML validation + DeploymentArtifactHeatConfiguration heatConfiguration = yamlToObjectConverter.convert(payload, DeploymentArtifactHeatConfiguration.class); + if (heatConfiguration == null || heatConfiguration.getHeat_template_version() == null || heatConfiguration.getResources() == null) { + log.debug("HEAT doesn't contain required \"heat_template_version\" and \"resources\" sections "); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactType); + return Either.right(responseFormat); + } + } + + return Either.left(true); + } + + private Either validateYmlPayload(byte[] decodedPayload, String artifactType) { + Either res = Either.left(true); + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + if (!yamlToObjectConverter.isValidYaml(decodedPayload)) { + log.debug("Invalid YAML format"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, artifactType); + res = Either.right(responseFormat); + } + + return res; + } + + private Either validateYangPayload(byte[] payload, String artifactType) { + boolean isXmlValid = isValidXml(payload); + if (!isXmlValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_XML, artifactType); + log.debug("Invalid XML content"); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateJsonPayload(byte[] payload, String type) { + boolean isJsonValid = isValidJson(payload); + if (!isJsonValid) { + ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus.INVALID_JSON, type); + log.debug("Invalid JSON content"); + return Either.right(responseFormat); + } + return Either.left(true); + } + + public void handleTransaction(Either opState) { + if (opState == null || opState.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + + public Either deleteArtifactByInterface(String resourceId, String interfaceType, String operationName, String userId, String artifactId, ImmutablePair userResourceAuditPair, boolean shouldLock, + boolean inTransaction) { + User user = new User(); + user.setUserId(userId); + Either parent = resourceOperation.getResource(resourceId); + if (parent.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(parent.right().value())); + return Either.right(responseFormat); + } + Either, ResponseFormat> handleDelete = handleDelete(resourceId, artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, parent.left().value(), interfaceType, operationName, + false, inTransaction); + if (handleDelete.isRight()) { + return Either.right(handleDelete.right().value()); + } + Either result = handleDelete.left().value(); + return Either.left(result.right().value()); + + } + + public StorageOperationStatus deleteAllComponentArtifactsIfNotOnGraph(List artifacts) { + + if (artifacts != null && !artifacts.isEmpty()) { + for (ArtifactDefinition artifactDefinition : artifacts) { + String esId = artifactDefinition.getEsId(); + if (esId != null && !esId.isEmpty()) { + StorageOperationStatus deleteIfNotOnGraph = deleteIfNotOnGraph(artifactDefinition.getUniqueId(), esId, false); + if (!deleteIfNotOnGraph.equals(StorageOperationStatus.OK)) { + return deleteIfNotOnGraph; + } + } + } + } + return StorageOperationStatus.OK; + } + + private Operation convertToOperation(ArtifactDefinition artifactInfo, String operationName) { + Operation op = new Operation(); + long time = System.currentTimeMillis(); + op.setCreationDate(time); + + String artifactName = artifactInfo.getArtifactName(); + artifactInfo.setArtifactName(createInterfaceArtifactNameFromOperation(operationName, artifactName)); + + op.setImplementation(artifactInfo); + op.setLastUpdateDate(time); + return op; + } + + private String createInterfaceArtifactNameFromOperation(String operationName, String artifactName) { + String newArtifactName = operationName + "_" + artifactName; + log.trace("converting artifact name {} to {}", artifactName, newArtifactName); + return newArtifactName; + } + + public StorageOperationStatus deleteIfNotOnGraph(String artifactId, String artifactEsId, boolean deleteOnlyPayload) { + log.debug("deleteIfNotOnGraph: delete only payload = {}", deleteOnlyPayload); + Either checkArtifactNode = titanGenericDao.getNode(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.ArtifactRef), artifactId, ArtifactData.class); + if ((artifactEsId != null && !artifactEsId.isEmpty())) { + boolean isNotExistOnGraph = checkArtifactNode.isRight() && checkArtifactNode.right().value().equals(TitanOperationStatus.NOT_FOUND); + + if ((isNotExistOnGraph) || (checkArtifactNode.left().value().getArtifactDataDefinition().getMandatory() && deleteOnlyPayload) + || (ArtifactGroupTypeEnum.SERVICE_API.equals(checkArtifactNode.left().value().getArtifactDataDefinition().getArtifactGroupType()) && deleteOnlyPayload)) { + // last one. need to delete in ES + log.debug("Entry on graph is deleted. Delete artifact in ES for id = {}", artifactEsId); + artifactCassandraDao.deleteArtifact(artifactEsId); + return StorageOperationStatus.OK; + // return + // componentsUtils.getResponseFormatByResourceId(ActionStatus.OK, + // resourceId); + + } else { + log.debug("Entry on graph is deleted. Exist more connections on this artifact. Don't delete artifact in ES for id = {}", artifactEsId); + return StorageOperationStatus.OK; + } + + } + return StorageOperationStatus.OK; + } + + // download by MSO + public Either downloadRsrcArtifactByNames(String serviceName, String serviceVersion, String resourceName, String resourceVersion, String artifactName) { + + // General validation + if (serviceName == null || serviceVersion == null || resourceName == null || resourceVersion == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Resource validation + Either validateResourceNameAndVersion = validateResourceNameAndVersion(resourceName, resourceVersion); + if (validateResourceNameAndVersion.isRight()) { + return Either.right(validateResourceNameAndVersion.right().value()); + } + + Resource resource = validateResourceNameAndVersion.left().value(); + String resourceId = resource.getUniqueId(); + + // Service validation + Either validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + Map artifacts = resource.getDeploymentArtifacts(); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Deployment artifacts of resource {} are not found", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + ArtifactDefinition deploymentArtifact = null; + + for (ArtifactDefinition artifactDefinition : artifacts.values()) { + if (artifactDefinition.getArtifactName() != null && artifactDefinition.getArtifactName().equals(artifactName)) { + log.debug("Found deployment artifact {}", artifactName); + deploymentArtifact = artifactDefinition; + break; + } + } + + if (deploymentArtifact == null) { + log.debug("No deployment artifact {} was found for resource {}", artifactName, resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + // Downloading the artifact + Either, ResponseFormat> downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of resource artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + // download by MSO + public Either downloadRsrcInstArtifactByNames(String serviceName, String serviceVersion, String resourceInstanceName, String artifactName) { + + // General validation + if (serviceName == null || serviceVersion == null || resourceInstanceName == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Resource validation + /* + * Either validateResourceNameAndVersion = validateResourceNameAndVersion(resourceName, resourceVersion); if (validateResourceNameAndVersion.isRight()) { return + * Either.right(validateResourceNameAndVersion.right().value()); } + * + * Resource resource = validateResourceNameAndVersion.left().value(); String resourceId = resource.getUniqueId(); + */ + + // Service validation + Either validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + Service service = validateServiceNameAndVersion.left().value(); + + // ResourceInstance validation + Either validateResourceInstance = validateResourceInstance(service, resourceInstanceName); + if (validateResourceInstance.isRight()) { + return Either.right(validateResourceInstance.right().value()); + } + + ComponentInstance resourceInstance = validateResourceInstance.left().value(); + + Map artifacts = resourceInstance.getDeploymentArtifacts(); + + final String finalArtifactName = artifactName; + Predicate filterArtifactByName = p -> p.getArtifactName().equals(finalArtifactName); + + boolean hasDeploymentArtifacts = artifacts != null && artifacts.values().stream().anyMatch(filterArtifactByName); + ArtifactDefinition deployableArtifact; + + if (!hasDeploymentArtifacts) { + log.debug("Deployment artifact with name {} not found", artifactName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + log.debug("Found deployment artifact {}", artifactName); + deployableArtifact = artifacts.values().stream().filter(filterArtifactByName).findFirst().get(); + // Downloading the artifact + Either, ResponseFormat> downloadArtifactEither = downloadArtifact(deployableArtifact); + + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of resource artifact succeeded, uniqueId {}", deployableArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + private Either validateResourceInstance(Service service, String resourceInstanceName) { + + List riList = service.getComponentInstances(); + for (ComponentInstance ri : riList) { + if (ri.getNormalizedName().equals(resourceInstanceName)) + return Either.left(ri); + } + + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, resourceInstanceName)); + } + + private Either validateServiceNameAndVersion(String serviceName, String serviceVersion) { + + Either, StorageOperationStatus> serviceListBySystemName = serviceOperation.getServiceListBySystemName(serviceName, false); + if (serviceListBySystemName.isRight()) { + log.debug("Couldn't fetch any service with name {}", serviceName); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceListBySystemName.right().value(), ComponentTypeEnum.SERVICE), serviceName)); + } + List serviceList = serviceListBySystemName.left().value(); + if (serviceList == null || serviceList.isEmpty()) { + log.debug("Couldn't fetch any service with name {}", serviceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceName)); + } + + Service foundService = null; + for (Service service : serviceList) { + if (service.getVersion().equals(serviceVersion)) { + log.trace("Found service with version {}", serviceVersion); + foundService = service; + break; + } + } + + if (foundService == null) { + log.debug("Couldn't find version {} for service {}", serviceVersion, serviceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.SERVICE.getValue(), serviceVersion)); + } + return Either.left(foundService); + } + + private Either validateResourceNameAndVersion(String resourceName, String resourceVersion) { + Either, StorageOperationStatus> resourceListBySystemName = resourceOperation.getResourceListBySystemName(resourceName, false); + if (resourceListBySystemName.isRight()) { + log.debug("Couldn't fetch any resource with name {}", resourceName); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceListBySystemName.right().value()), resourceName)); + } + List resourceList = resourceListBySystemName.left().value(); + if (resourceList == null || resourceList.isEmpty()) { + log.debug("Couldn't fetch any resource with name {}", resourceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceName)); + } + + Resource foundResource = null; + for (Resource resource : resourceList) { + if (resource.getVersion().equals(resourceVersion)) { + log.trace("Found resource with version {}", resourceVersion); + foundResource = resource; + break; + } + } + + if (foundResource == null) { + log.debug("Couldn't find version {} for resource {}", resourceVersion, resourceName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_VERSION_NOT_FOUND, ComponentTypeEnum.RESOURCE.getValue(), resourceVersion)); + } + return Either.left(foundResource); + } + + public Either downloadServiceArtifactByNames(String serviceName, String serviceVersion, String artifactName) { + // Validation + log.trace("Starting download of service interface artifact, serviceName {}, serviceVersion {}, artifact name {}", serviceName, serviceVersion, artifactName); + if (serviceName == null || serviceVersion == null || artifactName == null) { + log.debug("One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + // Normalizing artifact name + artifactName = ValidationUtils.normalizeFileName(artifactName); + + // Service validation + Either validateServiceNameAndVersion = validateServiceNameAndVersion(serviceName, serviceVersion); + if (validateServiceNameAndVersion.isRight()) { + return Either.right(validateServiceNameAndVersion.right().value()); + } + + String serviceId = validateServiceNameAndVersion.left().value().getUniqueId(); + + // Looking for deployment artifacts + Service service = validateServiceNameAndVersion.left().value(); + Map artifacts = service.getDeploymentArtifacts(); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Deployment artifacts of service {} are not found", serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + ArtifactDefinition deploymentArtifact = null; + + for (ArtifactDefinition artifactDefinition : artifacts.values()) { + if (artifactDefinition.getArtifactName().equals(artifactName)) { + log.debug("Found deployment artifact {}", artifactName); + deploymentArtifact = artifactDefinition; + } + } + + if (deploymentArtifact == null) { + log.debug("No deployment artifact {} was found for service {}", artifactName, serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + // Downloading the artifact + Either, ResponseFormat> downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Download artifact {} failed", artifactName); + return Either.right(downloadArtifactEither.right().value()); + } + log.trace("Download of service artifact succeeded, uniqueId {}", deploymentArtifact.getUniqueId()); + return Either.left(downloadArtifactEither.left().value().getRight()); + } + + public Either, ResponseFormat> downloadArtifact(String artifactUniqueId) { + log.trace("Starting download of artifact, uniqueId {}", artifactUniqueId); + Either artifactById = artifactOperation.getArtifactById(artifactUniqueId, false); + if (artifactById.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(artifactById.right().value()); + log.debug("Error when getting artifact info by id{}, error: {}", artifactUniqueId, actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, "")); + } + ArtifactDefinition artifactDefinition = artifactById.left().value(); + if (artifactDefinition == null) { + log.debug("Empty artifact definition returned from DB by artifact id {}", artifactUniqueId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, "")); + } + + return downloadArtifact(artifactDefinition); + } + + private boolean checkArtifactInComponent(org.openecomp.sdc.be.model.Component component, String artifactId) { + boolean found = false; + Map artifactsS = component.getArtifacts(); + if (artifactsS != null) { + for (Map.Entry entry : artifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + Map deploymentArtifactsS = component.getDeploymentArtifacts(); + if (!found && deploymentArtifactsS != null) { + for (Map.Entry entry : deploymentArtifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + Map toscaArtifactsS = component.getToscaArtifacts(); + if (!found && toscaArtifactsS != null) { + for (Map.Entry entry : toscaArtifactsS.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + switch (component.getComponentType()) { + case RESOURCE: + Map interfaces = ((Resource) component).getInterfaces(); + if (!found && interfaces != null) { + for (Map.Entry entry : interfaces.entrySet()) { + Map operations = entry.getValue().getOperations(); + for (Map.Entry entryOp : operations.entrySet()) { + if (entryOp.getValue().getImplementation() != null && entryOp.getValue().getImplementation().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + } + break; + case SERVICE: + Map apiArtifacts = ((Service) component).getServiceApiArtifacts(); + if (!found && apiArtifacts != null) { + for (Map.Entry entry : apiArtifacts.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + break; + default: + + } + + return found; + } + + private boolean checkArtifactInResourceInstance(Component component, String resourceInstanceId, String artifactId) { + + boolean found = false; + List resourceInstances = component.getComponentInstances(); + ComponentInstance resourceInstance = null; + for (ComponentInstance ri : resourceInstances) { + if (ri.getUniqueId().equals(resourceInstanceId)) { + resourceInstance = ri; + break; + } + } + if (resourceInstance != null) { + Map artifacts = resourceInstance.getDeploymentArtifacts(); + if (artifacts != null) { + for (Map.Entry entry : artifacts.entrySet()) { + if (entry.getValue().getUniqueId().equals(artifactId)) { + found = true; + break; + } + } + } + } + return found; + } + + private Either validateComponentExists(String componentId, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ComponentTypeEnum componentType, + String containerComponentType, boolean inTransaction) { + + NodeTypeEnum nodeType = componentType.getNodeType(); + if (containerComponentType != null && NodeTypeEnum.ResourceInstance == nodeType) { + nodeType = (ComponentTypeEnum.findByParamName(containerComponentType)).getNodeType(); + } + ComponentOperation componentOperation = getComponentOperation(nodeType); + + if (componentOperation == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + log.debug("addArtifact - not supported component type {}", componentType); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + Either componentResult = componentOperation.getComponent(componentId, inTransaction); + + if (componentResult.isRight()) { + ActionStatus status = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND; + ComponentTypeEnum componentForAudit = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ComponentTypeEnum.RESOURCE : ComponentTypeEnum.SERVICE; + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId); + log.debug("Service not found, serviceId {}", componentId); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentForAudit, null); + return Either.right(responseFormat); + } + return Either.left(componentResult.left().value()); + } + + private Either validateWorkOnComponent(org.openecomp.sdc.be.model.Component component, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperation operation, + ComponentTypeEnum componentType) { + if (operation != ArtifactOperation.Download) { + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + String uniqueId = component.getUniqueId(); + log.debug("Service status isn't CHECKOUT or user isn't owner, serviceId {}", uniqueId); + handleAuditing(auditingAction, component, uniqueId, user, null, null, artifactId, canWork.right().value(), component.getComponentType(), null); + return Either.right(canWork.right().value()); + } + } + return Either.left(true); + } + + private Either validateWorkOnResource(Resource resource, String userId, AuditingActionEnum auditingAction, User user, String artifactId, ArtifactOperation operation) { + if (operation != ArtifactOperation.Download) { + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + String uniqueId = resource.getUniqueId(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("Resource status isn't CHECKOUT or user isn't owner, resourceId {}", uniqueId); + handleAuditing(auditingAction, resource, uniqueId, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE, null); + return Either.right(responseFormat); + } + } + return Either.left(true); + } + + private Either validateUserRole(User user, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperation operation) { + + if (operation != ArtifactOperation.Download) { + String role = user.getRole(); + if (!role.equals(Role.ADMIN.name()) && !role.equals(Role.DESIGNER.name())) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("addArtifact - user isn't permitted to perform operation, userId {}, role {}", user.getUserId(), role); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } + return Either.left(true); + } + + private Either validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType) { + + return validateUserExists(userId, auditingAction, componentId, artifactId, componentType, false); + + } + + private Either validateUserExists(String userId, AuditingActionEnum auditingAction, String componentId, String artifactId, ComponentTypeEnum componentType, boolean inTransaction) { + Either validateUserExists = validateUserExists(userId, auditingAction.getName(), inTransaction); + + if (validateUserExists.isRight()) { + User user = new User(); + user.setUserId(userId); + handleAuditing(auditingAction, null, componentId, user, null, null, artifactId, validateUserExists.right().value(), componentType, null); + return Either.right(validateUserExists.right().value()); + } + return Either.left(validateUserExists.left().value()); + } + + private AuditingActionEnum detectAuditingType(ArtifactOperation operation, String origMd5) { + AuditingActionEnum auditingAction = null; + switch (operation) { + case Create: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : AuditingActionEnum.ARTIFACT_UPLOAD; + break; + case Update: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_UPLOAD_BY_API : origMd5 == null ? AuditingActionEnum.ARTIFACT_METADATA_UPDATE : AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE; + break; + case Delete: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.ARTIFACT_DELETE_BY_API : AuditingActionEnum.ARTIFACT_DELETE; + break; + case Download: + auditingAction = operation.isExternalApi() ? AuditingActionEnum.DOWNLOAD_ARTIFACT : AuditingActionEnum.ARTIFACT_DOWNLOAD; + break; + default: + break; + } + return auditingAction; + } + + private Either, ResponseFormat> downloadArtifact(ArtifactDefinition artifactDefinition) { + String esArtifactId = artifactDefinition.getEsId(); + Either artifactfromES = artifactCassandraDao.getArtifact(esArtifactId); + if (artifactfromES.isRight()) { + CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value(); + StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse); + log.debug("Error when getting artifact from ES, error: {}", actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName())); + } + + ESArtifactData esArtifactData = artifactfromES.left().value(); + byte[] data = esArtifactData.getDataAsArray(); + if (data == null) { + log.debug("Artifact data from ES is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactDefinition.getArtifactDisplayName())); + } + String artifactName = artifactDefinition.getArtifactName(); + log.trace("Download of artifact succeeded, uniqueId {}, artifact file name {}", artifactDefinition.getUniqueId(), artifactName); + return Either.left(new ImmutablePair(artifactName, data)); + } + + public ESArtifactData createEsArtifactData(ArtifactDataDefinition artifactInfo, byte[] artifactPayload) { + ESArtifactData artifactData = new ESArtifactData(artifactInfo.getEsId(), artifactPayload); + return artifactData; + } + + private boolean saveArtifacts(ESArtifactData artifactData, String resourceId, boolean reload) { + + CassandraOperationStatus resourceUploadStatus = artifactCassandraDao.saveArtifact(artifactData); + + if (resourceUploadStatus.equals(CassandraOperationStatus.OK)) { + log.debug("Artifact {} was saved in component {}.", artifactData.getId(), resourceId); + } else { + log.info("Failed to save artifact {}.", artifactData.getId()); + return false; + } + return true; + } + + private boolean isArtifactMetadataUpdate(AuditingActionEnum auditingActionEnum) { + return (auditingActionEnum.equals(AuditingActionEnum.ARTIFACT_METADATA_UPDATE)); + } + + private boolean isDeploymentArtifact(ArtifactDefinition artifactInfo) { + return (ArtifactGroupTypeEnum.DEPLOYMENT.equals(artifactInfo.getArtifactGroupType())); + } + + public IResourceOperation getResourceOperation() { + return this.resourceOperation; + } + + public Either createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map artifactInfoMap, String userId, ArtifactGroupTypeEnum groupType, boolean inTransaction) { + Either user = userAdminManager.getUser(userId, inTransaction); + if (user.isRight()) { + ResponseFormat responseFormat; + if (user.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + log.debug("create artifact placeholder - not authorized user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } else { + log.debug("create artifact placeholder - failed to authorize user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(user.right().value()); + } + return Either.right(responseFormat); + } + + ArtifactDefinition artifactDefinition = createArtifactPlaceHolderInfo(resourceId, logicalName, artifactInfoMap, user.left().value(), groupType); + return Either.left(artifactDefinition); + } + + public ArtifactDefinition createArtifactPlaceHolderInfo(String resourceId, String logicalName, Map artifactInfoMap, User user, ArtifactGroupTypeEnum groupType) { + ArtifactDefinition artifactInfo = new ArtifactDefinition(); + + String artifactName = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DISPLAY_NAME); + String artifactType = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_TYPE); + String artifactDescription = (String) artifactInfoMap.get(ARTIFACT_PLACEHOLDER_DESCRIPTION); + + artifactInfo.setArtifactDisplayName(artifactName); + artifactInfo.setArtifactLabel(logicalName.toLowerCase()); + artifactInfo.setArtifactType(artifactType); + artifactInfo.setDescription(artifactDescription); + artifactInfo.setArtifactGroupType(groupType); + setDefaultArtifactTimeout(groupType, artifactInfo); + + setArtifactPlaceholderCommonFields(resourceId, user, artifactInfo); + + return artifactInfo; + } + + private void setDefaultArtifactTimeout(ArtifactGroupTypeEnum groupType, ArtifactDefinition artifactInfo) { + if (groupType.equals(ArtifactGroupTypeEnum.DEPLOYMENT)) { + artifactInfo.setTimeout(defaultHeatTimeout); + } else { + artifactInfo.setTimeout(NON_HEAT_TIMEOUT); + } + } + + private void setArtifactPlaceholderCommonFields(String resourceId, User user, ArtifactDefinition artifactInfo) { + String uniqueId = null; + + if (resourceId != null) { + uniqueId = UniqueIdBuilder.buildPropertyUniqueId(resourceId.toLowerCase(), artifactInfo.getArtifactLabel().toLowerCase()); + artifactInfo.setUniqueId(uniqueId); + } + artifactInfo.setUserIdCreator(user.getUserId()); + String fullName = user.getFullName(); + artifactInfo.setUpdaterFullName(fullName); + + long time = System.currentTimeMillis(); + + artifactInfo.setCreatorFullName(fullName); + artifactInfo.setCreationDate(time); + + artifactInfo.setLastUpdateDate(time); + artifactInfo.setUserIdLastUpdater(user.getUserId()); + + artifactInfo.setMandatory(true); + } + + public Either, StorageOperationStatus> getArtifacts(String parentId, NodeTypeEnum parentType, boolean inTransaction, ArtifactGroupTypeEnum groupType) { + return artifactOperation.getArtifacts(parentId, parentType, inTransaction, groupType.getType()); + } + + public Either addHeatEnvArtifact(ArtifactDefinition artifactHeatEnv, ArtifactDefinition artifact, String parentId, NodeTypeEnum parentType, boolean inTransaction) { + return artifactOperation.addHeatEnvArtifact(artifactHeatEnv, artifact, parentId, parentType, inTransaction); + + } + + private Either createEsHeatEnvArtifactDataFromString(ArtifactDefinition artifactDefinition, String parameters) { + StringBuilder sb = new StringBuilder(); + + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader()); + sb.append(parameters); + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter()); + byte[] payload = sb.toString().getBytes(); + + YamlToObjectConverter yamlToObjectConverter = new YamlToObjectConverter(); + + /* + * if (!yamlToObjectConverter.isValidYaml(payload)) { log.debug("Invalid YAML format"); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML, ArtifactTypeEnum.HEAT_ENV.getType()); return + * Either.right(responseFormat); } + */ + + ESArtifactData artifactData = createEsArtifactData(artifactDefinition, payload); + return Either.left(artifactData); + } + + /** + * + * @param artifactDefinition + * @return + */ + public Either generateHeatEnvArtifact(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, boolean shouldLock) { + List heatParameters = artifactDefinition.getHeatParameters(); + heatParameters.sort(Comparator.comparing(e -> e.getName())); + StringBuilder sb = new StringBuilder("parameters:\n"); + if (heatParameters != null) { + + for (HeatParameterDefinition heatParameterDefinition : heatParameters) { + if (heatParameterDefinition.getCurrentValue() != null) { + HeatParameterType type = HeatParameterType.isValidType(heatParameterDefinition.getType()); + if (type != null) { + switch (type) { + case BOOLEAN: + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(Boolean.parseBoolean(heatParameterDefinition.getCurrentValue())).append("\n"); + break; + case NUMBER: + // if + // (ValidationUtils.isFloatNumber(heatParameterDefinition.getCurrentValue())) + // { + // sb.append(" + // ").append(heatParameterDefinition.getName()).append(":").append(" + // ").append(Float.parseFloat(heatParameterDefinition.getCurrentValue())).append("\n"); + // } else { + // sb.append(" + // ").append(heatParameterDefinition.getName()).append(":").append(" + // ").append(Integer.parseInt(heatParameterDefinition.getCurrentValue())).append("\n"); + // } + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(new BigDecimal(heatParameterDefinition.getCurrentValue()).toPlainString()).append("\n"); + break; + case COMMA_DELIMITED_LIST: + case JSON: + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(heatParameterDefinition.getCurrentValue()).append("\n"); + break; + default: + String value = heatParameterDefinition.getCurrentValue(); + boolean starts = value.startsWith("\""); + boolean ends = value.endsWith("\""); + if (!(starts && ends)) { + starts = value.startsWith("'"); + ends = value.endsWith("'"); + if (!(starts && ends)) { + value = "\"" + value + "\""; + } + } + sb.append(" ").append(heatParameterDefinition.getName()).append(":").append(" ").append(value); + sb.append("\n"); + break; + + } + } + } + } + } + return generateAndSaveHeatEnvArtifact(artifactDefinition, sb.toString(), component, resourceInstanceName, modifier, shouldLock); + + } + + /** + * + * @param artifactDefinition + * @param payload + * @return + */ + public Either generateAndSaveHeatEnvArtifact(ArtifactDefinition artifactDefinition, String payload, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, + boolean shouldLock) { + return generateArtifactPayload(artifactDefinition, component, resourceInstanceName, modifier, shouldLock, () -> artifactDefinition.getHeatParamsUpdateDate(), () -> createEsHeatEnvArtifactDataFromString(artifactDefinition, payload)); + + } + + protected Either generateArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, String resourceInstanceName, User modifier, boolean shouldLock, + Supplier payloadUpdateDateGen, Supplier> esDataCreator) { + + if (artifactDefinition.getPayloadUpdateDate() == null || artifactDefinition.getPayloadUpdateDate() == 0 || artifactDefinition.getPayloadUpdateDate() < payloadUpdateDateGen.get()) { + + log.trace("Generaing payload for {} artifact {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId()); + Either artifactDataRes = esDataCreator.get(); + ESArtifactData artifactData = null; + + if (artifactDataRes.isLeft()) { + artifactData = artifactDataRes.left().value(); + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(artifactDataRes.right().value()); + } + String newCheckSum = GeneralUtility.calculateMD5ByByteArray(artifactData.getDataAsArray()); + String oldCheckSum; + String esArtifactId = artifactDefinition.getEsId(); + Either artifactfromES; + ESArtifactData esArtifactData; + if (esArtifactId != null && !esArtifactId.isEmpty()) { + artifactfromES = artifactCassandraDao.getArtifact(esArtifactId); + if (artifactfromES.isRight()) { + CassandraOperationStatus resourceUploadStatus = artifactfromES.right().value(); + StorageOperationStatus storageResponse = DaoStatusConverter.convertCassandraStatusToStorageStatus(resourceUploadStatus); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageResponse); + log.debug("Error when getting artifact from ES, error: {}", actionStatus.name()); + return Either.right(componentsUtils.getResponseFormatByArtifactId(actionStatus, artifactDefinition.getArtifactDisplayName())); + } + esArtifactData = artifactfromES.left().value(); + oldCheckSum = GeneralUtility.calculateMD5ByByteArray(esArtifactData.getDataAsArray()); + } else { + oldCheckSum = artifactDefinition.getArtifactChecksum(); + } + Either updateArifactDefinitionStatus; + + if (shouldLock) { + Either lockComponent = lockComponent(component, "Update Artifact - lock resource: "); + if (lockComponent.isRight()) { + handleAuditing(AuditingActionEnum.ARTIFACT_METADATA_UPDATE, component, component.getUniqueId(), modifier, null, null, artifactDefinition.getUniqueId(), lockComponent.right().value(), component.getComponentType(), null); + return Either.right(lockComponent.right().value()); + } + } + try { + if (oldCheckSum != null && oldCheckSum.equals(newCheckSum)) { + + artifactDefinition.setPayloadUpdateDate(payloadUpdateDateGen.get()); + updateArifactDefinitionStatus = artifactOperation.updateArifactDefinition(artifactDefinition, false); + log.trace("No real update done in payload for {} artifact, updating payloadUpdateDate {}", artifactDefinition.getArtifactType(), artifactDefinition.getEsId()); + if (updateArifactDefinitionStatus.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + log.trace("Failed to update payloadUpdateDate ", artifactDefinition.getEsId()); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + } + } else { + + oldCheckSum = artifactDefinition.getArtifactChecksum(); + artifactDefinition.setArtifactChecksum(newCheckSum); + artifactOperation.updateUUID(artifactDefinition, oldCheckSum, artifactDefinition.getArtifactVersion()); + artifactDefinition.setEsId(artifactDefinition.getUniqueId()); + updateArifactDefinitionStatus = artifactOperation.updateArifactDefinition(artifactDefinition, true); + + log.trace("Update Payload ", artifactDefinition.getEsId()); + + if (updateArifactDefinitionStatus.isLeft()) { + + artifactData.setId(artifactDefinition.getUniqueId()); + CassandraOperationStatus saveArtifactStatus = artifactCassandraDao.saveArtifact(artifactData); + + if (saveArtifactStatus.equals(CassandraOperationStatus.OK)) { + titanGenericDao.commit(); + log.debug("Artifact Saved In ES {}", artifactData.getId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + } else { + titanGenericDao.rollback(); + log.info("Failed to save artifact {}.", artifactData.getId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + } + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByArtifactId(componentsUtils.convertFromStorageResponse(updateArifactDefinitionStatus.right().value()), artifactDefinition.getArtifactDisplayName()); + log.debug("Failed To update artifact {}", artifactData.getId()); + handleAuditing(AuditingActionEnum.ARTIFACT_PAYLOAD_UPDATE, component, component.getUniqueId(), modifier, artifactDefinition, artifactDefinition.getUniqueId(), artifactDefinition.getUniqueId(), responseFormat, + ComponentTypeEnum.RESOURCE_INSTANCE, resourceInstanceName); + + return Either.right(responseFormat); + + } + } + } finally { + if (shouldLock) { + graphLockOperation.unlockComponent(component.getUniqueId(), component.getComponentType().getNodeType()); + } + } + } + + return Either.left(artifactDefinition); + } + + private Either, ResponseFormat> handleUpdateHeatEnv(String componentId, ArtifactDefinition artifactInfo, AuditingActionEnum auditingAction, String artifactId, User user, ComponentTypeEnum componentType, + org.openecomp.sdc.be.model.Component parent, String originData, String origMd5, ArtifactOperation operation, boolean shouldLock, boolean inTransaction) { + NodeTypeEnum parentType = convertParentType(componentType); + String parentId = parent.getUniqueId(); + Either artifactRes = artifactOperation.getArtifactById(artifactId, false); + ArtifactDefinition currArtifact = artifactRes.left().value(); + + if (origMd5 != null) { + Either validateMd5 = validateMd5(origMd5, originData, artifactInfo.getPayloadData(), operation); + if (validateMd5.isRight()) { + ResponseFormat responseFormat = validateMd5.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + if (artifactInfo.getPayloadData() != null && artifactInfo.getPayloadData().length != 0) { + Either deploymentValidationResult = validateDeploymentArtifact(parent, componentId, user.getUserId(), false, artifactInfo, currArtifact, NodeTypeEnum.ResourceInstance); + if (deploymentValidationResult.isRight()) { + ResponseFormat responseFormat = deploymentValidationResult.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + + Either payloadEither = handlePayload(artifactInfo, isArtifactMetadataUpdate(auditingAction)); + if (payloadEither.isRight()) { + ResponseFormat responseFormat = payloadEither.right().value(); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } else { // duplicate + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, ARTIFACT_PAYLOAD); + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + } + + // lock resource + if (shouldLock) { + Either lockComponent = lockComponent(parent, "Update Artifact - lock "); + if (lockComponent.isRight()) { + handleAuditing(auditingAction, parent, parentId, user, null, null, artifactId, lockComponent.right().value(), componentType, null); + return Either.right(lockComponent.right().value()); + } + } + Either, ResponseFormat> resultOp = null; + try { + resultOp = updateHeatEnvParams(componentId, artifactId, artifactInfo, user, auditingAction, parent, componentType, currArtifact, origMd5, inTransaction); + return resultOp; + + } finally { + // unlock resource + if (resultOp == null || resultOp.isRight()) { + log.debug("all changes rollback"); + if (false == inTransaction) + titanGenericDao.rollback(); + } else { + log.debug("all changes committed"); + if (false == inTransaction) + titanGenericDao.commit(); + } + if (shouldLock) + componentType = parent.getComponentType(); + NodeTypeEnum nodeType = componentType.getNodeType(); + graphLockOperation.unlockComponent(parent.getUniqueId(), nodeType); + // graphLockOperation.unlockComponent(parentId, parentType); + } + } + + private Either, ResponseFormat> updateHeatEnvParams(String componentId, String artifactId, ArtifactDefinition artifactInfo, User user, AuditingActionEnum auditingAction, Component parent, + ComponentTypeEnum componentType, ArtifactDefinition currArtifact1, String origMd5, boolean inTransaction) { + + Either, ResponseFormat> resultOp = null; + Either insideEither = null; + /* + * currently getArtifactById does not retrieve heatParameters Either artifactRes = artifactOperation.getArtifactById(artifactId, false); ArtifactDefinition currArtifact = artifactRes.left().value(); + */ + Either getRI = getRIFromComponent(parent, componentId, artifactId, auditingAction, user); + if (getRI.isRight()) { + return Either.right(getRI.right().value()); + } + ComponentInstance ri = getRI.left().value(); + Either getArtifactRes = getArtifactFromRI(parent, ri, componentId, artifactId, auditingAction, user); + if (getArtifactRes.isRight()) { + return Either.right(getArtifactRes.right().value()); + } + ArtifactDefinition currArtifact = getArtifactRes.left().value(); + + if (currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_VOL.getType()) || currArtifact.getArtifactType().equals(ArtifactTypeEnum.HEAT_NET.getType())) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + List currentHeatEnvParams = currArtifact.getHeatParameters(); + List updatedHeatEnvParams = artifactInfo.getHeatParameters(); + List reducedHeatEnvParams = new ArrayList(); + + // upload + if (origMd5 != null) { + Either, ResponseFormat> uploadParamsValidationResult = validateUploadParamsFromEnvFile(auditingAction, parent, user, artifactInfo, artifactId, componentType, ri.getName(), currentHeatEnvParams, + updatedHeatEnvParams, currArtifact.getArtifactName()); + if (uploadParamsValidationResult.isRight()) { + ResponseFormat responseFormat = uploadParamsValidationResult.right().value(); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + artifactInfo.setHeatParameters(updatedHeatEnvParams); + } + + Either validateAndConvertHeatParamers = validateAndConvertHeatParamers(artifactInfo, ArtifactTypeEnum.HEAT_ENV.getType()); + if (validateAndConvertHeatParamers.isRight()) { + ResponseFormat responseFormat = validateAndConvertHeatParamers.right().value(); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + + if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty()) { + String paramName; + // fill reduced heat env parameters List for updating + for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) { + paramName = heatEnvParam.getName(); + for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) { + if (paramName.equalsIgnoreCase(currHeatParam.getName())) { + String updatedParamValue = heatEnvParam.getCurrentValue(); + if (updatedParamValue != null && updatedParamValue.equals("")) { // reset + heatEnvParam.setCurrentValue(heatEnvParam.getDefaultValue()); + reducedHeatEnvParams.add(heatEnvParam); + } else if (updatedParamValue != null) { + reducedHeatEnvParams.add(heatEnvParam); + } + } + } + } + if (reducedHeatEnvParams.size() > 0) { + ArtifactDefinition reducedArtifactInfo = new ArtifactDefinition(artifactInfo); + reducedArtifactInfo.setHeatParameters(reducedHeatEnvParams); + Either updateArtifactResult = artifactOperation.updateArifactOnResource(reducedArtifactInfo, componentId, artifactInfo.getUniqueId(), componentType.getNodeType(), inTransaction); + + if (updateArtifactResult.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArtifactResult.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + ArtifactDefinition updatedArtifact = updateArtifactResult.left().value(); + String updatedArtifactId = updatedArtifact.getUniqueId(); + if (!currArtifact.getUniqueId().equals(updatedArtifactId)) { + currArtifact.setUniqueId(updatedArtifactId); + currArtifact.setPayloadUpdateDate(updatedArtifact.getPayloadUpdateDate()); + currArtifact.setCreationDate(updatedArtifact.getCreationDate()); + currArtifact.setLastUpdateDate(updatedArtifact.getLastUpdateDate()); + currArtifact.setEsId(updatedArtifact.getEsId()); + } + currArtifact.setHeatParamsUpdateDate(System.currentTimeMillis()); + + Either, StorageOperationStatus> heatParamsForEnv = ((org.openecomp.sdc.be.model.operations.impl.ArtifactOperation) artifactOperation).getHeatParamsForEnv(currArtifact); + if (heatParamsForEnv.isRight()) { + log.debug("failed to get heat parameters values for heat artifact {}", updatedArtifact.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(heatParamsForEnv.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + List updatedHeatParaetersList = heatParamsForEnv.left().value(); + currArtifact.setHeatParameters(updatedHeatParaetersList); + + Either updateArifactRes = artifactOperation.updateArifactDefinition(currArtifact, true); + if (updateArifactRes.isRight()) { + log.debug("Failed to update artifact on graph - {}", artifactId); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateArifactRes.right().value())); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, ri.getName()); + return Either.right(responseFormat); + } + } + } + + insideEither = Either.left(currArtifact); + resultOp = Either.left(insideEither); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, currArtifact, null, artifactId, responseFormat, componentType, ri.getName()); + return resultOp; + } + + public Either, ResponseFormat> validateUploadParamsFromEnvFile(AuditingActionEnum auditingAction, Component parent, User user, ArtifactDefinition artifactInfo, String artifactId, ComponentTypeEnum componentType, + String riName, List currentHeatEnvParams, List updatedHeatEnvParams, String currArtifactName) { + + if (updatedHeatEnvParams == null || updatedHeatEnvParams.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, artifactInfo.getArtifactName(), currArtifactName); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName); + return Either.right(responseFormat); + } + + for (HeatParameterDefinition uploadedHeatParam : updatedHeatEnvParams) { + String paramName = uploadedHeatParam.getName(); + boolean isExistsInHeat = false; + for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) { + if (paramName.equalsIgnoreCase(currHeatParam.getName())) { + + isExistsInHeat = true; + uploadedHeatParam.setType(currHeatParam.getType()); + uploadedHeatParam.setCurrentValue(uploadedHeatParam.getDefaultValue()); + uploadedHeatParam.setDefaultValue(currHeatParam.getDefaultValue()); + uploadedHeatParam.setUniqueId(currHeatParam.getUniqueId()); + break; + } + } + if (!isExistsInHeat) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISMATCH_HEAT_VS_HEAT_ENV, currArtifactName); + handleAuditing(auditingAction, parent, parent.getUniqueId(), user, artifactInfo, null, artifactId, responseFormat, componentType, riName); + return Either.right(responseFormat); + } + } + return Either.left(updatedHeatEnvParams); + } + + private Either getRIFromComponent(Component component, String riID, String artifactId, AuditingActionEnum auditingAction, User user) { + ResponseFormat responseFormat = null; + List ris = component.getComponentInstances(); + for (ComponentInstance ri : ris) { + if (riID.equals(ri.getUniqueId())) { + return Either.left(ri); + } + } + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, riID); + log.debug("Resource Instance not found, resourceInstanceId {}", riID); + handleAuditing(auditingAction, null, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, null); + return Either.right(responseFormat); + } + + private Either getArtifactFromRI(Component component, ComponentInstance ri, String riID, String artifactId, AuditingActionEnum auditingAction, User user) { + ResponseFormat responseFormat = null; + Map rtifactsMap = ri.getDeploymentArtifacts(); + for (ArtifactDefinition artifact : rtifactsMap.values()) { + if (artifactId.equals(artifact.getUniqueId())) { + return Either.left(artifact); + } + } + responseFormat = componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, riID, component.getUniqueId()); + handleAuditing(auditingAction, component, riID, user, null, null, artifactId, responseFormat, ComponentTypeEnum.RESOURCE_INSTANCE, ri.getName()); + return Either.right(responseFormat); + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + + switch (componentType) { + case Service: + case ResourceInstance: + return serviceOperation; + case Resource: + return resourceOperation; + default: + return null; + } + } + + public ArtifactDefinition extractArtifactDefinition(Either eitherArtifact) { + ArtifactDefinition ret; + if (eitherArtifact.isLeft()) { + ret = eitherArtifact.left().value(); + } else { + ret = eitherArtifact.right().value().getImplementation(); + } + return ret; + } + + /** + * downloads artifact of component by UUIDs + * + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param auditAdditionalParam + * @return + */ + public Either downloadComponentArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String artifactUUID, Map auditAdditionalParam) { + Wrapper errorWrapper = new Wrapper<>(); + Either result; + byte[] downloadedArtifact = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + auditAdditionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName()); + downloadedArtifact = downloadArtifact(component.getDeploymentArtifacts(), artifactUUID, errorWrapper, component.getName()); + } + if (errorWrapper.isEmpty()) { + result = Either.left(downloadedArtifact); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + /** + * downloads an artifact of resource instance of component by UUIDs + * + * @param componentType + * @param componentUuid + * @param resourceName + * @param artifactUUID + * @param auditAdditionalParam + * @return + */ + public Either downloadResourceInstanceArtifactByUUIDs(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, Map auditAdditionalParam) { + Wrapper errorWrapper = new Wrapper<>(); + Either result; + byte[] downloadedArtifact = null; + ComponentInstance resourceInstance = getRelatedComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + if (errorWrapper.isEmpty()) { + auditAdditionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstance.getName()); + downloadedArtifact = downloadArtifact(resourceInstance.getDeploymentArtifacts(), artifactUUID, errorWrapper, resourceInstance.getName()); + } + if (errorWrapper.isEmpty()) { + result = Either.left(downloadedArtifact); + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + /** + * uploads an artifact to a component by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param additionalParams + * @return + */ + public Either uploadArtifactToComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, Map additionalParams) { + Wrapper errorWrapper = new Wrapper<>(); + Either, ResponseFormat> actionResult = null; + Either uploadArtifactResult; + ArtifactDefinition uploadArtifact; + Component component = null; + String componentId = null; + ArtifactOperation operation = ArtifactOperation.Create; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, null, artifactInfo, origMd5, data, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + uploadArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, uploadArtifact); + uploadArtifactResult = Either.left(uploadArtifact); + } else { + uploadArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return uploadArtifactResult; + } + + /** + * upload an artifact to a resource instance by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param additionalParams + * @return + */ + public Either uploadArtifactToRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, + Map additionalParams) { + Wrapper errorWrapper = new Wrapper<>(); + Either uploadArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition uploadArtifact; + Component component = null; + String componentInstanceId; + String componentId; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ImmutablePair componentRiPair = null; + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Create; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, null, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + uploadArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, uploadArtifact); + uploadArtifactResult = Either.left(uploadArtifact); + } else { + uploadArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return uploadArtifactResult; + } + + /** + * updates an artifact on a component by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either updateArtifactOnComponentByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, + Map additionalParams) { + Wrapper errorWrapper = new Wrapper<>(); + Either updateArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition updateArtifact; + Component component = null; + String componentId = null; + String artifactId = null; + ArtifactOperation operation = ArtifactOperation.Update; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentId, componentType); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + updateArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, updateArtifact); + updateArtifactResult = Either.left(updateArtifact); + + } else { + updateArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return updateArtifactResult; + } + + /** + * updates an artifact on a resource instance by UUID + * + * @param data + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either updateArtifactOnRiByUUID(String data, HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, + Map additionalParams) { + + Wrapper errorWrapper = new Wrapper<>(); + Either updateArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition updateArtifact; + Component component = null; + String componentInstanceId = null; + String componentId = null; + String artifactId = null; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ImmutablePair componentRiPair = null; + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentInstanceId, ComponentTypeEnum.RESOURCE_INSTANCE); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Update; + operation.setExternalApi(true); + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, artifactInfo, origMd5, data, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + updateArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, updateArtifact); + updateArtifactResult = Either.left(updateArtifact); + } else { + updateArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return updateArtifactResult; + + } + + /** + * deletes an artifact on a component by UUID + * + * @param request + * @param componentType + * @param componentUuid + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either deleteArtifactOnComponentByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String artifactUUID, Map additionalParams) { + + Wrapper errorWrapper = new Wrapper<>(); + Either deleteArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition deleteArtifact; + Component component = null; + String componentId = null; + String artifactId = null; + ArtifactOperation operation = ArtifactOperation.Delete; + operation.setExternalApi(true); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component != null) { + componentId = component.getUniqueId(); + } else { + componentId = getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(); + } + } + if (errorWrapper.isEmpty()) { + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentId, componentType); + } + if (errorWrapper.isEmpty()) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, getComponentRes.left().value().getMetadataDataDefinition().getName()); + + actionResult = handleArtifactRequest(componentId, userId, componentType, operation, artifactId, null, origMd5, null, null, null, null, null); + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + deleteArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, deleteArtifact); + deleteArtifactResult = Either.left(deleteArtifact); + } else { + deleteArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return deleteArtifactResult; + } + + /** + * deletes an artifact an a resource instance by UUID + * + * @param request + * @param componentType + * @param componentUuid + * @param resourceInstanceName + * @param artifactUUID + * @param additionalParams + * @return + */ + public Either deleteArtifactOnRiByUUID(HttpServletRequest request, ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, String artifactUUID, + Map additionalParams) { + + Wrapper errorWrapper = new Wrapper<>(); + Either deleteArtifactResult; + Either, ResponseFormat> actionResult = null; + ArtifactDefinition deleteArtifact; + Component component = null; + String componentInstanceId = null; + String componentId = null; + String artifactId = null; + String origMd5 = request.getHeader(Constants.MD5_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + ImmutablePair componentRiPair = null; + Either getComponentRes = getComponentOperation(componentType).getLatestComponentMetadataByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + if (errorWrapper.isEmpty() && !getComponentRes.left().value().getMetadataDataDefinition().getState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + component = checkoutParentComponent(componentType, getComponentRes.left().value().getMetadataDataDefinition().getUniqueId(), userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + if (component == null) { + componentRiPair = getRelatedComponentComponentInstance(componentType, componentUuid, resourceInstanceName, errorWrapper); + } else { + componentRiPair = getRelatedComponentComponentInstance(component, resourceInstanceName, errorWrapper); + } + } + if (errorWrapper.isEmpty()) { + componentInstanceId = componentRiPair.getRight().getUniqueId(); + componentId = componentRiPair.getLeft().getUniqueId(); + artifactId = getLatestParentArtifactDataIdByArtifactUUID(artifactUUID, errorWrapper, componentInstanceId, ComponentTypeEnum.RESOURCE_INSTANCE); + } + if (errorWrapper.isEmpty()) { + + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInstanceName); + ArtifactOperation operation = ArtifactOperation.Delete; + operation.setExternalApi(true); + + actionResult = handleArtifactRequest(componentInstanceId, userId, ComponentTypeEnum.RESOURCE_INSTANCE, operation, artifactId, null, origMd5, null, null, null, componentId, ComponentTypeEnum.findParamByType(componentType)); + + if (actionResult.isRight()) { + log.debug("Failed to upload artifact to component instance {} of component with type {} and uuid {}. Status is {}. ", resourceInstanceName, componentType, componentUuid, actionResult.right().value()); + errorWrapper.setInnerElement(actionResult.right().value()); + } + } + if (errorWrapper.isEmpty()) { + deleteArtifact = actionResult.left().value().left().value(); + updateAuditParametersWithArtifactDefinition(additionalParams, deleteArtifact); + deleteArtifactResult = Either.left(deleteArtifact); + } else { + deleteArtifactResult = Either.right(errorWrapper.getInnerElement()); + } + return deleteArtifactResult; + } + + private ComponentInstance getRelatedComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, Wrapper errorWrapper) { + ComponentInstance componentInstance = null; + StorageOperationStatus status; + Either getResourceInstanceRes = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } + } + if (errorWrapper.isEmpty()) { + getResourceInstanceRes = resourceInstanceOperation.getResourceInstanceById(componentInstance.getUniqueId()); + if (getResourceInstanceRes.isRight()) { + status = getResourceInstanceRes.right().value(); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } + } + if (errorWrapper.isEmpty()) { + componentInstance = getResourceInstanceRes.left().value(); + getResourceInstanceRes = resourceInstanceOperation.getFullComponentInstance(componentInstance, componentType.getNodeType()); + if (getResourceInstanceRes.isRight()) { + status = getResourceInstanceRes.right().value(); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } else { + componentInstance = getResourceInstanceRes.left().value(); + } + } + return componentInstance; + } + + private ImmutablePair getRelatedComponentComponentInstance(Component component, String resourceInstanceName, Wrapper errorWrapper) { + + ImmutablePair relatedComponentComponentInstancePair = null; + ComponentInstance componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } else { + relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance); + } + return relatedComponentComponentInstancePair; + } + + private ImmutablePair getRelatedComponentComponentInstance(ComponentTypeEnum componentType, String componentUuid, String resourceInstanceName, Wrapper errorWrapper) { + ComponentInstance componentInstance; + ImmutablePair relatedComponentComponentInstancePair = null; + Component component = getLatestComponentByUuid(componentType, componentUuid, errorWrapper); + if (errorWrapper.isEmpty()) { + componentInstance = component.getComponentInstances().stream().filter(ci -> ci.getNormalizedName().equals(resourceInstanceName)).findAny().get(); + if (componentInstance == null) { + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, resourceInstanceName, "resource instance", component.getComponentType().getValue(), component.getName())); + log.debug("Component instance {} was not found for component {}", resourceInstanceName, component.getName()); + } else { + relatedComponentComponentInstancePair = new ImmutablePair<>(component, componentInstance); + } + } + return relatedComponentComponentInstancePair; + } + + private byte[] downloadArtifact(Map artifacts, String artifactUUID, Wrapper errorWrapper, String componentName) { + + byte[] downloadedArtifact = null; + Either, ResponseFormat> downloadArtifactEither = null; + List deploymentArtifacts = null; + ArtifactDefinition deploymentArtifact = null; + if (artifacts != null && !artifacts.isEmpty()) { + deploymentArtifacts = artifacts.values().stream().filter(art -> art.getArtifactUUID() != null && art.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList()); + } + if (deploymentArtifacts == null || deploymentArtifacts.isEmpty()) { + log.debug("Deployment artifact with uuid {} was not found for component {}", artifactUUID, componentName); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactUUID)); + } + if (errorWrapper.isEmpty()) { + deploymentArtifact = deploymentArtifacts.get(0); + downloadArtifactEither = downloadArtifact(deploymentArtifact); + if (downloadArtifactEither.isRight()) { + log.debug("Failed to download artifact {}. ", deploymentArtifact.getArtifactName()); + errorWrapper.setInnerElement(downloadArtifactEither.right().value()); + } + } + if (errorWrapper.isEmpty()) { + log.trace("Succeeded to download artifact with uniqueId {}", deploymentArtifact.getUniqueId()); + downloadedArtifact = downloadArtifactEither.left().value().getRight(); + } + return downloadedArtifact; + } + + private Component getLatestComponentByUuid(ComponentTypeEnum componentType, String componentUuid, Wrapper errorWrapper) { + Component component = null; + Either getComponentRes = getComponentOperation(componentType).getLatestComponentByUuid(componentType.getNodeType(), componentUuid); + if (getComponentRes.isRight()) { + StorageOperationStatus status = getComponentRes.right().value(); + log.debug("Could not fetch component with type {} and uuid {}. Status is {}. ", componentType, componentUuid, status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(status))); + } else { + component = getComponentRes.left().value(); + } + return component; + } + + private String getLatestParentArtifactDataIdByArtifactUUID(String artifactUUID, Wrapper errorWrapper, String parentId, ComponentTypeEnum componentType) { + String artifactId = null; + ActionStatus actionStatus = ActionStatus.ARTIFACT_NOT_FOUND; + StorageOperationStatus storageStatus; + ArtifactDefinition latestArtifact = null; + List artifacts = null; + NodeTypeEnum parentType; + if (componentType.equals(ComponentTypeEnum.RESOURCE)) { + parentType = NodeTypeEnum.Resource; + } else { + parentType = NodeTypeEnum.Service; + } + Either, StorageOperationStatus> getArtifactsRes = artifactOperation.getArtifacts(parentId, parentType, false); + if (getArtifactsRes.isRight()) { + storageStatus = getArtifactsRes.right().value(); + log.debug("Couldn't fetch artifacts data for parent component {} with uid {}, error: {}", componentType.name(), parentId, storageStatus); + if (!storageStatus.equals(StorageOperationStatus.NOT_FOUND)) { + actionStatus = componentsUtils.convertFromStorageResponse(storageStatus); + } + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + if (errorWrapper.isEmpty()) { + artifacts = getArtifactsRes.left().value().values().stream().filter(a -> a.getArtifactUUID() != null && a.getArtifactUUID().equals(artifactUUID)).collect(Collectors.toList()); + if (artifacts == null || artifacts.isEmpty()) { + log.debug("Couldn't fetch artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType.name(), parentId, actionStatus); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + } + if (errorWrapper.isEmpty()) { + latestArtifact = artifacts.stream().max((a1, a2) -> { + int compareRes = Double.compare(Double.parseDouble(a1.getArtifactVersion()), Double.parseDouble(a2.getArtifactVersion())); + if (compareRes == 0) { + compareRes = Long.compare(a1.getLastUpdateDate() == null ? 0 : a1.getLastUpdateDate(), a2.getLastUpdateDate() == null ? 0 : a2.getLastUpdateDate()); + } + return compareRes; + }).get(); + if (latestArtifact == null) { + log.debug("Couldn't fetch latest artifact with UUID {} data for parent component {} with uid {}, error: {}", artifactUUID, componentType.name(), parentId, actionStatus); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus, artifactUUID)); + } + } + if (errorWrapper.isEmpty()) { + artifactId = latestArtifact.getUniqueId(); + } + return artifactId; + } + + private Component checkoutParentComponent(ComponentTypeEnum componentType, String parentId, String userId, Wrapper errorWrapper) { + + Component component = null; + Either getUserRes = userBusinessLogic.getUser(userId, false); + if (getUserRes.isRight()) { + log.debug("Could not fetch User of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId, getUserRes.right().value()); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(getUserRes.right().value())); + } + if (errorWrapper.isEmpty()) { + User modifier = getUserRes.left().value(); + LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction("External API checkout", LifecycleChanceActionEnum.UPDATE_FROM_EXTERNAL_API); + Either checkoutRes = lifecycleBusinessLogic.changeComponentState(componentType, parentId, modifier, LifeCycleTransitionEnum.CHECKOUT, changeInfo, false, true); + if (checkoutRes.isRight()) { + log.debug("Could not change state of component {} with uid {} to checked out. Status is {}. ", componentType.getNodeType(), parentId, checkoutRes.right().value().getStatus()); + errorWrapper.setInnerElement(checkoutRes.right().value()); + } else { + component = checkoutRes.left().value(); + } + } + return component; + } + + private void updateAuditParametersWithArtifactDefinition(Map additionalParams, ArtifactDefinition artifact) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_CURR_ARTIFACT_UUID, artifact.getArtifactUUID()); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_ARTIFACT_DATA, buildAuditingArtifactData(artifact)); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, artifact.getUpdaterFullName()); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java new file mode 100644 index 0000000000..15fe86da33 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/AttributeBusinessLogic.java @@ -0,0 +1,295 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Optional; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.AttributeData; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +/** + * This class holds the business logic relevant for attributes manipulation. + * + * @author mshitrit + * + */ +@Component("attributeBusinessLogic") +public class AttributeBusinessLogic extends BaseBusinessLogic { + + private static final String CREATE_ATTRIBUTE = "CreateAttribute"; + private static final String UPDATE_ATTRIBUTE = "UpdateAttribute"; + private static final String DELETE_ATTRIBUTE = "DeleteAttribute"; + + private static Logger log = LoggerFactory.getLogger(AttributeBusinessLogic.class.getName()); + + /** + * Created attribute on the resource with resourceId + * + * @param resourceId + * @param newAttributeDef + * @param userId + * @return AttributeDefinition if created successfully Or ResponseFormat + */ + public Either createAttribute(String resourceId, AttributeDefinition newAttributeDef, String userId) { + Either result = null; + Either resp = validateUserExists(userId, "create Attribute", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (lockResult != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_ATTRIBUTE, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + log.info("Failed to lock component {}. Error - {}", resourceId, lockResult); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + try { + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = status.left().value(); + + // verify that resource is checked-out and the user is the last updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + // verify attribute does not exist in resource + if (isAttributeExist(resource.getAttributes(), resourceId, newAttributeDef.getName())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ATTRIBUTE_ALREADY_EXIST, newAttributeDef.getName())); + } + Either, ResponseFormat> eitherAllDataTypes = getAllDataTypes(applicationDataTypeCache); + if (eitherAllDataTypes.isRight()) { + return Either.right(eitherAllDataTypes.right().value()); + } + // validate property default values + Either defaultValuesValidation = validatePropertyDefaultValue(newAttributeDef, eitherAllDataTypes.left().value()); + if (defaultValuesValidation.isRight()) { + return Either.right(defaultValuesValidation.right().value()); + } + + handleDefaultValue(newAttributeDef, eitherAllDataTypes.left().value()); + + // add the new attribute to resource on graph + // need to get StorageOpaerationStatus and convert to ActionStatus from + // componentsUtils + Either either = attributeOperation.addAttribute(newAttributeDef, resourceId); + if (either.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName())); + return result; + } + + result = Either.left(attributeOperation.convertAttributeDataToAttributeDefinition(either.left().value(), newAttributeDef.getName(), resourceId)); + return result; + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + + } + + private boolean isAttributeExist(List attributes, String resourceUid, String propertyName) { + boolean isExist = false; + if (attributes != null) { + isExist = attributes.stream().filter(p -> Objects.equals(p.getName(), propertyName) && Objects.equals(p.getParentUniqueId(), resourceUid)).findAny().isPresent(); + } + return isExist; + + } + + /** + * @param resourceId + * @param attributeId + * @param userId + * @return + */ + public Either getAttribute(String resourceId, String attributeId, String userId) { + + Either resp = validateUserExists(userId, "get Attribute", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = status.left().value(); + + List attributes = resource.getAttributes(); + if (attributes == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ATTRIBUTE_NOT_FOUND, "")); + } else { + Either result; + // verify attribute exist in resource + Optional optionalAtt = attributes.stream().filter(att -> att.getUniqueId().equals(attributeId) && att.getParentUniqueId().equals(resourceId)).findAny(); + + if (optionalAtt.isPresent()) { + result = Either.left(optionalAtt.get()); + } else { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.ATTRIBUTE_NOT_FOUND, "")); + } + return result; + } + + } + + /** + * Updates Attribute on resource + * + * @param resourceId + * @param attributeId + * @param newAttDef + * @param userId + * @return + */ + public Either updateAttribute(String resourceId, String attributeId, AttributeDefinition newAttDef, String userId) { + Either result = null; + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (lockResult != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(UPDATE_ATTRIBUTE, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + try { + // Get the resource from DB + Either eitherResource = getResource(resourceId); + if (eitherResource.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = eitherResource.left().value(); + + // verify that resource is checked-out and the user is the last updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + // verify attribute exist in resource + Either eitherAttribute = getAttribute(resourceId, attributeId, userId); + if (eitherAttribute.isRight()) { + return Either.right(eitherAttribute.right().value()); + } + Either, ResponseFormat> eitherAllDataTypes = getAllDataTypes(applicationDataTypeCache); + if (eitherAllDataTypes.isRight()) { + return Either.right(eitherAllDataTypes.right().value()); + } + + // validate attribute default values + Either defaultValuesValidation = validatePropertyDefaultValue(newAttDef, eitherAllDataTypes.left().value()); + if (defaultValuesValidation.isRight()) { + return Either.right(defaultValuesValidation.right().value()); + } + // add the new property to resource on graph + Either eitherAttUpdate = attributeOperation.updateAttribute(attributeId, newAttDef, eitherAllDataTypes.left().value()); + + if (eitherAttUpdate.isRight()) { + log.debug("Problem while updating attribute with id {}. Reason - {}", attributeId, eitherAttUpdate.right().value()); + result = Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherAttUpdate.right().value()), resource.getName())); + return result; + } + + result = Either.left(attributeOperation.convertAttributeDataToAttributeDefinition(eitherAttUpdate.left().value(), newAttDef.getName(), resourceId)); + return result; + } finally { + commitOrRollback(result); + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + } + + /** + * Deletes Attribute on resource + * + * @param resourceId + * @param attributeId + * @param userId + * @return + */ + public Either deleteAttribute(String resourceId, String attributeId, String userId) { + Either result = null; + Either resp = validateUserExists(userId, "delete Attribute", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (lockResult != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(DELETE_ATTRIBUTE, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + + try { + // Get the resource from DB + Either eitherResource = getResource(resourceId); + if (eitherResource.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = eitherResource.left().value(); + + // verify that resource is checked-out and the user is the last updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + // verify attribute exist in resource + Either eitherAttributeExist = getAttribute(resourceId, attributeId, userId); + if (eitherAttributeExist.isRight()) { + return Either.right(eitherAttributeExist.right().value()); + } + String attributeName = eitherAttributeExist.left().value().getName(); + + // delete attribute of resource from graph + Either eitherAttributeDelete = attributeOperation.deleteAttribute(attributeId); + if (eitherAttributeDelete.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(eitherAttributeDelete.right().value()), resource.getName())); + return result; + } + result = Either.left(attributeOperation.convertAttributeDataToAttributeDefinition(eitherAttributeDelete.left().value(), attributeName, resourceId)); + return result; + } finally { + commitOrRollback(result); + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java new file mode 100644 index 0000000000..93ddff38d5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/BaseBusinessLogic.java @@ -0,0 +1,571 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.IComplexDefaultValue; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.IAttributeOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public abstract class BaseBusinessLogic { + + @Autowired + protected ComponentsUtils componentsUtils; + + @Autowired + protected IUserBusinessLogic userAdmin; + + @Autowired + protected ResourceOperation resourceOperation; + + @Autowired + protected IGraphLockOperation graphLockOperation; + + @Autowired + protected ServiceOperation serviceOperation; + + @Autowired + protected ProductOperation productOperation; + + @Autowired + protected TitanGenericDao titanGenericDao; + + @Autowired + protected IElementOperation elementDao; + + @Autowired + protected IGroupOperation groupOperation; + + @Autowired + protected IGroupTypeOperation groupTypeOperation; + + @Autowired + protected IArtifactOperation artifactOperation; + + @Autowired + protected IAttributeOperation attributeOperation; + + @Autowired + protected IPropertyOperation propertyOperation; + + @Autowired + protected ApplicationDataTypeCache applicationDataTypeCache; + + public void setUserAdmin(UserBusinessLogic userAdmin) { + this.userAdmin = userAdmin; + } + + public void setComponentsUtils(ComponentsUtils componentsUtils) { + this.componentsUtils = componentsUtils; + } + + public void setGraphLockOperation(IGraphLockOperation graphLockOperation) { + this.graphLockOperation = graphLockOperation; + } + + private static Logger log = LoggerFactory.getLogger(BaseBusinessLogic.class.getName()); + + protected Either validateUserNotEmpty(User user, String ecompErrorContext) { + String userId = user.getUserId(); + + if (StringUtils.isEmpty(userId)) { + // user.setUserId("UNKNOWN"); + log.debug("User header is missing "); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, ecompErrorContext, user.getUserId()); + BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, user.getUserId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + return Either.right(responseFormat); + } + return Either.left(user); + } + + protected Either validateUserExists(User user, String ecompErrorContext, boolean inTransaction) { + return validateUserExists(user.getUserId(), ecompErrorContext, inTransaction); + } + + protected void validateUserExist(String userId, String ecompErrorContext, Wrapper errorWrapper) { + Either resp = validateUserExists(userId, ecompErrorContext, false); + if (resp.isRight()) { + errorWrapper.setInnerElement(resp.right().value()); + } + } + + public Either validateUserExistsActionStatus(String userId, String ecompErrorContext) { + Either eitherCreator = userAdmin.getUser(userId, false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + if (eitherCreator.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + log.debug("validateUserExists - not authorized user, userId {}", userId); + Either.right(ActionStatus.RESTRICTED_OPERATION); + } else { + log.debug("validateUserExists - failed to authorize user, userId {}", userId); + } + log.debug("User is not listed. userId {}", userId); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, ecompErrorContext, userId); + return Either.right(eitherCreator.right().value()); + } + return Either.left(eitherCreator.left().value()); + } + + public Either validateUserExists(String userId, String ecompErrorContext, boolean inTransaction) { + Either eitherCreator = userAdmin.getUser(userId, inTransaction); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + ResponseFormat responseFormat; + if (eitherCreator.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + if (log.isDebugEnabled()) + log.debug("validateUserExists - not authorized user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } else { + if (log.isDebugEnabled()) + log.debug("validateUserExists - failed to authorize user, userId {}", userId); + responseFormat = componentsUtils.getResponseFormat(eitherCreator.right().value()); + } + if (log.isDebugEnabled()) + log.debug("User is not listed. userId {}", userId); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, ecompErrorContext, userId); + BeEcompErrorManager.getInstance().logBeUserMissingError(ecompErrorContext, userId); + return Either.right(responseFormat); + } + return Either.left(eitherCreator.left().value()); + } + + protected Either validateUserRole(User user, List roles) { + Role userRole = Role.valueOf(user.getRole()); + if (roles != null) { + if (!roles.contains(userRole)) { + if (log.isDebugEnabled()) + log.debug("user is not in appropriate role to perform action"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + return Either.right(responseFormat); + } + return Either.left(Boolean.TRUE); + } + return Either.left(Boolean.FALSE); + } + + protected Either lockComponent(Component component, String ecompErrorContext) { + return lockComponent(component.getUniqueId(), component, ecompErrorContext); + } + + protected Either lockComponent(String componentId, Component component, String ecompErrorContext) { + ComponentTypeEnum componentType = component.getComponentType(); + NodeTypeEnum nodeType = componentType.getNodeType(); + StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(componentId, nodeType); + + if (lockResourceStatus.equals(StorageOperationStatus.OK)) { + return Either.left(true); + } else { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), componentId); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName()); + log.debug("Failed to lock component {} error - {}", componentId, actionStatus); + return Either.right(responseFormat); + } + } + + protected void unlockComponent(Either either, Component component, boolean inTransaction) { + ComponentTypeEnum componentType = component.getComponentType(); + NodeTypeEnum nodeType = componentType.getNodeType(); + if (false == inTransaction) { + if (either == null || either.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + // unlock resource + graphLockOperation.unlockComponent(component.getUniqueId(), nodeType); + } + + protected void unlockComponent(Either either, Component component) { + unlockComponent(either, component, false); + } + + protected Either validateJsonBody(T bodyObject, Class clazz) { + if (bodyObject == null) { + log.debug("Invalid JSON received for object of type {}", clazz.getSimpleName()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } else { + return Either.left(true); + } + } + + protected Either validateComponentType(String componentType) { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum == null) { + log.debug("Invalid component type {}", componentType); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, componentType)); + } else { + return Either.left(componentTypeEnum); + } + } + + protected Either validateComponentExists(String componentId, ComponentTypeEnum componentType, boolean inTransaction, boolean createNewTransaction) { + ComponentOperation componentOperation = getComponentOperation(componentType); + Either componentFound = null; + // if(createNewTransaction){ + // componentFound = componentOperation.getComponent_tx(componentId, + // inTransaction); + // } + // else{ + componentFound = componentOperation.getComponent(componentId, inTransaction); + // } + + if (componentFound.isRight()) { + StorageOperationStatus storageOperationStatus = componentFound.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING); + log.debug("Component with id {} was not found", componentId); + return Either.right(responseFormat); + } + return Either.left(componentFound.left().value()); + } + + protected Either validateComponentExists(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView, String userId, + AuditingActionEnum auditingAction, User user) { + + ComponentOperation componentOperation = getComponentOperation(componentType); + + if (componentOperation == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + log.debug("addGroup - not supported component type {}", componentType); + // handleAuditing(auditingAction, null, componentId, user, null, + // null, artifactId, responseFormat, componentType, null); + return Either.right(responseFormat); + } + Either componentResult = componentOperation.getComponent(componentId, componentParametersView, true); + + if (componentResult.isRight()) { + ActionStatus status = (componentType.equals(ComponentTypeEnum.RESOURCE)) ? ActionStatus.RESOURCE_NOT_FOUND : ActionStatus.SERVICE_NOT_FOUND; + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, componentId); + + log.debug("Service not found, serviceId {}", componentId); + // ComponentTypeEnum componentForAudit = + // (componentType.equals(ComponentTypeEnum.RESOURCE)) ? + // ComponentTypeEnum.RESOURCE : ComponentTypeEnum.SERVICE; + // handleAuditing(auditingAction, null, componentId, user, null, + // null, artifactId, responseFormat, componentForAudit, null); + return Either.right(responseFormat); + } + return Either.left(componentResult.left().value()); + } + + public Either validateCanWorkOnComponent(Component component, String userId) { + Either canWork = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + if (component.getLifecycleState() != LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + log.debug("Component {} is not checked-out", component.getName()); + return canWork; + } + + // verify user id is not null + if (userId == null) { + log.debug("Current user userId is null"); + return canWork; + } + + // verify component last update user is the current user + String lastUpdaterUserId = component.getLastUpdaterUserId(); + if (!userId.equals(lastUpdaterUserId)) { + log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", lastUpdaterUserId, userId); + return canWork; + } + + // verify resource is not deleted + if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) { + log.debug("Component {} is marked as deleted", component.getUniqueId()); + return canWork; + } + + return Either.left(true); + } + + public ComponentOperation getComponentOperation(ComponentTypeEnum componentTypeEnum) { + if (ComponentTypeEnum.SERVICE == componentTypeEnum) { + return serviceOperation; + } else if (ComponentTypeEnum.RESOURCE == componentTypeEnum) { + return resourceOperation; + } else if (ComponentTypeEnum.PRODUCT == componentTypeEnum) { + return productOperation; + } + return null; + } + + public IComponentOperation getIComponentOperation(ComponentTypeEnum componentTypeEnum) { + + switch (componentTypeEnum) { + case SERVICE: + return serviceOperation; + case RESOURCE: + return resourceOperation; + case PRODUCT: + return productOperation; + default: + break; + } + + return null; + } + + public ComponentOperation getComponentOperationByParentComponentType(ComponentTypeEnum parentComponentType) { + switch (parentComponentType) { + case SERVICE: + return resourceOperation; + case RESOURCE: + return resourceOperation; + case PRODUCT: + return serviceOperation; + default: + break; + } + return null; + } + + public ComponentTypeEnum getComponentTypeByParentComponentType(ComponentTypeEnum parentComponentType) { + switch (parentComponentType) { + case SERVICE: + return ComponentTypeEnum.RESOURCE; + case RESOURCE: + return ComponentTypeEnum.RESOURCE; + case PRODUCT: + return ComponentTypeEnum.SERVICE; + default: + break; + } + return null; + } + + // For UT + public void setTitanGenericDao(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + protected Either, ResponseFormat> getAllDataTypes(ApplicationDataTypeCache applicationDataTypeCache) { + Either, TitanOperationStatus> allDataTypes = applicationDataTypeCache.getAll(); + if (allDataTypes.isRight()) { + TitanOperationStatus operationStatus = allDataTypes.right().value(); + if (operationStatus == TitanOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInternalDataError("FetchDataTypes", "Data types are not loaded", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.DATA_TYPE_CANNOT_BE_EMPTY)); + } else { + BeEcompErrorManager.getInstance().logInternalFlowError("FetchDataTypes", "Failed to fetch data types", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + return Either.left(allDataTypes.left().value()); + } + + protected Either validatePropertyDefaultValue(IComplexDefaultValue property, Map dataTypes) { + log.debug("validate property"); + String type = null; + String innerType = null; + if (!propertyOperation.isPropertyTypeValid(property)) { + log.info("Invalid type for property"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName()); + return Either.right(responseFormat); + } + type = property.getType(); + if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) { + ImmutablePair propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, dataTypes); + innerType = propertyInnerTypeValid.getLeft(); + if (!propertyInnerTypeValid.getRight().booleanValue()) { + log.info("Invalid inner type for property"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName()); + return Either.right(responseFormat); + } + } + if (!propertyOperation.isPropertyDefaultValueValid(property, dataTypes)) { + log.info("Invalid default value for property"); + ResponseFormat responseFormat; + if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType, property.getDefaultValue()); + } else { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue()); + } + return Either.right(responseFormat); + + } + return Either.left(true); + } + + protected Either getResource(final String resourceId) { + + log.debug("Get resource with id {}", resourceId); + Either status = resourceOperation.getResource(resourceId); + if (status.isRight()) { + log.debug("Resource with id {} was not found", resourceId); + return Either.right(status.right().value()); + } + + Resource resource = status.left().value(); + if (resource == null) { + BeEcompErrorManager.getInstance().logBeComponentMissingError("Property Business Logic", ComponentTypeEnum.RESOURCE.getValue(), resourceId); + log.debug("General Error while get resource with id {}", resourceId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(resource); + } + + protected void handleDefaultValue(IComplexDefaultValue newAttributeDef, Map dataTypes) { + // convert property + ToscaPropertyType type = ToscaPropertyType.isValidType(newAttributeDef.getType()); + PropertyValueConverter converter = type.getConverter(); + // get inner type + String innerType = null; + + if (newAttributeDef != null) { + SchemaDefinition schema = newAttributeDef.getSchema(); + if (schema != null) { + PropertyDataDefinition prop = schema.getProperty(); + if (schema.getProperty() != null) { + innerType = prop.getType(); + } + } + String convertedValue = null; + if (newAttributeDef.getDefaultValue() != null) { + convertedValue = converter.convert(newAttributeDef.getDefaultValue(), innerType, dataTypes); + newAttributeDef.setDefaultValue(convertedValue); + } + } + } + + protected void validateComponentTypeEnum(ComponentTypeEnum componentTypeEnum, String errorContext, Wrapper errorWrapper) { + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError(errorContext, "invalid component type", ErrorSeverity.INFO); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + } + + } + + protected void validateCanWorkOnComponent(String componentId, ComponentTypeEnum componentTypeEnum, String userId, Wrapper errorWrapper) { + IComponentOperation componentOperation = getIComponentOperation(componentTypeEnum); + if (!ComponentValidationUtils.canWorkOnComponent(componentId, componentOperation, userId)) { + log.info("Restricted operation for user {} on {} {}", userId, componentTypeEnum.getValue(), componentId); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + } + + protected void validateComponentLock(String componentId, ComponentTypeEnum componentTypeEnum, Wrapper errorWrapper) { + StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); + if (lockStatus != StorageOperationStatus.OK) { + log.debug("Failed to lock {} {}", componentTypeEnum.getValue(), componentId); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus))); + } + + } + + protected ToscaPropertyType getType(String propertyType) { + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + + return type; + + } + + protected void commitOrRollback(Either result) { + if (result == null || result.isRight()) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + } + + protected Either lockComponentByName(String name, Component component, String ecompErrorContext) { + ComponentTypeEnum componentType = component.getComponentType(); + NodeTypeEnum nodeType = componentType.getNodeType(); + StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponentByName(name, nodeType); + + if (lockResourceStatus.equals(StorageOperationStatus.OK)) { + return Either.left(true); + } else { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(ecompErrorContext, nodeType.getName(), name); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(lockResourceStatus, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, component.getName()); + log.debug("Failed to lock component {} error - {}", name, actionStatus); + return Either.right(responseFormat); + } + } + + protected Either validateComponentExistsByFilter(String componentId, ComponentTypeEnum componentType, ComponentParametersView componentParametersView, boolean inTransaction) { + ComponentOperation componentOperation = getComponentOperation(componentType); + Either componentFound = null; + componentFound = componentOperation.getComponent(componentId, componentParametersView, inTransaction); + + if (componentFound.isRight()) { + StorageOperationStatus storageOperationStatus = componentFound.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING); + log.debug("Component with id {} was not found", componentId); + return Either.right(responseFormat); + } + return Either.left(componentFound.left().value()); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManager.java new file mode 100644 index 0000000000..5cf42cedd6 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CapabilityTypeImportManager.java @@ -0,0 +1,123 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("capabilityTypeImportManager") +public class CapabilityTypeImportManager { + + private static Logger log = LoggerFactory.getLogger(CapabilityTypeImportManager.class.getName()); + @Resource + private CapabilityTypeOperation capabilityTypeOperation; + @Resource + private ComponentsUtils componentsUtils; + @Resource + private CommonImportManager commonImportManager; + + public Either, ResponseFormat> createCapabilityTypes(String capabilityYml) { + Either, ActionStatus> capabilityTypes = createCapabilityTypesFromYml(capabilityYml); + if (capabilityTypes.isRight()) { + ActionStatus status = capabilityTypes.right().value(); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByCapabilityType(status, null); + return Either.right(responseFormat); + } + return createCapabilityTypesByDao(capabilityTypes.left().value()); + + } + + private Either, ActionStatus> createCapabilityTypesFromYml(String capabilityYml) { + return commonImportManager.createElementTypesFromYml(capabilityYml, (capTypeName, capTypeJsonData) -> createCapabilityType(capTypeName, capTypeJsonData)); + + } + + private Either, ResponseFormat> createCapabilityTypesByDao(List capabilityTypesToCreate) { + List createdCapabilities = new ArrayList<>(); + Either, ResponseFormat> eitherResult = Either.left(createdCapabilities); + Iterator capTypeItr = capabilityTypesToCreate.iterator(); + boolean stopDao = false; + while (capTypeItr.hasNext() && !stopDao) { + CapabilityTypeDefinition capabilityType = capTypeItr.next(); + + log.info("send capabilityType {} to dao for create", capabilityType.getType()); + Either dataModelResponse = capabilityTypeOperation.addCapabilityType(capabilityType); + if (dataModelResponse.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedAddingCapabilityTypeError, "Create CapabilityTypes"); + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("Create CapabilityTypes", "capability type"); + log.debug("failed to create capabilityType: {}", capabilityType.getType()); + if (dataModelResponse.right().value() != StorageOperationStatus.SCHEMA_VIOLATION) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByCapabilityType(componentsUtils.convertFromStorageResponseForCapabilityType(dataModelResponse.right().value()), capabilityType); + eitherResult = Either.right(responseFormat); + stopDao = true; + } + + } else { + createdCapabilities.add(capabilityType); + } + if (!capTypeItr.hasNext()) { + log.info("capabilityTypes were created successfully!!!"); + } + + } + + return eitherResult; + + } + + private CapabilityTypeDefinition createCapabilityType(String capabilityTypeName, Map toscaJson) { + CapabilityTypeDefinition capabilityType = new CapabilityTypeDefinition(); + + capabilityType.setType(capabilityTypeName); + + // Description + final Consumer descriptionSetter = description -> capabilityType.setDescription(description); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DESCRIPTION.getElementName(), descriptionSetter); + // Derived From + final Consumer derivedFromSetter = derivedFrom -> capabilityType.setDerivedFrom(derivedFrom); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DERIVED_FROM.getElementName(), derivedFromSetter); + // Properties + commonImportManager.setPropertiesMap(toscaJson, (values) -> capabilityType.setProperties(values)); + + return capabilityType; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java new file mode 100644 index 0000000000..26ea80ac4b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CategoriesImportManager.java @@ -0,0 +1,274 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; +import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.yaml.snakeyaml.Yaml; + +import fj.data.Either; + +@Component("categoriesImportManager") +public class CategoriesImportManager { + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + private static Logger log = LoggerFactory.getLogger(CategoriesImportManager.class.getName()); + + public Either>, ResponseFormat> createCategories(String categoriesTypesYml) { + + Map> allCategories = createCategoriesFromYml(categoriesTypesYml); + return createCategoriesByDao(allCategories); + } + + private Either>, ResponseFormat> createCategoriesByDao(Map> allCategories) { + Map> result = new HashMap<>(); + log.debug("createCategoriesByDao: starting to create Categories."); + for (Map.Entry> entry : allCategories.entrySet()) { + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(entry.getKey()); + NodeTypeEnum nodeTypeCategory = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentType, CategoryTypeEnum.CATEGORY); + NodeTypeEnum nodeTypeSubCategory = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentType, CategoryTypeEnum.SUBCATEGORY); + NodeTypeEnum nodeTypeGroup = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentType, CategoryTypeEnum.GROUPING); + if (log.isDebugEnabled()) { + log.debug("createCategoriesByDao: creating componentType:{} nodeTypeCategory:{} nodeTypeSubCategory:{} nodeTypeGroup:{}", componentType, nodeTypeCategory, nodeTypeSubCategory, nodeTypeGroup); + } + List newCategoriesvalue = new ArrayList<>(); + for (CategoryDefinition category : entry.getValue()) { + + Either createdCategoryRes = createCategorieDeo(entry, category, nodeTypeCategory); + if (createdCategoryRes.isRight()) { + return Either.right(createdCategoryRes.right().value()); + } + + CategoryDefinition newcategory = createdCategoryRes.left().value(); + String categoryId = newcategory.getUniqueId(); + log.debug("createCategoriesByDao: create category was successful {}", newcategory); + List newsubcategories = new ArrayList<>(); + List subcategories = category.getSubcategories(); + if (subcategories != null) { + for (SubCategoryDefinition subcategory : subcategories) { + Either createdSubCategory = createSubCategorieDeo(entry, newcategory, subcategory, nodeTypeSubCategory); + if (createdSubCategory.isRight()) { + return Either.right(createdCategoryRes.right().value()); + } + SubCategoryDefinition newsubcategory = createdSubCategory.left().value(); + List groupings = subcategory.getGroupings(); + if (groupings != null) { + List newgroupings = new ArrayList<>(); + for (GroupingDefinition grouping : groupings) { + Either createdGrouping = createGroupingDeo(entry, grouping, subcategory, category, nodeTypeGroup); + if (createdGrouping.isRight()) { + return Either.right(createdCategoryRes.right().value()); + } + newgroupings.add(createdGrouping.left().value()); + } + newsubcategory.setGroupings(newgroupings); + } + newsubcategories.add(newsubcategory); + } + newcategory.setSubcategories(newsubcategories); + } + newCategoriesvalue.add(newcategory); + } + result.put(entry.getKey(), newCategoriesvalue); + } + return Either.left(result); + } + + private Either createGroupingDeo(Map.Entry> entry, GroupingDefinition grouping, SubCategoryDefinition subcategory, CategoryDefinition category, NodeTypeEnum nodeTypeGroup) { + + log.debug("createGroupingDeo: creating grouping {}", grouping); + Either createdGrouping = elementOperation.createGrouping(subcategory.getUniqueId(), grouping, nodeTypeGroup); + if (createdGrouping.isRight()) { + if (ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY.equals(createdGrouping.right().value())) { + log.debug(" create grouping for {}. group {} already exists", entry.getKey(), grouping.getName()); + String groupingId = UniqueIdBuilder.buildGroupingUid(grouping.getUniqueId(), grouping.getNormalizedName()); + createdGrouping = elementOperation.getGroupingUniqueForType(nodeTypeGroup, groupingId); + if (createdGrouping.isRight()) { + log.debug("failed to get grouping that exists groupingId: {}, type: {}", groupingId, nodeTypeGroup); + return Either.right(componentsUtils.getResponseFormat(createdGrouping.right().value())); + } + } + log.debug("Failed to create groupingcategory for {}, category {}, subcategory {}, grouping {}, error {}", entry.getKey(), category.getName(), subcategory.getName(), (grouping != null ? grouping.getName() : null), + (createdGrouping != null && createdGrouping.right() != null ? createdGrouping.right().value() : null)); + return Either.right(componentsUtils.getResponseFormat(createdGrouping.right().value())); + } else { + log.debug("createGroupingDeo: create Grouping was successful {}", createdGrouping.left().value()); + } + return Either.left(createdGrouping.left().value()); + + } + + private Either createSubCategorieDeo(Map.Entry> entry, CategoryDefinition newcategory, SubCategoryDefinition subcategory, NodeTypeEnum nodeTypeSubCategory) { + log.debug("createSubCategorieDeo: creating subcategory {}", subcategory); + Either createdSubCategory = elementOperation.createSubCategory(newcategory.getUniqueId(), subcategory, nodeTypeSubCategory); + if (createdSubCategory.isRight()) { + if (ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY.equals(createdSubCategory.right().value())) { + log.debug(" create subcategory for {} category {}, alreay exists retrieving", entry.getKey(), newcategory.getName(), subcategory.getName()); + String subCategoryId = UniqueIdBuilder.buildSubCategoryUid(newcategory.getUniqueId(), subcategory.getNormalizedName()); + createdSubCategory = elementOperation.getSubCategory(nodeTypeSubCategory, subCategoryId); + if (createdSubCategory.isRight()) { + log.debug("failed to get sub category that exists subCategoryId: {}, type: {}", subCategoryId, nodeTypeSubCategory); + return Either.right(componentsUtils.getResponseFormat(createdSubCategory.right().value())); + } + } else { + log.debug("Failed to create subcategory for {} category {}, error {}", entry.getKey(), newcategory.getName(), subcategory.getName(), createdSubCategory.right().value()); + return Either.right(componentsUtils.getResponseFormat(createdSubCategory.right().value())); + } + } else { + log.debug("createSubCategorieDeo: create subcategory was successful {}", createdSubCategory.left().value()); + } + return Either.left(createdSubCategory.left().value()); + } + + private Either createCategorieDeo(Map.Entry> entry, CategoryDefinition category, NodeTypeEnum nodeTypeCategory) { + log.debug("createCategorieDeo: creating category {}", category); + Either createdCategory = elementOperation.createCategory(category, nodeTypeCategory); + if (createdCategory.isRight()) { + log.debug("Failed to create category for {}, error {}", entry.getKey(), category.getName(), createdCategory.right().value()); + if (!ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS.equals(createdCategory.right().value())) { + return Either.right(componentsUtils.getResponseFormat(createdCategory.right().value())); + } else { + log.debug("createCategorieDeo: category exists {} retriving.", category); + String categoryId = UniqueIdBuilder.buildCategoryUid(category.getNormalizedName(), nodeTypeCategory); + createdCategory = elementOperation.getCategory(nodeTypeCategory, categoryId); + if (createdCategory.isRight()) { + log.debug("failed to get category that exists categoryId: {}, type: {}", categoryId, nodeTypeCategory); + return Either.right(componentsUtils.getResponseFormat(createdCategory.right().value())); + } + } + } else { + log.debug("createCategorieDeo: create category was successful {}", createdCategory.left().value()); + } + return Either.left(createdCategory.left().value()); + } + + private Map> createCategoriesFromYml(String categoriesTypesYml) { + Map toscaJson = (Map) new Yaml().load(categoriesTypesYml); + Map> allCategories = new HashMap<>(); + + Iterator> categoryEntryItr = toscaJson.entrySet().iterator(); + while (categoryEntryItr.hasNext()) { + Entry categoryTypeEntry = categoryEntryItr.next(); + String categoryType = categoryTypeEntry.getKey(); + List categoriesPerType = null; + Map categoryPerType = null; + switch (categoryType) { + case ComponentTypeEnum.SERVICE_PARAM_NAME: + categoryPerType = (Map) categoryTypeEntry.getValue(); + categoriesPerType = createServiceCategories(categoryPerType); + break; + case ComponentTypeEnum.RESOURCE_PARAM_NAME: + categoryPerType = (Map) categoryTypeEntry.getValue(); + categoriesPerType = createResourceCategories(categoryPerType); + break; + case ComponentTypeEnum.PRODUCT_PARAM_NAME: + // TODO + break; + default: + log.debug("Not supported category type - {}", categoryType); + break; + } + if (categoriesPerType != null) { + allCategories.put(categoryType, categoriesPerType); + } + } + return allCategories; + } + + private List createServiceCategories(Map categories) { + List categroiesDef = new ArrayList<>(); + String catName = null; + List icons = null; + for (Entry entry : categories.entrySet()) { + CategoryDefinition catDef = new CategoryDefinition(); + Map category = (Map) entry.getValue(); + catName = (String) category.get("name"); + catDef.setName(catName); + icons = (List) category.get("icons"); + catDef.setIcons(icons); + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(catName); + catDef.setNormalizedName(normalizedName); + categroiesDef.add(catDef); + } + + return categroiesDef; + } + + private List createResourceCategories(Map categoryPerType) { + List categroiesDef = new ArrayList<>(); + for (Map.Entry entry : categoryPerType.entrySet()) { + Map category = (Map) entry.getValue(); + CategoryDefinition catDef = new CategoryDefinition(); + String catName = (String) category.get("name"); + catDef.setName(catName); + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(catName); + catDef.setNormalizedName(normalizedName); + Map subcategories = (Map) category.get("subcategories"); + List subcateDef = new ArrayList<>(); + for (Entry subcategory : subcategories.entrySet()) { + Map subcategoryInfo = (Map) subcategory.getValue(); + SubCategoryDefinition subDef = new SubCategoryDefinition(); + String subcategoryName = (String) subcategoryInfo.get("name"); + subDef.setName(subcategoryName); + List subcategoryIcons = (List) subcategoryInfo.get("icons"); + subDef.setIcons(subcategoryIcons); + normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subcategoryName); + subDef.setNormalizedName(normalizedName); + subcateDef.add(subDef); + } + + catDef.setSubcategories(subcateDef); + categroiesDef.add(catDef); + } + return categroiesDef; + } + + public static void setLog(Logger log) { + CategoriesImportManager.log = log; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java new file mode 100644 index 0000000000..9b99b665f7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CommonImportManager.java @@ -0,0 +1,309 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.BiFunction; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import jersey.repackaged.com.google.common.base.Function; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.yaml.snakeyaml.Yaml; + +import fj.data.Either; + +@Component("commonImportManager") +public class CommonImportManager { + + private static Logger log = LoggerFactory.getLogger(CommonImportManager.class.getName()); + + @Resource + private ComponentsUtils componentsUtils; + @Resource + private PropertyOperation propertyOperation; + + protected void setProperties(Map toscaJson, Consumer> consumer) { + consumer.accept(getProperties(toscaJson)); + } + + private List getProperties(Map toscaJson) { + List values = null; + Either, ResultStatusEnum> properties = ImportUtils.getProperties(toscaJson); + + if (properties.isLeft()) { + values = new ArrayList<>(); + Map propertiesMap = properties.left().value(); + if (propertiesMap != null && propertiesMap.isEmpty() == false) { + + for (Entry entry : propertiesMap.entrySet()) { + String propName = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + PropertyDefinition newPropertyDefinition = new PropertyDefinition(propertyDefinition); + newPropertyDefinition.setName(propName); + values.add(newPropertyDefinition); + } + } + } + + return values; + } + + protected void setPropertiesMap(Map toscaJson, Consumer> consumer) { + final List properties = getProperties(toscaJson); + if (properties != null) { + Map collect = properties.stream().collect(Collectors.toMap(e -> e.getName(), e -> e)); + consumer.accept(collect); + } + + } + + interface ICreateElementType { + ElementType createElement(T1 firstArg, T2 secondArg); + } + + protected Either, ActionStatus> createElementTypesFromYml(String elementTypesYml, ICreateElementType, ElementDefinition> createApi) { + + List elementTypes = new ArrayList<>(); + try { + Map toscaJson = (Map) new Yaml().load(elementTypesYml); + + Iterator> elementTypesEntryItr = toscaJson.entrySet().iterator(); + while (elementTypesEntryItr.hasNext()) { + Entry elementTypeNameDataEntry = elementTypesEntryItr.next(); + String elementTypeName = elementTypeNameDataEntry.getKey(); + Map elementTypeJsonData = (Map) elementTypeNameDataEntry.getValue(); + ElementDefinition elementDefinition = createApi.createElement(elementTypeName, elementTypeJsonData); + elementTypes.add(elementDefinition); + + } + + } catch (Exception e) { + log.debug("Failed to yaml file {} {}", elementTypesYml, e); + return Either.right(ActionStatus.INVALID_YAML_FILE); + } + return Either.left(elementTypes); + } + + protected void setField(Map toscaJson, String fieldName, Consumer setter) { + if (toscaJson.containsKey(fieldName)) { + FieldType fieldValue = (FieldType) toscaJson.get(fieldName); + setter.accept(fieldValue); + } + + } + + enum ElementTypeEnum { + PolicyType, GroupType, DataType, CapabilityType, InterfaceLifecycleType + }; + + private ActionStatus convertFromStorageResponseForElementType(StorageOperationStatus status, ElementTypeEnum elementTypeEnum) { + ActionStatus ret; + switch (elementTypeEnum) { + case GroupType: + ret = componentsUtils.convertFromStorageResponseForGroupType(status); + break; + case DataType: + ret = componentsUtils.convertFromStorageResponseForDataType(status); + break; + case CapabilityType: + ret = componentsUtils.convertFromStorageResponseForCapabilityType(status); + break; + case InterfaceLifecycleType: + ret = componentsUtils.convertFromStorageResponseForLifecycleType(status); + break; + default: + ret = componentsUtils.convertFromStorageResponse(status); + break; + } + return ret; + } + + private ResponseFormat getResponseFormatForElementType(ActionStatus actionStatus, ElementTypeEnum elementTypeEnum, ElementTypeDefinition elementTypeDefinition) { + ResponseFormat ret; + switch (elementTypeEnum) { + case GroupType: + ret = componentsUtils.getResponseFormatByGroupType(actionStatus, (GroupTypeDefinition) elementTypeDefinition); + break; + case PolicyType: + ret = componentsUtils.getResponseFormatByPolicyType(actionStatus, (PolicyTypeDefinition) elementTypeDefinition); + break; + case DataType: + ret = componentsUtils.getResponseFormatByDataType(actionStatus, (DataTypeDefinition) elementTypeDefinition, null); + break; + case CapabilityType: + ret = componentsUtils.getResponseFormatByCapabilityType(actionStatus, (CapabilityTypeDefinition) elementTypeDefinition); + break; + + default: + ret = componentsUtils.getResponseFormat(actionStatus); + break; + } + return ret; + } + + protected Either>, ResponseFormat> createElementTypesByDao(List elementTypesToCreate, + Function> validator, Function> elementInfoGetter, + Function> elementFetcher, Function> elementAdder, + BiFunction> elementUpgrader) { + + List> createdElementTypes = new ArrayList<>(); + + Either>, ResponseFormat> eitherResult = Either.left(createdElementTypes); + + Iterator elementTypeItr = elementTypesToCreate.iterator(); + + try { + + while (elementTypeItr.hasNext()) { + ElementTypeDefinition elementType = elementTypeItr.next(); + final ImmutablePair elementInfo = elementInfoGetter.apply(elementType); + ElementTypeEnum elementTypeEnum = elementInfo.left; + String elementName = elementInfo.right; + + Either validateElementType = validator.apply(elementType); + if (validateElementType.isRight()) { + ResponseFormat responseFormat = validateElementType.right().value(); + log.debug("Failed in validation of element type {}. Response is {}", elementType, responseFormat.getFormattedMessage()); + eitherResult = Either.right(responseFormat); + break; + } + + log.info("send {} : {} to dao for create", elementTypeEnum.name(), elementName); + + Either findElementType = elementFetcher.apply(elementName); + if (findElementType.isRight()) { + StorageOperationStatus status = findElementType.right().value(); + log.debug("searched {} finished with result:{}", elementTypeEnum.name(), status.name()); + if (status != StorageOperationStatus.NOT_FOUND) { + ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(status, elementTypeEnum), elementTypeEnum, elementType); + eitherResult = Either.right(responseFormat); + break; + } else { + Either dataModelResponse = elementAdder.apply(elementType); + + if (dataModelResponse.isRight()) { + try { + BeEcompErrorManager.getInstance().logBeFailedAddingNodeTypeError("Create {}", elementTypeEnum.name()); + log.debug("failed to create {}: {}", elementTypeEnum.name(), elementName); + if (dataModelResponse.right().value() != StorageOperationStatus.SCHEMA_VIOLATION) { + ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(dataModelResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType); + + eitherResult = Either.right(responseFormat); + break; + } else { + createdElementTypes.add(new ImmutablePair(elementType, false)); + } + } finally { + propertyOperation.getTitanGenericDao().rollback(); + } + } else { + propertyOperation.getTitanGenericDao().commit(); + createdElementTypes.add(new ImmutablePair(elementType, true)); + log.debug("{} : {} was created successfully.", elementTypeEnum.name(), elementName); + } + if (!elementTypeItr.hasNext()) { + log.info("all {} were created successfully!!!", elementTypeEnum.name()); + } + + } + } else { + + if (elementUpgrader != null) { + Either upgradeResponse = null; + try { + upgradeResponse = elementUpgrader.apply(elementType, findElementType.left().value()); + if (upgradeResponse.isRight()) { + StorageOperationStatus status = upgradeResponse.right().value(); + if (status == StorageOperationStatus.OK) { + createdElementTypes.add(new ImmutablePair(elementType, false)); + } else { + ResponseFormat responseFormat = getResponseFormatForElementType(convertFromStorageResponseForElementType(upgradeResponse.right().value(), elementTypeEnum), elementTypeEnum, elementType); + eitherResult = Either.right(responseFormat); + break; + } + } else { + log.debug("{} : {} was upgraded successfully.", elementTypeEnum.name(), elementName); + createdElementTypes.add(new ImmutablePair(elementType, true)); + } + } finally { + if (upgradeResponse == null || upgradeResponse.isRight()) { + propertyOperation.getTitanGenericDao().rollback(); + } else { + propertyOperation.getTitanGenericDao().commit(); + } + } + + } else { + // mshitrit Once GroupType Versions are supported add + // code here + createdElementTypes.add(new ImmutablePair(elementType, false)); + log.debug("{} : {} already exists.", elementTypeEnum.name(), elementName); + } + + } + + } + } finally { + if (eitherResult.isRight()) { + propertyOperation.getTitanGenericDao().rollback(); + } + } + + return eitherResult; + + } + + public Either>, ResponseFormat> createElementTypes(String elementTypesYml, Function, ActionStatus>> elementTypeFromYmlCreater, + Function, Either>, ResponseFormat>> elementTypeDaoCreater, ElementTypeEnum elementTypeEnum) { + + Either, ActionStatus> elementTypes = elementTypeFromYmlCreater.apply(elementTypesYml); + if (elementTypes.isRight()) { + ActionStatus status = elementTypes.right().value(); + ResponseFormat responseFormat = getResponseFormatForElementType(status, elementTypeEnum, null); + return Either.right(responseFormat); + } + return elementTypeDaoCreater.apply(elementTypes.left().value()); + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java new file mode 100644 index 0000000000..6c7b8b9bc7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentBusinessLogic.java @@ -0,0 +1,860 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.components.ServiceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ComponentCache; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.resources.data.ComponentMetadataData; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public abstract class ComponentBusinessLogic extends BaseBusinessLogic { + + @Autowired + protected ArtifactsBusinessLogic artifactsBusinessLogic; + + @Autowired + protected ComponentCache componentCache; + + private static Logger log = LoggerFactory.getLogger(ComponentBusinessLogic.class.getName()); + + private static final String TAG_FIELD_LABEL = "tag"; + + public abstract Either, ResponseFormat> deleteMarkedComponents(); + + public abstract ComponentInstanceBusinessLogic getComponentInstanceBL(); + + public abstract Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText); + + protected Either validateUser(User user, String ecompErrorContext, Component component, AuditingActionEnum auditAction, boolean inTransaction) { + Either userValidationResult = validateUserNotEmpty(user, ecompErrorContext); + ResponseFormat responseFormat; + if (userValidationResult.isRight()) { + user.setUserId("UNKNOWN"); + responseFormat = userValidationResult.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType()); + return Either.right(responseFormat); + } + Either userResult = validateUserExists(user, ecompErrorContext, inTransaction); + if (userResult.isRight()) { + responseFormat = userResult.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", auditAction, component.getComponentType()); + return Either.right(responseFormat); + } + user = userResult.left().value(); + return userResult; + } + + protected Either validateUserRole(User user, Component component, List roles, AuditingActionEnum auditAction, String comment) { + if (roles != null && roles.isEmpty()) { + roles.add(Role.ADMIN); + roles.add(Role.DESIGNER); + } + Either validationResult = validateUserRole(user, roles); + if (validationResult.isRight()) { + ComponentTypeEnum componentType = component.getComponentType(); + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + if (componentType.equals(ComponentTypeEnum.SERVICE)) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment); + String distributionStatus = ((ServiceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getDistributionStatus(); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, distributionStatus); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, distributionStatus); + } + componentsUtils.auditComponent(validationResult.right().value(), user, component, "", "", auditAction, componentType, additionalParams); + } + return validationResult; + } + + protected Either validateComponentName(User user, Component component, AuditingActionEnum actionEnum) { + ComponentTypeEnum type = component.getComponentType(); + String componentName = component.getName(); + if (!ValidationUtils.validateStringNotEmpty(componentName)) { + log.debug("component name is empty"); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, type.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + if (!ValidationUtils.validateComponentNameLength(componentName)) { + log.debug("Component name exceeds max length {} ", ValidationUtils.COMPONENT_NAME_MAX_LENGTH); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + if (!validateTagPattern(componentName)) { + log.debug("Component name {} has invalid format", componentName); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, type.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + component.setNormalizedName(ValidationUtils.normaliseComponentName(componentName)); + component.setSystemName(ValidationUtils.convertToSystemName(componentName)); + + return Either.left(true); + } + + protected Either validateDescriptionAndCleanup(User user, Component component, AuditingActionEnum actionEnum) { + ComponentTypeEnum type = component.getComponentType(); + String description = component.getDescription(); + if (!ValidationUtils.validateStringNotEmpty(description)) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_DESCRIPTION, type.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + description = ValidationUtils.removeNoneUtf8Chars(description); + description = ValidationUtils.normaliseWhitespace(description); + description = ValidationUtils.stripOctets(description); + description = ValidationUtils.removeHtmlTagsOnly(description); + + Either validatDescription = validateComponentDescription(description, type); + if (validatDescription.isRight()) { + ResponseFormat responseFormat = validatDescription.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type); + return Either.right(responseFormat); + } + component.setDescription(description); + return Either.left(true); + } + + public Either validateComponentDescription(String description, ComponentTypeEnum type) { + if (description != null) { + if (!ValidationUtils.validateDescriptionLength(description)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_DESCRIPTION_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.COMPONENT_DESCRIPTION_MAX_LENGTH)); + } + + if (!ValidationUtils.validateIsEnglish(description)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_DESCRIPTION, type.getValue())); + } + return Either.left(true); + } + return Either.left(false); + } + + protected Either validateComponentNameUnique(User user, Component component, AuditingActionEnum actionEnum) { + ComponentTypeEnum type = component.getComponentType(); + ComponentOperation componentOperation = getComponentOperation(type); + Either dataModelResponse; + dataModelResponse = componentOperation.validateComponentNameExists(component.getName()); + + if (dataModelResponse.isLeft()) { + if (dataModelResponse.left().value()) { + return Either.left(true); + } else { + log.info("Component with name {} already exists", component.getName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getName()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "validateComponentNameUnique"); + BeEcompErrorManager.getInstance().logBeSystemError("validateComponentNameUnique"); + log.debug("Error while validateComponentNameUnique for component: {}", component.getName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + protected Either validateContactId(User user, Component component, AuditingActionEnum actionEnum) { + log.debug("validate component contact info"); + ComponentTypeEnum type = component.getComponentType(); + String contactId = component.getContactId(); + + if (!ValidationUtils.validateStringNotEmpty(contactId)) { + log.info("contact info is missing."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT, type.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + Either validateContactIdResponse = validateContactId(contactId, type); + if (validateContactIdResponse.isRight()) { + ResponseFormat responseFormat = validateContactIdResponse.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type); + } + return validateContactIdResponse; + } + + private Either validateContactId(String contactId, ComponentTypeEnum type) { + if (contactId != null) { + if (!ValidationUtils.validateContactId(contactId)) { + log.info("contact info is invalid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, type.getValue()); + return Either.right(errorResponse); + } + return Either.left(true); + } + return Either.left(false); + } + + protected Either validateIcon(User user, Component component, AuditingActionEnum actionEnum) { + log.debug("validate Icon"); + ComponentTypeEnum type = component.getComponentType(); + String icon = component.getIcon(); + if (!ValidationUtils.validateStringNotEmpty(icon)) { + log.info("icon is missing."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_ICON, type.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, type); + return Either.right(errorResponse); + } + + Either validateIcon = validateIcon(icon, type); + if (validateIcon.isRight()) { + ResponseFormat responseFormat = validateIcon.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, type); + } + return validateIcon; + } + + private Either validateIcon(String icon, ComponentTypeEnum type) { + if (icon != null) { + if (!ValidationUtils.validateIconLength(icon)) { + log.debug("icon exceeds max length"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ICON_EXCEEDS_LIMIT, type.getValue(), "" + ValidationUtils.ICON_MAX_LENGTH)); + } + + if (!ValidationUtils.validateIcon(icon)) { + log.info("icon is invalid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_ICON, type.getValue()); + return Either.right(errorResponse); + } + return Either.left(true); + } + return Either.left(false); + } + + protected Either validateTagsListAndRemoveDuplicates(User user, Component component, AuditingActionEnum actionEnum) { + List tagsList = component.getTags(); + + Either validateTags = validateComponentTags(tagsList, component.getName(), component.getComponentType()); + if (validateTags.isRight()) { + ResponseFormat responseFormat = validateTags.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType()); + return Either.right(responseFormat); + } + ValidationUtils.removeDuplicateFromList(tagsList); + return Either.left(true); + } + + protected Either validateComponentTags(List tags, String name, ComponentTypeEnum componentType) { + log.debug("validate component tags"); + boolean includesComponentName = false; + int tagListSize = 0; + if (tags != null && !tags.isEmpty()) { + for (String tag : tags) { + if (!ValidationUtils.validateTagLength(tag)) { + log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH)); + } + if (validateTagPattern(tag)) { + if (!includesComponentName) { + includesComponentName = name.equals(tag); + } + } else { + log.debug("invalid tag {}", tag); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FIELD_FORMAT, componentType.getValue(), TAG_FIELD_LABEL)); + } + tagListSize += tag.length() + 1; + } + if (tagListSize > 0) { + tagListSize--; + } + + if (!includesComponentName) { + log.debug("tags must include component name"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_TAGS_NO_COMP_NAME)); + } + if (!ValidationUtils.validateTagListLength(tagListSize)) { + log.debug("overall tags length exceeds limit {}", ValidationUtils.TAG_LIST_MAX_LENGTH); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH)); + } + return Either.left(true); + } + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS)); + } + + protected boolean validateTagPattern(String tag) { + return ValidationUtils.validateComponentNamePattern(tag); + } + + protected Either validateProjectCode(User user, Component component, AuditingActionEnum actionEnum) { + if (ComponentTypeEnum.RESOURCE.equals(component.getComponentType())) { + return Either.left(true); + } + log.debug("validate PROJECT_CODE name "); + String projectCode = component.getProjectCode(); + + if (!ValidationUtils.validateStringNotEmpty(projectCode)) { + log.info("projectCode is missing."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_PROJECT_CODE); + componentsUtils.auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, component.getComponentType()); + return Either.right(errorResponse); + } + + Either validateProjectCodeResponse = validateProjectCode(projectCode); + if (validateProjectCodeResponse.isRight()) { + ResponseFormat responseFormat = validateProjectCodeResponse.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, component, "", "", actionEnum, component.getComponentType()); + } + return validateProjectCodeResponse; + + } + + private Either validateProjectCode(String projectCode) { + if (projectCode != null) { + if (!ValidationUtils.validateProjectCode(projectCode)) { + log.info("projectCode is not valid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROJECT_CODE); + return Either.right(errorResponse); + } + return Either.left(true); + } + return Either.left(false); + } + + protected void checkComponentFieldsForOverrideAttempt(Component component) { + if (component.getLifecycleState() != null) { + log.info("LifecycleState cannot be defined by user. This field will be overridden by the application"); + } + if (component.getVersion() != null) { + log.info("Version cannot be defined by user. This field will be overridden by the application"); + } + if ((component.getCreatorUserId() != null) || (component.getCreatorFullName() != null)) { + log.info("Creator cannot be defined by user. This field will be overridden by the application"); + } + if ((component.getLastUpdaterUserId() != null) || (component.getLastUpdaterFullName() != null)) { + log.info("Last Updater cannot be defined by user. This field will be overridden by the application"); + } + if ((component.getCreationDate() != null)) { + log.info("Creation Date cannot be defined by user. This field will be overridden by the application"); + } + if ((component.isHighestVersion() != null)) { + log.info("Is Highest Version cannot be defined by user. This field will be overridden by the application"); + } + if ((component.getUUID() != null)) { + log.info("UUID cannot be defined by user. This field will be overridden by the application"); + } + if ((component.getLastUpdateDate() != null)) { + log.info("Last Update Date cannot be defined by user. This field will be overridden by the application"); + } + if (component.getUniqueId() != null) { + log.info("uid cannot be defined by user. This field will be overridden by the application."); + component.setUniqueId(null); + } + if (component.getInvariantUUID() != null) { + log.info("Invariant UUID cannot be defined by user. This field will be overridden by the application."); + } + } + + protected Either validateComponentFieldsBeforeCreate(User user, Component component, AuditingActionEnum actionEnum) { + // validate component name uniqueness + log.debug("validate component name "); + Either componentNameValidation = validateComponentName(user, component, actionEnum); + if (componentNameValidation.isRight()) { + return componentNameValidation; + } + + // validate description + log.debug("validate description"); + Either descValidation = validateDescriptionAndCleanup(user, component, actionEnum); + if (descValidation.isRight()) { + return descValidation; + } + + // validate tags + log.debug("validate tags"); + Either tagsValidation = validateTagsListAndRemoveDuplicates(user, component, actionEnum); + if (tagsValidation.isRight()) { + return tagsValidation; + } + + // validate contact info + log.debug("validate contact info"); + Either contactIdValidation = validateContactId(user, component, actionEnum); + if (contactIdValidation.isRight()) { + return contactIdValidation; + } + + // validate icon + log.debug("validate icon"); + Either iconValidation = validateIcon(user, component, actionEnum); + if (iconValidation.isRight()) { + return iconValidation; + } + return Either.left(true); + } + + /*** + * Fetches Component From the DB + * + * @param componentId + * @param componentTypeEnum + * @return + */ + public Either getComponent(String componentId, ComponentTypeEnum componentTypeEnum) { + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + Either eitherComponent = componentOperation.getComponent(componentId, false); + return eitherComponent; + } + + public Either getRequirementsAndCapabilities(String componentId, ComponentTypeEnum componentTypeEnum, String userId) { + + Either resp = validateUserExists(userId, "create Component Instance", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Map> capabilities = new HashMap<>(); + Map> requirements = new HashMap<>(); + Either eitherRet; + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + Either eitherComponent = validateComponentExists(componentId, componentTypeEnum, false, true); + if (eitherComponent.isLeft()) { + Either>, TitanOperationStatus> eitherCapabilities = componentOperation.getCapabilities(eitherComponent.left().value(), componentTypeEnum.getNodeType(), false); + if (eitherCapabilities.isRight()) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + eitherRet = Either.right(errorResponse); + } else { + Either>, TitanOperationStatus> eitherRequirements = componentOperation.getRequirements(eitherComponent.left().value(), componentTypeEnum.getNodeType(), false); + if (eitherRequirements.isRight()) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + eitherRet = Either.right(errorResponse); + } else { + requirements = eitherRequirements.left().value(); + capabilities = eitherCapabilities.left().value(); + eitherRet = Either.left(new CapReqDef(requirements, capabilities)); + } + } + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeResourceMissingError, "getRequirementsAndCapabilities", componentId); + BeEcompErrorManager.getInstance().logBeComponentMissingError("getRequirementsAndCapabilities", componentTypeEnum.getValue(), componentId); + eitherRet = Either.right(eitherComponent.right().value()); + } + + return eitherRet; + } + + public Either, ResponseFormat> getLatestVersionNotAbstractComponents(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, List componentUids, + String userId) { + + long startUser = System.currentTimeMillis(); + Either resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false); + long endUser = System.currentTimeMillis(); + log.debug("Activation time of get user {} ms", (endUser - startUser)); + ResponseFormat responseFormat; + if (resp.isLeft()) { + + List result = new ArrayList(); + Set nonProcessesComponents = new HashSet<>(); + nonProcessesComponents.addAll(componentUids); + + long startGetComp = System.currentTimeMillis(); + // Read components from cache + Set filteredComponents = new HashSet<>(); + filteredComponents.addAll(componentUids); + + Either, List, Set>, ActionStatus> allPartialComponents = componentCache.getComponentsForLeftPanel(componentTypeEnum, internalComponentType, filteredComponents); + + if (allPartialComponents.isRight()) { + log.debug("Components was not fetched from cache. Status is {}", allPartialComponents.right().value()); + } else { + ImmutableTriple, List, Set> immutableTriple = allPartialComponents.left().value(); + List processedComponents = immutableTriple.left; + if (processedComponents != null) { + result.addAll(processedComponents); + } + List dirtyComponents = immutableTriple.middle; + if (dirtyComponents != null) { + result.addAll(dirtyComponents); + } + + Set nonProcessesComponentsFromCache = immutableTriple.right; + nonProcessesComponents = nonProcessesComponentsFromCache; + } + long endGetComp = System.currentTimeMillis(); + log.debug("Activation time of get Comp from cache {} ms", (endGetComp - startGetComp)); + + // Fecth non cached components + List componentsUidToFetch = new ArrayList(); + componentsUidToFetch.addAll(nonProcessesComponents); + + long startGetCompFromGraph = System.currentTimeMillis(); + if (componentsUidToFetch.size() > 0) { + log.debug("Number of Components to fetch from graph is {}", componentsUidToFetch.size()); + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + Boolean isHighest = isHighest(highestFilter); + Either, StorageOperationStatus> nonCheckoutCompResponse = componentOperation.getLatestVersionNotAbstractComponents(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType, componentsUidToFetch); + + if (nonCheckoutCompResponse.isLeft()) { + log.debug("Retrived Resource successfully."); + result.addAll(nonCheckoutCompResponse.left().value()); + } else { + responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())); + } + } + long endGetCompFromGraph = System.currentTimeMillis(); + log.debug("Activation time of get Comp from graph {} ms", (endGetCompFromGraph - startGetCompFromGraph)); + + return Either.left(result); + } else { + responseFormat = resp.right().value(); + } + + return Either.right(responseFormat); + } + + private Boolean isHighest(HighestFilterEnum highestFilter) { + Boolean isHighest = null; + switch (highestFilter) { + case ALL: + break; + case HIGHEST_ONLY: + isHighest = true; + break; + case NON_HIGHEST_ONLY: + isHighest = false; + break; + default: + break; + } + return isHighest; + } + + public Either>, ResponseFormat> getLatestVersionNotAbstractComponentsUidOnly(boolean isAbstractAbstract, HighestFilterEnum highestFilter, ComponentTypeEnum componentTypeEnum, String internalComponentType, String userId) { + Either resp = validateUserExists(userId, "get Latest Version Not Abstract Components", false); + ResponseFormat responseFormat; + if (resp.isLeft()) { + + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + Boolean isHighest = isHighest(highestFilter); + Either, StorageOperationStatus> nonCheckoutCompResponse = componentOperation.getLatestVersionNotAbstractComponentsMetadataOnly(isAbstractAbstract, isHighest, componentTypeEnum, internalComponentType); + + if (nonCheckoutCompResponse.isLeft()) { + log.debug("Retrived Resource successfully."); + List> res = new ArrayList<>(); + + // MapresMap = + // nonCheckoutCompResponse.left().value().stream().collect() + // .collect(Collectors.toMap( + // p -> p.getMetadataDataDefinition().getUniqueId(), + // p-> p.getMetadataDataDefinition().getVersion())); + + res = nonCheckoutCompResponse.left().value().stream().map(p -> { + HashMap map = new HashMap<>(); + map.put("uid", p.getMetadataDataDefinition().getUniqueId()); + map.put("version", p.getMetadataDataDefinition().getVersion()); + Long lastUpdateDate = p.getMetadataDataDefinition().getLastUpdateDate(); + String lastUpdateDateStr = lastUpdateDate != null ? String.valueOf(lastUpdateDate.longValue()) : "0"; + map.put("timestamp", lastUpdateDateStr); + return map; + }).collect(Collectors.toList()); + + return Either.left(res); + } + responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(nonCheckoutCompResponse.right().value())); + } else { + responseFormat = resp.right().value(); + } + + return Either.right(responseFormat); + } + + public void setDeploymentArtifactsPlaceHolder(Component component, User user) { + + } + + public void setToscaArtifactsPlaceHolders(Component component, User user) { + Map artifactMap = component.getToscaArtifacts(); + if (artifactMap == null) { + artifactMap = new HashMap(); + } + String componentUniqueId = component.getUniqueId(); + String componentSystemName = component.getSystemName(); + String componentType = component.getComponentType().getValue().toLowerCase(); + Map toscaArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getToscaArtifacts(); + + if (toscaArtifacts != null) { + for (Entry artifactInfoMap : toscaArtifacts.entrySet()) { + Map artifactInfo = (Map) artifactInfoMap.getValue(); + ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(componentUniqueId, artifactInfoMap.getKey(), artifactInfo, user, ArtifactGroupTypeEnum.TOSCA); + artifactDefinition.setArtifactName(componentType + "-" + componentSystemName + artifactInfo.get("artifactName")); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + } + } + component.setToscaArtifacts(artifactMap); + } + + public Either, ResponseFormat> populateToscaArtifacts(Component component, User user, boolean isInCertificationRequest, boolean inTransaction, boolean shouldLock) { + Either, ResponseFormat> generateToscaRes = null; + if (component.getToscaArtifacts() != null && !component.getToscaArtifacts().isEmpty()) { + ArtifactDefinition toscaArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_TEMPLATE.getType())).findAny().get(); + generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true); + if (generateToscaRes.isRight()) { + return generateToscaRes; + } + toscaArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get(); + generateToscaRes = saveToscaArtifactPayload(toscaArtifact, component, user, isInCertificationRequest, shouldLock, inTransaction, true); + } + // TODO if csar artifact fails delete template artifact + return generateToscaRes; + } + + public Either, ResponseFormat> saveToscaArtifactPayload(ArtifactDefinition artifactDefinition, org.openecomp.sdc.be.model.Component component, User user, boolean isInCertificationRequest, boolean shouldLock, + boolean inTransaction, boolean fetchTemplatesFromDB) { + return artifactsBusinessLogic.generateAndSaveToscaArtifact(artifactDefinition, component, user, isInCertificationRequest, shouldLock, inTransaction, fetchTemplatesFromDB); + } + + public Either, ResponseFormat> getToscaModelByComponentUuid(ComponentTypeEnum componentType, String uuid, EnumMap additionalParam) { + // get info + ComponentOperation componentOperation = getComponentOperation(componentType); + Either latestVersion = componentOperation.getLatestComponentByUuid(componentType.getNodeType(), uuid); + if (latestVersion.isRight()) { + ResponseFormat response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(latestVersion.right().value(), componentType)); + return Either.right(response); + + } + Component component = latestVersion.left().value(); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getName()); + // TODO remove after migration - handle artifact not found(no + // placeholder) + if (null == component.getToscaArtifacts() || component.getToscaArtifacts().isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, ArtifactTypeEnum.TOSCA_CSAR.name())); + } + ArtifactDefinition csarArtifact = component.getToscaArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.TOSCA_CSAR.getType())).findAny().get(); + return artifactsBusinessLogic.handleDownloadToscaModelRequest(component, csarArtifact, true, false); + } + + protected StorageOperationStatus markComponentToDelete(Component component) { + + ComponentTypeEnum componentType = component.getComponentType(); + String uniqueId = component.getUniqueId(); + if ((component.getIsDeleted() != null) && (component.getIsDeleted() == true)) { + log.info("component {} already marked as deleted. id= {}, type={}", component.getName(), uniqueId, componentType); + return StorageOperationStatus.NOT_FOUND; + } + + ComponentOperation componentOperation = getComponentOperation(componentType); + + Either markResourceToDelete = componentOperation.markComponentToDelete(component, true); + if (markResourceToDelete.isRight()) { + StorageOperationStatus result = markResourceToDelete.right().value(); + log.debug("failed to mark component {} of type {} for delete. error = {}", uniqueId, componentType, result); + return result; + } else { + log.debug("Component {} of type {} was marked as deleted", uniqueId, componentType); + return StorageOperationStatus.OK; + } + } + + public Either validateAndUpdateDescription(User user, Component currentComponent, Component updatedComponent, AuditingActionEnum audatingAction) { + String descriptionUpdated = updatedComponent.getDescription(); + String descriptionCurrent = currentComponent.getDescription(); + if (descriptionUpdated != null && !descriptionCurrent.equals(descriptionUpdated)) { + Either validateDescriptionResponse = validateDescriptionAndCleanup(user, updatedComponent, audatingAction); + if (validateDescriptionResponse.isRight()) { + ResponseFormat errorRespons = validateDescriptionResponse.right().value(); + return Either.right(errorRespons); + } + currentComponent.setDescription(updatedComponent.getDescription()); + } + return Either.left(true); + } + + public Either validateAndUpdateProjectCode(User user, Component currentComponent, Component updatedComponent) { + String projectCodeUpdated = updatedComponent.getProjectCode(); + String projectCodeCurrent = currentComponent.getProjectCode(); + if (projectCodeUpdated != null && !projectCodeCurrent.equals(projectCodeUpdated)) { + Either validatProjectCodeResponse = validateProjectCode(user, updatedComponent, null); + if (validatProjectCodeResponse.isRight()) { + ResponseFormat errorRespons = validatProjectCodeResponse.right().value(); + return Either.right(errorRespons); + } + currentComponent.setProjectCode(updatedComponent.getProjectCode()); + } + return Either.left(true); + } + + public Either validateAndUpdateIcon(User user, Component currentComponent, Component updatedComponent, boolean hasBeenCertified) { + String iconUpdated = updatedComponent.getIcon(); + String iconCurrent = currentComponent.getIcon(); + if (iconUpdated != null && !iconCurrent.equals(iconUpdated)) { + if (!hasBeenCertified) { + Either validatIconResponse = validateIcon(user, updatedComponent, null); + if (validatIconResponse.isRight()) { + ResponseFormat errorRespons = validatIconResponse.right().value(); + return Either.right(errorRespons); + } + currentComponent.setIcon(updatedComponent.getIcon()); + } else { + log.info("icon {} cannot be updated once the component has been certified once.", iconUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_PARAMETER_CANNOT_BE_CHANGED, "Icon", currentComponent.getComponentType().name().toLowerCase()); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + protected Either, ResponseFormat> deleteMarkedComponents(ComponentTypeEnum componentType) { + + List deletedComponents = new ArrayList(); + log.trace("start deleteMarkedComponents"); + ComponentOperation componentOperation = getComponentOperation(componentType); + Either, StorageOperationStatus> resourcesToDelete = componentOperation.getAllComponentsMarkedForDeletion(); + if (resourcesToDelete.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourcesToDelete.right().value(), componentType)); + return Either.right(responseFormat); + } + + for (String resourceToDelete : resourcesToDelete.left().value()) { + + Either deleteMarkedResource = deleteMarkedComponent(resourceToDelete, componentType); + if (deleteMarkedResource.isLeft()) { + deletedComponents.add(deleteMarkedResource.left().value()); + } + } + + log.trace("end deleteMarkedComponents"); + return Either.left(deletedComponents); + } + + private Either deleteMarkedComponent(String componentToDelete, ComponentTypeEnum componentType) { + + Either result = null; + ComponentOperation componentOperation = getComponentOperation(componentType); + NodeTypeEnum compNodeType = componentType.getNodeType(); + StorageOperationStatus lockResult = graphLockOperation.lockComponent(componentToDelete, compNodeType); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "Delete marked component"); + log.debug("Failed to lock component {}. error - {}", componentToDelete, lockResult); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + try { + + // check if resource has relations + Either isResourceInUse = componentOperation.isComponentInUse(componentToDelete); + if (isResourceInUse.isRight()) { + log.info("deleteMarkedResource - failed to find relations to resource. id = {}, type = {}, error = {}", componentToDelete, componentType, isResourceInUse.right().value().name()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + result = Either.right(responseFormat); + return result; + } + + if (isResourceInUse.isLeft() && isResourceInUse.left().value() == false) { + + // delete resource and its artifacts in one transaction + Either, StorageOperationStatus> artifactsRes = componentOperation.getComponentArtifactsForDelete(componentToDelete, compNodeType, true); + if (artifactsRes.isRight() && !artifactsRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + log.info("failed to check artifacts for component node. id = {}, type = {}, error = {}", componentToDelete, componentType, artifactsRes.right().value().name()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + result = Either.right(responseFormat); + return result; + } + List artifactsToDelete = new ArrayList<>(); + if (artifactsRes.isLeft()) { + artifactsToDelete = artifactsRes.left().value(); + } + + Either deleteComponentRes = componentOperation.deleteComponent(componentToDelete, true); + if (deleteComponentRes.isRight()) { + log.info("failed to delete component. id = {}, type = {}, error = {}", componentToDelete, componentType, deleteComponentRes.right().value().name()); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteComponentRes.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete); + result = Either.right(responseFormat); + } else { + log.trace("component was deleted, id = {}, type = {}", componentToDelete, componentType); + // delete related artifacts + StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(artifactsToDelete); + if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete); + result = Either.right(responseFormat); + return result; + } + log.debug("component and all its artifacts were deleted, id = {}, type = {}", componentToDelete, componentType); + result = Either.left(componentToDelete); + } + } else { + // resource in use + log.debug("componentis marked for delete but still in use, id = {}, type = {}", componentToDelete, componentType); + ActionStatus actionStatus = ActionStatus.RESTRICTED_OPERATION; + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, componentToDelete); + result = Either.right(responseFormat); + return result; + } + } finally { + if (result == null || result.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "delete marked component"); + log.debug("operation failed. do rollback"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(componentToDelete, compNodeType); + } + + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java new file mode 100644 index 0000000000..89ef6f7e19 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ComponentInstanceBusinessLogic.java @@ -0,0 +1,1661 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.GroupOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +public abstract class ComponentInstanceBusinessLogic extends BaseBusinessLogic { + + private static final String ARTIFACT_PLACEHOLDER_FILE_EXTENSION = "fileExtension"; + + static final String HEAT_ENV_NAME = "heatEnv"; + private static final String HEAT_ENV_SUFFIX = "env"; + + private static Logger log = LoggerFactory.getLogger(ComponentInstanceBusinessLogic.class.getName()); + + @Autowired + private IComponentInstanceOperation componentInstanceOperation; + + @Autowired + private PropertyOperation propertyOperation; + + @Autowired + private ArtifactsBusinessLogic artifactBusinessLogic; + + @Autowired + private GroupOperation groupOperation; + + public ComponentInstanceBusinessLogic() { + } + + public Either createComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance) { + return createComponentInstance(containerComponentParam, containerComponentId, userId, resourceInstance, true, true, true); + } + + public Either createComponentInstance(String containerComponentParam, String containerComponentId, String userId, ComponentInstance resourceInstance, boolean inTransaction, boolean needLock, + boolean createNewTransaction) { + + Either resp = validateUserExists(userId, "create Component Instance", inTransaction); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either validateValidJson = validateJsonBody(resourceInstance, ComponentInstance.class); + if (validateValidJson.isRight()) { + return Either.right(validateValidJson.right().value()); + } + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + final ComponentOperation containerOperation = getComponentOperation(containerComponentType); + + Either validateComponentExists = validateComponentExists(containerComponentId, containerComponentType, inTransaction, createNewTransaction); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateAllowedToContainCompInstances = validateAllowedToContainCompInstances(containerComponent); + if (validateAllowedToContainCompInstances.isRight()) { + return Either.right(validateAllowedToContainCompInstances.right().value()); + } + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + if (resourceInstance != null && containerComponentType != null) { + Either validateComponentInstanceParentState = validateComponentInstanceParentState(containerComponentType, resourceInstance); + if (validateComponentInstanceParentState.isRight()) { + return Either.right(validateComponentInstanceParentState.right().value()); + } + } + if (needLock) { + + Either lockComponent = lockComponent(containerComponent, "createComponentInstance"); + + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + Either resultOp = null; + try { + log.debug("Try to create entry on graph"); + Either eitherResourceName = getOriginComponentNameFromComponentInstance(resourceInstance, inTransaction); + + if (eitherResourceName.isRight()) { + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; + } + Component origComponent = eitherResourceName.left().value(); + + resultOp = createComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, userId, containerOperation, inTransaction); + return resultOp; + + } finally { + if (needLock) + unlockComponent(resultOp, containerComponent); + } + } + + public Either createAndAssociateRIToRI(String containerComponentParam, String containerComponentId, String userId, CreateAndAssotiateInfo createAndAssotiateInfo) { + + Either resultOp = null; + ComponentInstance resourceInstance = createAndAssotiateInfo.getNode(); + RequirementCapabilityRelDef associationInfo = createAndAssotiateInfo.getAssociate(); + + Either resp = validateUserExists(userId, "create And Associate RI To RI", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + final ComponentOperation containerOperation = getComponentOperation(containerComponentType); + + Either validateComponentExists = validateComponentExists(containerComponentId, containerComponentType, false, true); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateAllowedToContainCompInstances = validateAllowedToContainCompInstances(containerComponent); + if (validateAllowedToContainCompInstances.isRight()) { + return Either.right(validateAllowedToContainCompInstances.right().value()); + } + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + + Either lockComponent = lockComponent(containerComponent, "createAndAssociateRIToRI"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + + try { + log.debug("Try to create entry on graph"); + NodeTypeEnum containerNodeType = containerComponentType.getNodeType(); + Either eitherResourceName = getOriginComponentNameFromComponentInstance(resourceInstance, true); + + if (eitherResourceName.isRight()) { + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; + } + Component origComponent = eitherResourceName.left().value(); + + Either result = createComponentInstanceOnGraph(containerComponent, origComponent, resourceInstance, userId, containerOperation, true); + if (result.isRight()) { + log.debug("Failed to create resource instance {}", containerComponentId); + resultOp = Either.right(result.right().value()); + return resultOp; + + } + + log.debug("Entity on graph is created."); + ComponentInstance resResourceInfo = result.left().value(); + if (associationInfo.getFromNode() == null || associationInfo.getFromNode().isEmpty()) { + associationInfo.setFromNode(resResourceInfo.getUniqueId()); + } else { + associationInfo.setToNode(resResourceInfo.getUniqueId()); + } + + RequirementCapabilityRelDef requirementCapabilityRelDef = associationInfo;// createRequirementCapabilityrelDef(associationInfo); + + Either resultReqCapDef = componentInstanceOperation.associateResourceInstances(containerComponentId, containerNodeType, requirementCapabilityRelDef, true); + if (resultReqCapDef.isLeft()) { + log.debug("Enty on graph is created."); + RequirementCapabilityRelDef resReqCapabilityRelDef = resultReqCapDef.left().value(); + CreateAndAssotiateInfo resInfo = new CreateAndAssotiateInfo(resResourceInfo, resReqCapabilityRelDef); + resultOp = Either.left(resInfo); + return resultOp; + + } else { + log.info("Failed to associate node {} with node {}", associationInfo.getFromNode(), associationInfo.getToNode()); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(resultReqCapDef.right().value(), true), "", null)); + return resultOp; + } + + } finally { + unlockComponent(resultOp, containerComponent); + } + } + + private Either getOriginComponentNameFromComponentInstance(ComponentInstance componentInstance, boolean inTransaction) { + Either eitherResponse; + Either eitherComponent = getCompInstOriginComponentOperation().getComponent(componentInstance.getComponentUid(), inTransaction); + if (eitherComponent.isRight()) { + log.debug("Failed to get origin component with id {} for component instance {} ", componentInstance.getComponentUid(), componentInstance.getName()); + eitherResponse = Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponse(eitherComponent.right().value(), ComponentTypeEnum.RESOURCE), "", null)); + } else { + eitherResponse = Either.left(eitherComponent.left().value()); + } + return eitherResponse; + } + + private Either handleNameLogic(Component origComponent, ComponentInstance componentInstance, ComponentTypeEnum containerComponentType, String containerComponentId, boolean isCreate, boolean inTransaction) { + Either eitherResult; + final ComponentOperation containerOperation = getComponentOperation(containerComponentType); + + Either componentInNumberStatus = containerOperation.increaseAndGetComponentInstanceCounter(containerComponentId, true); + + if (componentInNumberStatus.isRight()) { + log.debug("Failed to get component instance number for container component {} ", containerComponentId); + eitherResult = Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(componentInNumberStatus.right().value(), true), "", null)); + } else { + String resourceInNumber = componentInNumberStatus.left().value().toString(); + eitherResult = Either.left(resourceInNumber); + } + + if (eitherResult.isLeft()) { + Either eitherSpecificLogic; + if (isCreate) { + eitherSpecificLogic = handleNameLogicForNewComponentInstance(origComponent, componentInstance, eitherResult.left().value(), containerComponentType, inTransaction); + } else { + eitherSpecificLogic = handleNameLogicForUpdatingComponentInstance(origComponent, componentInstance, componentInNumberStatus, containerComponentType, inTransaction); + } + if (eitherSpecificLogic.isRight()) { + eitherResult = Either.right(eitherSpecificLogic.right().value()); + } + } + return eitherResult; + } + + private Either handleNameLogicForUpdatingComponentInstance(Component origComponent, ComponentInstance componentInstance, Either componentInNumberStatus, + ComponentTypeEnum containerComponentType, boolean inTransaction) { + Either eitherResult = Either.left(true); + if (componentInstance.getName() == null || componentInstance.getName().isEmpty()) { + if (origComponent == null) { + Either eitherResourceName = getOriginComponentNameFromComponentInstance(componentInstance, inTransaction); + + if (eitherResourceName.isRight()) { + eitherResult = Either.right(eitherResourceName.right().value()); + return eitherResult; + } + origComponent = eitherResourceName.left().value(); + + String resourceName = origComponent.getName(); + String logicalName = componentInstanceOperation.createComponentInstLogicalName(componentInNumberStatus.left().value().toString(), resourceName); + componentInstance.setName(logicalName); + if (containerComponentType == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) origComponent; + componentInstance.setToscaComponentName(resource.getToscaResourceName()); + } + + } + } + + Either eitherValidation = validateComponentInstanceName(componentInstance.getName(), componentInstance, false); + if (eitherValidation.isRight()) { + eitherResult = Either.right(eitherValidation.right().value()); + } + return eitherResult; + } + + private Either handleNameLogicForNewComponentInstance(Component origComponent, ComponentInstance componentInstance, String resourceInNumber, ComponentTypeEnum containerComponentType, boolean inTransaction) { + Either eitherResult = Either.left(true); + + if (origComponent == null) { + Either eitherResourceName = getOriginComponentNameFromComponentInstance(componentInstance, inTransaction); + + if (eitherResourceName.isRight()) { + eitherResult = Either.right(eitherResourceName.right().value()); + return eitherResult; + } + + origComponent = eitherResourceName.left().value(); + } + + String resourceName = origComponent.getName(); + componentInstance.setComponentName(resourceName); + if (componentInstance.getName() == null || componentInstance.getName().isEmpty()) + componentInstance.setName(resourceName); + String logicalName = componentInstanceOperation.createComponentInstLogicalName(resourceInNumber, componentInstance.getName()); + + Either eitherValidation = validateComponentInstanceName(logicalName, componentInstance, true); + if (eitherValidation.isRight()) { + eitherResult = Either.right(eitherValidation.right().value()); + } + if (containerComponentType == ComponentTypeEnum.RESOURCE) { + Resource resource = (Resource) origComponent; + componentInstance.setToscaComponentName(resource.getToscaResourceName()); + } + + return eitherResult; + } + + public Either createComponentInstanceOnGraph(String containerComponentParam, org.openecomp.sdc.be.model.Component containerComponent, Component origComponent, ComponentInstance componentInstance, String userId, + boolean needLock, boolean inTransaction) { + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + final ComponentOperation containerOperation = getComponentOperation(containerComponentType); + Either resultOp = null; + if (needLock) { + + Either lockComponent = lockComponent(containerComponent, "createComponentInstance"); + + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + try { + resultOp = createComponentInstanceOnGraph(containerComponent, origComponent, componentInstance, userId, containerOperation, inTransaction); + return resultOp; + + } finally { + if (needLock) + unlockComponent(resultOp, containerComponent); + } + + } + + private Map getExistingEnvVersions(ComponentInstance componentInstance) { + if (null == componentInstance.getDeploymentArtifacts()) + return null; + return componentInstance.getDeploymentArtifacts().values() + //filter env artifacts + .stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())) + //map name to version + .collect(Collectors.toMap(a -> a.getArtifactName(), a -> a.getArtifactVersion())); + } + + private Either createComponentInstanceOnGraph(org.openecomp.sdc.be.model.Component containerComponent, Component origComponent, ComponentInstance componentInstance, String userId, + ComponentOperation containerOperation, boolean inTransaction) { + Either resultOp; + boolean nameAlreadyExist = true; + String resourceInNumber = ""; + String containerComponentId = containerComponent.getUniqueId(); + ComponentTypeEnum containerComponentType = containerComponent.getComponentType(); + NodeTypeEnum containerNodeType = containerComponentType.getNodeType(); + NodeTypeEnum compInstNodeType = getNodeTypeOfComponentInstanceOrigin(); + while (nameAlreadyExist) { + + Either eitherNameLogic = handleNameLogic(origComponent, componentInstance, containerComponent.getComponentType(), containerComponent.getUniqueId(), true, inTransaction); + if (eitherNameLogic.isRight()) { + return Either.right(eitherNameLogic.right().value()); + } else { + resourceInNumber = eitherNameLogic.left().value(); + } + + Either isNameExistStatus = componentInstanceOperation.isComponentInstanceNameExist(containerComponentId, containerNodeType, null, componentInstance.getNormalizedName()); + if (isNameExistStatus.isRight()) { + log.debug("Failed to check if component instance name exists for container component {}", containerComponentId); + + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND, componentInstance.getName(), containerComponentId)); + return resultOp; + } + nameAlreadyExist = isNameExistStatus.left().value(); + + } + + Either result = componentInstanceOperation.createComponentInstance(containerComponentId, containerNodeType, resourceInNumber, componentInstance, compInstNodeType, inTransaction); + + if (result.isRight()) { + log.debug("Failed to create entry on graph for component instance {}", componentInstance.getName()); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), "", null)); + return resultOp; + } + + log.debug("Entity on graph is created."); + ComponentInstance compInst = result.left().value(); + + Map existingEnvVersions = getExistingEnvVersions(componentInstance); + Either addComponentInstanceArtifacts = addComponentInstanceArtifacts(containerComponent, compInst, userId, inTransaction, existingEnvVersions); + if (addComponentInstanceArtifacts.isRight()) { + log.debug("Failed to create component instance {}", componentInstance.getName()); + resultOp = Either.right(addComponentInstanceArtifacts.right().value()); + return resultOp; + } + + resultOp = Either.left(compInst); + return resultOp; + } + + /** + * addResourceInstanceArtifacts - add artifacts (HEAT_ENV) to resource instance The instance artifacts are generated from the resource's artifacts + * + * @param componentInstance + * @param userId + * @param existingEnvVersions + * @param containerComponentId + * + * @return + */ + protected Either addComponentInstanceArtifacts(org.openecomp.sdc.be.model.Component containerComponent, ComponentInstance componentInstance, String userId, boolean inTransaction, + Map existingEnvVersions) { + log.debug("add artifacts to resource instance"); + + ActionStatus status = setResourceArtifactsOnResourceInstance(componentInstance); + if (!ActionStatus.OK.equals(status)) { + ResponseFormat resultOp = componentsUtils.getResponseFormatForResourceInstance(status, "", null); + return Either.right(resultOp); + } + + // generate heat_env if necessary + Map componentDeploymentArtifacts = componentInstance.getDeploymentArtifacts(); + if (componentDeploymentArtifacts == null) { + return Either.left(ActionStatus.OK); + } + Map finalDeploymentArtifacts = new HashMap(componentDeploymentArtifacts); + for (ArtifactDefinition artifact : componentDeploymentArtifacts.values()) { + // if (artifact.getArtifactType().equalsIgnoreCase( + // ArtifactTypeEnum.HEAT.getType())) { + String type = artifact.getArtifactType(); + + if (!(type.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || type.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()))) { + continue; + } + + if (artifact.checkEsIdExist()) { + Map deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceInstanceArtifacts(); + if (deploymentResourceArtifacts == null) { + log.debug("no deployment artifacts are configured for resource instance"); + break; + } + Map placeHolderData = (Map) deploymentResourceArtifacts.get(HEAT_ENV_NAME); + + String envLabel = (artifact.getArtifactLabel() + HEAT_ENV_SUFFIX).toLowerCase(); + Either createArtifactPlaceHolder = artifactBusinessLogic.createArtifactPlaceHolderInfo(componentInstance.getUniqueId(), envLabel, placeHolderData, userId, ArtifactGroupTypeEnum.DEPLOYMENT, + inTransaction); + if (createArtifactPlaceHolder.isRight()) { + return Either.right(createArtifactPlaceHolder.right().value()); + } + ArtifactDefinition artifactHeatEnv = createArtifactPlaceHolder.left().value(); + + artifactHeatEnv.setHeatParamsUpdateDate(System.currentTimeMillis()); + artifactHeatEnv.setTimeout(0); + buildHeatEnvFileName(artifact, artifactHeatEnv, placeHolderData); + + // rbetzer - keep env artifactVersion - changeComponentInstanceVersion flow + handleEnvArtifactVersion(artifactHeatEnv, existingEnvVersions); + Either addHeatEnvArtifact = artifactBusinessLogic.addHeatEnvArtifact(artifactHeatEnv, artifact, componentInstance.getUniqueId(), NodeTypeEnum.ResourceInstance, true); + if (addHeatEnvArtifact.isRight()) { + log.debug("failed to create heat env artifact on resource instance"); + return Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(addHeatEnvArtifact.right().value(), false), "", null)); + } + + ArtifactDefinition artifactDefinition = addHeatEnvArtifact.left().value(); + if (artifact.getHeatParameters() != null) { + List heatEnvParameters = new ArrayList(); + for (HeatParameterDefinition parameter : artifact.getHeatParameters()) { + HeatParameterDefinition heatEnvParameter = new HeatParameterDefinition(parameter); + heatEnvParameter.setDefaultValue(parameter.getCurrentValue()); + heatEnvParameters.add(heatEnvParameter); + } + artifactDefinition.setHeatParameters(heatEnvParameters); + } + finalDeploymentArtifacts.put(envLabel, artifactDefinition); + + // audit + EnumMap artifactAuditingFields = artifactBusinessLogic.createArtifactAuditingFields(artifactDefinition, "", artifactDefinition.getUniqueId()); + artifactAuditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, componentInstance.getName()); + handleAuditing(AuditingActionEnum.ARTIFACT_UPLOAD, containerComponent, userId, artifactAuditingFields, inTransaction); + } + // } + } + componentInstance.setDeploymentArtifacts(finalDeploymentArtifacts); + return Either.left(ActionStatus.OK); + } + + private void handleAuditing(AuditingActionEnum artifactUpload, org.openecomp.sdc.be.model.Component containerComponent, String userId, EnumMap artifactAuditingFields, boolean inTransaction) { + + Either user = userAdmin.getUser(userId, inTransaction); + if (user.isRight()) { + log.debug("failed to get user properties from graph for audit"); + return; + } + + componentsUtils.auditComponent(componentsUtils.getResponseFormat(ActionStatus.OK), user.left().value(), containerComponent, "", "", AuditingActionEnum.ARTIFACT_UPLOAD, ComponentTypeEnum.RESOURCE_INSTANCE, artifactAuditingFields); + + } + + private void handleEnvArtifactVersion(ArtifactDefinition heatEnvArtifact, Map existingEnvVersions) { + if (null != existingEnvVersions) { + String prevVersion = existingEnvVersions.get(heatEnvArtifact.getArtifactName()); + if (null != prevVersion) { + heatEnvArtifact.setArtifactVersion(prevVersion); + } + } + } + + private void buildHeatEnvFileName(ArtifactDefinition heatArtifact, ArtifactDefinition heatEnvArtifact, Map placeHolderData) { + String heatExtension = GeneralUtility.getFilenameExtension(heatArtifact.getArtifactName()); + String envExtension = (String) placeHolderData.get(ARTIFACT_PLACEHOLDER_FILE_EXTENSION); + String fileName = heatArtifact.getArtifactName().replaceAll("." + heatExtension, "." + envExtension); + heatEnvArtifact.setArtifactName(fileName); + } + + private ActionStatus setResourceArtifactsOnResourceInstance(ComponentInstance resourceInstance) { + Either, StorageOperationStatus> getResourceDeploymentArtifacts = artifactBusinessLogic.getArtifacts(resourceInstance.getComponentUid(), NodeTypeEnum.Resource, true, ArtifactGroupTypeEnum.DEPLOYMENT); + + Map deploymentArtifacts = new HashMap(); + if (getResourceDeploymentArtifacts.isRight()) { + StorageOperationStatus status = getResourceDeploymentArtifacts.right().value(); + if (!status.equals(StorageOperationStatus.NOT_FOUND)) { + log.debug("Failed to fetch resource artifacts. status is {}", status); + return componentsUtils.convertFromStorageResponseForResourceInstance(status, true); + } + } else { + deploymentArtifacts = getResourceDeploymentArtifacts.left().value(); + } + + if (!deploymentArtifacts.isEmpty()) { + Map tempDeploymentArtifacts = new HashMap(deploymentArtifacts); + for (Entry artifact : deploymentArtifacts.entrySet()) { + if (!artifact.getValue().checkEsIdExist()) { + tempDeploymentArtifacts.remove(artifact.getKey()); + } + } + + resourceInstance.setDeploymentArtifacts(tempDeploymentArtifacts); + } + + return ActionStatus.OK; + } + + public Either updateComponentInstance(String containerComponentParam, String containerComponentId, String componentInstanceId, String userId, ComponentInstance componentInstance) { + return updateComponentInstance(containerComponentParam, containerComponentId, componentInstanceId, userId, componentInstance, false, true, true); + } + + public Either updateComponentInstance(String containerComponentParam, String containerComponentId, String componentInstanceId, String userId, ComponentInstance componentInstance, boolean inTransaction, + boolean needLock, boolean createNewTransaction) { + + Either resp = validateUserExists(userId, "update Component Instance", inTransaction); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either resultOp = null; + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + + Either validateComponentExists = validateComponentExists(containerComponentId, containerComponentType, inTransaction, createNewTransaction); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + ComponentTypeEnum instanceType = getComponentType(containerComponentType); + Either validateParentStatus = componentInstanceOperation.validateParent(containerComponentId, componentInstanceId, inTransaction); + if (validateParentStatus.isRight()) { + log.debug("Failed to get component instance {} on service {}", componentInstanceId, containerComponentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, componentInstance.getName(), instanceType.getValue().toLowerCase())); + return resultOp; + } + Boolean isPrentValid = validateParentStatus.left().value(); + if (!isPrentValid) { + resultOp = Either.right( + componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(), instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), containerComponentId)); + return resultOp; + + } + + if (needLock) { + + Either lockComponent = lockComponent(containerComponent, "updateComponentInstance"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + try { + + Either eitherResourceName = getOriginComponentNameFromComponentInstance(componentInstance, inTransaction); + + if (eitherResourceName.isRight()) { + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; + } + Component origComponent = eitherResourceName.left().value(); + + resultOp = updateComponentInstance(containerComponentId, containerComponentType, origComponent, componentInstanceId, componentInstance, inTransaction); + return resultOp; + + } finally { + if (needLock) + unlockComponent(resultOp, containerComponent); + } + } + + // New Multiple Instance Update API + public Either, ResponseFormat> updateComponentInstance(String containerComponentParam, String containerComponentId, String userId, List componentInstanceList, boolean needLock, + boolean createNewTransaction) { + + Either, ResponseFormat> resultOp = null; + org.openecomp.sdc.be.model.Component containerComponent = null; + try { + Either resp = validateUserExists(userId, "update Component Instance", true); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + + ComponentParametersView componentFilter = new ComponentParametersView(); + componentFilter.disableAll(); + componentFilter.setIgnoreUsers(false); + Either validateComponentExists = validateComponentExistsByFilter(containerComponentId, containerComponentType, componentFilter, true); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + + containerComponent = validateComponentExists.left().value(); + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + + ComponentTypeEnum instanceType = getComponentType(containerComponentType); + + for (ComponentInstance componentInstance : componentInstanceList) { + Either validateParentStatus = componentInstanceOperation.validateParent(containerComponentId, componentInstance.getUniqueId(), true); + if (validateParentStatus.isRight()) { + log.debug("Failed to get component instance {} on service {}", componentInstance.getUniqueId(), containerComponentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND, componentInstance.getName(), instanceType.getValue().toLowerCase())); + return resultOp; + } + Boolean isPrentValid = validateParentStatus.left().value(); + if (!isPrentValid) { + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER, componentInstance.getName(), instanceType.getValue().toLowerCase(), containerComponentType.getValue().toLowerCase(), + containerComponentId)); + return resultOp; + } + } + + if (needLock) { + + Either lockComponent = lockComponent(containerComponent, "updateComponentInstance"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + List updatedList = new ArrayList<>(); + for (ComponentInstance componentInstance : componentInstanceList) { + + Either eitherResourceName = getOriginComponentNameFromComponentInstance(componentInstance, true); + + if (eitherResourceName.isRight()) { + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; + } + Component origComponent = eitherResourceName.left().value(); + + Either resultSingleUpdate = updateComponentInstance(containerComponentId, containerComponentType, origComponent, componentInstance.getUniqueId(), componentInstance, true); + + if (resultSingleUpdate.isRight()) { + resultOp = Either.right(resultSingleUpdate.right().value()); + return resultOp; + } + updatedList.add(resultSingleUpdate.left().value()); + } + + resultOp = Either.left(updatedList); + return resultOp; + + } finally { + if (needLock) { + unlockComponent(resultOp, containerComponent); + } + } + } + + private ComponentTypeEnum getComponentType(ComponentTypeEnum containerComponentType) { + if (ComponentTypeEnum.PRODUCT.equals(containerComponentType)) { + return ComponentTypeEnum.SERVICE_INSTANCE; + } else { + return ComponentTypeEnum.RESOURCE_INSTANCE; + } + } + + public Either updateComponentInstance(String containerComponentParam, org.openecomp.sdc.be.model.Component containerComponent, org.openecomp.sdc.be.model.Component origComponent, String componentInstanceId, + ComponentInstance componentInstance, boolean needLock, boolean inTransaction) { + Either resultOp = null; + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + if (needLock) { + + Either lockComponent = lockComponent(containerComponent, "updateComponentInstance"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + try { + + resultOp = updateComponentInstance(containerComponent.getUniqueId(), containerComponentType, origComponent, componentInstanceId, componentInstance, inTransaction); + return resultOp; + + } finally { + if (needLock) + unlockComponent(resultOp, containerComponent); + } + + } + + private Either updateComponentInstance(String containerComponentId, ComponentTypeEnum containerComponentType, org.openecomp.sdc.be.model.Component origComponent, String componentInstanceId, + ComponentInstance componentInstance, boolean inTransaction) { + Either resultOp; + + Either eitherNameLogic = handleNameLogic(origComponent, componentInstance, containerComponentType, containerComponentId, false, inTransaction); + if (eitherNameLogic.isRight()) { + return Either.right(eitherNameLogic.right().value()); + } + NodeTypeEnum containerNodeType = containerComponentType.getNodeType(); + + Either isNameExistStatus = componentInstanceOperation.isComponentInstanceNameExist(containerComponentId, containerNodeType, componentInstanceId, componentInstance.getNormalizedName()); + if (isNameExistStatus.isRight()) { + log.debug("Failed to get resource instance names for service {}", containerComponentId); + + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND, componentInstance.getName(), containerComponentId)); + return resultOp; + } + Boolean isNameExist = isNameExistStatus.left().value(); + if (isNameExist) { + containerComponentType = getComponentTypeOfComponentInstance(); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, containerComponentType.getValue(), componentInstance.getName())); + return resultOp; + + } + + log.debug("Try to update entry on graph"); + Either result = componentInstanceOperation.updateResourceInstance(containerComponentId, containerNodeType, componentInstanceId, componentInstance, inTransaction); + + if (result.isLeft()) { + log.debug("Enty on graph is updated."); + ComponentInstance resResourceInfo = result.left().value(); + resultOp = Either.left(resResourceInfo); + return resultOp; + + } else { + log.debug("Failed to update entry on graph for resource instance {}", componentInstance.getName()); + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstance(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), false), "", componentInstance.getName())); + return resultOp; + } + + } + + public Either deleteComponentInstance(String containerComponentParam, String containerComponentId, String resourceInstanceId, String userId) { + + Either resp = validateUserExists(userId, "delete Component Instance", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + Either validateComponentExists = validateComponentExists(containerComponentId, containerComponentType, false, true); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + + Either lockComponent = lockComponent(containerComponent, "deleteComponentInstance"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + // validate resource + /* + * if (!ComponentValidationUtils.canWorkOnComponent(containerComponentId, serviceOperation, userId)) { log.info( "Restricted operation for user {} on service {}", userId, containerComponentId); return Either.right(componentsUtils + * .getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); } // lock resource StorageOperationStatus lockStatus = graphLockOperation.lockComponent( containerComponentId, NodeTypeEnum.Service); if (lockStatus != StorageOperationStatus.OK) { + * log.debug("Failed to lock service {}", containerComponentId); resultOp = Either.right(componentsUtils .getResponseFormat(componentsUtils .convertFromStorageResponse(lockStatus))); return resultOp; } + */ + Either resultOp = null; + try { + resultOp = deleteComponentInstance(containerComponentId, resourceInstanceId, containerComponentType); + return resultOp; + + } finally { + /* + * if (resultOp == null || resultOp.isRight()) { titanGenericDao.rollback(); } else { titanGenericDao.commit(); } graphLockOperation.unlockComponent(containerComponentId, NodeTypeEnum.Service); + */ + unlockComponent(resultOp, containerComponent); + } + } + + private Either deleteComponentInstance(String containerComponentId, String resourceInstanceId, ComponentTypeEnum containerComponentType) { + Either resultOp; + NodeTypeEnum containerNodeType = containerComponentType.getNodeType(); + Either result = componentInstanceOperation.deleteComponentInstance(containerNodeType, containerComponentId, resourceInstanceId, true); + + if (result.isRight()) { + log.debug("Failed to delete entry on graph for resourceInstance {}", resourceInstanceId); + ActionStatus status = componentsUtils.convertFromStorageResponse(result.right().value(), containerComponentType); + // TODO check + /* + * if (ActionStatus.SERVICE_NOT_FOUND.equals(status)) { resultOp = Either .right(componentsUtils .getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND)); } else { + */ + resultOp = Either.right(componentsUtils.getResponseFormat(status, resourceInstanceId)); + // } + return resultOp; + } + ComponentInstance resResourceInfo = result.left().value(); + resultOp = Either.left(resResourceInfo); + + log.debug("Entry on graph is deleted. Exist more connections on this artifact."); + + Map deploymentArtifacts = resResourceInfo.getDeploymentArtifacts(); + if (deploymentArtifacts != null && !deploymentArtifacts.isEmpty()) { + StorageOperationStatus deleteArtifactsIfNotOnGraph = artifactBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(new ArrayList(deploymentArtifacts.values())); + if (!deleteArtifactsIfNotOnGraph.equals(StorageOperationStatus.OK)) { + log.debug("failed to delete artifact payload. status={}", deleteArtifactsIfNotOnGraph.name()); + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), resourceInstanceId)); + } + + } + return resultOp; + } + + public Either associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) { + return associateRIToRI(componentId, userId, requirementDef, componentTypeEnum, false, true, true); + } + + public Either associateRIToRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum, boolean inTransaction, boolean needLock, + boolean createNewTransaction) { + + Either resp = validateUserExists(userId, "associate Ri To RI", inTransaction); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either resultOp = null; + + Either validateComponentExists = validateComponentExists(componentId, componentTypeEnum, inTransaction, createNewTransaction); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + if (needLock) { + Either lockComponent = lockComponent(containerComponent, "associateRIToRI"); + + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + try { + + resultOp = associateRIToRIOnGraph(componentId, requirementDef, componentTypeEnum, inTransaction); + + return resultOp; + + } finally { + if (needLock) + unlockComponent(resultOp, containerComponent); + } + } + + public Either associateRIToRIOnGraph(String componentId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum, boolean inTransaction) { + + log.debug("Try to create entry on graph"); + Either resultOp = null; + + Either result = componentInstanceOperation.associateResourceInstances(componentId, componentTypeEnum.getNodeType(), requirementDef, inTransaction); + + if (result.isLeft()) { + log.debug("Enty on graph is created."); + RequirementCapabilityRelDef requirementCapabilityRelDef = result.left().value(); + resultOp = Either.left(requirementCapabilityRelDef); + return resultOp; + + } else { + log.debug("Failed to associate node {} with node {}", requirementDef.getFromNode(), requirementDef.getToNode()); + String fromNameOrId = ""; + String toNameOrId = ""; + Either fromResult = componentInstanceOperation.getResourceInstanceById(requirementDef.getFromNode()); + Either toResult = componentInstanceOperation.getResourceInstanceById(requirementDef.getToNode()); + + toNameOrId = requirementDef.getFromNode(); + fromNameOrId = requirementDef.getFromNode(); + if (fromResult.isLeft()) { + fromNameOrId = fromResult.left().value().getName(); + } + if (toResult.isLeft()) { + toNameOrId = toResult.left().value().getName(); + } + + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), fromNameOrId, toNameOrId, requirementDef.getRelationships().get(0).getRequirement())); + + return resultOp; + } + + } + + public Either dissociateRIFromRI(String componentId, String userId, RequirementCapabilityRelDef requirementDef, ComponentTypeEnum componentTypeEnum) { + Either resp = validateUserExists(userId, "dissociate RI From RI", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either resultOp = null; + Either validateComponentExists = validateComponentExists(componentId, componentTypeEnum, false, true); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + Either lockComponent = lockComponent(containerComponent, "associateRIToRI"); + + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + try { + log.debug("Try to create entry on graph"); + Either result = componentInstanceOperation.dissociateResourceInstances(componentId, componentTypeEnum.getNodeType(), requirementDef, true); + if (result.isLeft()) { + log.debug("Enty on graph is created."); + RequirementCapabilityRelDef requirementCapabilityRelDef = result.left().value(); + resultOp = Either.left(requirementCapabilityRelDef); + return resultOp; + + } else { + + log.debug("Failed to dissocaite node {} from node {}", requirementDef.getFromNode(), requirementDef.getToNode()); + String fromNameOrId = ""; + String toNameOrId = ""; + Either fromResult = componentInstanceOperation.getResourceInstanceById(requirementDef.getFromNode()); + Either toResult = componentInstanceOperation.getResourceInstanceById(requirementDef.getToNode()); + + toNameOrId = requirementDef.getFromNode(); + fromNameOrId = requirementDef.getFromNode(); + if (fromResult.isLeft()) { + fromNameOrId = fromResult.left().value().getName(); + } + if (toResult.isLeft()) { + toNameOrId = toResult.left().value().getName(); + } + + resultOp = Either + .right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForResourceInstance(result.right().value(), true), fromNameOrId, toNameOrId, requirementDef.getRelationships().get(0).getRequirement())); + return resultOp; + } + } finally { + unlockComponent(resultOp, containerComponent); + } + } + + private Either updateAttributeValue(ComponentInstanceAttribute attribute, String resourceInstanceId) { + Either eitherAttribute = componentInstanceOperation.updateAttributeValueInResourceInstance(attribute, resourceInstanceId, true); + Either result; + if (eitherAttribute.isLeft()) { + log.debug("Attribute value {} was updated on graph.", attribute.getValueUniqueUid()); + ComponentInstanceAttribute instanceAttribute = eitherAttribute.left().value(); + + result = Either.left(instanceAttribute); + + } else { + log.debug("Failed to update attribute value {} in resource instance {}", attribute, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(eitherAttribute.right().value()); + + result = Either.right(componentsUtils.getResponseFormat(actionStatus, "")); + + } + return result; + } + + private Either updateInputValue(ComponentInstanceInput input, String resourceInstanceId) { + Either eitherInput = componentInstanceOperation.updateInputValueInResourceInstance(input, resourceInstanceId, true); + Either result; + if (eitherInput.isLeft()) { + log.debug("Input value {} was updated on graph.", input.getValueUniqueUid()); + ComponentInstanceInput instanceInput = eitherInput.left().value(); + + result = Either.left(instanceInput); + + } else { + log.debug("Failed to update input value {} in resource instance {}", input, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(eitherInput.right().value()); + + result = Either.right(componentsUtils.getResponseFormat(actionStatus, "")); + + } + return result; + } + + private Either createAttributeValue(ComponentInstanceAttribute attribute, String resourceInstanceId) { + + Either result; + + Wrapper indexCounterWrapper = new Wrapper<>(); + Wrapper errorWrapper = new Wrapper<>(); + validateIncrementCounter(resourceInstanceId, GraphPropertiesDictionary.ATTRIBUTE_COUNTER, indexCounterWrapper, errorWrapper); + + if (!errorWrapper.isEmpty()) { + result = Either.right(errorWrapper.getInnerElement()); + } else { + Either eitherAttribute = componentInstanceOperation.addAttributeValueToResourceInstance(attribute, resourceInstanceId, indexCounterWrapper.getInnerElement(), true); + if (eitherAttribute.isLeft()) { + log.debug("Attribute value was added to resource instance {}", resourceInstanceId); + ComponentInstanceAttribute instanceAttribute = eitherAttribute.left().value(); + result = Either.left(instanceAttribute); + + } else { + log.debug("Failed to add attribute value {} to resource instance {}", attribute, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(eitherAttribute.right().value()); + result = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + } + } + return result; + } + + /** + * Create Or Updates Attribute Instance + * + * @param componentTypeEnum + * @param componentId + * @param resourceInstanceId + * @param attribute + * @param userId + * @return + */ + public Either createOrUpdateAttributeValue(ComponentTypeEnum componentTypeEnum, String componentId, String resourceInstanceId, ComponentInstanceAttribute attribute, String userId) { + Either result = null; + Wrapper errorWrapper = new Wrapper<>(); + + validateUserExist(userId, "create Or Update Attribute Value", errorWrapper); + if (errorWrapper.isEmpty()) { + validateComponentTypeEnum(componentTypeEnum, "CreateOrUpdateAttributeValue", errorWrapper); + } + if (errorWrapper.isEmpty()) { + validateCanWorkOnComponent(componentId, componentTypeEnum, userId, errorWrapper); + } + if (errorWrapper.isEmpty()) { + validateComponentLock(componentId, componentTypeEnum, errorWrapper); + } + + try { + if (errorWrapper.isEmpty()) { + final boolean isCreate = Objects.isNull(attribute.getValueUniqueUid()); + if (isCreate) { + result = createAttributeValue(attribute, resourceInstanceId); + } else { + result = updateAttributeValue(attribute, resourceInstanceId); + } + } else { + result = Either.right(errorWrapper.getInnerElement()); + } + return result; + } + + finally { + if (result == null || result.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + // unlock resource + graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType()); + } + } + + public Either createOrUpdatePropertyValue(ComponentTypeEnum componentTypeEnum, String componentId, String resourceInstanceId, ComponentInstanceProperty property, String userId) { + + Either resultOp = null; + + Either resp = validateUserExists(userId, "create Or Update Property Value", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertyValue", "invalid component type", ErrorSeverity.INFO); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + return resultOp; + } + + IComponentOperation componentOperation = getIComponentOperation(componentTypeEnum); + + if (!ComponentValidationUtils.canWorkOnComponent(componentId, componentOperation, userId)) { + log.info("Restricted operation for user {} on service {}", userId, componentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return resultOp; + } + // lock resource + StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); + if (lockStatus != StorageOperationStatus.OK) { + log.debug("Failed to lock service {}", componentId); + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus))); + return resultOp; + } + try { + String propertyValueUid = property.getValueUniqueUid(); + if (propertyValueUid == null) { + + Either counterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.PROPERTY_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourcePropertyCounter failed resource instance {} property {}", resourceInstanceId, property); + StorageOperationStatus status = counterRes.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status); + resultOp = Either.right(componentsUtils.getResponseFormat(actionStatus)); + } + Integer index = counterRes.left().value(); + Either result = componentInstanceOperation.addPropertyValueToResourceInstance(property, resourceInstanceId, index, true); + + if (result.isLeft()) { + log.debug("Property value was added to resource instance {}", resourceInstanceId); + ComponentInstanceProperty instanceProperty = result.left().value(); + + resultOp = Either.left(instanceProperty); + return resultOp; + + } else { + log.debug("Failed to add property value {} to resource instance {}", property, resourceInstanceId); + // TODO: esofer add error + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + return resultOp; + } + + } else { + Either result = componentInstanceOperation.updatePropertyValueInResourceInstance(property, resourceInstanceId, true); + + if (result.isLeft()) { + log.debug("Property value {} was updated on graph.", property.getValueUniqueUid()); + ComponentInstanceProperty instanceProperty = result.left().value(); + + resultOp = Either.left(instanceProperty); + return resultOp; + + } else { + log.debug("Failed to update property value {} in resource instance {}", property, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + return resultOp; + } + } + + } finally { + if (resultOp == null || resultOp.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + // unlock resource + graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType()); + } + + } + + public Either createOrUpdateInputValue(ComponentTypeEnum componentTypeEnum, String componentId, String resourceInstanceId, ComponentInstanceInput inputProperty, String userId) { + + Either resultOp = null; + + Either resp = validateUserExists(userId, "create Or Update Input Value", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("createOrUpdateInputValue", "invalid component type", ErrorSeverity.INFO); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + return resultOp; + } + + IComponentOperation componentOperation = getIComponentOperation(componentTypeEnum); + + if (!ComponentValidationUtils.canWorkOnComponent(componentId, componentOperation, userId)) { + log.info("Restricted operation for user {} on service {}", userId, componentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return resultOp; + } + // lock resource + StorageOperationStatus lockStatus = graphLockOperation.lockComponent(componentId, componentTypeEnum.getNodeType()); + if (lockStatus != StorageOperationStatus.OK) { + log.debug("Failed to lock service {}", componentId); + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus))); + return resultOp; + } + try { + String propertyValueUid = inputProperty.getValueUniqueUid(); + if (propertyValueUid == null) { + + Either counterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.INPUT_COUNTER, true); + + if (counterRes.isRight()) { + log.debug("increaseAndGetResourceInputCounter failed resource instance {} inputProperty {}", resourceInstanceId, inputProperty); + StorageOperationStatus status = counterRes.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status); + resultOp = Either.right(componentsUtils.getResponseFormat(actionStatus)); + } + Integer index = counterRes.left().value(); + Either result = componentInstanceOperation.addInputValueToResourceInstance(inputProperty, resourceInstanceId, index, true); + + if (result.isLeft()) { + log.debug("Property value was added to resource instance {}", resourceInstanceId); + ComponentInstanceInput instanceProperty = result.left().value(); + + resultOp = Either.left(instanceProperty); + return resultOp; + + } else { + log.debug("Failed to add input value {} to resource instance {}", inputProperty, resourceInstanceId); + // TODO: esofer add error + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + return resultOp; + } + + } else { + Either result = componentInstanceOperation.updateInputValueInResourceInstance(inputProperty, resourceInstanceId, true); + + if (result.isLeft()) { + log.debug("Input value {} was updated on graph.", inputProperty.getValueUniqueUid()); + ComponentInstanceInput instanceProperty = result.left().value(); + + resultOp = Either.left(instanceProperty); + return resultOp; + + } else { + log.debug("Failed to update property value {} in reosurce instance {}", inputProperty, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + return resultOp; + } + } + + } finally { + if (resultOp == null || resultOp.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + // unlock resource + graphLockOperation.unlockComponent(componentId, componentTypeEnum.getNodeType()); + } + + } + + public Either deletePropertyValue(ComponentTypeEnum componentTypeEnum, String serviceId, String resourceInstanceId, String propertyValueId, String userId) { + + Either resp = validateUserExists(userId, "delete Property Value", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either resultOp = null; + + if (componentTypeEnum == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("CreateOrUpdatePropertyValue", "invalid component type", ErrorSeverity.INFO); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_ALLOWED)); + return resultOp; + } + + IComponentOperation componentOperation = getIComponentOperation(componentTypeEnum); + + if (!ComponentValidationUtils.canWorkOnComponent(serviceId, componentOperation, userId)) { + log.info("Restricted operation for user {} on service {}", userId, serviceId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return resultOp; + } + // lock resource + StorageOperationStatus lockStatus = graphLockOperation.lockComponent(serviceId, componentTypeEnum.getNodeType()); + if (lockStatus != StorageOperationStatus.OK) { + log.debug("Failed to lock service {}", serviceId); + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockStatus))); + return resultOp; + } + try { + Either result = propertyOperation.removePropertyValueFromResourceInstance(propertyValueId, resourceInstanceId, true); + + if (result.isLeft()) { + log.debug("Property value {} was removed from graph.", propertyValueId); + ComponentInstanceProperty instanceProperty = result.left().value(); + + resultOp = Either.left(instanceProperty); + return resultOp; + + } else { + log.debug("Failed to remove property value {} in resource instance {}", propertyValueId, resourceInstanceId); + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + + resultOp = Either.right(componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, "")); + + return resultOp; + } + + } finally { + if (resultOp == null || resultOp.isRight()) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + // unlock resource + graphLockOperation.unlockComponent(serviceId, componentTypeEnum.getNodeType()); + } + + } + + private Either validateComponentInstanceName(String resourceInstanceName, ComponentInstance resourceInstance, boolean isCreate) { + ComponentTypeEnum containerComponentType = getComponentTypeOfComponentInstance(); + if (!isCreate) { + if (resourceInstanceName == null) + return Either.left(true); + } + + if (!ValidationUtils.validateStringNotEmpty(resourceInstanceName)) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, containerComponentType.getValue()); + + return Either.right(errorResponse); + } + resourceInstance.setNormalizedName(ValidationUtils.normaliseComponentInstanceName(resourceInstanceName)); + if (!isCreate) { + if (!ValidationUtils.validateResourceInstanceNameLength(resourceInstanceName)) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_EXCEEDS_LIMIT, containerComponentType.getValue(), "" + ValidationUtils.COMPONENT_NAME_MAX_LENGTH); + + return Either.right(errorResponse); + } + if (!ValidationUtils.validateResourceInstanceName(resourceInstanceName)) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, containerComponentType.getValue()); + + return Either.right(errorResponse); + } + } + + return Either.left(true); + + } + + private Either validateComponentInstanceParentState(ComponentTypeEnum containerComponentType, ComponentInstance resourceInstance) { + String componentId = resourceInstance.getComponentUid(); + Either eitherResourceResponse = Either.right(StorageOperationStatus.GENERAL_ERROR); + + ComponentTypeEnum componentType = getComponentTypeByParentComponentType(containerComponentType); + ComponentOperation componentOperation = getComponentOperation(componentType); + if (componentOperation != null) + eitherResourceResponse = componentOperation.getComponent(componentId, true); + + Component component = null; + ResponseFormat errorResponse = null; + if (eitherResourceResponse.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(eitherResourceResponse.right().value(), componentType); + errorResponse = componentsUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING); + return Either.right(errorResponse); + } + component = eitherResourceResponse.left().value(); + LifecycleStateEnum resourceCurrState = component.getLifecycleState(); + if (resourceCurrState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) { + ActionStatus actionStatus = ActionStatus.ILLEGAL_COMPONENT_STATE; + errorResponse = componentsUtils.getResponseFormat(actionStatus, component.getComponentType().toString(), component.getName(), resourceCurrState.toString()); + return Either.right(errorResponse); + } + return Either.left(true); + } + + public Either changeComponentInstanceVersion(String containerComponentParam, String containerComponentId, String componentInstanceId, String userId, ComponentInstance newComponentInstance) { + + Either resp = validateUserExists(userId, "change Component Instance Version", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either resultOp = null; + + Either validateComponentType = validateComponentType(containerComponentParam); + if (validateComponentType.isRight()) { + return Either.right(validateComponentType.right().value()); + } + + final ComponentTypeEnum containerComponentType = validateComponentType.left().value(); + final ComponentOperation containerOperation = getComponentOperation(containerComponentType); + + Either validateComponentExists = validateComponentExists(containerComponentId, containerComponentType, false, true); + if (validateComponentExists.isRight()) { + return Either.right(validateComponentExists.right().value()); + } + org.openecomp.sdc.be.model.Component containerComponent = validateComponentExists.left().value(); + + Either validateCanWorkOnComponent = validateCanWorkOnComponent(containerComponent, userId); + if (validateCanWorkOnComponent.isRight()) { + return Either.right(validateCanWorkOnComponent.right().value()); + } + + Either validateParentStatus = componentInstanceOperation.validateParent(containerComponentId, componentInstanceId, false); + if (validateParentStatus.isRight()) { + log.debug("Failed to get resource instance {} on service {}", componentInstanceId, containerComponentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, componentInstanceId)); + return resultOp; + } + Boolean isPrentValid = validateParentStatus.left().value(); + if (!isPrentValid) { + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE, componentInstanceId, containerComponentId)); + return resultOp; + + } + + Either resourceInstanceStatus = componentInstanceOperation.getResourceInstanceById(componentInstanceId); + if (resourceInstanceStatus.isRight()) { + log.debug("Failed to get resource instance {} on service {}", componentInstanceId, containerComponentId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_INSTANCE_NOT_FOUND, componentInstanceId)); + return resultOp; + } + ComponentInstance currentResourceInstance = resourceInstanceStatus.left().value(); + + Either lockComponent = lockComponent(containerComponent, "changeComponentInstanceVersion"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + + try { + if (currentResourceInstance.getComponentUid().equals(newComponentInstance.getComponentUid())) { + resultOp = Either.left(currentResourceInstance); + return resultOp; + + } + String resourceId = newComponentInstance.getComponentUid(); + if (!getCompInstOriginComponentOperation().isComponentExist(resourceId)) { + log.debug("resource {} not found.", resourceId); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + return resultOp; + } + + // esofer - before deleting component instance, we should keep the + // groups which holds this instance + List groupsToRevert = new ArrayList<>(); + Either, StorageOperationStatus> associatedGroups = groupOperation.getAssociatedGroupsToComponentInstance(componentInstanceId, true); + if (associatedGroups.isRight()) { + StorageOperationStatus status = associatedGroups.right().value(); + if (status != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("ChangeComponentInstanceVersion", "Failed to getch groups of current component instance", ErrorSeverity.ERROR); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return resultOp; + } + } else { + List groups = associatedGroups.left().value(); + groupsToRevert.addAll(groups); + } + // rbetzer - before deleting component instance, retrieve env artifacts to keep track of artifactVersion + + Either, StorageOperationStatus> retrieveEnvArtifacts = componentInstanceOperation.fetchCIEnvArtifacts(componentInstanceId); + if (retrieveEnvArtifacts.isLeft()) + newComponentInstance.setDeploymentArtifacts(retrieveEnvArtifacts.left().value()); + else if (retrieveEnvArtifacts.right().value() != StorageOperationStatus.OK) { + log.debug("falied to fetch instance deployment artifacts {}", componentInstanceId ); + } + + resultOp = deleteComponentInstance(containerComponentId, componentInstanceId, containerComponentType); + if (resultOp.isRight()) { + + log.debug("failed to delete resource instance {}", resourceId); + + return resultOp; + + } + + Either eitherResourceName = getOriginComponentNameFromComponentInstance(newComponentInstance, true); + + if (eitherResourceName.isRight()) { + resultOp = Either.right(eitherResourceName.right().value()); + return resultOp; + } + + Component origComponent = eitherResourceName.left().value(); + + ComponentInstance resResourceInfo = resultOp.left().value(); + newComponentInstance.setName(resResourceInfo.getName()); + newComponentInstance.setPosX(resResourceInfo.getPosX()); + newComponentInstance.setPosY(resResourceInfo.getPosY()); + newComponentInstance.setDescription(resResourceInfo.getDescription()); + + resultOp = createComponentInstanceOnGraph(containerComponent, origComponent, newComponentInstance, userId, containerOperation, true); + + if (resultOp.isRight()) { + + log.debug("failed to create resource instance {}", resourceId); + + return resultOp; + + } + + newComponentInstance = resultOp.left().value(); + newComponentInstance.setName(resResourceInfo.getName()); + resultOp = updateComponentInstance(containerComponentId, containerComponentType, origComponent, newComponentInstance.getUniqueId(), newComponentInstance, true); + + ComponentInstance updatedComponentInstance = resultOp.left().value(); + if (resultOp.isRight()) { + log.debug("failed to create resource instance {}", resourceId); + return resultOp; + } + + if (false == groupsToRevert.isEmpty()) { + StorageOperationStatus associatedGroupsToComponentInstance = groupOperation.associateGroupsToComponentInstance(groupsToRevert, updatedComponentInstance.getUniqueId(), updatedComponentInstance.getName(), true); + if (associatedGroupsToComponentInstance != StorageOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError("ChangeComponentInstanceVersion", "Failed to associate groups to new component instance", ErrorSeverity.ERROR); + resultOp = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return resultOp; + } + } + + Either fullResourceInstance = componentInstanceOperation.getFullComponentInstance(resultOp.left().value(), getNodeTypeOfComponentInstanceOrigin()); + if (fullResourceInstance.isRight()) { + resultOp = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(fullResourceInstance.right().value()), resourceId)); + return resultOp; + } + resultOp = Either.left(fullResourceInstance.left().value()); + return resultOp; + + } finally { + unlockComponent(resultOp, containerComponent); + } + } + + protected abstract Either validateAllowedToContainCompInstances(org.openecomp.sdc.be.model.Component containerComponent); + + protected abstract NodeTypeEnum getNodeTypeOfComponentInstanceOrigin(); + + protected abstract ComponentTypeEnum getComponentTypeOfComponentInstance(); + + protected abstract ComponentOperation getContainerComponentOperation(); + + protected abstract ComponentOperation getCompInstOriginComponentOperation(); + + protected void validateIncrementCounter(String resourceInstanceId, GraphPropertiesDictionary counterType, Wrapper instaceCounterWrapper, Wrapper errorWrapper) { + Either counterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, counterType, true); + + if (counterRes.isRight()) { + log.debug("increase And Get {} failed resource instance {}", counterType.name(), resourceInstanceId); + StorageOperationStatus status = counterRes.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(status); + errorWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus)); + } else { + instaceCounterWrapper.setInnerElement(counterRes.left().value()); + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CompositionBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CompositionBusinessLogic.java new file mode 100644 index 0000000000..6cebc7dd53 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CompositionBusinessLogic.java @@ -0,0 +1,285 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +/** + * This class holds the logic of arranging resource instance on the canvas for imported VF + * + * @author mshitrit + * + */ +@Component("compositionBusinessLogic") +public class CompositionBusinessLogic { + @Autowired + private VFComponentInstanceBusinessLogic vfComponentInstanceBusinessLogic; + + private static final int VFC_CANVAS_ELEMENT_SIZE = 50; + private static final int CP_CANVAS_ELEMENT_SIZE = 21; + private static final int CANVAS_WIDTH = 1000; + private static final int CANVAS_HEIGHT = 700; + private static final int SPACE_BETWEEN_ELEMENTS = VFC_CANVAS_ELEMENT_SIZE * 4; + private static final double CP_RADIUS_FACTOR = 0.4; + + enum RelativePosition { + LEFT, RIGHT, UP, DOWN + }; + + protected Either, ResponseFormat> setPositionsForComponentInstances(Resource resource, String userId) { + Either, ResponseFormat> result = Either.left(resource.getComponentInstances()); + + boolean isNotAllPositionsCalculated = resource.getComponentInstances() == null + || resource.getComponentInstances().stream().filter(p -> (p.getPosX() == null || p.getPosX().isEmpty()) || (p.getPosY() == null || p.getPosY().isEmpty())).findAny().isPresent(); + + if (isNotAllPositionsCalculated) { + // Arrange Icons In Spiral Pattern + Map, ComponentInstance> componentInstanceLocations = buildSpiralPatternPositioningForComponentInstances(resource); + + // Set Relative Locations According to Canvas Size + componentInstanceLocations.entrySet().stream().forEach(e -> setRelativePosition(e)); + + // Update in DB + result = vfComponentInstanceBusinessLogic.updateComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, resource.getUniqueId(), userId, resource.getComponentInstances(), false, false); + + } + return result; + + } + + private void setRelativePosition(Entry, ComponentInstance> entry) { + int xCenter = CANVAS_WIDTH / 2; + int yCenter = CANVAS_HEIGHT / 2; + + ImmutablePair matrixPosition = entry.getKey(); + ComponentInstance componentInstance = entry.getValue(); + componentInstance.setPosX(calculateCompositionPosition(xCenter, matrixPosition.getLeft(), componentInstance)); + componentInstance.setPosY(calculateCompositionPosition(yCenter, matrixPosition.getRight(), componentInstance)); + } + + private String calculateCompositionPosition(int center, double relativePosition, ComponentInstance componentInstance) { + final double topLeftCanvasPosition = center + relativePosition * CompositionBusinessLogic.SPACE_BETWEEN_ELEMENTS; + double offsetedCanvasPosition; + switch (componentInstance.getOriginType()) { + case CP: + offsetedCanvasPosition = topLeftCanvasPosition - CompositionBusinessLogic.CP_CANVAS_ELEMENT_SIZE / 2; + break; + case VL: + offsetedCanvasPosition = topLeftCanvasPosition - CompositionBusinessLogic.CP_CANVAS_ELEMENT_SIZE / 2; + break; + case VF: + offsetedCanvasPosition = topLeftCanvasPosition - CompositionBusinessLogic.VFC_CANVAS_ELEMENT_SIZE / 2; + break; + case VFC: + offsetedCanvasPosition = topLeftCanvasPosition - CompositionBusinessLogic.VFC_CANVAS_ELEMENT_SIZE / 2; + break; + default: + offsetedCanvasPosition = topLeftCanvasPosition - CompositionBusinessLogic.VFC_CANVAS_ELEMENT_SIZE / 2; + break; + } + return String.valueOf(offsetedCanvasPosition); + } + + protected Map, ComponentInstance> buildSpiralPatternPositioningForComponentInstances(Resource resource) { + + Map, ComponentInstance> componentInstanceLocations = new HashMap<>(); + + List componentInstances = new ArrayList<>(); + componentInstances.addAll(resource.getComponentInstances()); + Map> connectededCps = getCpsConnectedToVFC(componentInstances, resource); + // Remove all cp that are connected from the list + componentInstances.removeAll(connectededCps.values().stream().flatMap(e -> e.stream()).collect(Collectors.toList())); + + buildSpiralPatternForMajorComponents(componentInstanceLocations, componentInstances); + buildCirclePatternForCps(componentInstanceLocations, connectededCps); + + return componentInstanceLocations; + } + + protected void buildCirclePatternForCps(Map, ComponentInstance> componentInstLocations, Map> connectedCps) { + + for (Entry> vfcCpList : connectedCps.entrySet()) { + Entry, ComponentInstance> vfcOfTheCps = componentInstLocations.entrySet().stream().filter(p -> p.getValue().getUniqueId().equals(vfcCpList.getKey().getUniqueId())).findAny().get(); + buildCirclePatternForOneGroupOfCps(vfcOfTheCps.getKey(), vfcCpList.getValue(), componentInstLocations); + } + + } + + private void buildCirclePatternForOneGroupOfCps(ImmutablePair vfcLocation, List cpsGroup, Map, ComponentInstance> componentInstLocations) { + final int numberOfCps = cpsGroup.size(); + double angleBetweenCps = (!cpsGroup.isEmpty()) ? Math.toRadians(360) / numberOfCps : 0; + double currentAngle = 0; + Double xCenter = vfcLocation.getLeft(); + Double yCenter = vfcLocation.getRight(); + for (ComponentInstance currCp : cpsGroup) { + double cpXposition = xCenter + CompositionBusinessLogic.CP_RADIUS_FACTOR * Math.cos(currentAngle); + double cpYposition = yCenter + CompositionBusinessLogic.CP_RADIUS_FACTOR * Math.sin(currentAngle); + componentInstLocations.put(new ImmutablePair(cpXposition, cpYposition), currCp); + currentAngle += angleBetweenCps; + } + + } + + private void buildSpiralPatternForMajorComponents(Map, ComponentInstance> componentInstanceLocations, List componentInstances) { + int elementsCounter = 0; + ImmutablePair currPlacement; + ImmutablePair prevPlacement = null; + RelativePosition relationToPrevElement = null; + for (ComponentInstance curr : componentInstances) { + elementsCounter++; + if (elementsCounter == 1) { + currPlacement = new ImmutablePair(0D, 0D); + } else if (elementsCounter == 2) { + currPlacement = new ImmutablePair(-1D, 0D); + relationToPrevElement = RelativePosition.LEFT; + } else { + relationToPrevElement = getRelativePositionForCurrentElement(componentInstanceLocations, relationToPrevElement, prevPlacement); + currPlacement = getRelativeElementLocation(prevPlacement, relationToPrevElement); + + } + + componentInstanceLocations.put(currPlacement, curr); + prevPlacement = currPlacement; + } + } + + protected Map> getCpsConnectedToVFC(List allComponentInstances, Resource vf) { + Map> vfcWithItsCps = new HashMap<>(); + List allRelations = vf.getComponentInstancesRelations(); + for (ComponentInstance curr : allComponentInstances) { + // Filters Only CPs + if (curr.getOriginType() == OriginTypeEnum.CP) { + // List Of elements the CP is connected to + List connectedToList = allRelations.stream().filter(p -> p.getFromNode().equals(curr.getUniqueId()) || p.getToNode().equals(curr.getUniqueId())).collect(Collectors.toList()); + // Adds Only CPs Which are connected to VFC + filterCpConnectedToVFC(allComponentInstances, vfcWithItsCps, curr, connectedToList); + } + } + return vfcWithItsCps; + } + + private void filterCpConnectedToVFC(List allComponentInstances, Map> vfcWithItsCps, ComponentInstance currCP, List connectedToTheCPList) { + if (!connectedToTheCPList.isEmpty()) { + // Set Of Ids Of components Instances which are connected certain CP + Set mateIds = connectedToTheCPList.stream().map(cpRelation -> cpRelation.getFromNode().equals(currCP.getUniqueId()) ? cpRelation.getToNode() : cpRelation.getFromNode()).collect(Collectors.toSet()); + + // Vfc Component instance Connected to the CP + Optional optionalVfcConnectedToCP = allComponentInstances.stream(). + // All instances connected to CP + filter(p -> mateIds.contains(p.getUniqueId())). + // Filter in only VFC connected to the CP + filter(p -> p.getOriginType() == OriginTypeEnum.VFC).findAny(); + + if (optionalVfcConnectedToCP.isPresent()) { + final ComponentInstance vfcWithCps = optionalVfcConnectedToCP.get(); + if (vfcWithItsCps.containsKey(vfcWithCps)) { + vfcWithItsCps.get(vfcWithCps).add(currCP); + } else { + List cpsList = new ArrayList<>(); + cpsList.add(currCP); + vfcWithItsCps.put(vfcWithCps, cpsList); + } + } + } + } + + private RelativePosition getRelativePositionForCurrentElement(Map, ComponentInstance> componentInstanceLocations, RelativePosition relationToPrevElement, ImmutablePair prevPlacement) { + switch (relationToPrevElement) { + case LEFT: { + boolean isOccupied = isAdjacentElementOccupied(prevPlacement, RelativePosition.UP, componentInstanceLocations); + relationToPrevElement = isOccupied ? RelativePosition.LEFT : RelativePosition.UP; + break; + } + case RIGHT: { + boolean isOccupied = isAdjacentElementOccupied(prevPlacement, RelativePosition.DOWN, componentInstanceLocations); + relationToPrevElement = isOccupied ? RelativePosition.RIGHT : RelativePosition.DOWN; + break; + } + case UP: { + boolean isOccupied = isAdjacentElementOccupied(prevPlacement, RelativePosition.RIGHT, componentInstanceLocations); + relationToPrevElement = isOccupied ? RelativePosition.UP : RelativePosition.RIGHT; + break; + } + case DOWN: { + boolean isOccupied = isAdjacentElementOccupied(prevPlacement, RelativePosition.LEFT, componentInstanceLocations); + relationToPrevElement = isOccupied ? RelativePosition.DOWN : RelativePosition.LEFT; + break; + } + default: { + throw new UnsupportedOperationException(); + } + } + return relationToPrevElement; + } + + private boolean isAdjacentElementOccupied(ImmutablePair currElement, RelativePosition adjacentElementRelationToCurrElement, Map, ComponentInstance> allElements) { + + ImmutablePair adjacentElementPosition = getRelativeElementLocation(currElement, adjacentElementRelationToCurrElement); + return allElements.containsKey(adjacentElementPosition); + } + + private ImmutablePair getRelativeElementLocation(ImmutablePair currElement, RelativePosition relativeLocation) { + ImmutablePair relativeElementPosition; + switch (relativeLocation) { + + case LEFT: { + relativeElementPosition = new ImmutablePair(currElement.getLeft() - 1, currElement.getRight()); + break; + } + case RIGHT: { + relativeElementPosition = new ImmutablePair(currElement.getLeft() + 1, currElement.getRight()); + break; + } + case UP: { + relativeElementPosition = new ImmutablePair(currElement.getLeft(), currElement.getRight() + 1); + break; + } + case DOWN: { + relativeElementPosition = new ImmutablePair(currElement.getLeft(), currElement.getRight() - 1); + break; + } + default: { + throw new UnsupportedOperationException(); + } + } + return relativeElementPosition; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ConsumerBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ConsumerBusinessLogic.java new file mode 100644 index 0000000000..226225a07c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ConsumerBusinessLogic.java @@ -0,0 +1,313 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.Date; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ConsumerDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ConsumerOperation; +import org.openecomp.sdc.be.resources.data.ConsumerData; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("ConsumerBusinessLogic") +public class ConsumerBusinessLogic extends BaseBusinessLogic { + + private static final String CONSUMER_NAME = "Consumer name"; + private static final String CONSUMER_SALT = "Consumer salt"; + private static final String CONSUMER_PW = "Consumer password"; + + @javax.annotation.Resource + private IUserBusinessLogic userAdmin; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + @javax.annotation.Resource + private ConsumerOperation consumerOperation; + + @javax.annotation.Resource + private IGraphLockOperation graphLockOperation; + + private static Logger log = LoggerFactory.getLogger(ConsumerBusinessLogic.class.getName()); + + public Either createConsumer(User user, ConsumerDefinition consumer) { + + Either userValidation = validateUser(user, consumer, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS); + + if (userValidation.isRight()) { + return Either.right(userValidation.right().value()); + } + checkFieldsForOverrideAttempt(consumer); + user = userValidation.left().value(); + consumer.setLastModfierAtuid(user.getUserId()); + + Either consumerValidationResponse = validateConsumer(consumer, user, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS); + if (consumerValidationResponse.isRight()) { + ResponseFormat responseFormat = consumerValidationResponse.right().value(); + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.right(responseFormat); + } + String consumerName = consumer.getConsumerName(); + StorageOperationStatus lockResult = graphLockOperation.lockComponent(consumerName, NodeTypeEnum.ConsumerCredentials); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "createConsumer"); + BeEcompErrorManager.getInstance().logBeFailedLockObjectError("createConsumer", NodeTypeEnum.ConsumerCredentials.getName(), consumerName); + log.debug("Failed to lock consumer {} error - {}", consumerName, lockResult); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.right(responseFormat); + } + try { + Either getResponse = consumerOperation.getCredentials(consumerName); + if (getResponse.isLeft() && getResponse.left().value() != null) { + return updateConsumer(consumer, user, true); + } + + Date date = new Date(); + consumer.setConsumerDetailsLastupdatedtime(date.getTime()); + consumer.setConsumerLastAuthenticationTime(Long.valueOf(0)); + + Either createResponse = consumerOperation.createCredentials(new ConsumerData(consumer)); + + if (createResponse.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForConsumer(createResponse.right().value())); + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.right(responseFormat); + } + log.debug("Consumer created successfully!!!"); + consumer = new ConsumerDefinition(createResponse.left().value().getConsumerDataDefinition()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.left(consumer); + } finally { + graphLockOperation.unlockComponent(consumerName, NodeTypeEnum.ConsumerCredentials); + } + } + + private Either validateUser(User user, ConsumerDefinition consumer, AuditingActionEnum auditAction) { + + if (user.getUserId() == null || user.getUserId().trim().isEmpty()) { + log.debug("createEcompUser method - user is missing. userId={}", user.getUserId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + log.debug("audit before sending response"); + componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user); + return Either.right(responseFormat); + } + log.debug("get user from DB"); + Either eitherCreator = userAdmin.getUser(user.getUserId(), false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + log.debug("createEcompUser method - user is not listed. userId={}", user.getUserId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_ACCESS); + log.debug("audit before sending response"); + componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user); + return Either.right(responseFormat); + } + + user = eitherCreator.left().value(); + // validate user role + log.debug("validate user role"); + if (!user.getRole().equals(Role.ADMIN.name())) { + log.info("role {} is not allowed to perform this action", user.getRole()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("audit before sending response"); + componentsUtils.auditConsumerCredentialsEvent(auditAction, consumer, responseFormat, user); + return Either.right(responseFormat); + } + return Either.left(user); + } + + private Either validateConsumer(ConsumerDefinition consumer, User user, AuditingActionEnum audatingAction) { + Either validateConsumerName = validateConsumerName(consumer); + if (validateConsumerName.isRight()) { + return Either.right(validateConsumerName.right().value()); + } + Either validateConsumerPassword = validateConsumerPassword(consumer); + if (validateConsumerPassword.isRight()) { + return Either.right(validateConsumerPassword.right().value()); + } + consumer = validateConsumerPassword.left().value(); + Either validateEcompUserSalt = validateConsumerSalt(consumer); + if (validateEcompUserSalt.isRight()) { + return Either.right(validateEcompUserSalt.right().value()); + } + return Either.left(consumer); + + } + + private Either validateConsumerName(ConsumerDefinition consumer) { + String name = consumer.getConsumerName(); + if (!ValidationUtils.validateStringNotEmpty(name)) { + log.debug("Consumer name cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_NAME)); + } + if (!ValidationUtils.validateConsumerName(name)) { + log.debug("Consumer name is invalid."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_NAME)); + } + if (!ValidationUtils.validateLength(name, ValidationUtils.CONSUMER_NAME_MAX_LENGTH)) { + log.debug("Consumer name exceeds limit."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, CONSUMER_NAME, String.valueOf(ValidationUtils.CONSUMER_NAME_MAX_LENGTH))); + } + if (!ValidationUtils.isUTF8Str(name)) { + log.debug("Consumer name includes non UTF 8 characters."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_NAME)); + } + + return Either.left(consumer); + } + + private Either validateConsumerPassword(ConsumerDefinition consumer) { + String password = consumer.getConsumerPassword(); + if (!ValidationUtils.validateStringNotEmpty(password)) { + log.debug("Consumer password cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_PW)); + } + if (password.length() != ValidationUtils.CONSUMER_PASSWORD_LENGTH) { + log.debug("Consumer password length is not valid."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_LENGTH, CONSUMER_PW)); + } + consumer.setConsumerPassword(password.toLowerCase()); + if (!ValidationUtils.validateConsumerPassSalt(consumer.getConsumerPassword())) { + log.debug("Consumer password is invalid."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_PW)); + } + + return Either.left(consumer); + } + + private Either validateConsumerSalt(ConsumerDefinition consumer) { + String salt = consumer.getConsumerSalt(); + if (!ValidationUtils.validateStringNotEmpty(salt)) { + log.debug("Consumer salt cannot be empty."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_DATA, CONSUMER_SALT)); + } + if (salt.length() != ValidationUtils.CONSUMER_SALT_LENGTH) { + log.debug("Consumer salt length is not valid."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_LENGTH, CONSUMER_SALT)); + } + if (!ValidationUtils.validateConsumerPassSalt(salt)) { + log.debug("Consumer salt is invalid."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT_PARAM, CONSUMER_SALT)); + } + + return Either.left(consumer); + } + + public Either getConsumer(String consumerId, User user) { + ConsumerDefinition tmpConsumer = new ConsumerDefinition(); + tmpConsumer.setConsumerName(consumerId); + // In case of filter (southbound) call + if (user != null) { + Either userValidation = validateUser(user, tmpConsumer, AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS); + if (userValidation.isRight()) { + return Either.right(userValidation.right().value()); + } + user = userValidation.left().value(); + } + Either getResult = consumerOperation.getCredentials(consumerId); + if (getResult.isRight()) { + ActionStatus action = componentsUtils.convertFromStorageResponseForConsumer(getResult.right().value()); + ResponseFormat responseFormat; + if (action == ActionStatus.ECOMP_USER_NOT_FOUND) { + responseFormat = componentsUtils.getResponseFormat(action, consumerId); + } else { + responseFormat = componentsUtils.getResponseFormat(action); + } + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS, tmpConsumer, responseFormat, user); + return Either.right(responseFormat); + } + ConsumerDefinition consumer = new ConsumerDefinition(getResult.left().value().getConsumerDataDefinition()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.GET_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.left(consumer); + } + + public Either getConsumer(String consumerId) { + return getConsumer(consumerId, null); + } + + public Either deleteConsumer(String consumerId, User user) { + ConsumerDefinition tmpConsumer = new ConsumerDefinition(); + tmpConsumer.setConsumerName(consumerId); + Either userValidation = validateUser(user, tmpConsumer, AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS); + if (userValidation.isRight()) { + return Either.right(userValidation.right().value()); + } + user = userValidation.left().value(); + Either deleteResult = consumerOperation.deleteCredentials(consumerId); + if (deleteResult.isRight()) { + ActionStatus action = componentsUtils.convertFromStorageResponseForConsumer(deleteResult.right().value()); + ResponseFormat responseFormat; + if (action == ActionStatus.ECOMP_USER_NOT_FOUND) { + responseFormat = componentsUtils.getResponseFormat(action, consumerId); + } else { + responseFormat = componentsUtils.getResponseFormat(action); + } + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS, tmpConsumer, responseFormat, user); + return Either.right(responseFormat); + } + ConsumerDefinition consumer = new ConsumerDefinition(deleteResult.left().value().getConsumerDataDefinition()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + componentsUtils.auditConsumerCredentialsEvent(AuditingActionEnum.DELETE_ECOMP_USER_CREDENTIALS, consumer, responseFormat, user); + return Either.left(consumer); + } + + public Either updateConsumer(ConsumerDefinition consumer, User modifier, boolean isCreateRequest) { + Either updateResult = consumerOperation.updateCredentials(new ConsumerData(consumer)); + if (updateResult.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForConsumer(updateResult.right().value())); + return Either.right(responseFormat); + } + consumer = new ConsumerDefinition(updateResult.left().value().getConsumerDataDefinition()); + return Either.left(consumer); + } + + private void checkFieldsForOverrideAttempt(ConsumerDefinition consumer) { + if (consumer.getConsumerDetailsLastupdatedtime() != null) { + log.info("Consumer Details Last updated time cannot be defined by user. This field will be overridden by the application"); + } + if (consumer.getConsumerLastAuthenticationTime() != null) { + log.info("Consumer Last Authentication time cannot be defined by user. This field will be overridden by the application"); + } + if (consumer.getLastModfierAtuid() != null) { + log.info("Consumer Last Modifier USER_ID cannot be defined by user. This field will be overridden by the application"); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CsarValidationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CsarValidationUtils.java new file mode 100644 index 0000000000..badb257a80 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/CsarValidationUtils.java @@ -0,0 +1,265 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.util.Map; +import java.util.Properties; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CsarValidationUtils { + + private static Logger log = LoggerFactory.getLogger(CsarValidationUtils.class.getName()); + + private static final String TOSCA_META_FILE_VERSION = "TOSCA-Meta-File-Version"; + + private static final String CSAR_VERSION = "CSAR-Version"; + + private static final String CREATED_BY = "Created-By"; + + private static final String NEW_LINE_DELM = "\n"; + + public final static String TOSCA_METADATA_FILE = "TOSCA-Metadata/TOSCA.meta"; + + public static final String TOSCA_META_ENTRY_DEFINITIONS = "Entry-Definitions"; + + public final static String[] TOSCA_METADATA_FIELDS = { TOSCA_META_FILE_VERSION, CSAR_VERSION, CREATED_BY, TOSCA_META_ENTRY_DEFINITIONS }; + + public final static String ARTIFACTS_METADATA_FILE = "HEAT.meta"; + + public final static String ARTIFACTS = "Artifacts/"; + + public static final String TOSCA_CSAR_EXTENSION = ".csar"; + + public static Either validateCsar(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + Either validateStatus = validateIsTOSCAMetadataExist(csar, csarUUID, componentsUtils); + if (validateStatus.isRight()) { + return Either.right(validateStatus.right().value()); + } + log.trace("TOSCA-Metadata/TOSCA.meta file found, CSAR id {}", csarUUID); + return validateTOSCAMetadataFile(csar, csarUUID, componentsUtils); + + } + + public static Either, ResponseFormat> getToscaYaml(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + Either validateStatus = validateIsTOSCAMetadataExist(csar, csarUUID, componentsUtils); + if (validateStatus.isRight()) { + return Either.right(validateStatus.right().value()); + } + byte[] toscaMetaBytes = csar.get(TOSCA_METADATA_FILE); + Properties props = new Properties(); + try { + props.load(new ByteArrayInputStream(toscaMetaBytes)); + } catch (IOException e) { + log.debug("TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + + String yamlFileName = props.getProperty(TOSCA_META_ENTRY_DEFINITIONS); + + if (!csar.containsKey(yamlFileName)) { + log.debug("Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, yamlFileName)); + } + + log.trace("Found Entry-Definitions property in TOSCA-Metadata/TOSCA.meta, Entry-Definitions: {}, CSAR id: {}", yamlFileName, csarUUID); + byte[] yamlFileBytes = csar.get(yamlFileName); + if (yamlFileBytes == null) { + log.debug("Entry-Definitions {} file not found in csar, csar ID {}", yamlFileName, csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions " + yamlFileName + " file not found in CSAR with id " + csarUUID, "CSAR structure is invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, yamlFileName)); + } + + String yamlFileContents = new String(yamlFileBytes); + + return Either.left(new ImmutablePair(yamlFileName, yamlFileContents)); + } + + public static Either, ResponseFormat> getArtifactsMeta(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + + if (!csar.containsKey(ARTIFACTS + ARTIFACTS_METADATA_FILE)) { + log.debug("Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, ARTIFACTS_METADATA_FILE)); + } + + log.trace("Found Entry-Definitions property in TOSCA-Metadata/TOSCA.meta, Entry-Definitions: {}, CSAR id: {}", ARTIFACTS_METADATA_FILE, csarUUID); + byte[] artifactsMetaBytes = csar.get(ARTIFACTS + ARTIFACTS_METADATA_FILE); + if (artifactsMetaBytes == null) { + log.debug("Entry-Definitions {} file not found in csar, csar ID {}", ARTIFACTS + ARTIFACTS_METADATA_FILE, csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions " + ARTIFACTS + ARTIFACTS_METADATA_FILE + " file not found in CSAR with id " + csarUUID, "CSAR structure is invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.YAML_NOT_FOUND_IN_CSAR, csarUUID, ARTIFACTS + ARTIFACTS_METADATA_FILE)); + } + + String artifactsFileContents = new String(artifactsMetaBytes); + + return Either.left(new ImmutablePair(ARTIFACTS + ARTIFACTS_METADATA_FILE, artifactsFileContents)); + } + + public static Either, ResponseFormat> getArtifactsContent(String csarUUID, Map csar, String artifactName, ComponentsUtils componentsUtils) { + if (!csar.containsKey(ARTIFACTS + artifactName)) { + log.debug("Entry-Definitions entry not found in Artifacts/HEAT.meta file, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions entry not found in TOSCA-Metadata/TOSCA.meta file in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, ARTIFACTS + artifactName, csarUUID)); + } + + log.trace("Found Entry-Definitions property in Artifacts/HEAT.meta, Entry-Definitions: {}, CSAR id: {}", ARTIFACTS + artifactName, csarUUID); + byte[] artifactFileBytes = csar.get(ARTIFACTS + artifactName); + if (artifactFileBytes == null) { + log.debug("Entry-Definitions {} file not found in csar, csar ID {}", ARTIFACTS + artifactName, csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("Entry-Definitions " + ARTIFACTS + artifactName + " file not found in CSAR with id " + csarUUID, "CSAR structure is invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND_IN_CSAR, ARTIFACTS + artifactName, csarUUID)); + } + + return Either.left(new ImmutablePair(artifactName, artifactFileBytes)); + } + + private static Either validateTOSCAMetadataFile(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + + byte[] toscaMetaBytes = csar.get(TOSCA_METADATA_FILE); + String toscaMetadata = new String(toscaMetaBytes); + String[] splited = toscaMetadata.split(NEW_LINE_DELM); + if (splited == null || splited.length < TOSCA_METADATA_FIELDS.length) { + log.debug("TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + /* + * if(splited.length == TOSCA_METADATA_FIELDS.length){ if(!toscaMetadata.endsWith(NEW_LINE_DELM)){ log. debug("TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}" , csarUUID); + * BeEcompErrorManager.getInstance(). logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " +csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); return + * Either.right(componentsUtils.getResponseFormat(ActionStatus. CSAR_INVALID_FORMAT, csarUUID)); } } + */ + + Either block_0Status = validateBlock_0(csarUUID, splited, componentsUtils); + if (block_0Status.isRight()) { + return Either.right(block_0Status.right().value()); + } + + return Either.left(true); + + } + + private static Either validateBlock_0(String csarUUID, String[] splited, ComponentsUtils componentsUtils) { + int index = 0; + for (String toscaField : TOSCA_METADATA_FIELDS) { + + Properties props = new Properties(); + + try { + props.load(new ByteArrayInputStream(splited[index].getBytes())); + } catch (IOException e) { + log.debug("TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + if (!props.containsKey(toscaField)) { + log.debug("TOSCA.meta file format is invalid: No new line after block_0 as expected in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + String value = props.getProperty(toscaField); + if (value == null || value.isEmpty()) { + log.debug("TOSCA-Metadata/TOSCA.meta file is not in expected key-value form in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + + // TOSCA-Meta-File-Version & CSAR-Version : digit.digit - format + // validation + if (toscaField.equals(TOSCA_META_FILE_VERSION) || toscaField.equals(CSAR_VERSION)) { + if (!validateTOSCAMetaProperty(value)) { + log.debug("TOSCA-Metadata/TOSCA.meta file contains {} in wrong format (digit.digit), csar ID {}", toscaField, csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not in expected key-value form in CSAR with id " + csarUUID, "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, csarUUID)); + } + } + index++; + } + return Either.left(true); + } + + private static boolean validateTOSCAMetaProperty(String toscaProperty) { + final String FLOAT_STRING = "^\\d{1}[.]\\d{1}$"; + final Pattern FLOAT_PATTERN = Pattern.compile(FLOAT_STRING); + + Matcher floatMatcher = FLOAT_PATTERN.matcher(toscaProperty); + return floatMatcher.matches(); + } + + private static Either validateIsTOSCAMetadataExist(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + if (csar == null || csar.isEmpty()) { + log.debug("Error when fetching csar with ID {}", csarUUID); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID); + return Either.right(responseFormat); + } + if (!csar.containsKey(TOSCA_METADATA_FILE)) { + log.debug("TOSCA-Metadata/TOSCA.meta file not found in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not found in CSAR with id " + csarUUID, "CSAR structure is invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID)); + } + byte[] toscaMetaBytes = csar.get(TOSCA_METADATA_FILE); + // Tal && exchanged for || + if (toscaMetaBytes == null || toscaMetaBytes.length == 0) { + log.debug("TOSCA-Metadata/TOSCA.meta file not found in csar, csar ID {}", csarUUID); + BeEcompErrorManager.getInstance().logInternalDataError("TOSCA-Metadata/TOSCA.meta file not found in CSAR with id " + csarUUID, "CSAR structure is invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID)); + } + + return Either.left(Boolean.TRUE); + } + + public static Either getToscaYamlChecksum(Map csar, String csarUUID, ComponentsUtils componentsUtils) { + + Either, ResponseFormat> toscaYamlRes = getToscaYaml(csar, csarUUID, componentsUtils); + if (toscaYamlRes.isRight() || toscaYamlRes.left().value() == null || toscaYamlRes.left().value().getRight() == null) { + log.debug("Faild to create toscaYamlChecksum for csar, csar ID {}", csarUUID); + return Either.right(toscaYamlRes.right().value()); + } + + String newCheckSum = GeneralUtility.calculateMD5ByByteArray(toscaYamlRes.left().value().getRight().getBytes()); + return Either.left(newCheckSum); + + } + + public static boolean isCsarPayloadName(String payloadName) { + if (payloadName == null) + return false; + return payloadName.toLowerCase().endsWith(TOSCA_CSAR_EXTENSION); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java new file mode 100644 index 0000000000..e5fba0dff5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DataTypeImportManager.java @@ -0,0 +1,255 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.CommonImportManager.ElementTypeEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("dataTypeImportManager") +public class DataTypeImportManager { + + public static void main(String[] args) { + + List properties = new ArrayList<>(); + PropertyDefinition propertyDefintion = new PropertyDefinition(); + propertyDefintion.setName("aaa"); + properties.add(propertyDefintion); + + List allParentsProps = new ArrayList<>(); + allParentsProps.add("aaa"); + allParentsProps.add("bbb"); + + Set alreadyExistPropsCollection = properties.stream().filter(p -> allParentsProps.contains(p.getName())).map(p -> p.getName()).collect(Collectors.toSet()); + System.out.println(alreadyExistPropsCollection); + + } + + private static Logger log = LoggerFactory.getLogger(DataTypeImportManager.class.getName()); + @Resource + private PropertyOperation propertyOperation; + @Resource + private ComponentsUtils componentsUtils; + @Resource + private CommonImportManager commonImportManager; + + public Either>, ResponseFormat> createDataTypes(String dataTypeYml) { + return commonImportManager.createElementTypes(dataTypeYml, elementTypeYml -> createDataTypesFromYml(elementTypeYml), elementTypesList -> createDataTypesByDao(elementTypesList), ElementTypeEnum.DataType); + } + + private Either, ActionStatus> createDataTypesFromYml(String dataTypesYml) { + + return commonImportManager.createElementTypesFromYml(dataTypesYml, (dataTypeName, dataTypeJsonData) -> createDataType(dataTypeName, dataTypeJsonData)); + + } + + private Either>, ResponseFormat> createDataTypesByDao(List dataTypesToCreate) { + + return commonImportManager.createElementTypesByDao(dataTypesToCreate, dataType -> validateDataType(dataType), dataType -> new ImmutablePair<>(ElementTypeEnum.DataType, dataType.getName()), + dataTypeName -> propertyOperation.getDataTypeByNameWithoutDerived(dataTypeName), dataType -> propertyOperation.addDataType(dataType), (newDataType, oldDataType) -> propertyOperation.updateDataType(newDataType, oldDataType)); + } + + private Either validateDataType(DataTypeDefinition dataType) { + + String dataTypeName = dataType.getName(); + List properties = dataType.getProperties(); + if (properties == null) { + // At least one parameter should be defined either in the properties + // section or at one of the parents + String derivedDataType = dataType.getDerivedFromName(); + // If there are no properties, then we can create a data type if it + // is an abstract one or it derives from non abstract data type + if ((derivedDataType == null || derivedDataType.isEmpty())) { + if (false == isAbstract(dataType.getName())) { + if (false == ToscaPropertyType.isScalarType(dataTypeName)) { + log.debug("Data type {} must have properties unless it derives from non abstract data type", dataType.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM, dataType, null); + + return Either.right(responseFormat); + } + } + } else { + // if it is not a scalar data type and it derives from abstract + // data type, we should reject the request. + if (false == ToscaPropertyType.isScalarType(dataTypeName) && true == isAbstract(derivedDataType)) { + log.debug("Data type {} which derived from abstract data type must have at least one property", dataType.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM, dataType, null); + + return Either.right(responseFormat); + } + } + } else { + // properties tag cannot be empty + if (properties.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY, dataType, null); + + return Either.right(responseFormat); + } + + // check no duplicates + Set collect = properties.stream().map(p -> p.getName()).collect(Collectors.toSet()); + if (collect != null) { + if (properties.size() != collect.size()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_DUPLICATE_PROPERTY, dataType, null); + + return Either.right(responseFormat); + } + } + + List propertiesWithSameTypeAsDataType = properties.stream().filter(p -> p.getType().equals(dataType.getName())).map(p -> p.getName()).collect(Collectors.toList()); + if (propertiesWithSameTypeAsDataType != null && propertiesWithSameTypeAsDataType.isEmpty() == false) { + log.debug("The data type {} contains properties with the type {}", dataType.getName(), dataType.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE, dataType, propertiesWithSameTypeAsDataType); + + return Either.right(responseFormat); + } + } + + String derivedDataType = dataType.getDerivedFromName(); + if (derivedDataType != null) { + Either derivedDataTypeByName = propertyOperation.getDataTypeByName(derivedDataType, true); + if (derivedDataTypeByName.isRight()) { + StorageOperationStatus status = derivedDataTypeByName.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_DERIVED_IS_MISSING, dataType, null); + + return Either.right(responseFormat); + } else { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.GENERAL_ERROR, dataType, null); + + return Either.right(responseFormat); + + } + } else { + + DataTypeDefinition derivedDataTypeDef = derivedDataTypeByName.left().value(); + if (properties != null && properties.isEmpty() == false) { + + if (true == isScalarType(derivedDataTypeDef)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_CANNOT_HAVE_PROPERTIES, dataType, null); + + return Either.right(responseFormat); + } + + Set allParentsProps = new HashSet<>(); + do { + List currentParentsProps = derivedDataTypeDef.getProperties(); + if (currentParentsProps != null) { + for (PropertyDefinition propertyDefinition : currentParentsProps) { + allParentsProps.add(propertyDefinition.getName()); + } + } + derivedDataTypeDef = derivedDataTypeDef.getDerivedFrom(); + } while (derivedDataTypeDef != null); + + // Check that no property is already defined in one of the + // ancestors + Set alreadyExistPropsCollection = properties.stream().filter(p -> allParentsProps.contains(p.getName())).map(p -> p.getName()).collect(Collectors.toSet()); + if (alreadyExistPropsCollection != null && alreadyExistPropsCollection.isEmpty() == false) { + List duplicateProps = new ArrayList<>(); + duplicateProps.addAll(alreadyExistPropsCollection); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByDataType(ActionStatus.DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR, dataType, duplicateProps); + + return Either.right(responseFormat); + } + + } + } + } + return Either.left(ActionStatus.OK); + } + + private boolean isAbstract(String dataTypeName) { + + ToscaPropertyType isPrimitiveToscaType = ToscaPropertyType.isValidType(dataTypeName); + + return isPrimitiveToscaType != null && isPrimitiveToscaType.isAbstract() == true; + + } + + private boolean isScalarType(DataTypeDefinition dataTypeDef) { + + boolean isScalar = false; + DataTypeDefinition dataType = dataTypeDef; + + while (dataType != null) { + + String name = dataType.getName(); + if (ToscaPropertyType.isScalarType(name)) { + isScalar = true; + break; + } + + dataType = dataType.getDerivedFrom(); + } + + return isScalar; + } + + private DataTypeDefinition createDataType(String dataTypeName, Map toscaJson) { + DataTypeDefinition dataType = new DataTypeDefinition(); + + dataType.setName(dataTypeName); + + if (toscaJson != null) { + // Description + final Consumer descriptionSetter = description -> dataType.setDescription(description); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DESCRIPTION.getElementName(), descriptionSetter); + // Derived From + final Consumer derivedFromSetter = derivedFrom -> dataType.setDerivedFromName(derivedFrom); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DERIVED_FROM.getElementName(), derivedFromSetter); + // Properties + commonImportManager.setProperties(toscaJson, (values) -> dataType.setProperties(values)); + + setConstraints(toscaJson, dataType); + } + return dataType; + } + + private void setConstraints(Map toscaJson, DataTypeDefinition dataType) { + // TODO Auto-generated method stub + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java new file mode 100644 index 0000000000..9d9425ea85 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/DistributionMonitoringBusinessLogic.java @@ -0,0 +1,214 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.info.DistributionStatusInfo; +import org.openecomp.sdc.be.info.DistributionStatusListResponse; +import org.openecomp.sdc.be.info.DistributionStatusOfServiceInfo; +import org.openecomp.sdc.be.info.DistributionStatusOfServiceListResponce; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; +import org.openecomp.sdc.be.resources.data.auditing.DistributionStatusEvent; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.ESTimeBasedEvent; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component("distributionMonitoringBusinessLogic") +public class DistributionMonitoringBusinessLogic extends BaseBusinessLogic { + private static final String DEPLOYED = "Deployed"; + + private static final String ERROR = "Error"; + + private static final String DISTRIBUTED = "Distributed"; + + private static final String IN_PROGRESS = "In Progress"; + + private static Logger log = LoggerFactory.getLogger(ArtifactsBusinessLogic.class.getName()); + + // @javax.annotation.Resource + // private AuditingDao auditingDao; + + @Autowired + private AuditCassandraDao cassandraDao; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + public DistributionMonitoringBusinessLogic() { + } + + public Either getListOfDistributionStatus(String did, String userId) { + + Either resp = validateUserExists(userId, "get List Of Distribution Status", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.trace("getListOfDistributionStatus for did {}", did); + Either, ActionStatus> distributionStatus = cassandraDao.getListOfDistributionStatuses(did); + if (distributionStatus.isRight()) { + log.debug("not found distribution statuses for did {} status is {} ", did, distributionStatus.right().value()); + return Either.right(componentsUtils.getResponseFormat(distributionStatus.right().value(), did)); + } + List distribStatusInfoList = new ArrayList(); + List distributionStatusEventList = distributionStatus.left().value(); + if (distributionStatusEventList != null) { + for (ESTimeBasedEvent distributionStatusEvent : distributionStatusEventList) { + distribStatusInfoList.add(new DistributionStatusInfo(distributionStatusEvent)); + } + } + + DistributionStatusListResponse distributionStatusListResponse = new DistributionStatusListResponse(); + distributionStatusListResponse.setDistributionStatusList(distribStatusInfoList); + log.trace("list statuses for did {} is {} ", did, distribStatusInfoList); + return Either.left(distributionStatusListResponse); + } + + public Either getListOfDistributionServiceStatus(String serviceUuid, String userId) { + Either resp = validateUserExists(userId, "get List Of Distribution Service Status", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.trace("getListOfDistributionServiceStatus for serviceUUID {}", serviceUuid); + Either, ActionStatus> status = cassandraDao.getServiceDistributionStatusesList(serviceUuid); + if (status.isRight()) { + log.debug("failed to find service distribution statuses. error: {}", status); + return Either.right(componentsUtils.getResponseFormat(status.right().value(), serviceUuid)); + } + List distribStatusInfoList = new ArrayList(); + List distributionStatusEventList = status.left().value(); + distribStatusInfoList = handleAuditingDaoResponse(distributionStatusEventList); + DistributionStatusOfServiceListResponce distributionStatusListResponse = new DistributionStatusOfServiceListResponce(); + distributionStatusListResponse.setDistributionStatusOfServiceList(distribStatusInfoList); + return Either.left(distributionStatusListResponse); + } + + private List handleAuditingDaoResponse(List distribStatusInfoList) { + List reslist = new ArrayList(); + Map> serviceDidMap = createServiceDidMap(distribStatusInfoList); + Set didSet = serviceDidMap.keySet(); + for (String did : didSet) { + DistributionStatusOfServiceInfo distributionStatusOfServiceInfo = new DistributionStatusOfServiceInfo(); + distributionStatusOfServiceInfo.setDistributionID(did); + String dReguestStatus = ""; + String dNotifyStatus = ""; + boolean isResult = false; + List auditingGenericEventList = serviceDidMap.get(did); + ESTimeBasedEvent resAuditingGenericEvent = null; + for (AuditingGenericEvent auditingGenericEvent : auditingGenericEventList) { + auditingGenericEvent.fillFields(); + + String action = (String) auditingGenericEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_ACTION.getDisplayName()); + Object modifierUserId = auditingGenericEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID.getDisplayName()); + if (modifierUserId != null) { + distributionStatusOfServiceInfo.setUserId((String) modifierUserId); + } + + if (action.equals(AuditingActionEnum.DISTRIBUTION_DEPLOY.getName())) { + + isResult = true; + resAuditingGenericEvent = auditingGenericEvent; + break; + } else if (action.equals(AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName())) { + dReguestStatus = getStatusFromAuditEvent(auditingGenericEvent); + } else if (action.equals(AuditingActionEnum.DISTRIBUTION_NOTIFY.getName())) { + dNotifyStatus = getStatusFromAuditEvent(auditingGenericEvent); + } + + resAuditingGenericEvent = auditingGenericEvent; + + } + distributionStatusOfServiceInfo.setTimestamp((String) resAuditingGenericEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP.getDisplayName())); + + if (!isResult) { + if (dReguestStatus.equals(String.valueOf(HttpStatus.SC_OK))) { + if (dNotifyStatus.isEmpty()) { + distributionStatusOfServiceInfo.setDeployementStatus(IN_PROGRESS); + + } else { + if (dNotifyStatus.equals(String.valueOf(HttpStatus.SC_OK))) + distributionStatusOfServiceInfo.setDeployementStatus(DISTRIBUTED); + else + distributionStatusOfServiceInfo.setDeployementStatus(ERROR); + } + } else + distributionStatusOfServiceInfo.setDeployementStatus(ERROR); + } else + distributionStatusOfServiceInfo.setDeployementStatus(DEPLOYED); + reslist.add(distributionStatusOfServiceInfo); + } + + return reslist; + } + + private String getStatusFromAuditEvent(ESTimeBasedEvent auditingGenericEvent) { + String status = ""; + Object requestStatus = auditingGenericEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_STATUS.getDisplayName()); + if (requestStatus instanceof String) { + status = (String) requestStatus; + } + return status; + } + + private Map> createServiceDidMap(List distribStatusInfoList) { + + Map> serviceDidMap = new HashMap>(); + for (AuditingGenericEvent auditingGenericEvent : distribStatusInfoList) { + List auditingGenericEventList = null; + String did = ""; + auditingGenericEvent.fillFields(); + + Object didValue = auditingGenericEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID.getDisplayName()); + if (didValue != null) { + did = (String) didValue; + } + + if (!did.isEmpty()) { + if (serviceDidMap.containsKey(did)) { + auditingGenericEventList = serviceDidMap.get(did); + } + if (auditingGenericEventList == null) { + auditingGenericEventList = new ArrayList(); + + } + auditingGenericEventList.add(auditingGenericEvent); + serviceDidMap.put(did, auditingGenericEventList); + } + } + return serviceDidMap; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java new file mode 100644 index 0000000000..5ebb86f1ba --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ElementBusinessLogic.java @@ -0,0 +1,1125 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.function.Predicate; + +import org.apache.http.NameValuePair; +import org.apache.http.client.utils.URLEncodedUtils; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; +import org.openecomp.sdc.be.datamodel.utils.NodeTypeConvertUtils; +import org.openecomp.sdc.be.datatypes.enums.AssetTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.Tag; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("elementsBusinessLogic") +public class ElementBusinessLogic extends BaseBusinessLogic { + + private static Logger log = LoggerFactory.getLogger(ElementBusinessLogic.class.getName()); + + @javax.annotation.Resource + private IElementOperation elementOperation; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + @javax.annotation.Resource + private UserBusinessLogic userAdminManager; + + /** + * + * @param user + * @return + */ + public Either>, ResponseFormat> getFollowed(User user) { + Either>, ResponseFormat> response = null; + // Getting the role + String role = user.getRole(); + String userId = null; + Role currentRole = Role.valueOf(role); + + switch (currentRole) { + case DESIGNER: + userId = user.getUserId(); + response = handleDesigner(userId); + break; + + case TESTER: + userId = user.getUserId(); + response = handleTester(userId); + break; + + case GOVERNOR: + userId = user.getUserId(); + response = handleGovernor(userId); + break; + + case OPS: + userId = user.getUserId(); + response = handleOps(userId); + break; + + case PRODUCT_STRATEGIST: + userId = user.getUserId(); + response = handleProductStrategist(userId); + break; + + case PRODUCT_MANAGER: + userId = user.getUserId(); + response = handleProductManager(userId); + break; + + case ADMIN: + response = handleAdmin(); + break; + + default: + response = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + break; + } + return response; + + } + + private Either>, ResponseFormat> handleAdmin() { + Either>, ResponseFormat> response; + // userId should stay null + Set lifecycleStates = new HashSet(); + Set lastStateStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + response = getFollowedResourcesAndServices(null, lifecycleStates, lastStateStates); + return response; + } + + private Either>, ResponseFormat> handleDesigner(String userId) { + Set lifecycleStates = new HashSet(); + Set lastStateStates = new HashSet(); + Either>, ResponseFormat> response; + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + // more states + lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + response = getFollowedResourcesAndServices(userId, lifecycleStates, lastStateStates); + return response; + } + + private Either>, ResponseFormat> handleGovernor(String userId) { + Either>, ResponseFormat> result = handleFollowedCertifiedServices(null); + return result; + } + + private Either>, ResponseFormat> handleProductStrategist(String userId) { + // Should be empty list according to Ella, 13/03/16 + Map> result = new HashMap>(); + result.put("products", new ArrayList<>()); + return Either.left(result); + } + + private Either>, ResponseFormat> handleProductManager(String userId) { + Set lifecycleStates = new HashSet(); + Set lastStateStates = new HashSet(); + Either>, ResponseFormat> response; + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN); + lifecycleStates.add(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + lifecycleStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + lifecycleStates.add(LifecycleStateEnum.CERTIFIED); + // more states + lastStateStates.add(LifecycleStateEnum.READY_FOR_CERTIFICATION); + response = getFollowedProducts(userId, lifecycleStates, lastStateStates); + return response; + } + + private Either>, ResponseFormat> handleOps(String userId) { + Set distStatus = new HashSet(); + distStatus.add(DistributionStatusEnum.DISTRIBUTION_APPROVED); + distStatus.add(DistributionStatusEnum.DISTRIBUTED); + + Either>, ResponseFormat> result = handleFollowedCertifiedServices(distStatus); + return result; + } + + private Either>, ResponseFormat> handleFollowedCertifiedServices(Set distStatus) { + Map propertiesToMatch = new HashMap<>(); + propertiesToMatch.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFIED.name()); + + Either, StorageOperationStatus> services = serviceOperation.getCertifiedServicesWithDistStatus(propertiesToMatch, distStatus, false); + if (services.isLeft()) { + Map> result = new HashMap>(); + List list = new ArrayList<>(); + list.addAll(services.left().value()); + result.put("services", list); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); + } + } + + private Either>, ResponseFormat> handleTester(String userId) { + Set lifecycleStates = new HashSet(); + lifecycleStates.add(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS); + Either, StorageOperationStatus> resources = resourceOperation.getTesterFollowed(userId, lifecycleStates, false); + + if (resources.isLeft()) { + Either, StorageOperationStatus> services = serviceOperation.getTesterFollowed(userId, lifecycleStates, false); + if (services.isLeft()) { + Map> result = new HashMap>(); + result.put("services", services.left().value()); + result.put("resources", resources.left().value()); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); + } + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value()))); + } + } + + private Either>, ResponseFormat> getFollowedResourcesAndServices(String userId, Set lifecycleStates, Set lastStateStates) { + Either, StorageOperationStatus> resources = resourceOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); + + if (resources.isLeft()) { + Either, StorageOperationStatus> services = serviceOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); + if (services.isLeft()) { + Map> result = new HashMap>(); + result.put("services", services.left().value()); + result.put("resources", resources.left().value()); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(services.right().value()))); + } + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resources.right().value()))); + } + } + + private Either>, ResponseFormat> getFollowedProducts(String userId, Set lifecycleStates, Set lastStateStates) { + Either, StorageOperationStatus> products = productOperation.getFollowed(userId, lifecycleStates, lastStateStates, false); + if (products.isLeft()) { + Map> result = new HashMap>(); + result.put("products", products.left().value()); + return Either.left(result); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(products.right().value()))); + } + } + + /* + * New categories flow - start + */ + public Either, ActionStatus> getAllResourceCategories() { + return elementOperation.getAllResourceCategories(); + } + + public Either, ActionStatus> getAllServiceCategories() { + return elementOperation.getAllServiceCategories(); + } + + public Either createCategory(CategoryDefinition category, String componentTypeParamName, String userId) { + + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_CATEGORY; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); + CategoryTypeEnum categoryType = CategoryTypeEnum.CATEGORY; + + User user = new User(); + Either validateUser = validateUser(userId); + if (validateUser.isRight()) { + log.debug("Validation of user failed, userId {}", userId); + ResponseFormat responseFormat = validateUser.right().value(); + user = new User(); + user.setUserId(userId); + String currCategoryName = (category == null ? null : category.getName()); + handleCategoryAuditing(responseFormat, user, currCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + user = validateUser.left().value(); + + if (category == null) { + log.debug("Category json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, null, auditingAction, componentType); + return Either.right(responseFormat); + } + + String categoryName = category.getName(); + // For auditing of failures we need the original non-normalized name + String origCategoryName = categoryName; + if (componentTypeEnum == null) { + log.debug("Component type {} is invalid", componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug("Validation of user role failed, userId {}", userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + if (!ValidationUtils.validateCategoryDisplayNameFormat(categoryName)) { + log.debug("Category display name format is invalid, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + categoryName = ValidationUtils.normalizeCategoryName4Display(categoryName); + + if (!ValidationUtils.validateCategoryDisplayNameLength(categoryName)) { + log.debug("Category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + category.setName(categoryName); + + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(categoryName); + category.setNormalizedName(normalizedName); + + NodeTypeEnum nodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, categoryType); + + Either categoryUniqueEither = elementOperation.isCategoryUniqueForType(nodeType, normalizedName); + if (categoryUniqueEither.isRight()) { + log.debug("Failed to check category uniqueness, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(categoryUniqueEither.right().value()); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Boolean isCategoryUnique = categoryUniqueEither.left().value(); + if (!isCategoryUnique) { + log.debug("Category is not unique, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either createCategoryByType = elementOperation.createCategory(category, nodeType); + if (createCategoryByType.isRight()) { + log.debug("Failed to create category, name {}, componentType {}", categoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_CATEGORY_ALREADY_EXISTS, componentType, categoryName); + handleCategoryAuditing(responseFormat, user, origCategoryName, auditingAction, componentType); + return Either.right(componentsUtils.getResponseFormat(createCategoryByType.right().value())); + } + category = createCategoryByType.left().value(); + log.debug("Created category for component {}, name {}, uniqueId {}", componentType, categoryName, category.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, category.getName(), auditingAction, componentType); + return Either.left(category); + } + + public Either createSubCategory(SubCategoryDefinition subCategory, String componentTypeParamName, String parentCategoryId, String userId) { + + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_SUB_CATEGORY; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); + CategoryTypeEnum categoryType = CategoryTypeEnum.SUBCATEGORY; + // For auditing + String parentCategoryName = parentCategoryId; + + if (subCategory == null) { + log.debug("Sub-category json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, null, parentCategoryName, null, auditingAction, componentType); + return Either.right(responseFormat); + } + + String subCategoryName = subCategory.getName(); + // For auditing of failures we need the original non-normalized name + String origSubCategoryName = subCategoryName; + + User user = new User(); + /* + * if (userId == null) { user.setUserId("UNKNOWN"); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, + * auditingAction, componentType); return Either.right(responseFormat); } + */ + Either validateUser = validateUserExists(userId, "createSubCategory", false); + if (validateUser.isRight()) { + log.debug("Validation of user failed, userId {}", userId); + ResponseFormat responseFormat = validateUser.right().value(); + user = new User(); + user.setUserId(userId); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + user = validateUser.left().value(); + + if (componentTypeEnum == null) { + log.debug("Component type {} is invalid", componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); + if (validateComponentType.isRight()) { + log.debug("Validation of component type for sub-category failed"); + ResponseFormat responseFormat = validateComponentType.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug("Validation of user role failed, userId {}", userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + + CategoryDefinition categoryDefinition; + Either validateCategoryExists = validateCategoryExists(parentNodeType, parentCategoryId, componentTypeEnum); + if (validateCategoryExists.isRight()) { + log.debug("Validation of parent category exists failed, parent categoryId {}", parentCategoryId); + ResponseFormat responseFormat = validateCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + categoryDefinition = validateCategoryExists.left().value(); + parentCategoryName = categoryDefinition.getName(); + + if (!ValidationUtils.validateCategoryDisplayNameFormat(subCategoryName)) { + log.debug("Sub-category display name format is invalid, name {}, componentType {}", subCategoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + subCategoryName = ValidationUtils.normalizeCategoryName4Display(subCategoryName); + + if (!ValidationUtils.validateCategoryDisplayNameLength(subCategoryName)) { + log.debug("Sub-category display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", subCategoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(subCategoryName); + subCategory.setNormalizedName(normalizedName); + + // Uniqueness under this category + Either subCategoryUniqueForCategory = elementOperation.isSubCategoryUniqueForCategory(childNodeType, normalizedName, parentCategoryId); + if (subCategoryUniqueForCategory.isRight()) { + log.debug("Failed to check sub-category uniqueness, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForCategory.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Boolean isSubUnique = subCategoryUniqueForCategory.left().value(); + if (!isSubUnique) { + log.debug("Sub-category is not unique for category, parent name {}, subcategory norm name {}, componentType {}", parentCategoryName, normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY, componentType, subCategoryName, parentCategoryName); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + // Setting name of subcategory to fit the similar subcategory name + // ignoring cases. + // For example if Network-->kUKU exists for service category Network, + // and user is trying to create Router-->Kuku for service category + // Router, + // his subcategory name will be Router-->kUKU. + Either subCategoryUniqueForType = elementOperation.getSubCategoryUniqueForType(childNodeType, normalizedName); + if (subCategoryUniqueForType.isRight()) { + log.debug("Failed validation of whether similar sub-category exists, normalizedName {} componentType {}", normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + SubCategoryDefinition subCategoryDefinition = subCategoryUniqueForType.left().value(); + if (subCategoryDefinition != null) { + subCategoryName = subCategoryDefinition.getName(); + } + + subCategory.setName(subCategoryName); + ///////////////////////////////////////////// Validations end + + Either createSubCategory = elementOperation.createSubCategory(parentCategoryId, subCategory, childNodeType); + if (createSubCategory.isRight()) { + log.debug("Failed to create sub-category, name {}, componentType {}", subCategoryName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(subCategoryUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, origSubCategoryName, auditingAction, componentType); + return Either.right(responseFormat); + } + + SubCategoryDefinition subCategoryCreated = createSubCategory.left().value(); + log.debug("Created sub-category for component {}, name {}, uniqueId {}", componentType, subCategoryName, subCategoryCreated.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, parentCategoryName, subCategoryCreated.getName(), auditingAction, componentType); + return Either.left(subCategoryCreated); + } + + public Either createGrouping(GroupingDefinition grouping, String componentTypeParamName, String grandParentCategoryId, String parentSubCategoryId, String userId) { + + AuditingActionEnum auditingAction = AuditingActionEnum.ADD_GROUPING; + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + String componentType = (componentTypeEnum == null ? componentTypeParamName : componentTypeEnum.getValue()); + CategoryTypeEnum categoryType = CategoryTypeEnum.GROUPING; + // For auditing + String parentCategoryName = grandParentCategoryId; + String parentSubCategoryName = parentSubCategoryId; + + User user; + Either validateUser = validateUserExists(userId, "create Grouping", false); + if (validateUser.isRight()) { + log.debug("Validation of user failed, userId {}", userId); + ResponseFormat responseFormat = validateUser.right().value(); + user = new User(); + user.setUserId(userId); + String groupingNameForAudit = (grouping == null ? null : grouping.getName()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingNameForAudit, auditingAction, componentType); + return Either.right(responseFormat); + } + + user = validateUser.left().value(); + + if (grouping == null) { + log.debug("Grouping json is invalid"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, null, auditingAction, componentType); + return Either.right(responseFormat); + } + + String groupingName = grouping.getName(); + // For auditing of failures we need the original non-normalized name + String origGroupingName = groupingName; + + if (componentTypeEnum == null) { + log.debug("Component type {} is invalid", componentTypeParamName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either validateComponentType = validateComponentTypeForCategory(componentTypeEnum, categoryType); + if (validateComponentType.isRight()) { + log.debug("Validation of component type for grouping failed"); + ResponseFormat responseFormat = validateComponentType.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Either validateUserRole = validateUserRole(user, componentTypeEnum); + if (validateUserRole.isRight()) { + log.debug("Validation of user role failed, userId {}", userId); + ResponseFormat responseFormat = validateUserRole.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + NodeTypeEnum grandParentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + NodeTypeEnum parentNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + NodeTypeEnum childNodeType = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); + + // Validate category + CategoryDefinition categoryDefinition; + Either validateCategoryExists = validateCategoryExists(grandParentNodeType, grandParentCategoryId, componentTypeEnum); + if (validateCategoryExists.isRight()) { + log.debug("Validation of parent category exists failed, parent categoryId {}", grandParentCategoryId); + ResponseFormat responseFormat = validateCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + categoryDefinition = validateCategoryExists.left().value(); + parentCategoryName = categoryDefinition.getName(); + + // Validate subcategory + SubCategoryDefinition subCategoryDefinition; + Either validateSubCategoryExists = validateSubCategoryExists(parentNodeType, parentSubCategoryId, componentTypeEnum); + if (validateSubCategoryExists.isRight()) { + log.debug("Validation of parent sub-category exists failed, parent sub-category id {}", parentSubCategoryId); + ResponseFormat responseFormat = validateSubCategoryExists.right().value(); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + subCategoryDefinition = validateSubCategoryExists.left().value(); + parentSubCategoryName = subCategoryDefinition.getName(); + + if (!ValidationUtils.validateCategoryDisplayNameFormat(groupingName)) { + log.debug("Sub-category display name format is invalid, name {}, componentType {}", groupingName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + groupingName = ValidationUtils.normalizeCategoryName4Display(groupingName); + + if (!ValidationUtils.validateCategoryDisplayNameLength(groupingName)) { + log.debug("Grouping display name length is invalid, should be from 4 to 25 chars, name {}, componentType {}", groupingName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, componentType, categoryType.getValue()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + String normalizedName = ValidationUtils.normalizeCategoryName4Uniqueness(groupingName); + grouping.setNormalizedName(normalizedName); + + // Uniqueness under this category + Either groupingUniqueForSubCategory = elementOperation.isGroupingUniqueForSubCategory(childNodeType, normalizedName, parentSubCategoryId); + if (groupingUniqueForSubCategory.isRight()) { + log.debug("Failed to check grouping uniqueness, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForSubCategory.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + Boolean isGroupingUnique = groupingUniqueForSubCategory.left().value(); + if (!isGroupingUnique) { + log.debug("Grouping is not unique for sub-category, parent name {}, grouping norm name {}, componentType {}", parentSubCategoryName, normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY, componentType, groupingName, parentSubCategoryName); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + // Setting name of grouping to fit the similar grouping name ignoring + // cases. + // For example if Network-->kUKU exists for service sub-category + // Network, and user is trying to create grouping Router-->Kuku for + // service sub-category Router, + // his grouping name will be Router-->kUKU. + Either groupingUniqueForType = elementOperation.getGroupingUniqueForType(childNodeType, normalizedName); + if (groupingUniqueForType.isRight()) { + log.debug("Failed validation of whether similar grouping exists, normalizedName {} componentType {}", normalizedName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(groupingUniqueForType.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + GroupingDefinition groupingDefinition = groupingUniqueForType.left().value(); + if (groupingDefinition != null) { + groupingName = groupingDefinition.getName(); + } + + grouping.setName(groupingName); + ///////////////////////////////////////////// Validations end + + Either createGrouping = elementOperation.createGrouping(parentSubCategoryId, grouping, childNodeType); + if (createGrouping.isRight()) { + log.debug("Failed to create grouping, name {}, componentType {}", groupingName, componentType); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(createGrouping.right().value()); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, origGroupingName, auditingAction, componentType); + return Either.right(responseFormat); + } + + GroupingDefinition groupingCreated = createGrouping.left().value(); + log.debug("Created grouping for component {}, name {}, uniqueId {}", componentType, groupingName, groupingCreated.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleCategoryAuditing(responseFormat, user, parentCategoryName, parentSubCategoryName, groupingCreated.getName(), auditingAction, componentType); + return Either.left(groupingCreated); + } + + public Either, ResponseFormat> getAllCategories(String componentType, String userId) { + AuditingActionEnum auditingAction = AuditingActionEnum.GET_CATEGORY_HIERARCHY; + ResponseFormat responseFormat; + User user = new User(); + if (userId == null) { + user.setUserId("UNKNOWN"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); + return Either.right(responseFormat); + } + + Either validateUser = validateUserExists(userId, "get All Categories", false); + if (validateUser.isRight()) { + user.setUserId(userId); + log.debug("Validation of user failed, userId {}", userId); + responseFormat = validateUser.right().value(); + componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); + return Either.right(responseFormat); + } + user = validateUser.left().value(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum == null) { + log.debug("Cannot create category for component type {}", componentType); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, "component type"); + componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); + return Either.right(responseFormat); + } + + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + Either, ActionStatus> getAllCategoriesByType = elementOperation.getAllCategories(nodeTypeEnum, false); + if (getAllCategoriesByType.isRight()) { + responseFormat = componentsUtils.getResponseFormat(getAllCategoriesByType.right().value()); + componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); + return Either.right(responseFormat); + } + List categories = getAllCategoriesByType.left().value(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + componentsUtils.auditGetCategoryHierarchy(auditingAction, user, componentType, responseFormat); + return Either.left(categories); + } + + public Either deleteCategory(String categoryId, String componentTypeParamName, String userId) { + + Either resp = validateUserExists(userId, "delete Category", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot create category for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.CATEGORY); + + Either deleteCategoryByType = elementOperation.deleteCategory(nodeTypeEnum, categoryId); + if (deleteCategoryByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteCategoryByType.right().value())); + } + CategoryDefinition category = deleteCategoryByType.left().value(); + log.debug("Delete category for component {}, name {}, uniqueId {}", nodeTypeEnum, category.getName(), category.getUniqueId()); + return Either.left(category); + } + + public Either deleteSubCategory(String grandParentCategoryId, String parentSubCategoryId, String componentTypeParamName, String userId) { + + Either resp = validateUserExists(userId, "delete Sub Category", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot delete sub-category for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.SUBCATEGORY); + + Either deleteSubCategoryByType = elementOperation.deleteSubCategory(nodeTypeEnum, parentSubCategoryId); + if (deleteSubCategoryByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteSubCategoryByType.right().value())); + } + SubCategoryDefinition subCategory = deleteSubCategoryByType.left().value(); + log.debug("Deleted sub-category for component {}, name {}, uniqueId {}", nodeTypeEnum, subCategory.getName(), subCategory.getUniqueId()); + return Either.left(subCategory); + } + + public Either deleteGrouping(String grandParentCategoryId, String parentSubCategoryId, String groupingId, String componentTypeParamName, String userId) { + + Either resp = validateUserExists(userId, "delete Grouping", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentTypeParamName); + if (componentTypeEnum == null) { + log.debug("Cannot delete grouping for component type {}", componentTypeParamName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + NodeTypeEnum nodeTypeEnum = NodeTypeConvertUtils.getCategoryNodeTypeByComponentParam(componentTypeEnum, CategoryTypeEnum.GROUPING); + + Either deleteGroupingByType = elementOperation.deleteGrouping(nodeTypeEnum, groupingId); + if (deleteGroupingByType.isRight()) { + // auditing, logging here... + return Either.right(componentsUtils.getResponseFormat(deleteGroupingByType.right().value())); + } + GroupingDefinition deletedGrouping = deleteGroupingByType.left().value(); + log.debug("Deleted grouping for component {}, name {}, uniqueId {}", nodeTypeEnum, deletedGrouping.getName(), deletedGrouping.getUniqueId()); + return Either.left(deletedGrouping); + } + + private Either validateUser(String userId) { + + // validate user exists + if (userId == null) { + log.debug("User id is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION)); + } + + Either userResult = userAdminManager.getUser(userId, false); + if (userResult.isRight()) { + ResponseFormat responseFormat; + if (userResult.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + log.debug("Not authorized user, userId = {}", userId); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } else { + log.debug("Failed to authorize user, userId = {}", userId); + responseFormat = componentsUtils.getResponseFormat(userResult.right().value()); + } + + return Either.right(responseFormat); + } + return Either.left(userResult.left().value()); + // ========================================- + } + + private Either validateUserRole(User user, ComponentTypeEnum componentTypeEnum) { + String role = user.getRole(); + boolean validAdminAction = (role.equals(Role.ADMIN.name()) && (componentTypeEnum == ComponentTypeEnum.SERVICE || componentTypeEnum == ComponentTypeEnum.RESOURCE)); + boolean validProductAction = (role.equals(Role.PRODUCT_STRATEGIST.name()) && (componentTypeEnum == ComponentTypeEnum.PRODUCT)); + + if (!(validAdminAction || validProductAction)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("User not permitted to perform operation on category, userId = {}, role = {}, componentType = {}", user.getUserId(), role, componentTypeEnum); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateComponentTypeForCategory(ComponentTypeEnum componentType, CategoryTypeEnum categoryType) { + boolean validResourceAction = (componentType == ComponentTypeEnum.RESOURCE && (categoryType == CategoryTypeEnum.CATEGORY || categoryType == CategoryTypeEnum.SUBCATEGORY)); + boolean validServiceAction = (componentType == ComponentTypeEnum.SERVICE && categoryType == CategoryTypeEnum.CATEGORY); + boolean validProductAction = (componentType == ComponentTypeEnum.PRODUCT); // can + // be + // any + // category + // type + + if (!(validResourceAction || validServiceAction || validProductAction)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + log.debug("It's not allowed to create category type {} for component type {}", categoryType, componentType); + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateCategoryExists(NodeTypeEnum nodeType, String categoryId, ComponentTypeEnum componentType) { + Either categoryByTypeAndId = elementOperation.getCategory(nodeType, categoryId); + if (categoryByTypeAndId.isRight()) { + log.debug("Failed to fetch parent category, parent categoryId {}", categoryId); + ActionStatus actionStatus = categoryByTypeAndId.right().value(); + ResponseFormat responseFormat; + if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { + responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.CATEGORY.getValue(), ""); + } else { + responseFormat = componentsUtils.getResponseFormat(actionStatus); + } + return Either.right(responseFormat); + } + return Either.left(categoryByTypeAndId.left().value()); + } + + private Either validateSubCategoryExists(NodeTypeEnum nodeType, String subCategoryId, ComponentTypeEnum componentType) { + Either subCategoryByTypeAndId = elementOperation.getSubCategory(nodeType, subCategoryId); + if (subCategoryByTypeAndId.isRight()) { + log.debug("Failed to fetch parent category, parent categoryId {}", subCategoryId); + ActionStatus actionStatus = subCategoryByTypeAndId.right().value(); + ResponseFormat responseFormat; + if (actionStatus == ActionStatus.COMPONENT_CATEGORY_NOT_FOUND) { + responseFormat = componentsUtils.getResponseFormat(actionStatus, componentType.getValue().toLowerCase(), CategoryTypeEnum.SUBCATEGORY.getValue(), ""); + } else { + responseFormat = componentsUtils.getResponseFormat(actionStatus); + } + return Either.right(responseFormat); + } + return Either.left(subCategoryByTypeAndId.left().value()); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, AuditingActionEnum auditingAction, String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, null, null, auditingAction, componentType); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, AuditingActionEnum auditingAction, String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, subCategory, null, auditingAction, componentType); + } + + private void handleCategoryAuditing(ResponseFormat responseFormat, User user, String category, String subCategory, String grouping, AuditingActionEnum auditingAction, String componentType) { + componentsUtils.auditCategory(responseFormat, user, category, subCategory, grouping, auditingAction, componentType); + } + + /* + * New categories flow - end + */ + + public Either, ActionStatus> getAllTags(String userId) { + Either resp = validateUserExistsActionStatus(userId, "get All Tags"); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + return elementOperation.getAllTags(); + } + + public Either, ActionStatus> getAllPropertyScopes(String userId) { + Either resp = validateUserExistsActionStatus(userId, "get All Property Scopes"); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + return elementOperation.getAllPropertyScopes(); + } + + public Either, ActionStatus> getAllArtifactTypes(String userId) { + Either resp = validateUserExistsActionStatus(userId, "get All Artifact Types"); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + return elementOperation.getAllArtifactTypes(); + } + + public Either, ActionStatus> getAllDeploymentArtifactTypes() { + return elementOperation.getAllDeploymentArtifactTypes(); + } + + public Either getDefaultHeatTimeout() { + return elementOperation.getDefaultHeatTimeout(); + } + + public Either>, ResponseFormat> getCatalogComponents(String userId) { + Either resp = validateUserExists(userId, "get Catalog Components", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Map> resMap = new HashMap<>(); + + Either, StorageOperationStatus> resResources = resourceOperation.getResourceCatalogData(false); + if (resResources.isLeft()) { + Either, StorageOperationStatus> resServices = serviceOperation.getServiceCatalogData(false); + if (resServices.isLeft()) { + Either, StorageOperationStatus> resProducts = productOperation.getProductCatalogData(false); + if (resProducts.isLeft()) { + resMap.put("resources", resResources.left().value()); + resMap.put("services", resServices.left().value()); + resMap.put("products", resProducts.left().value()); + return Either.left(resMap); + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resProducts.right().value()))); + } + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resServices.right().value()))); + } + } else { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resResources.right().value()))); + } + } + + public Either, ResponseFormat> getFilteredCatalogComponents(String assetType, Map filters, String query) { + ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); + + if (query != null) { + Optional invalidFilter = findInvalidFilter(query, assetTypeEnum); + if (invalidFilter.isPresent()) { + log.debug("getFilteredAssetList: invalid filter key"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_FILTER_KEY, invalidFilter.get().getName(), FilterKeyEnum.getValidFiltersByAssetType(assetTypeEnum).toString())); + } + } + + if (filters == null || filters.isEmpty()) { + return getCatalogComponentsByAssetType(assetTypeEnum); + } + + ComponentOperation componentOperation = getComponentOperation(assetTypeEnum); + Either, StorageOperationStatus> result = componentOperation.getFilteredComponents(filters, false); + + if (result.isRight()) {// category hierarchy mismatch or + // category/subCategory/distributionStatus not + // found + List params = getErrorResponseParams(filters, assetTypeEnum); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(result.right().value()), params.get(0), params.get(1), params.get(2))); + } + if (result.left().value().isEmpty()) {// no assets found for requested + // criteria + return Either.right(componentsUtils.getResponseFormat(ActionStatus.NO_ASSETS_FOUND, assetType, query)); + } + return Either.left(result.left().value()); + } + + public Either, ResponseFormat> getCatalogComponentsByAssetType(ComponentTypeEnum assetTypeEnum) { + + if (assetTypeEnum == null) { + log.debug("getCatalogComponentsByAssetType: Corresponding ComponentTypeEnum not found"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + switch (assetTypeEnum) { + case RESOURCE: + + Either, StorageOperationStatus> resourceCatalogData = resourceOperation.getResourceCatalogDataVFLatestCertifiedAndNonCertified(false); + if (resourceCatalogData.isLeft()) { + log.debug("getCatalogComponentsByAssetType: Resource fetching successful"); + return Either.left(resourceCatalogData.left().value()); + } else { + log.debug("getCatalogComponentsByAssetType: Resource fetching failed"); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceCatalogData.right().value()))); + } + + case SERVICE: + Either, StorageOperationStatus> serviceCatalogData = serviceOperation.getServiceCatalogDataLatestCertifiedAndNotCertified(false); + if (serviceCatalogData.isLeft()) { + log.debug("getCatalogComponentsByAssetType: Service fetching successful"); + return Either.left(serviceCatalogData.left().value()); + } else { + log.debug("getCatalogComponentsByAssetType: Service fetching failed"); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceCatalogData.right().value()))); + } + /* + * case PRODUCT: Either, StorageOperationStatus> resCatalogData = productOperation.getProductCatalogData(false); if(resCatalogData.isLeft()){ log. debug("getCatalogComponentsByAssetType: Product fetching successful" ); + * return Either.left(resCatalogData.left().value()); }else { log. debug("getCatalogComponentsByAssetType: Product fetching failed" ); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse( + * resCatalogData.right().value()))); } + */ + default: + log.debug("Invalid Asset Type"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + + // TODO new story Tal + public Either, ResponseFormat> getCatalogComponentsByUuidAndAssetType(String assetType, String uuid) { + + if (assetType == null || assetType == null) { + log.debug("getCatalogComponentsByUuidAndAssetType: One of the function parameteres is null"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + ComponentTypeEnum assetTypeEnum = AssetTypeEnum.convertToComponentTypeEnum(assetType); + + if (assetTypeEnum == null) { + log.debug("getCatalogComponentsByUuidAndAssetType: Corresponding ComponentTypeEnum not found"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + switch (assetTypeEnum) { + + case RESOURCE: + Either, StorageOperationStatus> resourceListByUuid = resourceOperation.getLatestResourceByUuid(uuid, false); + + if (resourceListByUuid.isLeft()) { + log.debug("getCatalogComponentsByUuidAndAssetType: Resource fetching successful"); + return Either.left(resourceListByUuid.left().value()); + } + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(resourceListByUuid.right().value()); + log.debug("getCatalogComponentsByUuidAndAssetType: Resource fetching failed"); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + + case SERVICE: + Either, StorageOperationStatus> serviceCatalogData = serviceOperation.getLatestServiceByUuid(uuid, false); + + if (serviceCatalogData.isLeft()) { + log.debug("getCatalogComponentsByUuidAndAssetType: Service fetching successful"); + return Either.left(serviceCatalogData.left().value()); + } + + log.debug("getCatalogComponentsByUuidAndAssetType: Service fetching failed"); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceCatalogData.right().value()))); + // case Product is for future US + /* + * case PRODUCT: Either, StorageOperationStatus> resCatalogData = productOperation.getProductCatalogData(false); if(resCatalogData.isLeft()){ log. debug("getCatalogComponentsByAssetType: Product fetching successful" ); return + * Either.left(resCatalogData.left().value()); }else { log. debug("getCatalogComponentsByAssetType: Product fetching failed" ); return Either.right(componentsUtils .getResponseFormat(componentsUtils.convertFromStorageResponse( + * resCatalogData.right().value()))); } + */ + default: + log.debug("Invalid Asset Type"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + + public List getAllComponentTypesParamNames() { + List paramNames = new ArrayList<>(); + paramNames.add(ComponentTypeEnum.SERVICE_PARAM_NAME); + paramNames.add(ComponentTypeEnum.RESOURCE_PARAM_NAME); + paramNames.add(ComponentTypeEnum.PRODUCT_PARAM_NAME); + return paramNames; + } + + public List getAllSupportedRoles() { + Role[] values = Role.values(); + List roleNames = new ArrayList<>(); + for (Role role : values) { + roleNames.add(role.name()); + } + return roleNames; + } + + public Either, ActionStatus> getResourceTypesMap() { + return elementOperation.getResourceTypesMap(); + } + + private Optional findInvalidFilter(String query, ComponentTypeEnum assetType) { + List params = URLEncodedUtils.parse(query, StandardCharsets.UTF_8); + List validKeys = FilterKeyEnum.getValidFiltersByAssetType(assetType); + Predicate noMatch = p -> !validKeys.contains(p.getName()); + return params.stream().filter(noMatch).findAny(); + } + + private List getErrorResponseParams(Map filters, ComponentTypeEnum assetType) { + List params = new ArrayList(); + if (1 == filters.size()) { + params.add(assetType.getValue().toLowerCase()); + params.add(filters.keySet().iterator().next().getName()); + params.add(filters.values().iterator().next()); + } else { + params.add(assetType.getValue()); + params.add(filters.get(FilterKeyEnum.SUB_CATEGORY)); + params.add(filters.get(FilterKeyEnum.CATEGORY)); + } + return params; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java new file mode 100644 index 0000000000..3b4528d3a3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupBusinessLogic.java @@ -0,0 +1,1512 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import org.apache.commons.io.FilenameUtils; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.info.ArtifactDefinitionInfo; +import org.openecomp.sdc.be.info.ArtifactTemplateInfo; +import org.openecomp.sdc.be.info.GroupDefinitionInfo; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.GroupOperation; +import org.openecomp.sdc.be.model.operations.impl.GroupTypeOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +@org.springframework.stereotype.Component("groupBusinessLogic") +public class GroupBusinessLogic extends BaseBusinessLogic { + + public static String INITIAL_VERSION = "1"; + + private static final String CREATE_GROUP = "CreateGroup"; + + private static final String UPDATE_GROUP = "UpdateGroup"; + + private static final String GET_GROUP = "GetGroup"; + + private static Logger log = LoggerFactory.getLogger(GroupBusinessLogic.class.getName()); + + public GroupBusinessLogic() { + + } + + @javax.annotation.Resource + private GroupTypeOperation groupTypeOperation; + + @javax.annotation.Resource + private GroupOperation groupOperation; + + /** + * + * 1. validate user exist + * + * 2. validate component can be edited + * + * 3. verify group not already exist + * + * 4. verify type of group exist + * + * 5. verify Component instances exist under the component + * + * 6. verify the component instances type are allowed according to the member types in the group type + * + * 7. verify the artifacts belongs to the component + * + * @param componentId + * @param userId + * @param componentType + * @param groupDefinition + * @param inTransaction + * @return + */ + public Either createGroup(String componentId, String userId, ComponentTypeEnum componentType, GroupDefinition groupDefinition, boolean inTransaction) { + + Either result = null; + + try { + Either validateUserExists = validateUserExists(userId, CREATE_GROUP, inTransaction); + + if (validateUserExists.isRight()) { + result = Either.right(validateUserExists.right().value()); + return result; + } + + User user = validateUserExists.left().value(); + // 5. check service/resource existence + // 6. check service/resource check out + // 7. user is owner of checkout state + org.openecomp.sdc.be.model.Component component = null; + + // String realComponentId = componentType == + // ComponentTypeEnum.RESOURCE_INSTANCE ? parentId : componentId; + String realComponentId = componentId; + + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreComponentInstances(false); + + Either validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView, userId, null, user); + + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + component = validateComponent.left().value(); + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + result = Either.right(canWork.right().value()); + return result; + } + + result = this.createGroup(component, user, componentType, groupDefinition, inTransaction); + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + } + + private String getComponentTypeForResponse(org.openecomp.sdc.be.model.Component component) { + String componentTypeForResponse = "SERVICE"; + if (component instanceof Resource) { + componentTypeForResponse = ((Resource) component).getResourceType().name(); + } + return componentTypeForResponse; + } + + /** + * Verify that the artifact members belongs to the component + * + * @param component + * @param artifacts + * @return + */ + private Either verifyArtifactsBelongsToComponent(Component component, List artifacts, String context) { + + if (artifacts == null || true == artifacts.isEmpty()) { + return Either.left(true); + } + + Map deploymentArtifacts = component.getDeploymentArtifacts(); + if (deploymentArtifacts == null || true == deploymentArtifacts.isEmpty()) { + BeEcompErrorManager.getInstance().logInvalidInputError(context, "No deployment artifact found under component " + component.getNormalizedName(), ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + List currentArtifacts = deploymentArtifacts.values().stream().map(p -> p.getUniqueId()).collect(Collectors.toList()); + log.debug("The deployment artifacts of component {} are {}", component.getNormalizedName(), deploymentArtifacts); + if (false == currentArtifacts.containsAll(artifacts)) { + BeEcompErrorManager.getInstance().logInvalidInputError(context, "Not all artifacts belongs to component " + component.getNormalizedName(), ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + return Either.left(true); + + } + + /** + * Verify that the artifact members belongs to the component + * + * @param component + * @param artifacts + * @return + */ + private Either, ResponseFormat> getArtifactsBelongsToComponent(Component component, List artifacts, String context) { + + /* + * if (artifacts == null || true == artifacts.isEmpty()) { return Either.left(true); } + */ + + Map deploymentArtifacts = component.getDeploymentArtifacts(); + if (deploymentArtifacts == null || true == deploymentArtifacts.isEmpty()) { + BeEcompErrorManager.getInstance().logInvalidInputError(context, "No deployment artifact found under component " + component.getNormalizedName(), ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + List resultList = new ArrayList(); + + for (String artifactId : artifacts) { + Optional groupArtifactOp = deploymentArtifacts.values().stream().filter(p -> p.getUniqueId().equals(artifactId)).findAny(); + + if (groupArtifactOp.isPresent()) { + ArtifactDefinition groupArtifact = groupArtifactOp.get(); + resultList.add(groupArtifact); + } else { + BeEcompErrorManager.getInstance().logInvalidInputError(context, "Not all artifacts belongs to component " + component.getNormalizedName(), ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + + } + } + + return Either.left(resultList); + + } + + /** + * verify that the members are component instances of the component + * + * @param component + * @param componentType + * @param groupMembers + * @param memberToscaTypes + * @return + */ + private Either verifyComponentInstancesAreValidMembers(Component component, ComponentTypeEnum componentType, String groupName, String groupType, Map groupMembers, List memberToscaTypes) { + + if (groupMembers == null || true == groupMembers.isEmpty()) { + return Either.left(true); + } + + if (memberToscaTypes == null || true == memberToscaTypes.isEmpty()) { + return Either.left(true); + } + + List componentInstances = component.getComponentInstances(); + if (componentInstances != null && false == componentInstances.isEmpty()) { + Map compInstUidToCompInstMap = componentInstances.stream().collect(Collectors.toMap(p -> p.getUniqueId(), p -> p)); + + Set allCompInstances = compInstUidToCompInstMap.keySet(); + + for (Entry groupMember : groupMembers.entrySet()) { + String compName = groupMember.getKey(); + String compUid = groupMember.getValue(); + + if (false == allCompInstances.contains(compUid)) { + /* + * %1 - member name %2 - group name %3 - VF name %4 - component type [VF ] + */ + String componentTypeForResponse = getComponentTypeForResponse(component); + + BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Not all group members exists under the component", ErrorSeverity.INFO); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, compName, groupName, component.getNormalizedName(), componentTypeForResponse)); + } + } + + ComponentOperation componentOperation = getComponentOperationByParentComponentType(componentType); + if (componentOperation instanceof ResourceOperation) { + ResourceOperation resourceOperation = (ResourceOperation) componentOperation; + + for (Entry groupMember : groupMembers.entrySet()) { + + String componentInstName = groupMember.getKey(); + String componentInstUid = groupMember.getValue(); + + ComponentInstance componentInstance = compInstUidToCompInstMap.get(componentInstUid); + String componentUid = componentInstance.getComponentUid(); + List componentToscaNames = new ArrayList<>(); + TitanOperationStatus status = resourceOperation.fillResourceDerivedListFromGraph(componentUid, componentToscaNames); + if (status != TitanOperationStatus.OK) { + BeEcompErrorManager.getInstance().logInternalFlowError(CREATE_GROUP, "Cannot find tosca list of component id " + componentUid, ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + log.debug("The tosca names of component id {} are {}", componentUid, memberToscaTypes); + + boolean found = false; + for (String memberToscaType : memberToscaTypes) { + if (componentToscaNames.contains(memberToscaType)) { + found = true; + break; + } + } + if (found == false) { + BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, + "No tosca types from " + memberToscaTypes + " can be found in the tosca list " + componentToscaNames + " of component " + componentInstance.getNormalizedName(), ErrorSeverity.INFO); + /* + * # %1 - member name # %2 - group name # %3 - group type + */ + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE, componentInstName, groupName, groupType)); + } else { + log.debug("Component instance {} fits to one of the required tosca types", componentInstance.getNormalizedName()); + } + } + } else { + BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "Cannot find tosca list since it is not supported for product", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + return Either.left(true); + } + + public ComponentOperation getComponentOperation(NodeTypeEnum componentType) { + + switch (componentType) { + case Service: + case ResourceInstance: + return serviceOperation; + case Resource: + return resourceOperation; + default: + return null; + } + } + + /** + * Update specific group version + * + * @param groupDefinition + * @param inTransaction + * @return + */ + public Either updateGroupVersion(GroupDefinition groupDefinition, boolean inTransaction) { + Either result = null; + List groupIdsToUpdateVersion = new ArrayList<>(); + groupIdsToUpdateVersion.add(groupDefinition.getUniqueId()); + Either, StorageOperationStatus> updateGroupVersion = updateGroupVersion(groupIdsToUpdateVersion, inTransaction); + if (updateGroupVersion.isLeft()) { + result = Either.left(updateGroupVersion.left().value().get(0)); + } else { + log.debug("Failed to update group version. Status is {} ", updateGroupVersion.right().value()); + result = Either.right(updateGroupVersion.right().value()); + } + return result; + } + + /** + * Update list of groups versions + * + * @param groupsUniqueId + * @param inTransaction + * @return + */ + public Either, StorageOperationStatus> updateGroupVersion(List groupsUniqueId, boolean inTransaction) { + + Either, StorageOperationStatus> result = null; + + try { + + result = groupOperation.updateGroupVersion(groupsUniqueId, true); + + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + + } + + /** + * Update GroupDefinition metadata + * + * @param componentId + * @param user + * @param groupId + * @param componentType + * @param groupUpdate + * @param inTransaction + * @return + */ + public Either updateGroupMetadata(String componentId, User user, String groupUniqueId, ComponentTypeEnum componentType, GroupDefinition groupUpdate, boolean inTransaction) { + + Either result = null; + + // Validate user and validate group belongs to component + List groups = new ArrayList<>(); + groups.add(groupUpdate); + Either validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, user.getUserId(), componentType, groups, inTransaction); + if (validateGroupsBeforeUpdate.isRight()) { + result = Either.right(validateGroupsBeforeUpdate.right().value()); + return result; + } + Component component = validateGroupsBeforeUpdate.left().value(); + + // Get the GroupDefinition object + Either groupStatus = groupOperation.getGroup(groupUniqueId); + if (groupStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(groupStatus.right().value(), ComponentTypeEnum.SERVICE), "")); + } + GroupDefinition currentGroup = groupStatus.left().value(); + + // Validate group type is vfModule + if (!currentGroup.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE)) { + log.error("Group update metadata: Group type is different then: {}", Constants.DEFAULT_GROUP_VF_MODULE); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_TYPE, groupUpdate.getType()); + return Either.right(responseFormat); + } + + Either validationRsponse = validateAndUpdateGroupMetadata(currentGroup, groupUpdate); + if (validationRsponse.isRight()) { + log.info("Group update metadata: validations field."); + return validationRsponse; + } + GroupDefinition groupToUpdate = validationRsponse.left().value(); + + // lock resource + Either lockResult = lockComponent(componentId, component, "Update GroupDefinition Metadata"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either updateResponse = groupOperation.updateGroupName(groupUniqueId, groupUpdate.getName(), inTransaction); + if (updateResponse.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Update GroupDefinition Metadata"); + BeEcompErrorManager.getInstance().logBeSystemError("Update GroupDefinition Metadata"); + log.debug("failed to update sevice {}", groupToUpdate.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + return Either.left(updateResponse.left().value()); + } finally { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + } + + /** + * Validate and update GroupDefinition metadata + * + * @param user + * @param currentGroup + * @param groupUpdate + * @return + */ + private Either validateAndUpdateGroupMetadata(GroupDefinition currentGroup, GroupDefinition groupUpdate) { + // Check if to update, and update GroupDefinition name. + Either response = validateAndUpdateGroupName(currentGroup, groupUpdate); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + // Do not allow to update GroupDefinition version directly. + String versionUpdated = groupUpdate.getVersion(); + String versionCurrent = currentGroup.getVersion(); + if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) { + log.info("update Group: recived request to update version to {} the field is not updatable ignoring.", versionUpdated); + } + + return Either.left(currentGroup); + } + + /** + * Validate and update GroupDefinition name + * + * @param user + * @param currentGroup + * @param groupUpdate + * @return + */ + private Either validateAndUpdateGroupName(GroupDefinition currentGroup, GroupDefinition groupUpdate) { + String nameUpdated = groupUpdate.getName(); + String nameCurrent = currentGroup.getName(); + if (!nameCurrent.equals(nameUpdated)) { + Either validatNameResponse = validateGroupName(currentGroup.getName(), groupUpdate.getName()); + if (validatNameResponse.isRight()) { + ResponseFormat errorRespons = validatNameResponse.right().value(); + return Either.right(errorRespons); + } + currentGroup.setName(groupUpdate.getName()); + } + return Either.left(true); + } + + /** + * Validate that group name to update is valid (same as current group name except for middle part). For example: Current group name: MyResource..MyDesc..Module-1 Group to update: MyResource..MyDesc2..Module-1 Verify that only the second part + * MyDesc was changed. + * + * @param currentGroupName + * @param groupUpdateName + * @return + */ + private Either validateGroupName(String currentGroupName, String groupUpdateName) { + try { + // Check if the group name is in old format. + if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupUpdateName).matches()) { + log.error("Group name {} is in old format", groupUpdateName); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME, groupUpdateName)); + } + + // Check that name pats 1 and 3 did not changed (only the second + // part can be changed) + // But verify before that the current group format is the new one + if (!Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(currentGroupName).matches()) { + String[] split1 = currentGroupName.split("\\.\\."); + String currentResourceName = split1[0]; + String currentCounter = split1[2]; + + String[] split2 = groupUpdateName.split("\\.\\."); + String groupUpdateResourceName = split2[0]; + String groupUpdateCounter = split2[2]; + + if (!currentResourceName.equals(groupUpdateResourceName)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentResourceName)); + } + + if (!currentCounter.equals(groupUpdateCounter)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME_MODIFICATION, currentCounter)); + } + } + + return Either.left(true); + } catch (Exception e) { + log.error("Error valiadting group name", e); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + + /** + * associate artifacts to a given group + * + * @param componentId + * @param userId + * @param componentType + * @param groups + * @param shouldLockComp + * @param inTransaction + * @return + */ + public Either, ResponseFormat> associateArtifactsToGroup(String componentId, String userId, ComponentTypeEnum componentType, List groups, boolean shouldLockComp, boolean inTransaction) { + + Either, ResponseFormat> result = null; + + if (shouldLockComp == true && inTransaction == true) { + BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); + // Cannot lock component since we are in a middle of another + // transaction. + ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + } + + Component component = null; + try { + + if (groups == null || groups.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); + } + + Either validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); + if (validateGroupsBeforeUpdate.isRight()) { + result = Either.right(validateGroupsBeforeUpdate.right().value()); + return result; + } + + component = validateGroupsBeforeUpdate.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, "Group - Associate Artifacts"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + List updatedGroups = new ArrayList<>(); + + List componentGroups = component.getGroups(); + + // per group, associate to it the artifacts + for (GroupDefinition groupDefinition : groups) { + + GroupDefinition componentGroup = componentGroups.stream().filter(p -> p.getUniqueId().equals(groupDefinition.getUniqueId())).findFirst().orElse(null); + if (componentGroup != null) { + List componentArtifacts = componentGroup.getArtifacts(); + int artifactsSizeInGroup = componentArtifacts == null ? 0 : componentArtifacts.size(); + if (artifactsSizeInGroup > 0) { + List artifactsToAssociate = groupDefinition.getArtifacts(); + + // if no artifcats sent + if (artifactsToAssociate == null || true == artifactsToAssociate.isEmpty()) { + continue; + } + + boolean isChanged = componentArtifacts.removeAll(artifactsToAssociate); + if (isChanged) {// I.e. At least one artifact is already + // associated to the group + log.debug("Some of the artifacts already associated to group {}", groupDefinition.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_ASSOCIATED, componentGroup.getName())); + } + } + } + + Either associateArtifactsToGroup = groupOperation.associateArtifactsToGroup(groupDefinition.getUniqueId(), groupDefinition.getArtifacts(), true); + + if (associateArtifactsToGroup.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateArtifactsToGroup.right().value()); + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); + return result; + } + updatedGroups.add(associateArtifactsToGroup.left().value()); + + } + + result = Either.left(updatedGroups); + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + } + + public Either, ResponseFormat> associateMembersToGroup(String componentId, String userId, ComponentTypeEnum componentType, List groups, boolean shouldLockComp, boolean inTransaction) { + + Either, ResponseFormat> result = null; + + if (shouldLockComp == true && inTransaction == true) { + BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); + // Cannot lock component since we are in a middle of another + // transaction. + ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + } + + Component component = null; + try { + + if (groups == null || groups.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); + } + + Either validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); + if (validateGroupsBeforeUpdate.isRight()) { + result = Either.right(validateGroupsBeforeUpdate.right().value()); + return result; + } + + component = validateGroupsBeforeUpdate.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, "Group - Associate Members"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + List updatedGroups = new ArrayList<>(); + + // per group, associate to it the members + for (GroupDefinition groupDefinition : groups) { + + Either associateMembersToGroup = groupOperation.associateMembersToGroup(groupDefinition.getUniqueId(), groupDefinition.getMembers(), true); + + if (associateMembersToGroup.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateMembersToGroup.right().value()); + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); + return result; + } else { + updatedGroups.add(associateMembersToGroup.left().value()); + } + + } + + result = Either.left(updatedGroups); + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + } + + /** + * associate artifacts to a given group + * + * @param componentId + * @param userId + * @param componentType + * @param groups + * @param shouldLockComp + * @param inTransaction + * @return + */ + public Either getGroupWithArtifactsById(ComponentTypeEnum componentType, String componentId, String groupId, String userId, boolean inTransaction) { + + Either result = null; + + // Validate user exist + Either validateUserExists = validateUserExists(userId, UPDATE_GROUP, true); + + if (validateUserExists.isRight()) { + result = Either.right(validateUserExists.right().value()); + return result; + } + + User user = validateUserExists.left().value(); + + // Validate component exist + org.openecomp.sdc.be.model.Component component = null; + String realComponentId = componentId; + + try { + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreComponentInstances(false); + + Either validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView, userId, null, user); + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + component = validateComponent.left().value(); + + // validate we can work on component + /* + * Either canWork = validateCanWorkOnComponent( component, userId); if (canWork.isRight()) { result = Either.right(canWork.right().value()); return result; } + */ + List groups = component.getGroups(); + Optional findAny = groups.stream().filter(p -> p.getUniqueId().equals(groupId)).findAny(); + if (findAny.isPresent()) { + GroupDefinition group = findAny.get(); + Boolean isBase = null;// Constants.IS_BASE; + List props = group.getProperties(); + if (props != null && !props.isEmpty()) { + Optional isBasePropOp = props.stream().filter(p -> p.getName().equals(Constants.IS_BASE)).findAny(); + if (isBasePropOp.isPresent()) { + GroupProperty propIsBase = isBasePropOp.get(); + isBase = Boolean.parseBoolean(propIsBase.getValue()); + + } else { + BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "failed to find prop isBase " + component.getNormalizedName(), ErrorSeverity.INFO); + // return + // Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + + } + } + + List artifacts = new ArrayList(); + List artifactsIds = group.getArtifacts(); + if (artifactsIds != null && !artifactsIds.isEmpty()) { + Either, ResponseFormat> getArtifacts = getArtifactsBelongsToComponent(component, artifactsIds, GET_GROUP); + if (getArtifacts.isRight()) { + log.debug("Faild to find artifacts in group {} under component {}", groupId, component.getUniqueId()); + // result = Either.right(getArtifacts.right().value()); + // return result; + } else { + + List artifactsFromComponent = getArtifacts.left().value(); + if (artifactsFromComponent != null && !artifactsFromComponent.isEmpty()) { + for (ArtifactDefinition artifactDefinition : artifactsFromComponent) { + ArtifactDefinitionInfo artifactDefinitionInfo = new ArtifactDefinitionInfo(artifactDefinition); + artifacts.add(artifactDefinitionInfo); + } + } + } + } + GroupDefinitionInfo resultInfo = new GroupDefinitionInfo(group); + resultInfo.setIsBase(isBase); + if (!artifacts.isEmpty()) + resultInfo.setArtifacts(artifacts); + + result = Either.left(resultInfo); + + return result; + + } else { + log.debug("Faild to find group {} under component {}", groupId, component.getUniqueId()); + BeEcompErrorManager.getInstance().logInvalidInputError(GET_GROUP, "group " + groupId + " not found under component " + component.getUniqueId(), ErrorSeverity.INFO); + String componentTypeForResponse = getComponentTypeForResponse(component); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, groupId, component.getSystemName(), componentTypeForResponse)); + return result; + + } + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + + } + + /** + * @param componentId + * @param userId + * @param componentType + * @param groups + * @param inTransaction + * @return + */ + private Either validateGroupsBeforeUpdate(String componentId, String userId, ComponentTypeEnum componentType, List groups, boolean inTransaction) { + + Either result; + + // Validate user exist + Either validateUserExists = validateUserExists(userId, UPDATE_GROUP, inTransaction); + if (validateUserExists.isRight()) { + result = Either.right(validateUserExists.right().value()); + return result; + } + User user = validateUserExists.left().value(); + + // Validate component exist + String realComponentId = componentId; + + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreComponentInstances(false); + + Either validateComponent = validateComponentExists(realComponentId, componentType, componentParametersView, userId, null, user); + + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + org.openecomp.sdc.be.model.Component component = validateComponent.left().value(); + + // validate we can work on component + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + result = Either.right(canWork.right().value()); + return result; + } + + // Validate groups exists in the component + ResponseFormat validateGroupsInComponent = validateGroupsInComponentByFunc(groups, component, p -> p.getUniqueId()); + if (validateGroupsInComponent != null) { + result = Either.right(validateGroupsInComponent); + return result; + } + + Set artifacts = new HashSet<>(); + groups.forEach(p -> { + if (p.getArtifacts() != null) { + artifacts.addAll(p.getArtifacts()); + } + }); + // validate all artifacts belongs to the component + Either verifyArtifactsBelongsToComponent = verifyArtifactsBelongsToComponent(component, new ArrayList<>(artifacts), UPDATE_GROUP); + if (verifyArtifactsBelongsToComponent.isRight()) { + result = Either.right(verifyArtifactsBelongsToComponent.right().value()); + return result; + } + + return Either.left(component); + } + + private ResponseFormat validateGroupsInComponent(List groups, org.openecomp.sdc.be.model.Component component) { + + Function getByName = s -> s.getName(); + + return validateGroupsInComponentByFunc(groups, component, getByName); + + } + + /** + * @param groups + * @param component + * @param getByParam + * - the method to fetch the key of the GroupDefinition(from groups) in order to compare to groups in the component + * @return + */ + private ResponseFormat validateGroupsInComponentByFunc(List groups, org.openecomp.sdc.be.model.Component component, Function getByParam) { + ResponseFormat result = null; + + List currentGroups = component.getGroups(); + + boolean found = false; + List updatedGroupsName = groups.stream().map(getByParam).collect(Collectors.toList()); + + List missingGroupNames = updatedGroupsName; + + if (currentGroups != null && false == currentGroups.isEmpty()) { + List currentGroupsName = currentGroups.stream().map(getByParam).collect(Collectors.toList()); + + if (currentGroupsName.containsAll(updatedGroupsName)) { + found = true; + } else { + currentGroupsName.removeAll(currentGroupsName); + missingGroupNames = currentGroupsName; + } + } + if (false == found) { + String componentTypeForResponse = getComponentTypeForResponse(component); + String listOfGroups = getAsString(missingGroupNames); + result = componentsUtils.getResponseFormat(ActionStatus.GROUP_IS_MISSING, listOfGroups, component.getSystemName(), componentTypeForResponse); + return result; + } + + return null; + } + + public String getAsString(List list) { + + if (list == null || list.isEmpty()) { + return ""; + } + StringBuilder builder = new StringBuilder(); + list.forEach(p -> builder.append(p + ",")); + + String result = builder.toString(); + return result.substring(0, result.length()); + + } + + /** + * dissociate artifacts from a given group + * + * @param componentId + * @param userId + * @param componentType + * @param groups + * @param shouldLockComp + * @param inTransaction + * @return + */ + public Either, ResponseFormat> dissociateArtifactsFromGroup(String componentId, String userId, ComponentTypeEnum componentType, List groups, boolean shouldLockComp, boolean inTransaction) { + + Either, ResponseFormat> result = null; + + if (shouldLockComp == true && inTransaction == true) { + BeEcompErrorManager.getInstance().logInternalFlowError("dissociateArtifactsFromGroup", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); + // Cannot lock component since we are in a middle of another + // transaction. + ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + } + + Component component = null; + + try { + + if (groups == null || groups.isEmpty()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.OK)); + } + + Either validateGroupsBeforeUpdate = validateGroupsBeforeUpdate(componentId, userId, componentType, groups, inTransaction); + if (validateGroupsBeforeUpdate.isRight()) { + result = Either.right(validateGroupsBeforeUpdate.right().value()); + return result; + } + + component = validateGroupsBeforeUpdate.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, "Group - Dissociate Artifacts"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + List updatedGroups = new ArrayList<>(); + + List componentGroups = component.getGroups(); + // per group, associate to it the artifacts + for (GroupDefinition groupDefinition : groups) { + + GroupDefinition componentGroup = componentGroups.stream().filter(p -> p.getUniqueId().equals(groupDefinition.getUniqueId())).findFirst().orElse(null); + if (componentGroup != null) { + List componentArtifacts = componentGroup.getArtifacts(); + int artifactsSizeInGroup = componentArtifacts == null ? 0 : componentArtifacts.size(); + List artifactsToDissociate = groupDefinition.getArtifacts(); + + // if no artifcats sent + if (artifactsToDissociate == null || true == artifactsToDissociate.isEmpty()) { + continue; + } + + if (artifactsSizeInGroup > 0) { + + boolean containsAll = componentArtifacts.containsAll(artifactsToDissociate); + if (false == containsAll) { // At least one artifact is + // not associated to the + // group + log.debug("Some of the artifacts already dissociated to group {}", groupDefinition.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_DISSOCIATED, componentGroup.getName())); + } + } else { + if (artifactsSizeInGroup == 0) { + if (artifactsToDissociate != null && false == artifactsToDissociate.isEmpty()) { + log.debug("No artifact is found under the group {}", groupDefinition.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ARTIFACT_ALREADY_DISSOCIATED, componentGroup.getName())); + } + } + } + } + + Either associateArtifactsToGroup = groupOperation.dissociateArtifactsFromGroup(groupDefinition.getUniqueId(), groupDefinition.getArtifacts(), true); + + if (associateArtifactsToGroup.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(associateArtifactsToGroup.right().value()); + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + log.debug("Failed to update group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); + return result; + } + updatedGroups.add(associateArtifactsToGroup.left().value()); + + } + + result = Either.left(updatedGroups); + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + + } + + public Either, ResponseFormat> createGroups(String componentId, String userId, ComponentTypeEnum componentType, List groupDefinitions, boolean shouldLockComp, boolean inTransaction) { + + Either, ResponseFormat> result = null; + + List groups = new ArrayList<>(); + org.openecomp.sdc.be.model.Component component = null; + try { + + if (groupDefinitions != null && false == groupDefinitions.isEmpty()) { + + if (shouldLockComp == true && inTransaction == true) { + BeEcompErrorManager.getInstance().logInternalFlowError("createGroups", "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); + // Cannot lock component since we are in a middle of another + // transaction. + ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + } + + Either validateUserExists = validateUserExists(userId, CREATE_GROUP, true); + if (validateUserExists.isRight()) { + result = Either.right(validateUserExists.right().value()); + return result; + } + + User user = validateUserExists.left().value(); + + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreComponentInstances(false); + + Either validateComponent = validateComponentExists(componentId, componentType, componentParametersView, userId, null, user); + + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + component = validateComponent.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, "CreateGroups"); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + result = Either.right(canWork.right().value()); + return result; + } + + for (GroupDefinition groupDefinition : groupDefinitions) { + Either createGroup = this.createGroup(component, user, componentType, groupDefinition, true); + if (createGroup.isRight()) { + log.debug("Failed to create group {}.", groupDefinition); + result = Either.right(createGroup.right().value()); + return result; + } + GroupDefinition createdGroup = createGroup.left().value(); + groups.add(createdGroup); + } + } + + result = Either.left(groups); + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + + } + + public Either createGroup(Component component, User user, ComponentTypeEnum componentType, GroupDefinition groupDefinition, boolean inTransaction) { + + Either result = null; + + log.debug("Going to create group {}", groupDefinition); + + try { + + // 3. verify group not already exist + List groups = component.getGroups(); + boolean found = false; + if (groups != null && false == groups.isEmpty()) { + + GroupDefinition existGroupDef = groups.stream().filter(p -> p.getName().equalsIgnoreCase(groupDefinition.getName())).findFirst().orElse(null); + + found = existGroupDef != null; + } + + if (true == found) { + String componentTypeForResponse = getComponentTypeForResponse(component); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_ALREADY_EXIST, groupDefinition.getName(), component.getNormalizedName(), componentTypeForResponse)); + return result; + } + + // 4. verify type of group exist + String groupType = groupDefinition.getType(); + if (groupType == null || groupType.isEmpty()) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupDefinition.getName())); + return result; + } + Either getGroupType = groupTypeOperation.getLatestGroupTypeByType(groupType, true); + if (getGroupType.isRight()) { + StorageOperationStatus status = getGroupType.right().value(); + if (status == StorageOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().logInvalidInputError(CREATE_GROUP, "group type " + groupType + " cannot be found", ErrorSeverity.INFO); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_TYPE_IS_INVALID, groupType)); + return result; + } else { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + } + + // 6. verify the component instances type are allowed according to + // the member types in the group type + GroupTypeDefinition groupTypeDefinition = getGroupType.left().value(); + + Either areValidMembers = verifyComponentInstancesAreValidMembers(component, componentType, groupDefinition.getName(), groupType, groupDefinition.getMembers(), groupTypeDefinition.getMembers()); + + if (areValidMembers.isRight()) { + ResponseFormat responseFormat = areValidMembers.right().value(); + result = Either.right(responseFormat); + return result; + } + + // 7. verify the artifacts belongs to the component + Either areValidArtifacts = verifyArtifactsBelongsToComponent(component, groupDefinition.getArtifacts(), CREATE_GROUP); + if (areValidArtifacts.isRight()) { + ResponseFormat responseFormat = areValidArtifacts.right().value(); + result = Either.right(responseFormat); + return result; + } + + NodeTypeEnum nodeTypeEnum = componentType.getNodeType(); + + // add invariantUUID + String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + groupDefinition.setInvariantUUID(invariantUUID); + + // add groupUUID + String groupUUID = UniqueIdBuilder.generateUUID(); + groupDefinition.setGroupUUID(groupUUID); + + // add version + groupDefinition.setVersion(INITIAL_VERSION); + + // set groupType uid + groupDefinition.setTypeUid(groupTypeDefinition.getUniqueId()); + + Either addGroupToGraph = groupOperation.addGroup(nodeTypeEnum, component.getUniqueId(), groupDefinition, true); + + if (addGroupToGraph.isRight()) { + StorageOperationStatus storageOperationStatus = addGroupToGraph.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus); + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + log.debug("Failed to create group {} under component {}, error: {}", groupDefinition.getName(), component.getNormalizedName(), actionStatus.name()); + } else { + GroupDefinition groupDefinitionCreated = addGroupToGraph.left().value(); + result = Either.left(groupDefinitionCreated); + } + + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + + } + + public Either, ResponseFormat> updateVfModuleGroupNames(String resourceSystemName, List groups, boolean inTransaction) { + List updatedGroups = new ArrayList<>(); + Either, ResponseFormat> updateGroupNamesRes = Either.left(updatedGroups); + Either updateGroupNameRes; + Either validateGenerateGroupNameRes; + int counter; + for (GroupDefinition group : groups) { + if (!group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(group.getName()).matches()) { + continue; + } + counter = Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]); + validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), counter); + if (validateGenerateGroupNameRes.isRight()) { + updateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value()); + break; + } + updateGroupNameRes = groupOperation.updateGroupName(group.getUniqueId(), validateGenerateGroupNameRes.left().value(), inTransaction); + if (updateGroupNameRes.isRight()) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(updateGroupNameRes.right().value()); + updateGroupNamesRes = Either.right(componentsUtils.getResponseFormat(actionStatus)); + break; + } + updatedGroups.add(updateGroupNameRes.left().value()); + } + return updateGroupNamesRes; + } + + public Either validateGenerateVfModuleGroupNames(List allGroups, String resourceSystemName, int startGroupCounter) { + Either validateGenerateGroupNamesRes = Either.left(true); + Collections.sort(allGroups, (art1, art2) -> ArtifactTemplateInfo.compareByGroupName(art1, art2)); + for (ArtifactTemplateInfo group : allGroups) { + Either validateGenerateGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), startGroupCounter++); + if (validateGenerateGroupNameRes.isRight()) { + validateGenerateGroupNamesRes = Either.right(validateGenerateGroupNameRes.right().value()); + break; + } + group.setGroupName(validateGenerateGroupNameRes.left().value()); + } + return validateGenerateGroupNamesRes; + } + + /** + * Generate module name from resourceName, description and counter + * + * @param resourceSystemName + * @param description + * @param groupCounter + * @return + */ + private Either validateGenerateVfModuleGroupName(String resourceSystemName, String description, int groupCounter) { + Either validateGenerateGroupNameRes; + if (resourceSystemName != null && description != null && Pattern.compile(Constants.MODULE_DESC_PATTERN).matcher(description).matches()) { + final String fileName = description.replaceAll("\\.\\.", "\\."); + validateGenerateGroupNameRes = Either.left(String.format(Constants.MODULE_NAME_FORMAT, resourceSystemName, FilenameUtils.removeExtension(fileName), groupCounter)); + } else { + validateGenerateGroupNameRes = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_VF_MODULE_NAME)); + } + return validateGenerateGroupNameRes; + } + + public Either, ResponseFormat> validateUpdateVfGroupNames(Map groups, String resourceSystemName) { + + Map updatedNamesGroups = new HashMap<>(); + Either, ResponseFormat> result = Either.left(updatedNamesGroups); + for (Entry groupEntry : groups.entrySet()) { + GroupDefinition curGroup = groupEntry.getValue(); + String groupType = curGroup.getType(); + String groupName = groupEntry.getKey(); + int counter; + String description; + Either newGroupNameRes; + if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && !Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(groupName).matches()) { + + if (Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(groupEntry.getKey()).matches()) { + counter = Integer.parseInt(groupEntry.getKey().split(Constants.MODULE_NAME_DELIMITER)[1]); + description = curGroup.getDescription(); + } else { + counter = getNextVfModuleNameCounter(updatedNamesGroups); + description = groupName; + } + newGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, description, counter); + if (newGroupNameRes.isRight()) { + log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value()); + result = Either.right(newGroupNameRes.right().value()); + break; + } + groupName = newGroupNameRes.left().value(); + curGroup.setName(groupName); + } + updatedNamesGroups.put(groupName, curGroup); + } + return result; + } + + public int getNextVfModuleNameCounter(Map groups) { + int counter = 0; + if (groups != null && !groups.isEmpty()) { + counter = getNextVfModuleNameCounter(groups.values()); + } + return counter; + } + + public int getNextVfModuleNameCounter(Collection groups) { + int counter = 0; + if (groups != null && !groups.isEmpty()) { + List counters = groups.stream().filter(group -> Pattern.compile(Constants.MODULE_NEW_NAME_PATTERN).matcher(group.getName()).matches() || Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(group.getName()).matches()) + .map(group -> Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1])).collect(Collectors.toList()); + counter = (counters == null || counters.isEmpty()) ? 0 : counters.stream().max((a, b) -> Integer.compare(a, b)).get() + 1; + } + return counter; + } + + public Either, ResponseFormat> validateUpdateVfGroupNamesOnGraph(List groups, String resourceSystemName, boolean inTransaction) { + List updatedGroups = new ArrayList<>(); + Either, ResponseFormat> result = Either.left(updatedGroups); + + for (GroupDefinition group : groups) { + String groupType = group.getType(); + String oldGroupName = group.getName(); + String newGroupName; + Either newGroupNameRes; + Either updateGroupNameRes; + int counter; + if (groupType.equals(Constants.DEFAULT_GROUP_VF_MODULE) && Pattern.compile(Constants.MODULE_OLD_NAME_PATTERN).matcher(oldGroupName).matches()) { + counter = Integer.parseInt(group.getName().split(Constants.MODULE_NAME_DELIMITER)[1]); + newGroupNameRes = validateGenerateVfModuleGroupName(resourceSystemName, group.getDescription(), counter); + if (newGroupNameRes.isRight()) { + log.debug("Failed to generate new vf module group name. Status is {} ", newGroupNameRes.right().value()); + result = Either.right(newGroupNameRes.right().value()); + break; + } + newGroupName = newGroupNameRes.left().value(); + updateGroupNameRes = groupOperation.updateGroupName(group.getUniqueId(), newGroupName, inTransaction); + if (updateGroupNameRes.isRight()) { + log.debug("Failed to update vf module group name for group {} . Status is {} ", oldGroupName, updateGroupNameRes.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateGroupNameRes.right().value())); + result = Either.right(responseFormat); + break; + } + } + updatedGroups.add(group); + } + return result; + } + + public Either, ResponseFormat> createGroups(Component component, User user, ComponentTypeEnum componentType, List groupDefinitions, boolean inTransaction) { + + List generatedGroups = new ArrayList<>(); + Either, ResponseFormat> result = Either.left(generatedGroups); + + try { + + if (groupDefinitions != null && false == groupDefinitions.isEmpty()) { + for (GroupDefinition groupDefinition : groupDefinitions) { + Either createGroup = this.createGroup(component, user, componentType, groupDefinition, true); + if (createGroup.isRight()) { + result = Either.right(createGroup.right().value()); + return result; + } + GroupDefinition generatedGroup = createGroup.left().value(); + generatedGroups.add(generatedGroup); + } + } + + return result; + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupTypeImportManager.java new file mode 100644 index 0000000000..3dee3839b1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/GroupTypeImportManager.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Consumer; +import java.util.stream.Collectors; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.CommonImportManager.ElementTypeEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.operations.api.IGroupTypeOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("groupTypeImportManager") +public class GroupTypeImportManager { + + public static void main(String[] args) { + + List properties = new ArrayList<>(); + PropertyDefinition propertyDefintion = new PropertyDefinition(); + propertyDefintion.setName("aaa"); + properties.add(propertyDefintion); + + List allParentsProps = new ArrayList<>(); + allParentsProps.add("aaa"); + allParentsProps.add("bbb"); + + Set alreadyExistPropsCollection = properties.stream().filter(p -> allParentsProps.contains(p.getName())).map(p -> p.getName()).collect(Collectors.toSet()); + System.out.println(alreadyExistPropsCollection); + + } + + private static Logger log = LoggerFactory.getLogger(GroupTypeImportManager.class.getName()); + @Resource + private PropertyOperation propertyOperation; + @Resource + private IGroupTypeOperation groupTypeOperation; + @Resource + private ComponentsUtils componentsUtils; + @Resource + private IResourceOperation resourceOperation; + + @Resource + private CommonImportManager commonImportManager; + + public Either>, ResponseFormat> createGroupTypes(String groupTypesYml) { + return commonImportManager.createElementTypes(groupTypesYml, elementTypeYml -> createGroupTypesFromYml(elementTypeYml), groupTypesList -> createGroupTypesByDao(groupTypesList), ElementTypeEnum.GroupType); + } + + private Either, ActionStatus> createGroupTypesFromYml(String groupTypesYml) { + + return commonImportManager.createElementTypesFromYml(groupTypesYml, (groupTypeName, groupTypeJsonData) -> createGroupType(groupTypeName, groupTypeJsonData)); + } + + private Either>, ResponseFormat> createGroupTypesByDao(List groupTypesToCreate) { + return commonImportManager.createElementTypesByDao(groupTypesToCreate, groupType -> validateGroupType(groupType), groupType -> new ImmutablePair<>(ElementTypeEnum.GroupType, groupType.getType()), + groupTypeName -> groupTypeOperation.getLatestGroupTypeByType(groupTypeName), groupType -> groupTypeOperation.addGroupType(groupType), null); + } + + private Either validateGroupType(GroupTypeDefinition groupType) { + Either result = Either.left(ActionStatus.OK); + if (groupType.getMembers() != null) { + if (groupType.getMembers().isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GROUP_MEMBER_EMPTY, groupType.getType()); + result = Either.right(responseFormat); + } else { + for (String member : groupType.getMembers()) { + // Verify that such Resource exist + Either eitherMemberExist = resourceOperation.getLatestByToscaResourceName(member, false); + if (eitherMemberExist.isRight()) { + StorageOperationStatus operationStatus = eitherMemberExist.right().value(); + log.debug("Error when fetching parent resource {}, error: {}", member, operationStatus); + ActionStatus convertFromStorageResponse = componentsUtils.convertFromStorageResponse(operationStatus); + BeEcompErrorManager.getInstance().logBeComponentMissingError("Import GroupType", "resource", member); + result = Either.right(componentsUtils.getResponseFormat(convertFromStorageResponse, member)); + break; + } + } + + } + } + return result; + } + + private GroupTypeDefinition createGroupType(String groupTypeName, Map toscaJson) { + + GroupTypeDefinition groupType = new GroupTypeDefinition(); + + if (toscaJson != null) { + // Description + final Consumer descriptionSetter = description -> groupType.setDescription(description); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DESCRIPTION.getElementName(), descriptionSetter); + // Derived From + final Consumer derivedFromSetter = derivedFrom -> groupType.setDerivedFrom(derivedFrom); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DERIVED_FROM.getElementName(), derivedFromSetter); + // Properties + commonImportManager.setProperties(toscaJson, (values) -> groupType.setProperties(values)); + // Metadata + final Consumer> metadataSetter = metadata -> groupType.setMetadata(metadata); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.METADATA.getElementName(), metadataSetter); + // Members + final Consumer> membersSetter = members -> groupType.setMembers(members); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.MEMBERS.getElementName(), membersSetter); + + groupType.setType(groupTypeName); + + groupType.setHighestVersion(true); + + groupType.setVersion(ImportUtils.Constants.FIRST_CERTIFIED_VERSION_VERSION); + } + return groupType; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/HealthCheckBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/HealthCheckBusinessLogic.java new file mode 100644 index 0000000000..81dfc1a256 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/HealthCheckBusinessLogic.java @@ -0,0 +1,441 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.annotation.Resource; +import javax.servlet.ServletContext; + +import org.openecomp.sdc.be.components.distribution.engine.DistributionEngineClusterHealth; +import org.openecomp.sdc.be.components.distribution.engine.UebHealthCheckCall; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.IEsHealthCheckDao; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.switchover.detector.SwitchoverDetector; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckComponent; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +@Component("healthCheckBusinessLogic") +public class HealthCheckBusinessLogic { + + protected static String BE_HEALTH_LOG_CONTEXT = "be.healthcheck"; + + private static Logger healthLogger = LoggerFactory.getLogger(BE_HEALTH_LOG_CONTEXT); + + private static final String BE_HEALTH_CHECK_STR = "beHealthCheck"; + + @Resource + private TitanGenericDao titanGenericDao; + + @Resource + private IEsHealthCheckDao esHealthCheckDao; + + @Resource + private DistributionEngineClusterHealth distributionEngineClusterHealth; + + @Autowired + private SwitchoverDetector switchoverDetector; + + private static Logger log = LoggerFactory.getLogger(HealthCheckBusinessLogic.class.getName()); + + private volatile List lastBeHealthCheckInfos = null; + + // private static volatile HealthCheckBusinessLogic instance; + // + public HealthCheckBusinessLogic() { + + } + + private ScheduledFuture scheduledFuture = null; + + ScheduledExecutorService healthCheckScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "BE-Health-Check-Task"); + } + }); + + HealthCheckScheduledTask healthCheckScheduledTask = null; + + @PostConstruct + public void init() { + + lastBeHealthCheckInfos = getBeHealthCheckInfos(); + + log.debug("After initializing lastBeHealthCheckInfos :{}", lastBeHealthCheckInfos); + + healthCheckScheduledTask = new HealthCheckScheduledTask(); + + if (this.scheduledFuture == null) { + this.scheduledFuture = this.healthCheckScheduler.scheduleAtFixedRate(healthCheckScheduledTask, 0, 3, TimeUnit.SECONDS); + } + + } + + // + // public static HealthCheckBusinessLogic getInstance(){ + //// if (instance == null){ + //// instance = init(); + //// } + // return instance; + // } + + // private synchronized static HealthCheckBusinessLogic init() { + // if (instance == null){ + // instance = new HealthCheckBusinessLogic(); + // } + // return instance; + // } + + private List getBeHealthCheckInfos(ServletContext servletContext) { + + List healthCheckInfos = new ArrayList(); + + // BE + getBeHealthCheck(servletContext, healthCheckInfos); + + // ES + getEsHealthCheck(servletContext, healthCheckInfos); + + // Titan + getTitanHealthCheck(servletContext, healthCheckInfos); + + // Distribution Engine + getDistributionEngineCheck(servletContext, healthCheckInfos); + + return healthCheckInfos; + } + + private List getBeHealthCheck(ServletContext servletContext, List healthCheckInfos) { + String appVersion = ExternalConfiguration.getAppVersion(); + String description = "OK"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.BE, HealthCheckStatus.UP, appVersion, description)); + return healthCheckInfos; + } + + public List getTitanHealthCheck(ServletContext servletContext, List healthCheckInfos) { + // Titan health check and version + TitanGenericDao titanStatusDao = (TitanGenericDao) getDao(servletContext, TitanGenericDao.class); + String description; + boolean isTitanUp; + + try { + isTitanUp = titanStatusDao.isGraphOpen(); + } catch (Exception e) { + description = "Titan error: " + e.getMessage(); + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.DOWN, null, description)); + return healthCheckInfos; + } + if (isTitanUp) { + description = "OK"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.UP, null, description)); + } else { + description = "Titan graph is down"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.DOWN, null, description)); + } + return healthCheckInfos; + } + + public List getEsHealthCheck(ServletContext servletContext, List healthCheckInfos) { + + // ES health check and version + IEsHealthCheckDao esStatusDao = (IEsHealthCheckDao) getDao(servletContext, IEsHealthCheckDao.class); + HealthCheckStatus healthCheckStatus; + String description; + + try { + healthCheckStatus = esStatusDao.getClusterHealthStatus(); + } catch (Exception e) { + healthCheckStatus = HealthCheckStatus.DOWN; + description = "ES cluster error: " + e.getMessage(); + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.ES, healthCheckStatus, null, description)); + return healthCheckInfos; + } + if (healthCheckStatus.equals(HealthCheckStatus.DOWN)) { + description = "ES cluster is down"; + } else { + description = "OK"; + } + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.ES, healthCheckStatus, null, description)); + return healthCheckInfos; + } + + public Object getDao(ServletContext servletContext, Class clazz) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) servletContext.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(servletContext); + + return webApplicationContext.getBean(clazz); + } + + private void getDistributionEngineCheck(ServletContext servletContext, List healthCheckInfos) { + + DistributionEngineClusterHealth deDao = (DistributionEngineClusterHealth) getDao(servletContext, DistributionEngineClusterHealth.class); + HealthCheckInfo healthCheckInfo = deDao.getHealthCheckInfo(); + + healthCheckInfos.add(healthCheckInfo); + + } + + public boolean isDistributionEngineUp(ServletContext servletContext) { + + DistributionEngineClusterHealth deDao = (DistributionEngineClusterHealth) getDao(servletContext, DistributionEngineClusterHealth.class); + HealthCheckInfo healthCheckInfo = deDao.getHealthCheckInfo(); + if (healthCheckInfo.getHealthCheckStatus().equals(HealthCheckStatus.DOWN)) { + return false; + } + return true; + } + + public List getBeHealthCheckInfosStatus() { + + return lastBeHealthCheckInfos; + + } + + private List getBeHealthCheckInfos() { + + log.trace("In getBeHealthCheckInfos"); + + List healthCheckInfos = new ArrayList(); + + // BE + getBeHealthCheck(healthCheckInfos); + + // ES + getEsHealthCheck(healthCheckInfos); + + // Titan + getTitanHealthCheck(healthCheckInfos); + + // Distribution Engine + getDistributionEngineCheck(healthCheckInfos); + + return healthCheckInfos; + } + + private List getBeHealthCheck(List healthCheckInfos) { + String appVersion = ExternalConfiguration.getAppVersion(); + String description = "OK"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.BE, HealthCheckStatus.UP, appVersion, description)); + return healthCheckInfos; + } + + public List getEsHealthCheck(List healthCheckInfos) { + + // ES health check and version + HealthCheckStatus healthCheckStatus; + String description; + + try { + healthCheckStatus = esHealthCheckDao.getClusterHealthStatus(); + } catch (Exception e) { + healthCheckStatus = HealthCheckStatus.DOWN; + description = "ES cluster error: " + e.getMessage(); + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.ES, healthCheckStatus, null, description)); + return healthCheckInfos; + } + if (healthCheckStatus.equals(HealthCheckStatus.DOWN)) { + description = "ES cluster is down"; + } else { + description = "OK"; + } + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.ES, healthCheckStatus, null, description)); + return healthCheckInfos; + } + + public List getTitanHealthCheck(List healthCheckInfos) { + // Titan health check and version + String description; + boolean isTitanUp; + + try { + isTitanUp = titanGenericDao.isGraphOpen(); + } catch (Exception e) { + description = "Titan error: " + e.getMessage(); + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.DOWN, null, description)); + return healthCheckInfos; + } + if (isTitanUp) { + description = "OK"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.UP, null, description)); + } else { + description = "Titan graph is down"; + healthCheckInfos.add(new HealthCheckInfo(HealthCheckComponent.TITAN, HealthCheckStatus.DOWN, null, description)); + } + return healthCheckInfos; + } + + private void getDistributionEngineCheck(List healthCheckInfos) { + + HealthCheckInfo healthCheckInfo = distributionEngineClusterHealth.getHealthCheckInfo(); + + healthCheckInfos.add(healthCheckInfo); + + } + + @PreDestroy + private void destroy() { + + if (scheduledFuture != null) { + scheduledFuture.cancel(true); + scheduledFuture = null; + } + + if (healthCheckScheduler != null) { + healthCheckScheduler.shutdown(); + } + + } + + public class HealthCheckScheduledTask implements Runnable { + + List healthCheckCalls = new ArrayList<>(); + + public HealthCheckScheduledTask() { + + } + + @Override + public void run() { + + healthLogger.trace("Executing BE Health Check Task"); + + List beHealthCheckInfos = getBeHealthCheckInfos(); + boolean healthStatus = getAggregateBeStatus(beHealthCheckInfos); + + boolean lastHealthStatus = getAggregateBeStatus(lastBeHealthCheckInfos); + + if (lastHealthStatus != healthStatus) { + log.trace("BE Health State Changed to {}. Issuing alarm / recovery alarm...", healthStatus); + + lastBeHealthCheckInfos = beHealthCheckInfos; + logAlarm(healthStatus); + + } else { + // check if we need to update the status's list in case one of + // the statuses was changed + if (true == anyStatusChanged(beHealthCheckInfos, lastBeHealthCheckInfos)) { + lastBeHealthCheckInfos = beHealthCheckInfos; + } + + } + + } + + } + + private void logAlarm(boolean lastHealthState) { + if (lastHealthState == true) { + BeEcompErrorManager.getInstance().logBeHealthCheckRecovery(BE_HEALTH_CHECK_STR); + } else { + BeEcompErrorManager.getInstance().logBeHealthCheckError(BE_HEALTH_CHECK_STR); + } + } + + private boolean getAggregateBeStatus(List beHealthCheckInfos) { + + boolean status = true; + + for (HealthCheckInfo healthCheckInfo : beHealthCheckInfos) { + if (healthCheckInfo.getHealthCheckStatus().equals(HealthCheckStatus.DOWN) && healthCheckInfo.getHealthCheckComponent() != HealthCheckComponent.DE) { + status = false; + break; + } + } + return status; + } + + public String getSiteMode() { + return switchoverDetector.getSiteMode(); + } + + public boolean anyStatusChanged(List beHealthCheckInfos, List lastBeHealthCheckInfos) { + + boolean result = false; + + if (beHealthCheckInfos != null && lastBeHealthCheckInfos != null) { + + Map currentValues = beHealthCheckInfos.stream().collect(Collectors.toMap(p -> p.getHealthCheckComponent(), p -> p.getHealthCheckStatus())); + Map lastValues = lastBeHealthCheckInfos.stream().collect(Collectors.toMap(p -> p.getHealthCheckComponent(), p -> p.getHealthCheckStatus())); + + if (currentValues != null && lastValues != null) { + int currentSize = currentValues.size(); + int lastSize = lastValues.size(); + + if (currentSize != lastSize) { + result = true; + } else { + + for (Entry entry : currentValues.entrySet()) { + HealthCheckComponent key = entry.getKey(); + HealthCheckStatus value = entry.getValue(); + + if (false == lastValues.containsKey(key)) { + result = true; + break; + } + + HealthCheckStatus lastHealthCheckStatus = lastValues.get(key); + + if (value != lastHealthCheckStatus) { + result = true; + break; + } + } + } + } else if (currentValues == null && lastValues == null) { + result = false; + } else { + result = true; + } + + } else if (beHealthCheckInfos == null && lastBeHealthCheckInfos == null) { + result = false; + } else { + result = true; + } + + return result; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/IDeploymentArtifactTypeConfigGetter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/IDeploymentArtifactTypeConfigGetter.java new file mode 100644 index 0000000000..68569ebc3b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/IDeploymentArtifactTypeConfigGetter.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; + +public interface IDeploymentArtifactTypeConfigGetter { + DeploymentArtifactTypeConfig getDeploymentArtifactConfig(); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java new file mode 100644 index 0000000000..94a7340ff7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ImportUtils.java @@ -0,0 +1,722 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Consumer; +import java.util.function.Function; + +import org.apache.commons.lang3.StringEscapeUtils; +import org.apache.commons.lang3.text.translate.CharSequenceTranslator; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.util.GsonFactory; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.representer.Representer; +import org.yaml.snakeyaml.resolver.Resolver; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; + +public final class ImportUtils { + private ImportUtils() { + + } + + private static CustomResolver customResolver = new CustomResolver(); + + private static class CustomResolver extends Resolver { + protected void addImplicitResolvers() { + // avoid implicit resolvers + } + } + + public static Either, ResultStatusEnum> getHeatParamsWithoutImplicitTypes(String heatDecodedPayload, String artifactType) { + Map heatData = (Map) new Yaml(new Constructor(), new Representer(), new DumperOptions(), customResolver).load(heatDecodedPayload); + return getHeatParameters(heatData, artifactType); + } + + public static class Constants { + + public static final String FIRST_CERTIFIED_VERSION_VERSION = "1.0"; + public static final String FIRST_NON_CERTIFIED_VERSION = "0.1"; + public static final String VENDOR_NAME = "ATT (Tosca)"; + public static final String VENDOR_RELEASE = "1.0.0.wd03"; + public static final LifecycleStateEnum NORMATIVE_TYPE_LIFE_CYCLE = LifecycleStateEnum.CERTIFIED; + public static final boolean NORMATIVE_TYPE_HIGHEST_VERSION = true; + // public static final String ABSTRACT_CATEGORY = "Generic/Abstract"; + public static final String ABSTRACT_CATEGORY_NAME = "Generic"; + public static final String ABSTRACT_SUBCATEGORY = "Abstract"; + public static final String DEFAULT_ICON = "defaulticon"; + public static final String INNER_VFC_DESCRIPTION = "Not reusable inner VFC"; + public static final String USER_DEFINED_RESOURCE_NAMESPACE_PREFIX = "org.openecomp.resource."; + public static final List TOSCA_DEFINITION_VERSIONS = Arrays.asList(new String[] { "tosca_simple_yaml_1_0_0", "tosca_simple_profile_for_nfv_1_0_0", "tosca_simple_yaml_1_0" }); + public static final List TOSCA_YML_CSAR_VALID_SUFFIX = Arrays.asList(new String[] { ".yml", ".yaml", ".csar" }); + public static final String UI_JSON_PAYLOAD_NAME = "payloadName"; + public static final String ABSTRACT_NODE = "abstact"; + } + + public enum ResultStatusEnum { + ELEMENT_NOT_FOUND, GENERAL_ERROR, OK, INVALID_PROPERTY_DEFAULT_VALUE, INVALID_PROPERTY_TYPE, INVALID_PROPERTY_VALUE, MISSING_ENTRY_SCHEMA_TYPE + } + + public enum ToscaElementTypeEnum { + BOOLEAN, STRING, MAP, LIST, ALL + } + + public enum ToscaTagNamesEnum { + DERIVED_FROM("derived_from"), IS_PASSWORD("is_password"), + // Properties + PROPERTIES("properties"), TYPE("type"), STATUS("status"), ENTRY_SCHEMA("entry_schema"), REQUIRED("required"), DESCRIPTION("description"), DEFAULT_VALUE("default"), VALUE("value"), CONSTRAINTS("constraints"), + // Group Types + MEMBERS("members"), METADATA("metadata"), + // Policy Types + TARGETS("targets"), + // Capabilities + CAPABILITIES("capabilities"), VALID_SOURCE_TYPES("valid_source_types"), + // Requirements + REQUIREMENTS("requirements"), NODE("node"), RELATIONSHIP("relationship"), CAPABILITY("capability"), INTERFACES("interfaces"), + // Heat env Validation + PARAMETERS("parameters"), + // Import Validations + TOSCA_VERSION("tosca_definitions_version"), TOPOLOGY_TEMPLATE("topology_template"), NODE_TYPES("node_types"), OCCURRENCES("occurrences"), NODE_TEMPLATES("node_templates"), GROUPS("groups"), INPUTS("inputs"), + // Attributes + ATTRIBUTES("attributes"), LABEL("label"), HIDDEN("hidden"), IMMUTABLE("immutable"), GET_INPUT("get_input"); + + private String elementName; + + private ToscaTagNamesEnum(String elementName) { + this.elementName = elementName; + } + + public String getElementName() { + return elementName; + } + } + + @SuppressWarnings("unchecked") + private static void handleElementNameNotFound(String elementName, Object elementValue, ToscaElementTypeEnum elementType, List returnedList) { + if (elementValue instanceof Map) { + ImportUtils.findToscaElements((Map) elementValue, elementName, elementType, returnedList); + } else if (elementValue instanceof List) { + ImportUtils.findAllToscaElementsInList((List) elementValue, elementName, elementType, returnedList); + } + } + + @SuppressWarnings("unchecked") + private static void handleElementNameFound(String elementName, ToscaElementTypeEnum elementType, List returnedList, Object elementValue) { + + if (elementValue instanceof Boolean) { + if (elementType == ToscaElementTypeEnum.BOOLEAN || elementType == ToscaElementTypeEnum.ALL) { + returnedList.add(elementValue); + } + } + + else if (elementValue instanceof String) { + if (elementType == ToscaElementTypeEnum.STRING || elementType == ToscaElementTypeEnum.ALL) { + returnedList.add(elementValue); + } + } else if (elementValue instanceof Map) { + if (elementType == ToscaElementTypeEnum.MAP || elementType == ToscaElementTypeEnum.ALL) { + returnedList.add(elementValue); + } + ImportUtils.findToscaElements((Map) elementValue, elementName, elementType, returnedList); + + } else if (elementValue instanceof List) { + if (elementType == ToscaElementTypeEnum.LIST || elementType == ToscaElementTypeEnum.ALL) { + returnedList.add(elementValue); + } + ImportUtils.findAllToscaElementsInList((List) elementValue, elementName, elementType, returnedList); + + } + // For Integer, Double etc... + else if (elementType == ToscaElementTypeEnum.ALL) { + if (elementValue != null) { + returnedList.add(String.valueOf(elementValue)); + } else { + returnedList.add(elementValue); + } + + } + } + + private static void findAllToscaElementsInList(List list, String elementName, ToscaElementTypeEnum elementType, List returnedList) { + Iterator listItr = list.iterator(); + while (listItr.hasNext()) { + Object elementValue = listItr.next(); + handleElementNameNotFound(elementName, elementValue, elementType, returnedList); + } + + } + + public static Either findToscaElement(Map toscaJson, ToscaTagNamesEnum elementName, ToscaElementTypeEnum elementType) { + List foundElements = new ArrayList<>(); + Either returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + ImportUtils.findToscaElements(toscaJson, elementName.getElementName(), elementType, foundElements); + if (foundElements.size() > 0) { + returnedElement = Either.left(foundElements.get(0)); + } + return returnedElement; + + } + + /** + * Recursively searches for all tosca elements with key equals to elementName and value equals to elementType.
+ * Returns Either element with:
+ * List with all value if values found
+ * Or ELEMENT_NOT_FOUND ActionStatus + * + * @param toscaJson + * @param toscaTagName + * @return + */ + public static Either, ResultStatusEnum> findToscaElements(Map toscaJson, String elementName, ToscaElementTypeEnum elementType, List returnedList) { + Either, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + String skipKey = null; + if (toscaJson.containsKey(elementName)) { + Object elementValue = toscaJson.get(elementName); + handleElementNameFound(elementName, elementType, returnedList, elementValue); + skipKey = elementName; + } + + Iterator> keyValItr = toscaJson.entrySet().iterator(); + while (keyValItr.hasNext()) { + Entry keyValEntry = keyValItr.next(); + if (!String.valueOf(keyValEntry.getKey()).equals(skipKey)) { + handleElementNameNotFound(elementName, keyValEntry.getValue(), elementType, returnedList); + } + } + + if (returnedList.size() > 0) { + returnedElement = Either.left(returnedList); + } + + return returnedElement; + } + + @SuppressWarnings("unchecked") + public static Either, ResultStatusEnum> findFirstToscaListElement(Map toscaJson, ToscaTagNamesEnum toscaTagName) { + Either, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.LIST); + if (findFirstToscaElement.isLeft()) { + returnedElement = Either.left((List) findFirstToscaElement.left().value()); + } + return returnedElement; + + } + + @SuppressWarnings("unchecked") + public static Either, ResultStatusEnum> findFirstToscaMapElement(Map toscaJson, ToscaTagNamesEnum toscaTagName) { + Either, ResultStatusEnum> returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either findFirstToscaElement = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.MAP); + if (findFirstToscaElement.isLeft()) { + returnedElement = Either.left((Map) findFirstToscaElement.left().value()); + } + return returnedElement; + + } + + public static Either findFirstToscaStringElement(Map toscaJson, ToscaTagNamesEnum toscaTagName) { + Either returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.STRING); + if (findFirstToscaElements.isLeft()) { + returnedElement = Either.left((String) findFirstToscaElements.left().value()); + } + return returnedElement; + } + + /** + * searches for first Tosca in Json map (toscaJson) boolean element by name (toscaTagName) returns found element or ELEMENT_NOT_FOUND status + * + * @param toscaJson + * @param toscaTagName + * @return + */ + public static Either findFirstToscaBooleanElement(Map toscaJson, ToscaTagNamesEnum toscaTagName) { + Either returnedElement = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either findFirstToscaElements = findToscaElement(toscaJson, toscaTagName, ToscaElementTypeEnum.BOOLEAN); + if (findFirstToscaElements.isLeft()) { + returnedElement = Either.left(String.valueOf(findFirstToscaElements.left().value())); + } + return returnedElement; + } + + private static void setPropertyConstraints(Map propertyValue, PropertyDefinition property) { + Either, ResultStatusEnum> propertyFieldconstraints = findFirstToscaListElement(propertyValue, ToscaTagNamesEnum.CONSTRAINTS); + if (propertyFieldconstraints.isLeft()) { + List jsonConstraintList = propertyFieldconstraints.left().value(); + + List constraintList = new ArrayList<>(); + Type constraintType = new TypeToken() { + }.getType(); + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + + for (Object constraintJson : jsonConstraintList) { + PropertyConstraint propertyConstraint = gson.fromJson(gson.toJson(constraintJson), constraintType); + constraintList.add(propertyConstraint); + } + property.setConstraints(constraintList); + } + } + + public static PropertyDefinition createModuleProperty(Map propertyValue) { + + PropertyDefinition propertyDef = new PropertyDefinition(); + ImportUtils.setField(propertyValue, ToscaTagNamesEnum.TYPE, type -> propertyDef.setType(type)); + ImportUtils.setPropertyFieldRequired(propertyValue, propertyDef); + ImportUtils.setField(propertyValue, ToscaTagNamesEnum.DESCRIPTION, desc -> propertyDef.setDescription(desc)); + + Either findToscaElement = ImportUtils.findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + if (findToscaElement.isLeft()) { + String propertyJsonStringValue = getPropertyJsonStringValue(findToscaElement.left().value(), propertyDef.getType()); + propertyDef.setDefaultValue(propertyJsonStringValue); + } + ImportUtils.setField(propertyValue, ToscaTagNamesEnum.IS_PASSWORD, pass -> propertyDef.setPassword(Boolean.parseBoolean(pass))); + ImportUtils.setField(propertyValue, ToscaTagNamesEnum.STATUS, status -> propertyDef.setStatus(status)); + ImportUtils.setPropertyScheme(propertyValue, propertyDef); + ImportUtils.setPropertyConstraints(propertyValue, propertyDef); + + return propertyDef; + } + + public static InputDefinition createModuleInput(Map inputValue) { + + InputDefinition inputDef = new InputDefinition(); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.TYPE, type -> inputDef.setType(type)); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.REQUIRED, req -> inputDef.setRequired(Boolean.parseBoolean(req))); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.DESCRIPTION, desc -> inputDef.setDescription(desc)); + + Either findToscaElement = ImportUtils.findToscaElement(inputValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + if (findToscaElement.isLeft()) { + String propertyJsonStringValue = getPropertyJsonStringValue(findToscaElement.left().value(), inputDef.getType()); + inputDef.setDefaultValue(propertyJsonStringValue); + } + ImportUtils.setField(inputValue, ToscaTagNamesEnum.IS_PASSWORD, pass -> inputDef.setPassword(Boolean.parseBoolean(pass))); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.STATUS, status -> inputDef.setStatus(status)); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.LABEL, label -> inputDef.setLabel(label)); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.HIDDEN, hidden -> inputDef.setHidden(Boolean.parseBoolean(hidden))); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.HIDDEN, immutable -> inputDef.setImmutable(Boolean.parseBoolean(immutable))); + ImportUtils.setField(inputValue, ToscaTagNamesEnum.LABEL, label -> inputDef.setLabel(label)); + ImportUtils.setPropertyScheme(inputValue, inputDef); + ImportUtils.setPropertyConstraints(inputValue, inputDef); + + return inputDef; + } + + public static AttributeDefinition createModuleAttribute(Map attributeMap) { + + AttributeDefinition attributeDef = new AttributeDefinition(); + ImportUtils.setField(attributeMap, ToscaTagNamesEnum.TYPE, type -> attributeDef.setType(type)); + ImportUtils.setField(attributeMap, ToscaTagNamesEnum.DESCRIPTION, desc -> attributeDef.setDescription(desc)); + ImportUtils.setField(attributeMap, ToscaTagNamesEnum.STATUS, status -> attributeDef.setStatus(status)); + Either eitherDefaultValue = ImportUtils.findToscaElement(attributeMap, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + if (eitherDefaultValue.isLeft()) { + String attributeDefaultValue = getPropertyJsonStringValue(eitherDefaultValue.left().value(), attributeDef.getType()); + attributeDef.setDefaultValue(attributeDefaultValue); + } + Either eitherValue = ImportUtils.findToscaElement(attributeMap, ToscaTagNamesEnum.VALUE, ToscaElementTypeEnum.ALL); + if (eitherValue.isLeft()) { + String attributeValue = getPropertyJsonStringValue(eitherValue.left().value(), attributeDef.getType()); + attributeDef.setValue(attributeValue); + } + ImportUtils.setAttributeScheme(attributeMap, attributeDef); + return attributeDef; + } + + private static void setPropertyFieldStatus(Map propertyValue, PropertyDefinition propertyDef) { + Either propertyFieldIsStatus = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.STATUS); + if (propertyFieldIsStatus.isLeft()) { + propertyDef.setStatus(propertyFieldIsStatus.left().value()); + } + + } + + private static void setAttributeFieldStatus(Map propertyValue, AttributeDefinition propertyDef) { + Either propertyFieldIsStatus = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.STATUS); + if (propertyFieldIsStatus.isLeft()) { + propertyDef.setStatus(propertyFieldIsStatus.left().value()); + } + + } + + private static void setPropertyScheme(Map propertyValue, PropertyDefinition propertyDefinition) { + Either eitherSchema = getSchema(propertyValue); + if (eitherSchema.isLeft()) { + SchemaDefinition schemaDef = new SchemaDefinition(); + schemaDef.setProperty(eitherSchema.left().value().getProperty()); + propertyDefinition.setSchema(schemaDef); + } + + } + + private static void setAttributeScheme(Map propertyValue, AttributeDefinition propertyDefinition) { + Either eitherSchema = getSchema(propertyValue); + if (eitherSchema.isLeft()) { + SchemaDefinition schemaDef = new SchemaDefinition(); + schemaDef.setProperty(eitherSchema.left().value().getProperty()); + propertyDefinition.setSchema(schemaDef); + } + + } + + private static Either getSchema(Map propertyValue) { + Either result = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either propertyFieldEntryScheme = findToscaElement(propertyValue, ToscaTagNamesEnum.ENTRY_SCHEMA, ToscaElementTypeEnum.ALL); + if (propertyFieldEntryScheme.isLeft()) { + if (propertyFieldEntryScheme.left().value() instanceof String) { + String schemaType = (String) propertyFieldEntryScheme.left().value(); + SchemaDefinition schema = new SchemaDefinition(); + PropertyDefinition schemeProperty = new PropertyDefinition(); + schemeProperty.setType(schemaType); + schema.setProperty(schemeProperty); + result = Either.left(schema); + + } else if (propertyFieldEntryScheme.left().value() instanceof Map) { + PropertyDefinition schemeProperty = createModuleProperty((Map) propertyFieldEntryScheme.left().value()); + SchemaDefinition schema = new SchemaDefinition(); + schema.setProperty(schemeProperty); + result = Either.left(schema); + + } + + } + return result; + } + + private static void setPropertyFieldIsPassword(Map propertyValue, PropertyDefinition dataDefinition) { + Either propertyFieldIsPassword = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.IS_PASSWORD); + if (propertyFieldIsPassword.isLeft()) { + dataDefinition.setPassword(Boolean.parseBoolean(propertyFieldIsPassword.left().value())); + } + } + + private static ResultStatusEnum setPropertyFieldDefaultValue(Map propertyValue, PropertyDefinition dataDefinition) { + Either propertyFieldDefaultValue = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + Gson gson = GsonFactory.getGson(); + if (propertyFieldDefaultValue.isLeft()) { + Object defaultValue = propertyFieldDefaultValue.left().value(); + String type = dataDefinition.getType(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(type); + // esofer - supporting customized data types. The validation of the + // type will be in the creation of the property. + // if(innerToscaType == null){ + // return ResultStatusEnum.MISSING_ENTRY_SCHEMA_TYPE; + // } + // customized data types value is represented as json. + // Also customized data types which are scalar ones, for example, + // data type which derived from integer, their value will be + // represented as json. + if (innerToscaType == null || innerToscaType.equals(ToscaPropertyType.LIST) || innerToscaType.equals(ToscaPropertyType.MAP)) { + String jsonObj = null; + if (defaultValue != null) { + jsonObj = gson.toJson(defaultValue); + } + + dataDefinition.setDefaultValue(jsonObj); + } else { + dataDefinition.setDefaultValue(String.valueOf(defaultValue)); + } + + } + + return ResultStatusEnum.OK; + } + + private static ResultStatusEnum setAttributeFieldDefaultValue(Map propertyValue, AttributeDefinition dataDefinition) { + Either propertyFieldDefaultValue = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + Gson gson = GsonFactory.getGson(); + if (propertyFieldDefaultValue.isLeft()) { + Object defaultValue = propertyFieldDefaultValue.left().value(); + String type = dataDefinition.getType(); + ToscaPropertyType innerToscaType = ToscaPropertyType.isValidType(type); + // esofer - supporting customized data types. The validation of the + // type will be in the creation of the property. + // if(innerToscaType == null){ + // return ResultStatusEnum.MISSING_ENTRY_SCHEMA_TYPE; + // } + // customized data types value is represented as json. + // Also customized data types which are scalar ones, for example, + // data type which derived from integer, their value will be + // represented as json. + if (innerToscaType == null || innerToscaType.equals(ToscaPropertyType.LIST) || innerToscaType.equals(ToscaPropertyType.MAP)) { + String jsonObj = null; + if (defaultValue != null) { + jsonObj = gson.toJson(defaultValue); + } + + dataDefinition.setDefaultValue(jsonObj); + } else { + dataDefinition.setDefaultValue(String.valueOf(defaultValue)); + } + + } + + return ResultStatusEnum.OK; + } + + public static void setField(Map toscaJson, ToscaTagNamesEnum tagName, Consumer setter) { + Either fieldStringValue = findFirstToscaStringElement(toscaJson, tagName); + if (fieldStringValue.isLeft()) { + setter.accept(fieldStringValue.left().value()); + } + + } + + private static void setPropertyFieldDescription(Map propertyValue, PropertyDefinition dataDefinition) { + Either propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION); + if (propertyFieldDescription.isLeft()) { + dataDefinition.setDescription(propertyFieldDescription.left().value()); + } + } + + private static void setPropertyFieldRequired(Map propertyValue, PropertyDefinition dataDefinition) { + Either propertyFieldRequired = findFirstToscaBooleanElement(propertyValue, ToscaTagNamesEnum.REQUIRED); + if (propertyFieldRequired.isLeft()) { + dataDefinition.setRequired(Boolean.parseBoolean(propertyFieldRequired.left().value())); + } + } + + private static void setAttributeFieldType(Map propertyValue, AttributeDefinition dataDefinition) { + Either propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE); + if (propertyFieldType.isLeft()) { + dataDefinition.setType(propertyFieldType.left().value()); + } + } + + private static void setPropertyFieldType(Map propertyValue, PropertyDefinition dataDefinition) { + Either propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE); + if (propertyFieldType.isLeft()) { + dataDefinition.setType(propertyFieldType.left().value()); + } + } + + private static void setAttributeFieldDescription(Map propertyValue, AttributeDefinition dataDefinition) { + Either propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION); + if (propertyFieldDescription.isLeft()) { + dataDefinition.setDescription(propertyFieldDescription.left().value()); + } + } + + public static Either, ResultStatusEnum> getProperties(Map toscaJson) { + Function elementGenByName = elementName -> createProperties(elementName); + Function, PropertyDefinition> func = map -> createModuleProperty(map); + + return getElements(toscaJson, ToscaTagNamesEnum.PROPERTIES, elementGenByName, func); + + } + + public static Either, ResultStatusEnum> getInputs(Map toscaJson) { + Function elementGenByName = elementName -> createInputs(elementName); + Function, InputDefinition> func = map -> createModuleInput(map); + + return getElements(toscaJson, ToscaTagNamesEnum.INPUTS, elementGenByName, func); + + } + + public static Either, ResultStatusEnum> getAttributes(Map toscaJson) { + Function elementGenByName = elementName -> createAttribute(elementName); + Function, AttributeDefinition> func = map -> createModuleAttribute(map); + + return getElements(toscaJson, ToscaTagNamesEnum.ATTRIBUTES, elementGenByName, func); + } + + public static Either, ResultStatusEnum> getElements(Map toscaJson, ToscaTagNamesEnum elementTagName, Function elementGenByName, + Function, ElementDefinition> func) { + Either, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either, ResultStatusEnum> toscaAttributes = findFirstToscaMapElement(toscaJson, elementTagName); + if (toscaAttributes.isLeft()) { + Map jsonAttributes = toscaAttributes.left().value(); + Map moduleAttributes = new HashMap<>(); + Iterator> propertiesNameValue = jsonAttributes.entrySet().iterator(); + while (propertiesNameValue.hasNext()) { + Entry attributeNameValue = propertiesNameValue.next(); + if (attributeNameValue.getValue() instanceof Map) { + @SuppressWarnings("unchecked") + ElementDefinition attribute = func.apply((Map) attributeNameValue.getValue()); + moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), attribute); + } else { + + ElementDefinition element = elementGenByName.apply(String.valueOf(attributeNameValue.getValue())); + + moduleAttributes.put(String.valueOf(attributeNameValue.getKey()), element); + } + + } + + if (moduleAttributes.size() > 0) { + eitherResult = Either.left(moduleAttributes); + } + + } + return eitherResult; + + } + + private static AttributeDefinition createAttribute(String name) { + AttributeDefinition attribute = new AttributeDefinition(); + + attribute.setName(name); + return attribute; + } + + private static PropertyDefinition createProperties(String name) { + PropertyDefinition property = new PropertyDefinition(); + property.setDefaultValue(name); + property.setName(name); + return property; + } + + private static InputDefinition createInputs(String name) { + InputDefinition input = new InputDefinition(); + + input.setName(name); + return input; + } + + public static Either, ResultStatusEnum> getHeatParameters(Map heatData, String artifactType) { + + Either, ResultStatusEnum> eitherResult = Either.right(ResultStatusEnum.ELEMENT_NOT_FOUND); + Either, ResultStatusEnum> toscaProperties = findFirstToscaMapElement(heatData, ToscaTagNamesEnum.PARAMETERS); + if (toscaProperties.isLeft()) { + Map jsonProperties = toscaProperties.left().value(); + List moduleProperties = new ArrayList<>(); + Iterator> propertiesNameValue = jsonProperties.entrySet().iterator(); + while (propertiesNameValue.hasNext()) { + Entry propertyNameValue = propertiesNameValue.next(); + if (propertyNameValue.getValue() instanceof Map) { + if (!artifactType.equals(ArtifactTypeEnum.HEAT_ENV.getType())) { + @SuppressWarnings("unchecked") + Either propertyStatus = createModuleHeatParameter((Map) propertyNameValue.getValue()); + if (propertyStatus.isRight()) { + return Either.right(propertyStatus.right().value()); + } + HeatParameterDefinition property = propertyStatus.left().value(); + property.setName(String.valueOf(propertyNameValue.getKey())); + moduleProperties.add(property); + } else { + addHeatParamDefinition(moduleProperties, propertyNameValue, true); + } + } else { + addHeatParamDefinition(moduleProperties, propertyNameValue, false); + } + + } + + if (moduleProperties.size() > 0) { + eitherResult = Either.left(moduleProperties); + } + + } + return eitherResult; + + } + + private static void addHeatParamDefinition(List moduleProperties, Entry propertyNameValue, boolean isJson) { + HeatParameterDefinition property = new HeatParameterDefinition(); + Object value = propertyNameValue.getValue(); + if (value != null) { + property.setDefaultValue(isJson ? new Gson().toJson(value).toString() : StringEscapeUtils.escapeJava(String.valueOf(value))); + } + property.setName(String.valueOf(propertyNameValue.getKey())); + moduleProperties.add(property); + } + + private static Either createModuleHeatParameter(Map propertyValue) { + HeatParameterDefinition propertyDef = new HeatParameterDefinition(); + String type; + Either propertyFieldType = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.TYPE); + if (propertyFieldType.isLeft()) { + type = propertyFieldType.left().value(); + propertyDef.setType(type); + } else { + return Either.right(ResultStatusEnum.INVALID_PROPERTY_TYPE); + } + Either propertyFieldDescription = findFirstToscaStringElement(propertyValue, ToscaTagNamesEnum.DESCRIPTION); + if (propertyFieldDescription.isLeft()) { + propertyDef.setDescription(propertyFieldDescription.left().value()); + } + + Either propertyFieldDefaultVal = findToscaElement(propertyValue, ToscaTagNamesEnum.DEFAULT_VALUE, ToscaElementTypeEnum.ALL); + if (propertyFieldDefaultVal.isLeft()) { + if (propertyFieldDefaultVal.left().value() == null) { + return Either.right(ResultStatusEnum.INVALID_PROPERTY_VALUE); + } + Object value = propertyFieldDefaultVal.left().value(); + String defaultValue = type.equals(HeatParameterType.JSON.getType()) ? new Gson().toJson(value).toString() : StringEscapeUtils.escapeJava(String.valueOf(value)); + propertyDef.setDefaultValue(defaultValue); + propertyDef.setCurrentValue(defaultValue); + } + + return Either.left(propertyDef); + } + + public static String getPropertyJsonStringValue(Object value, String type) { + Gson gson = new Gson(); + if (type == null) { + return null; + } + ToscaPropertyType validType = ToscaPropertyType.isValidType(type); + if (validType == null || validType.equals(ToscaPropertyType.MAP) || validType.equals(ToscaPropertyType.LIST)) { + return gson.toJson(value); + } + return value.toString(); + } + + /** + * removes from Json map (toscaJson) first element found by name (elementName) note that this method could update the received argument toscaJson + * + * @param toscaJson + * @param elementName + */ + public static void removeElementFromJsonMap(Map toscaJson, String elementName) { + for (Entry entry : toscaJson.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + if (key.equals(elementName)) { + toscaJson.remove(elementName); + return; + } else if (value instanceof Map) { + removeElementFromJsonMap((Map) value, elementName); + } + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InformationDeployedArtifactsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InformationDeployedArtifactsBusinessLogic.java new file mode 100644 index 0000000000..129110e13f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InformationDeployedArtifactsBusinessLogic.java @@ -0,0 +1,117 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import org.apache.commons.codec.binary.Base64; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +//Pavel +//currently NOT IN USE - there are no informational deployed artifacts after US601880 + +@org.springframework.stereotype.Component("informationDeployedArtifactsBusinessLogic") +public class InformationDeployedArtifactsBusinessLogic { + + /* + * private static Logger log = LoggerFactory.getLogger(InformationDeployedArtifactsBusinessLogic.class. getName()); + * + * @javax.annotation.Resource private ArtifactsBusinessLogic artifactBusinessLogic; + * + * public boolean isInformationDeployedArtifact(ArtifactDefinition artifactInfo) { log.debug("checking if artifact {} is informationalDeployable", artifactInfo.getArtifactName()); boolean informationDeployedArtifact = false; Map resourceInformationalDeployedArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() .getResourceInformationalDeployedArtifacts(); if( resourceInformationalDeployedArtifacts != null && + * resourceInformationalDeployedArtifacts.containsKey(artifactInfo. getArtifactType())){ if( artifactInfo.getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL && artifactInfo.checkEsIdExist()){ informationDeployedArtifact = true; + * + * } } String message = (informationDeployedArtifact) ? "artifact {} is informationalDeployable" : "artifact {} is not informationalDeployable"; log.debug(message, artifactInfo.getArtifactName()); return informationDeployedArtifact; } + * + * public Either validateArtifact(boolean isCreate, ArtifactDefinition artifactInfo, Component parent, NodeTypeEnum parentType) { + * + * log.debug("checking if informationalDeployable artifact {} is valid ", artifactInfo.getArtifactName()); Wrapper responseFormatWrapper = new Wrapper(); Map + * resourceInformationalDeployedArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration(). getResourceInformationalDeployedArtifacts(); + * + * + * artifactBusinessLogic.validateArtifactTypeExists(responseFormatWrapper, artifactInfo); if( responseFormatWrapper.isEmpty() && isCreate ){ artifactBusinessLogic.validateSingleArtifactType(responseFormatWrapper, + * ArtifactTypeEnum.findType(artifactInfo.getArtifactType()), parent, parentType); } if( responseFormatWrapper.isEmpty() ){ ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactInfo.getArtifactType()); + * artifactBusinessLogic.validateFileExtension(responseFormatWrapper, () -> resourceInformationalDeployedArtifacts.get(artifactInfo.getArtifactType() ), artifactInfo, parentType, artifactType); } + * + * if( responseFormatWrapper.isEmpty() ){ validatePayloadContent(responseFormatWrapper, artifactInfo); } + * + * Either response; if( responseFormatWrapper.isEmpty() ){ response = Either.left(true); } else{ response = Either.right(responseFormatWrapper.getInnerElement()); } + * + * String message = (response.isLeft()) ? "informationalDeployable artifact {} is valid" : "informationalDeployable artifact {} is not valid"; log.debug(message, artifactInfo.getArtifactName()); return response; } + * + * private void validatePayloadContent(Wrapper responseFormatWrapper, ArtifactDefinition artifactToVerify) { ArtifactTypeEnum artifactType = ArtifactTypeEnum.findType(artifactToVerify.getArtifactType()); if( artifactType == + * ArtifactTypeEnum.YANG_XML ){ String rawPayloadData = artifactToVerify.getPayloadData(); String xmlToParse = Base64.isBase64(rawPayloadData) ? new String(org.apache.commons.codec.binary.Base64.decodeBase64(rawPayloadData )) : rawPayloadData; + * + * boolean isXmlValid = artifactBusinessLogic.isValidXml(xmlToParse.getBytes()); if( !isXmlValid ){ ResponseFormat responseFormat = ResponseFormatManager.getInstance().getResponseFormat(ActionStatus. INVALID_XML, + * artifactToVerify.getArtifactType()); responseFormatWrapper.setInnerElement(responseFormat); log.debug("Xml is not valid for artifact : {}", artifactToVerify.getArtifactName()); } } } + * + * + * + * + * public List getInformationalDeployedArtifactsForResourceInstance( ComponentInstance resourceInstance ) { String resourceUid = resourceInstance.getComponentUid(); String resourceName = resourceInstance.getComponentName(); + * return getInformationalDeployedArtifactsForResource(resourceUid, resourceName); } + * + * private List getInformationalDeployedArtifactsForResource( String resourceUid, String resourceName) { List informationalDeployedArtifacts = new ArrayList(); log. + * debug("checking if informationalDeployable artifacts exist for resource {} " , resourceName); Map resourceInformationalDeployedArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration() + * .getResourceInformationalDeployedArtifacts(); + * + * + * Either, StorageOperationStatus> eitherArtifacts = artifactBusinessLogic.getArtifacts(resourceUid, NodeTypeEnum.Resource, false, ArtifactGroupTypeEnum.INFORMATIONAL); + * + * if( eitherArtifacts.isLeft() && resourceInformationalDeployedArtifacts != null ){ Predicate predicate = p -> resourceInformationalDeployedArtifacts.containsKey(p.getArtifactType()) && p.checkEsIdExist() && + * p.getArtifactGroupType() == ArtifactGroupTypeEnum.INFORMATIONAL; informationalDeployedArtifacts = eitherArtifacts.left().value().values().stream().filter( predicate ).collect(Collectors.toList()); } + * + * if( informationalDeployedArtifacts.isEmpty() ){ log.debug("no informationalDeployable artifacts exist for resource {} ", resourceName); } else{ log. debug("informationalDeployable artifacts found for resource {} are :{}", resourceName, + * informationalDeployedArtifacts.toString()); } + * + * + * return informationalDeployedArtifacts; } + * + * public List getAllDeployableArtifacts( Resource resource ){ List merged = new ArrayList(); + * + * List deploymentArtifacts = artifactBusinessLogic.getDeploymentArtifacts(resource, NodeTypeEnum.Resource); merged.addAll(deploymentArtifacts); + * + * List informationalDeployedArtifactsForResource = getInformationalDeployedArtifactsForResource( resource.getUniqueId(), resource.getName()); merged.addAll(informationalDeployedArtifactsForResource); + * + * return merged; } + */ +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java new file mode 100644 index 0000000000..7d0624440e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InputsBusinessLogic.java @@ -0,0 +1,526 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.InputsOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.resources.data.InputsData; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("inputsBusinessLogic") +public class InputsBusinessLogic extends BaseBusinessLogic { + + private static final String CREATE_INPUT = "CreateInput"; + + private static Logger log = LoggerFactory.getLogger(InputsBusinessLogic.class.getName()); + + @Autowired + private IResourceOperation resourceOperation = null; + + @javax.annotation.Resource + private InputsOperation inputsOperation = null; + + @javax.annotation.Resource + private PropertyOperation propertyOperation = null; + + @Autowired + private ComponentsUtils componentsUtils; + + /** + * associate inputs to a given component with paging + * + * @param componentId + * @param userId + * @param fromId + * @param amount + * @return + */ + public Either, ResponseFormat> getInputs(String userId, String componentId, String fromName, + int amount) { + + Either resp = validateUserExists(userId, "get Inputs", false); + + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either, StorageOperationStatus> inputsEitherRes = inputsOperation + .getInputsOfComponent(componentId, fromName, amount); + if (inputsEitherRes.isRight()) { + if (inputsEitherRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList()); + } + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(inputsEitherRes.right().value()); + log.debug("Failed to get inputs under component {}, error: {}", componentId, actionStatus.name()); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + + } + + return Either.left(inputsEitherRes.left().value()); + + } + + /** + * associate properties to a given component instance input + * + * @param instanceId + * @param userId + * @param inputId + * @return + */ + + public Either, ResponseFormat> getComponentInstancePropertiesByInputId( + String userId, String instanceId, String inputId) { + Either resp = validateUserExists(userId, "get Properties by input", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either, StorageOperationStatus> propertiesEitherRes = inputsOperation + .getComponentInstancePropertiesByInputId(instanceId, inputId); + if (propertiesEitherRes.isRight()) { + + if (propertiesEitherRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList()); + } + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(propertiesEitherRes.right().value()); + log.debug("Failed to get inputs under component {}, error: {}", instanceId, actionStatus.name()); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + + } + + return Either.left(propertiesEitherRes.left().value()); + + } + + public Either, ResponseFormat> getInputsForComponentInput(String userId, + String componentId, String inputId) { + Either resp = validateUserExists(userId, "get Inputs by input", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either, StorageOperationStatus> inputsEitherRes = inputsOperation + .getComponentInstanceInputsByInputId(componentId, inputId); + if (inputsEitherRes.isRight()) { + + if (inputsEitherRes.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList()); + } + + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(inputsEitherRes.right().value()); + log.debug("Failed to get inputs for input under component {}, error: {}", componentId, actionStatus.name()); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + + } + + return Either.left(inputsEitherRes.left().value()); + + } + + public Either, ResponseFormat> createMultipleInputs(String userId, String componentId, + ComponentTypeEnum componentType, ComponentInstInputsMap componentInstInputsMapUi, boolean shouldLockComp, + boolean inTransaction) { + + Either, ResponseFormat> result = null; + org.openecomp.sdc.be.model.Component component = null; + try { + Either resp = validateUserExists(userId, "get Properties by input", false); + + if (resp.isRight()) { + result = Either.right(resp.right().value()); + return result; + } + + User user = resp.left().value(); + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreUsers(false); + + Either validateComponent = validateComponentExists( + componentId, componentType, componentParametersView, userId, null, user); + + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + component = validateComponent.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, CREATE_INPUT); + if (lockComponent.isRight()) { + result = Either.right(lockComponent.right().value()); + return result; + } + } + + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + result = Either.right(canWork.right().value()); + return result; + } + + Either, ResponseFormat> allDataTypes = getAllDataTypes( + applicationDataTypeCache); + if (allDataTypes.isRight()) { + result = Either.right(allDataTypes.right().value()); + return result; + } + + Map dataTypes = allDataTypes.left().value(); + + Either, StorageOperationStatus> createInputsResult = this.inputsOperation + .addInputsToComponent(componentId, componentType.getNodeType(), componentInstInputsMapUi, + dataTypes); + + if (createInputsResult.isRight()) { + ActionStatus actionStatus = componentsUtils + .convertFromStorageResponse(createInputsResult.right().value()); + log.debug("Failed to create inputs under component {}, error: {}", componentId, actionStatus.name()); + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + + } + result = Either.left(createInputsResult.left().value()); + + return result; + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + + } + + public Either, ResponseFormat> createInputs(String componentId, String userId, + ComponentTypeEnum componentType, List inputsDefinitions, boolean shouldLockComp, + boolean inTransaction) { + + Either, ResponseFormat> result = null; + + org.openecomp.sdc.be.model.Component component = null; + try { + + if (inputsDefinitions != null && false == inputsDefinitions.isEmpty()) { + + if (shouldLockComp == true && inTransaction == true) { + BeEcompErrorManager.getInstance().logInternalFlowError("createGroups", + "Cannot lock component since we are inside a transaction", ErrorSeverity.ERROR); + // Cannot lock component since we are in a middle of another + // transaction. + ActionStatus actionStatus = ActionStatus.INVALID_CONTENT; + result = Either.right(componentsUtils.getResponseFormat(actionStatus)); + return result; + } + + Either validateUserExists = validateUserExists(userId, CREATE_INPUT, true); + if (validateUserExists.isRight()) { + result = Either.right(validateUserExists.right().value()); + return result; + } + + User user = validateUserExists.left().value(); + + Either validateComponent = validateComponentExists( + componentId, componentType, inTransaction, false); + if (validateComponent.isRight()) { + result = Either.right(validateComponent.right().value()); + return result; + } + component = validateComponent.left().value(); + + if (shouldLockComp) { + Either lockComponent = lockComponent(component, CREATE_INPUT); + if (lockComponent.isRight()) { + return Either.right(lockComponent.right().value()); + } + } + + Either canWork = validateCanWorkOnComponent(component, userId); + if (canWork.isRight()) { + result = Either.right(canWork.right().value()); + return result; + } + + result = createInputsInGraph(inputsDefinitions, component, user, inTransaction); + } + + return result; + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + // unlock resource + if (shouldLockComp && component != null) { + graphLockOperation.unlockComponent(componentId, componentType.getNodeType()); + } + + } + + } + + public Either, ResponseFormat> createInputsInGraph(List inputsDefinitions, + org.openecomp.sdc.be.model.Component component, User user, boolean inTransaction) { + Either, ResponseFormat> result; + List inputs = new ArrayList(); + for (InputDefinition inputDefinition : inputsDefinitions) { + // String resourceId, String inputName, InputDefinition + // newInputDefinition, String userId, boolean inTransaction + Either createInput = createInput(component, user, + component.getComponentType(), inputDefinition.getName(), inputDefinition, inTransaction); + if (createInput.isRight()) { + log.debug("Failed to create group {}.", createInput); + result = Either.right(createInput.right().value()); + return result; + } + InputDefinition createdGroup = createInput.left().value(); + inputs.add(createdGroup); + } + result = Either.left(inputs); + return result; + } + + /** + * Delete input from service + * + * @param component + * @param user + * @param componentType + * @param inputId + * @param inTransaction + * @return + */ + public Either deleteInput(String componentType, String componentId, String userId, String inputId, boolean inTransaction) { + + if (log.isDebugEnabled()) + log.debug("Going to delete input id: {}", inputId); + + // Validate user (exists) + Either userEither = validateUserExists(userId, "Delete input", true); + if (userEither.isRight()) { + return Either.right(userEither.right().value()); + } + + // Get component using componentType, componentId + Either componentEither = serviceOperation.getComponent(componentId, true); + if (componentEither.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentEither.right().value()))); + } + org.openecomp.sdc.be.model.Component component = componentEither.left().value(); + + // Validate inputId is child of the component + // And get the inputDefinition for the response + InputDefinition inputDefinition = null; + Optional optionalInput = component.getInputs().stream(). + // filter by ID + filter(input -> input.getUniqueId().equals(inputId)). + // Get the input + findAny(); + if (optionalInput.isPresent()) { + inputDefinition = optionalInput.get(); + } else { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INPUT_IS_NOT_CHILD_OF_COMPONENT, inputId, componentId)); + } + + // Lock component + Either lockResultEither = lockComponent(componentId, component, "deleteInput"); + if (lockResultEither.isRight()) { + ResponseFormat responseFormat = lockResultEither.right().value(); + return Either.right(responseFormat); + } + + // Delete input operations + Either deleteEither = Either.right(StorageOperationStatus.GENERAL_ERROR); + try { + deleteEither = inputsOperation.deleteInput(inputId); + if (deleteEither.isRight()){ + log.debug("Component id: {} delete input id: {} failed", componentId, inputId); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deleteEither.right().value()), component.getName())); + } + return Either.left(inputDefinition); + } finally { + if (deleteEither.isRight()) { + log.debug("Component id: {} delete input id: {} failed", componentId, inputId); + titanGenericDao.rollback(); + } else { + log.debug("Component id: {} delete input id: {} success", componentId, inputId); + titanGenericDao.commit(); + } + unlockComponent(deleteEither, component); + } + } + + /** + * Create new property on resource in graph + * + * @param resourceId + * @param propertyName + * @param newPropertyDefinition + * @param userId + * @return Either + */ + + private Either createInput(org.openecomp.sdc.be.model.Component component, + User user, ComponentTypeEnum componentType, String inputName, InputDefinition newInputDefinition, + boolean inTransaction) { + + Either result = null; + if (log.isDebugEnabled()) + log.debug("Going to create input {}", newInputDefinition); + + try { + + // verify property not exist in resource + List resourceProperties = component.getInputs(); + + if (resourceProperties != null) { + if (inputsOperation.isInputExist(resourceProperties, component.getUniqueId(), inputName)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, "")); + } + } + + Either, ResponseFormat> allDataTypes = getAllDataTypes( + applicationDataTypeCache); + if (allDataTypes.isRight()) { + return Either.right(allDataTypes.right().value()); + } + + Map dataTypes = allDataTypes.left().value(); + + // validate input default values + Either defaultValuesValidation = validatePropertyDefaultValue(newInputDefinition, + dataTypes); + if (defaultValuesValidation.isRight()) { + return Either.right(defaultValuesValidation.right().value()); + } + // convert property + ToscaPropertyType type = getType(newInputDefinition.getType()); + PropertyValueConverter converter = type.getConverter(); + // get inner type + String innerType = null; + if (newInputDefinition != null) { + SchemaDefinition schema = newInputDefinition.getSchema(); + if (schema != null) { + PropertyDataDefinition prop = schema.getProperty(); + if (prop != null) { + innerType = prop.getType(); + } + } + String convertedValue = null; + if (newInputDefinition.getDefaultValue() != null) { + convertedValue = converter.convert(newInputDefinition.getDefaultValue(), innerType, + allDataTypes.left().value()); + newInputDefinition.setDefaultValue(convertedValue); + } + } + + // add the new property to resource on graph + // need to get StorageOpaerationStatus and convert to ActionStatus + // from componentsUtils + Either either = inputsOperation.addInput(inputName, newInputDefinition, + component.getUniqueId(), componentType.getNodeType()); + if (either.isRight()) { + return Either.right(componentsUtils.getResponseFormat( + componentsUtils.convertFromStorageResponse(either.right().value()), component.getName())); + } + // @TODO commit + // inputsOperation.getTitanGenericDao().commit(); + InputDefinition createdInputyDefinition = inputsOperation + .convertInputDataToInputDefinition(either.left().value()); + createdInputyDefinition.setName(inputName); + createdInputyDefinition.setParentUniqueId(component.getUniqueId()); + + return Either.left(createdInputyDefinition); + + } finally { + + if (false == inTransaction) { + + if (result == null || result.isRight()) { + log.debug("Going to execute rollback on create group."); + titanGenericDao.rollback(); + } else { + log.debug("Going to execute commit on create group."); + titanGenericDao.commit(); + } + + } + + } + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceLifecycleTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceLifecycleTypeImportManager.java new file mode 100644 index 0000000000..780980ba08 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/InterfaceLifecycleTypeImportManager.java @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("interfaceLifecycleTypeImportManager") +public class InterfaceLifecycleTypeImportManager { + + @Resource + private IInterfaceLifecycleOperation interfaceLifecycleOperation; + + @Resource + private ComponentsUtils componentsUtils; + @Resource + private CommonImportManager commonImportManager; + + private static Logger log = LoggerFactory.getLogger(InterfaceLifecycleTypeImportManager.class.getName()); + + public Either, ResponseFormat> createLifecycleTypes(String interfaceLifecycleTypesYml) { + + Either, ActionStatus> interfaces = createLifecyclyTypeFromYml(interfaceLifecycleTypesYml); + if (interfaces.isRight()) { + ActionStatus status = interfaces.right().value(); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByGroupType(status, null); + return Either.right(responseFormat); + } + return createInterfacesByDao(interfaces.left().value()); + + } + + private Either, ActionStatus> createLifecyclyTypeFromYml(String interfaceLifecycleTypesYml) { + return commonImportManager.createElementTypesFromYml(interfaceLifecycleTypesYml, (lifecycleTypeName, lifecycleTypeJsonData) -> createLifecycleType(lifecycleTypeName, lifecycleTypeJsonData)); + + } + + private Either, ResponseFormat> createInterfacesByDao(List interfacesToCreate) { + List createdInterfaces = new ArrayList<>(); + Either, ResponseFormat> eitherResult = Either.left(createdInterfaces); + Iterator interfaceItr = interfacesToCreate.iterator(); + boolean stopDao = false; + while (interfaceItr.hasNext() && !stopDao) { + InterfaceDefinition interfaceDef = interfaceItr.next(); + + log.info("send interfaceDefinition {} to dao for create", interfaceDef.getType()); + + Either dataModelResponse = interfaceLifecycleOperation.createInterfaceType(interfaceDef); + if (dataModelResponse.isRight()) { + log.info("failed to create interface : {} error: {}", interfaceDef.getType(), dataModelResponse.right().value().name()); + if (dataModelResponse.right().value() != StorageOperationStatus.SCHEMA_VIOLATION) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponseForLifecycleType(dataModelResponse.right().value()), interfaceDef.getType()); + eitherResult = Either.right(responseFormat); + stopDao = true; + } + + } else { + createdInterfaces.add(dataModelResponse.left().value()); + } + if (!interfaceItr.hasNext()) { + log.info("lifecycle types were created successfully!!!"); + } + } + return eitherResult; + } + + private InterfaceDefinition createLifecycleType(String interfaceDefinition, Map toscaJson) { + InterfaceDefinition interfaceDef = new InterfaceDefinition(); + interfaceDef.setType(interfaceDefinition); + + Map operations = new HashMap(); + + for (Map.Entry entry : toscaJson.entrySet()) { + Operation operation = new Operation(); + Map opProp = (Map) entry.getValue(); + + operation.setDescription((String) opProp.get("description")); + operations.put(entry.getKey(), operation); + } + interfaceDef.setOperations(operations); + return interfaceDef; + } + + public static void setLog(Logger log) { + InterfaceLifecycleTypeImportManager.log = log; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/MonitoringBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/MonitoringBusinessLogic.java new file mode 100644 index 0000000000..e9708f50d5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/MonitoringBusinessLogic.java @@ -0,0 +1,71 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.impl.MonitoringDao; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.common.monitoring.MonitoringEvent; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("monitoringBusinessLogic") +public class MonitoringBusinessLogic { + + private static Logger log = LoggerFactory.getLogger(MonitoringBusinessLogic.class.getName()); + + @javax.annotation.Resource + private MonitoringDao monitoringDao; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + public Either logMonitoringEvent(MonitoringEvent monitoringEvent) { + if (monitoringDao == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + ActionStatus status = monitoringDao.addRecord(monitoringEvent); + if (!status.equals(ActionStatus.OK)) { + log.warn("Failed to persist monitoring event: {}", status.name()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return Either.left(true); + } + + public String getEsHost() { + + String res = monitoringDao.getEsHost(); + res = res.replaceAll("[\\[\\]]", ""); + res = res.split(",")[0]; + res = res.replaceAll("[']", ""); + res = res.split(":")[0]; + return res; + } + + public String getEsPort() { + return monitoringDao.getEsPort(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyTypeImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyTypeImportManager.java new file mode 100644 index 0000000000..1e0670daa2 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PolicyTypeImportManager.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.List; +import java.util.Map; +import java.util.function.Consumer; + +import javax.annotation.Resource; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.CommonImportManager.ElementTypeEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.operations.api.IGroupOperation; +import org.openecomp.sdc.be.model.operations.api.IPolicyTypeOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("policyTypeImportManager") +public class PolicyTypeImportManager { + + @Resource + private PropertyOperation propertyOperation; + @Resource + private IPolicyTypeOperation policyTypeOperation; + @Resource + private ComponentsUtils componentsUtils; + @Resource + private IResourceOperation resourceOperation; + @Autowired + protected IGroupOperation groupOperation; + + @Resource + private CommonImportManager commonImportManager; + + public Either>, ResponseFormat> createPolicyTypes(String groupTypesYml) { + return commonImportManager.createElementTypes(groupTypesYml, elementTypeYml -> createPolicyTypesFromYml(elementTypeYml), groupTypesList -> createPolicyTypesByDao(groupTypesList), ElementTypeEnum.PolicyType); + } + + private Either, ActionStatus> createPolicyTypesFromYml(String policyTypesYml) { + + return commonImportManager.createElementTypesFromYml(policyTypesYml, (policyTypeName, groupTypeJsonData) -> createPolicyType(policyTypeName, groupTypeJsonData)); + } + + private Either>, ResponseFormat> createPolicyTypesByDao(List policyTypesToCreate) { + return commonImportManager.createElementTypesByDao(policyTypesToCreate, policyType -> validatePolicyType(policyType), policyType -> new ImmutablePair<>(ElementTypeEnum.PolicyType, policyType.getType()), + policyTypeName -> policyTypeOperation.getLatestPolicyTypeByType(policyTypeName), policyType -> policyTypeOperation.addPolicyType(policyType), null); + } + + private Either validatePolicyType(PolicyTypeDefinition policyType) { + Either result = Either.left(ActionStatus.OK); + if (policyType.getTargets() != null) { + if (policyType.getTargets().isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.TARGETS_EMPTY, policyType.getType()); + result = Either.right(responseFormat); + } + if (result.isLeft()) { + for (String targetName : policyType.getTargets()) { + boolean isValid = resourceOperation.getLatestByToscaResourceName(targetName, false).isLeft(); + if (!isValid) { + isValid = groupOperation.isGroupExist(targetName, false); + } + if (!isValid) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.TARGETS_NON_VALID, policyType.getType(), targetName); + result = Either.right(responseFormat); + break; + } + } + } + } + + return result; + } + + private PolicyTypeDefinition createPolicyType(String groupTypeName, Map toscaJson) { + + PolicyTypeDefinition policyType = new PolicyTypeDefinition(); + + if (toscaJson != null) { + // Description + final Consumer descriptionSetter = description -> policyType.setDescription(description); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DESCRIPTION.getElementName(), descriptionSetter); + // Derived From + final Consumer derivedFromSetter = derivedFrom -> policyType.setDerivedFrom(derivedFrom); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.DERIVED_FROM.getElementName(), derivedFromSetter); + // Properties + commonImportManager.setProperties(toscaJson, (values) -> policyType.setProperties(values)); + // Metadata + final Consumer> metadataSetter = metadata -> policyType.setMetadata(metadata); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.METADATA.getElementName(), metadataSetter); + // Targets + final Consumer> targetsSetter = targets -> policyType.setTargets(targets); + commonImportManager.setField(toscaJson, ToscaTagNamesEnum.TARGETS.getElementName(), targetsSetter); + + policyType.setType(groupTypeName); + + policyType.setHighestVersion(true); + + policyType.setVersion(ImportUtils.Constants.FIRST_CERTIFIED_VERSION_VERSION); + } + return policyType; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductBusinessLogic.java new file mode 100644 index 0000000000..3a54513b0b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductBusinessLogic.java @@ -0,0 +1,887 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +@org.springframework.stereotype.Component("productBusinessLogic") +public class ProductBusinessLogic extends ComponentBusinessLogic { + + private static final String PRODUCT_FULL_NAME = "full"; + private static final String PRODUCT_ABBREVIATED_NAME = "abbreviated"; + private static Logger log = LoggerFactory.getLogger(ProductBusinessLogic.class.getName()); + private static final String INITIAL_VERSION = "0.1"; + private static List creationRoles; + private static List updateRoles; + private static List contactsRoles; + + public ProductBusinessLogic() { + creationRoles = new ArrayList<>(); + updateRoles = new ArrayList<>(); + contactsRoles = new ArrayList<>(); + + // only PM is allowed to create/update products + creationRoles.add(Role.PRODUCT_MANAGER); + updateRoles.add(Role.PRODUCT_MANAGER); + // Only PM is allowed to be product contacts + contactsRoles.add(Role.PRODUCT_MANAGER); + } + + @Autowired + private IElementOperation elementDao; + + @Autowired + private ProductComponentInstanceBusinessLogic productComponentInstanceBusinessLogic; + + @Autowired + private ICacheMangerOperation cacheManagerOperation; + + public Either createProduct(Product product, User user) { + AuditingActionEnum actionEnum = AuditingActionEnum.CREATE_RESOURCE; + ComponentTypeEnum typeEnum = ComponentTypeEnum.PRODUCT; + + // validate user - should be first to get the maximum auditing info in + // case of subsequent failures + log.debug("get user from DB"); + Either eitherCreator = validateUser(user, "Create Product", product, actionEnum, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either validateRes = validateUserRole(user, product, creationRoles, actionEnum, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + + if (product == null) { + log.debug("Invalid product json. Check product servlet log for createProduct entry params"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + componentsUtils.auditComponentAdmin(responseFormat, user, product, Constants.EMPTY_STRING, Constants.EMPTY_STRING, actionEnum, typeEnum); + return Either.right(responseFormat); + } + + // warn about non-updatable fields + checkUnupdatableProductFields(product); + + Either validateProductResponse = validateProductBeforeCreate(product, user, actionEnum); + if (validateProductResponse.isRight()) { + return Either.right(validateProductResponse.right().value()); + } + + log.debug("send product {} to dao for create", product.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + + Either lockResult = lockComponentByName(product.getSystemName(), product, "Create Product"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + log.debug("Product name locked is {}, status = {}", product.getSystemName(), lockResult); + + try { + Either createProductEither = productOperation.createProduct(product); + + if (createProductEither.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(createProductEither.right().value()), product, typeEnum); + componentsUtils.auditComponentAdmin(responseFormat, user, product, Constants.EMPTY_STRING, Constants.EMPTY_STRING, actionEnum, typeEnum); + return Either.right(responseFormat); + } + + log.debug("Product created successfully"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditComponentAdmin(responseFormat, user, product, Constants.EMPTY_STRING, Constants.EMPTY_STRING, actionEnum, typeEnum); + + // //Add product to cache + Product createdProduct = createProductEither.left().value(); + // cacheManagerOperation.updateComponentInCache(createdProduct.getUniqueId(), + // createdProduct.getLastUpdateDate(), NodeTypeEnum.Product); + + return Either.left(createdProduct); + + } finally { + graphLockOperation.unlockComponentByName(product.getSystemName(), product.getUniqueId(), NodeTypeEnum.Product); + } + + } + + private void checkUnupdatableProductFields(Product product) { + checkComponentFieldsForOverrideAttempt(product); + if (product.getNormalizedName() != null) { + log.info("NormalizedName cannot be defined by user. This field will be overridden by the application"); + } + } + + private Either validateProductBeforeCreate(Product product, User user, AuditingActionEnum actionEnum) { + + Either validateProductFields = validateProductFieldsBeforeCreate(user, product, actionEnum); + if (validateProductFields.isRight()) { + return Either.right(validateProductFields.right().value()); + } + + if (product.getIsActive() == null) { + log.debug("no isActive value was provided, setting to default: false"); + product.setIsActive(false); + } + + product.setCreatorUserId(user.getUserId()); + + // enrich object + log.debug("enrich product with version and state"); + product.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + product.setVersion(INITIAL_VERSION); + + // Generate invariant UUID - must be here and not in operation since it + // should stay constant during clone + String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + product.setInvariantUUID(invariantUUID); + + return Either.left(product); + } + + private Either validateProductFieldsBeforeCreate(User user, Product product, AuditingActionEnum actionEnum) { + + // To be removed in 1607 + // See below + String oldName = product.getName(); + + Either componentNameValidation = validateProductNameAndCleanup(user, product, actionEnum); + if (componentNameValidation.isRight()) { + return componentNameValidation; + } + + Either componentNameUniquenessValidation = validateComponentNameUnique(user, product, actionEnum); + if (componentNameUniquenessValidation.isRight()) { + return componentNameUniquenessValidation; + } + + // To be removed in 1607 and replaced with generic + // validateTagsListAndRemoveDuplicates() + // See comments on the validateTagsListAndRemoveDuplicates(user, + // product, oldName, actionEnum) function + Either tagsValidation = validateTagsListAndRemoveDuplicates(user, product, oldName, actionEnum); + if (tagsValidation.isRight()) { + return tagsValidation; + } + + Either validateIconResponse = validateIcon(user, product, actionEnum); + if (validateIconResponse.isRight()) { + return validateIconResponse; + } + + Either projectCodeValidation = validateProjectCode(user, product, actionEnum); + if (projectCodeValidation.isRight()) { + return projectCodeValidation; + } + Either categoryValidation = validateGrouping(user, product, actionEnum); + if (categoryValidation.isRight()) { + return categoryValidation; + } + + Either contactsListValidation = validateAndUpdateProductContactsList(user, product, actionEnum); + if (contactsListValidation.isRight()) { + return contactsListValidation; + } + + Either productFullNameValidation = validateProductFullNameAndCleanup(user, product, actionEnum); + if (productFullNameValidation.isRight()) { + return productFullNameValidation; + } + + Either descValidation = validateDescriptionAndCleanup(user, product, actionEnum); + if (descValidation.isRight()) { + return descValidation; + } + + return Either.left(true); + } + + public Either, ResponseFormat> validateProductNameExists(String productName, String userId) { + + Either resp = validateUserExists(userId, "validate Product Name Exists", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either dataModelResponse = productOperation.validateComponentNameExists(productName); + + if (dataModelResponse.isLeft()) { + Map result = new HashMap<>(); + result.put("isValid", dataModelResponse.left().value()); + log.debug("validation was successfully performed."); + return Either.left(result); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value())); + + return Either.right(responseFormat); + } + + private Either validateAndUpdateProductContactsList(User user, Product product, AuditingActionEnum actionEnum) { + List contacts = product.getContacts(); + if (!ValidationUtils.validateListNotEmpty(contacts)) { + log.debug("Contacts list cannot be empty for product {}", product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.EMPTY_PRODUCT_CONTACTS_LIST); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + boolean isProductCreatorInContacts = false; + String modifierUserId = user.getUserId(); + for (String contact : contacts) { + if (contact.equals(modifierUserId)) { + log.trace("modifier userId found in product contacts"); + isProductCreatorInContacts = true; + // No need to validate for this userId - it's modifier's + continue; + } + if (!ValidationUtils.validateContactId(contact)) { + log.debug("Product contacts has invalid userId {} for product {}", contact, product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CONTACT, ComponentTypeEnum.PRODUCT.getValue()); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + User contactUser = new User(); + contactUser.setUserId(contact); + Either validateUser = validateUserExists(contact, "Create Product", false); + if (validateUser.isRight()) { + log.debug("Cannot set contact with userId {} as product contact, error: {}", contact, validateUser.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PRODUCT_CONTACT, contact); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + contactUser = validateUser.left().value(); + + Either validateUserRole = validateUserRole(contactUser, contactsRoles); + if (validateUserRole.isRight()) { + log.debug("Cannot set contact with userId {} as product contact, error: {}", contact, validateUserRole.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PRODUCT_CONTACT, contact); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + } + + if (!isProductCreatorInContacts) { + log.debug("modifier userId {} not found in product contacts - adding it", modifierUserId); + contacts.add(modifierUserId); + } + + // passed - setting all contacts user ids to lowercase + List tempContacts = contacts.stream().map(e -> e.toLowerCase()).collect(Collectors.toList()); + ValidationUtils.removeDuplicateFromList(tempContacts); + product.setContacts(tempContacts); + + return Either.left(true); + } + + private Either validateGrouping(User user, Product product, AuditingActionEnum actionEnum) { + List categories = product.getCategories(); + if (categories == null || categories.isEmpty()) { + log.debug("Grouping list is empty for product {}", product.getName()); + return Either.left(true); + } + Map>> nonDuplicatedCategories = new HashMap>>(); + // remove duplicated entries + for (CategoryDefinition cat : categories) { + String catName = cat.getName(); + if (ValidationUtils.validateStringNotEmpty(catName) == false) { + // error missing cat name + log.debug("Missing category name for product {}", product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.PRODUCT.getValue()); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + Map> catEntry = nonDuplicatedCategories.get(catName); + if (catEntry == null) { + catEntry = new HashMap>(); + nonDuplicatedCategories.put(catName, catEntry); + } + List subcategories = cat.getSubcategories(); + if (subcategories == null || subcategories.isEmpty()) { + // error missing subcat for cat + log.debug("Missing sub-categories for category {} in product {}", catName, product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + for (SubCategoryDefinition subcat : subcategories) { + String subCatName = subcat.getName(); + if (ValidationUtils.validateStringNotEmpty(subCatName) == false) { + // error missing sub cat name for cat + log.debug("Missing or empty sub-category for category {} in product {}", catName, product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + Set subcatEntry = catEntry.get(subCatName); + if (subcatEntry == null) { + subcatEntry = new HashSet(); + catEntry.put(subCatName, subcatEntry); + } + List groupings = subcat.getGroupings(); + for (GroupingDefinition group : groupings) { + String groupName = group.getName(); + if (ValidationUtils.validateStringNotEmpty(groupName) == false) { + // error missing grouping for sub cat name and cat + log.debug("Missing or empty groupng name for sub-category {} for category {} in product {}", subCatName, catName, product.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + if (!subcatEntry.contains(groupName)) { + subcatEntry.add(groupName); + } else { + log.debug("Grouping [ {} ] already exist for category [ {} ] and subcategory [ {} ]", groupName, catName, subCatName); + } + } + } + } // for end of checking duplicated + // validate existence + Either, ActionStatus> allProductCategories = elementDao.getAllProductCategories(); + + if (allProductCategories.isRight()) { + log.debug("No product categories {}", allProductCategories.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(allProductCategories.right().value()); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + boolean catExist; + // convert non-duplicated to data modeling format and update in the + // input object + List newCatList = new ArrayList(); + + // over all categories from request + for (Map.Entry>> entry : nonDuplicatedCategories.entrySet()) { + catExist = false; + CategoryDefinition categoryDefinition = null; + // over all categories from Titan + List categoriesList = allProductCategories.left().value(); + if (categoriesList != null) { + for (CategoryDefinition catInDb : categoriesList) { + if (entry.getKey().equals(catInDb.getName())) { + catExist = true; + boolean subcatExist; + // copy data + categoryDefinition = new CategoryDefinition(catInDb); + SubCategoryDefinition subCategory = null; + + Map> subcats = entry.getValue(); + for (Map.Entry> subcat : subcats.entrySet()) { + subcatExist = false; + List subcategoriesList = catInDb.getSubcategories(); + if (subcategoriesList != null) { + for (SubCategoryDefinition subcatInDb : subcategoriesList) { + if (subcatInDb.getName().equals(subcat.getKey())) { + // copy data + subCategory = new SubCategoryDefinition(subcatInDb); + subcatExist = true; + Set grouping = subcat.getValue(); + boolean groupExist; + GroupingDefinition groupingDefinition = null; + for (String group : grouping) { + groupExist = false; + List groupings = subcatInDb.getGroupings(); + if (groupings != null) { + for (GroupingDefinition groupInDb : groupings) { + if (groupInDb.getName().equals(group)) { + groupExist = true; + groupingDefinition = new GroupingDefinition(groupInDb); + } + } + } + if (!groupExist) { + // error grouping isn't defined + // in Titan + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_ASSOCIATION, CategoryTypeEnum.GROUPING.getValue(), group); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + subCategory.addGrouping(groupingDefinition); + } + } + } + } + if (!subcatExist) { + // error sub category isn't defined in Titan + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_ASSOCIATION, CategoryTypeEnum.SUBCATEGORY.getValue(), subcat.getKey()); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + categoryDefinition.addSubCategory(subCategory); + } + } + } + } + if (!catExist) { + // error category isn't defined in Titan + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_GROUP_ASSOCIATION, CategoryTypeEnum.CATEGORY.getValue(), entry.getKey()); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + newCatList.add(categoryDefinition); + } + product.setCategories(newCatList); + return Either.left(true); + } + + public Either getProduct(String productId, User user) { + String ecompErrorContext = "Get product"; + Either validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return Either.right(validateEmptyResult.right().value()); + } + + Either eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + + Either storageStatus = productOperation.getComponent(productId, false); + + if (storageStatus.isRight()) { + log.debug("failed to get resource by id {}", productId); + if (storageStatus.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + // TODO check error + return Either.right(componentsUtils.getResponseFormat(ActionStatus.PRODUCT_NOT_FOUND, ComponentTypeEnum.PRODUCT.getValue())); + } else { + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), "")); + } + } + return Either.left(storageStatus.left().value()); + } + + public Either deleteProduct(String productId, User user) { + String ecompErrorContext = "Delete product"; + Either validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return Either.right(validateEmptyResult.right().value()); + } + + Either eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + + Either storageStatus = productOperation.deleteProduct(productId, false); + + if (storageStatus.isRight()) { + log.debug("failed to delete resource by id {}", productId); + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), "")); + } + return Either.left(storageStatus.left().value()); + } + + private Either validateProductFullNameAndCleanup(User user, Product product, AuditingActionEnum actionEnum) { + String fullName = product.getFullName(); + if (!ValidationUtils.validateStringNotEmpty(fullName)) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_FULL_NAME); + componentsUtils.auditComponentAdmin(errorResponse, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(errorResponse); + } + + fullName = ValidationUtils.removeNoneUtf8Chars(fullName); + fullName = ValidationUtils.removeHtmlTags(fullName); + fullName = ValidationUtils.normaliseWhitespace(fullName); + fullName = ValidationUtils.stripOctets(fullName); + + if (!ValidationUtils.validateProductFullNameLength(fullName)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_FULL_NAME); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + if (!ValidationUtils.validateIsEnglish(fullName)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_FULL_NAME); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + product.setFullName(fullName); + return Either.left(true); + } + + private Either validateProductNameAndCleanup(User user, Product product, AuditingActionEnum actionEnum) { + String name = product.getName(); + if (!ValidationUtils.validateStringNotEmpty(name)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_ONE_OF_COMPONENT_NAMES, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_ABBREVIATED_NAME); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + // Product name is required to have same validation and normalization as + // category + if (!ValidationUtils.validateCategoryDisplayNameFormat(name)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_FORMAT, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_ABBREVIATED_NAME); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + String normalizedName4Display = ValidationUtils.normalizeCategoryName4Display(name); + + if (!ValidationUtils.validateCategoryDisplayNameLength(normalizedName4Display)) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_ELEMENT_INVALID_NAME_LENGTH, ComponentTypeEnum.PRODUCT.getValue(), PRODUCT_ABBREVIATED_NAME); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + + product.setName(normalizedName4Display); + String normalizedName4Uniqueness = ValidationUtils.normaliseComponentName(normalizedName4Display); + product.setNormalizedName(normalizedName4Uniqueness); + + return Either.left(true); + } + + // This is a workaround for a current tag--->product name behaviour, which + // will be changed in 1607. + // It was agreed with Ella on 23/2/16 that the tag validation of product + // will be made against the old product name (before normalization), + // and in 1607 US will be defined where UI will no longer pass tag of + // component name, and BE will add it by itself after all needed + // normalizations. + private Either validateTagsListAndRemoveDuplicates(User user, Product product, String oldProductName, AuditingActionEnum actionEnum) { + List tagsList = product.getTags(); + + Either validateTags = validateComponentTags(tagsList, oldProductName, ComponentTypeEnum.PRODUCT); + if (validateTags.isRight()) { + ResponseFormat responseFormat = validateTags.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, product, "", "", actionEnum, ComponentTypeEnum.PRODUCT); + return Either.right(responseFormat); + } + ValidationUtils.removeDuplicateFromList(tagsList); + return Either.left(true); + } + + @Override + public void setDeploymentArtifactsPlaceHolder(org.openecomp.sdc.be.model.Component component, User user) { + + } + + public Either updateProductMetadata(String productId, Product updatedProduct, User user) { + ComponentTypeEnum typeEnum = ComponentTypeEnum.PRODUCT; + Either eitherCreator = validateUser(user, "Update Product", updatedProduct, null, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either validateRes = validateUserRole(user, updatedProduct, updateRoles, null, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + + if (updatedProduct == null) { + log.debug("Invalid product json. Check product servlet log for updateProduct entry params"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(responseFormat); + } + + Either storageStatus = productOperation.getComponent(productId, false); + if (storageStatus.isRight()) { + if (storageStatus.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.PRODUCT_NOT_FOUND, ComponentTypeEnum.PRODUCT.name().toLowerCase())); + } + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), typeEnum), "")); + } + + Product currentProduct = storageStatus.left().value(); + + if (!ComponentValidationUtils.canWorkOnComponent(productId, productOperation, user.getUserId())) { + log.info("Restricted operation for user {} on product {}", user.getUserId(), currentProduct.getCreatorUserId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + Either validationRsponse = validateAndUpdateProductMetadata(user, currentProduct, updatedProduct); + if (validationRsponse.isRight()) { + log.info("product update metadata: validations field."); + return validationRsponse; + } + + Product productToUpdate = validationRsponse.left().value(); + // lock resource + Either lockResult = lockComponent(currentProduct.getUniqueId(), currentProduct, "Update Product Metadata"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either updateResponse = productOperation.updateComponent(productToUpdate, true); + if (updateResponse.isRight()) { + productOperation.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Update Product Metadata"); + log.debug("failed to update product {}", productToUpdate.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + productOperation.commit(); + return Either.left(updateResponse.left().value()); + } finally { + graphLockOperation.unlockComponent(productId, NodeTypeEnum.Product); + } + } + + private Either validateAndUpdateProductMetadata(User user, Product currentProduct, Product updatedProduct) { + + boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentProduct.getVersion()); + Either response = validateAndUpdateProductName(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateFullName(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateDescription(user, currentProduct, updatedProduct, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateCategory(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateContactList(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateTags(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateProjectCode(user, currentProduct, updatedProduct); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + if (updatedProduct.getIsActive() != null) { + currentProduct.setIsActive(updatedProduct.getIsActive()); + } + + response = validateAndUpdateIcon(user, currentProduct, updatedProduct, hasBeenCertified); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + String currentInvariantUuid = currentProduct.getInvariantUUID(); + String updatedInvariantUuid = updatedProduct.getInvariantUUID(); + + if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) { + log.warn("Product invariant UUID is automatically set and cannot be updated"); + updatedProduct.setInvariantUUID(currentInvariantUuid); + } + return Either.left(currentProduct); + + } + + private Either validateAndUpdateProductName(User user, Product currentProduct, Product updatedProduct) { + String updatedProductName = updatedProduct.getName(); + String tags = ""; + String currentProductName = currentProduct.getName(); + if (updatedProductName != null) { + Either validatProductNameResponse = validateProductNameAndCleanup(user, updatedProduct, null); + if (validatProductNameResponse.isRight()) { + ResponseFormat errorRespons = validatProductNameResponse.right().value(); + return Either.right(errorRespons); + } + updatedProductName = updatedProduct.getName(); + if (!currentProductName.equals(updatedProductName)) { + Either productNameUniquenessValidation = validateComponentNameUnique(user, updatedProduct, null); + if (productNameUniquenessValidation.isRight()) { + return productNameUniquenessValidation; + } + currentProduct.setName(updatedProductName); + tags = updatedProductName; + updatedProductName = ValidationUtils.normalizeCategoryName4Display(updatedProductName); + currentProduct.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(updatedProductName)); + List updatedTags = updatedProduct.getTags(); + // As discussed with Ella currently (1604) we are not removing + // the old name from tags. + if (updatedTags == null) { + updatedTags = currentProduct.getTags(); + } + updatedTags.add(tags); + } + } + return Either.left(true); + } + + private Either validateAndUpdateFullName(User user, Product currentProduct, Product updatedProduct) { + String updatedProductName = updatedProduct.getFullName(); + String currentProductName = currentProduct.getFullName(); + if (updatedProductName != null && !currentProductName.equals(updatedProductName)) { + Either validatProductNameResponse = validateProductFullNameAndCleanup(user, updatedProduct, null); + if (validatProductNameResponse.isRight()) { + ResponseFormat errorRespons = validatProductNameResponse.right().value(); + return Either.right(errorRespons); + } + currentProduct.setFullName(updatedProduct.getFullName()); + } + return Either.left(true); + } + + private Either validateAndUpdateCategory(User user, Product currentProduct, Product updatedProduct) { + List categoryUpdated = updatedProduct.getCategories(); + List categoryCurrent = currentProduct.getCategories(); + + Either validatCategoryResponse = validateGrouping(user, updatedProduct, null); + if (validatCategoryResponse.isRight()) { + ResponseFormat errorResponse = validatCategoryResponse.right().value(); + return Either.right(errorResponse); + } + + categoryUpdated = updatedProduct.getCategories(); + if (categoryUpdated != null) { + currentProduct.setCategories(categoryUpdated); + } + return Either.left(true); + } + + private Either validateAndUpdateContactList(User user, Product currentProduct, Product updatedProduct) { + List updatedContacts = updatedProduct.getContacts(); + List currentContacts = currentProduct.getContacts(); + if (updatedContacts != null) { + if (!(currentContacts.containsAll(updatedContacts) && updatedContacts.containsAll(currentContacts))) { + Either validatResponse = validateAndUpdateProductContactsList(user, updatedProduct, null); + if (validatResponse.isRight()) { + ResponseFormat errorRespons = validatResponse.right().value(); + return Either.right(errorRespons); + } + currentProduct.setContacts(updatedProduct.getContacts()); + } + } + return Either.left(true); + } + + private Either validateAndUpdateTags(User user, Product currentProduct, Product updatedProduct) { + List tagsUpdated = updatedProduct.getTags(); + List tagsCurrent = currentProduct.getTags(); + if (tagsUpdated != null) { + if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) { + Either validatResponse = validateTagsListAndRemoveDuplicates(user, updatedProduct, currentProduct.getName(), null); + if (validatResponse.isRight()) { + ResponseFormat errorRespons = validatResponse.right().value(); + return Either.right(errorRespons); + } + currentProduct.setTags(updatedProduct.getTags()); + } + } + return Either.left(true); + } + + @Override + public Either, ResponseFormat> deleteMarkedComponents() { + // markAsDeleted isnt implemented yet + return Either.left(new ArrayList<>()); + } + + @Override + protected boolean validateTagPattern(String tag) { + return ValidationUtils.validateCategoryDisplayNameFormat(tag); + } + + public Either getProductByNameAndVersion(String productName, String productVersion, String userId) { + Either resp = validateUserExists(userId, "get Service By Name And Version", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either storageStatus = productOperation.getProductByNameAndVersion(productName, productVersion, false); + if (storageStatus.isRight()) { + log.debug("failed to get service by name {} and version {}", productName, productVersion); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.PRODUCT), productName)); + } + Product product = storageStatus.left().value(); + return Either.left(product); + } + + @Override + public ComponentInstanceBusinessLogic getComponentInstanceBL() { + return productComponentInstanceBusinessLogic; + } + + @Override + public Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + return null; + } + + public ICacheMangerOperation getCacheManagerOperation() { + return cacheManagerOperation; + } + + public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) { + this.cacheManagerOperation = cacheManagerOperation; + } + + public void setProductOperation(ProductOperation productOperation) { + this.productOperation = productOperation; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductComponentInstanceBusinessLogic.java new file mode 100644 index 0000000000..46188012d8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ProductComponentInstanceBusinessLogic.java @@ -0,0 +1,59 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("productComponentInstanceBusinessLogic") +public class ProductComponentInstanceBusinessLogic extends ComponentInstanceBusinessLogic { + + @Override + protected Either validateAllowedToContainCompInstances(org.openecomp.sdc.be.model.Component containerComponent) { + return Either.left(true); + } + + @Override + protected NodeTypeEnum getNodeTypeOfComponentInstanceOrigin() { + // TODO Pavel this might be also a resource? + return NodeTypeEnum.Service; + } + + @Override + protected ComponentOperation getContainerComponentOperation() { + return productOperation; + } + + @Override + protected ComponentOperation getCompInstOriginComponentOperation() { + return serviceOperation; + } + + @Override + protected ComponentTypeEnum getComponentTypeOfComponentInstance() { + return ComponentTypeEnum.SERVICE_INSTANCE; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java new file mode 100644 index 0000000000..1e6b1c1d82 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/PropertyBusinessLogic.java @@ -0,0 +1,391 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.servlet.ServletContext; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.elements.PropertyDataDefinition; +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.PropertyValueConverter; +import org.openecomp.sdc.be.resources.data.EntryData; +import org.openecomp.sdc.be.resources.data.PropertyData; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; + +import fj.data.Either; + +@Component("propertyBusinessLogic") +public class PropertyBusinessLogic extends BaseBusinessLogic { + + private static final String CREATE_PROPERTY = "CreateProperty"; + + private static Logger log = LoggerFactory.getLogger(PropertyBusinessLogic.class.getName()); + + @javax.annotation.Resource + private IResourceOperation resourceOperation = null; + + @javax.annotation.Resource + private PropertyOperation propertyOperation = null; + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + protected static IElementOperation getElementDao(Class class1, ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + + return webApplicationContext.getBean(class1); + } + + public Either, ResponseFormat> getAllDataTypes() { + Either, ResponseFormat> eitherAllDataTypes = getAllDataTypes(applicationDataTypeCache); + return eitherAllDataTypes; + } + + /** + * Create new property on resource in graph + * + * @param resourceId + * @param propertyName + * @param newPropertyDefinition + * @param userId + * @return Either + */ + public Either, ResponseFormat> createProperty(String resourceId, String propertyName, PropertyDefinition newPropertyDefinition, String userId) { + + Either, ResponseFormat> result = null; + + Either resp = validateUserExists(userId, "create Property", false); + if (resp.isRight()) { + result = Either.right(resp.right().value()); + return result; + } + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + log.info("Failed to lock component {}. Error - {}", resourceId, lockResult); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + + try { + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + return result; + } + Resource resource = status.left().value(); + + // verify that resource is checked-out and the user is the last + // updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return result; + } + + // verify property not exist in resource + List resourceProperties = resource.getProperties(); + + if (resourceProperties != null) { + if (propertyOperation.isPropertyExist(resourceProperties, resourceId, propertyName)) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_ALREADY_EXIST, "")); + return result; + } + } + + Either, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache); + if (allDataTypes.isRight()) { + result = Either.right(allDataTypes.right().value()); + return result; + } + + Map dataTypes = allDataTypes.left().value(); + + // validate property default values + Either defaultValuesValidation = validatePropertyDefaultValue(newPropertyDefinition, dataTypes); + if (defaultValuesValidation.isRight()) { + result = Either.right(defaultValuesValidation.right().value()); + return result; + } + // convert property + ToscaPropertyType type = getType(newPropertyDefinition.getType()); + if (type != null) { + PropertyValueConverter converter = type.getConverter(); + // get inner type + String innerType = null; + if (newPropertyDefinition != null) { + SchemaDefinition schema = newPropertyDefinition.getSchema(); + if (schema != null) { + PropertyDataDefinition prop = schema.getProperty(); + if (prop != null) { + innerType = prop.getType(); + } + } + String convertedValue = null; + if (newPropertyDefinition.getDefaultValue() != null) { + convertedValue = converter.convert(newPropertyDefinition.getDefaultValue(), innerType, allDataTypes.left().value()); + newPropertyDefinition.setDefaultValue(convertedValue); + } + } + } + + // add the new property to resource on graph + // need to get StorageOpaerationStatus and convert to ActionStatus + // from componentsUtils + Either either = propertyOperation.addProperty(propertyName, newPropertyDefinition, resourceId); + if (either.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName())); + return result; + } + + PropertyDefinition createdPropertyDefinition = propertyOperation.convertPropertyDataToPropertyDefinition(either.left().value(), propertyName, resourceId); + EntryData property = new EntryData(propertyName, createdPropertyDefinition); + result = Either.left(property); + return result; + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + + } + + /** + * Get property of resource + * + * @param resourceId + * @param propertyId + * @param userId + * TODO + * @return + */ + public Either, ResponseFormat> getProperty(String resourceId, String propertyId, String userId) { + + Either resp = validateUserExists(userId, "create Component Instance", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = status.left().value(); + + // verify property exist in resource + List properties = resource.getProperties(); + if (properties == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, "")); + } + for (PropertyDefinition property : properties) { + // esofer - check also that the property belongs to the current + // resource + if (property.getUniqueId().equals(propertyId) && property.getParentUniqueId().equals(resourceId)) { + Map propMap = new HashMap<>(); + propMap.put(property.getName(), property); + return Either.left(propMap.entrySet().iterator().next()); + } + } + return Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, "")); + } + + /** + * delete property of resource from graph + * + * @param resourceId + * @param propertyId + * @param userId + * @return + */ + public Either, ResponseFormat> deleteProperty(String resourceId, String propertyId, String userId) { + + Either, ResponseFormat> result = null; + + Either resp = validateUserExists(userId, "delete Property", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + + try { + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + return result; + } + Resource resource = status.left().value(); + + // verify that resource is checked-out and the user is the last + // updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + return result; + } + + // verify property exist in resource + Either, ResponseFormat> statusGetProperty = getProperty(resourceId, propertyId, userId); + if (statusGetProperty.isRight()) { + result = Either.right(statusGetProperty.right().value()); + return result; + } + String propertyName = statusGetProperty.left().value().getKey(); + + // delete property of resource from graph + // TODO: need to get StorageOperationStatus + Either either = propertyOperation.deleteProperty(propertyId); + // Either either = + // propertyOperation.deletePropertyFromGraph(propertyId); + if (either.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName())); + return result; + } + // propertyOperation.getTitanGenericDao().commit(); + PropertyDefinition createdPropertyDefinition = propertyOperation.convertPropertyDataToPropertyDefinition(either.left().value(), propertyName, resourceId); + EntryData property = new EntryData(propertyName, createdPropertyDefinition); + result = Either.left(property); + return result; + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + } + + /** + * update property + * + * @param resourceId + * @param propertyId + * @param newPropertyDefinition + * @param userId + * @return + */ + public Either, ResponseFormat> updateProperty(String resourceId, String propertyId, PropertyDefinition newPropertyDefinition, String userId) { + + Either, ResponseFormat> result = null; + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, "")); + } + Resource resource = status.left().value(); + + // verify that resource is checked-out and the user is the last updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceId, NodeTypeEnum.Resource); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().logBeFailedLockObjectError(CREATE_PROPERTY, NodeTypeEnum.Resource.name().toLowerCase(), resourceId); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + return result; + } + + try { + + // verify property exist in resource + Either, ResponseFormat> statusGetProperty = getProperty(resourceId, propertyId, userId); + if (statusGetProperty.isRight()) { + result = Either.right(statusGetProperty.right().value()); + return result; + } + String propertyName = statusGetProperty.left().value().getKey(); + + Either, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache); + if (allDataTypes.isRight()) { + result = Either.right(allDataTypes.right().value()); + return result; + } + Map dataTypes = allDataTypes.left().value(); + // validate property default values + Either defaultValuesValidation = validatePropertyDefaultValue(newPropertyDefinition, dataTypes); + if (defaultValuesValidation.isRight()) { + result = Either.right(defaultValuesValidation.right().value()); + return result; + } + + // add the new property to resource on graph + // TODO: convert TitanOperationStatus to Storgae... + Either either = propertyOperation.updateProperty(propertyId, newPropertyDefinition, dataTypes); + // Either either = + // propertyOperation.updatePropertyFromGraph(propertyId, + // newPropertyDefinition); + if (either.isRight()) { + log.debug("Problem while updating property with id {}. Reason - {}", propertyId, either.right().value()); + result = Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(either.right().value()), resource.getName())); + return result; + // return Either.right(ActionStatus.GENERAL_ERROR); + } + + PropertyDefinition createdPropertyDefinition = propertyOperation.convertPropertyDataToPropertyDefinition(either.left().value(), propertyName, resourceId); + EntryData property = new EntryData(propertyName, createdPropertyDefinition); + result = Either.left(property); + return result; + + } finally { + commitOrRollback(result); + // unlock component + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementsBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementsBusinessLogic.java new file mode 100644 index 0000000000..f8dde98010 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/RequirementsBusinessLogic.java @@ -0,0 +1,94 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("requirementsBusinessLogic") +public class RequirementsBusinessLogic { + private static Logger log = LoggerFactory.getLogger(RequirementsBusinessLogic.class.getName()); + + @javax.annotation.Resource + private ComponentsUtils componentsUtils; + + @javax.annotation.Resource + private ResourceBusinessLogic resourceBusinessLogic; + + @javax.annotation.Resource + private IResourceOperation resourceOperation; + + public Either updateRequirement(String resourceId, String requirementId, RequirementDefinition requirementDefinition, String userId) { + + // Get the resource from DB + Either status = getResource(resourceId); + if (status.isRight()) { + log.debug("Couldn't get resource {} from DB", resourceId); + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(status.right().value()), "")); + } + Resource resource = status.left().value(); + if (resource == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeResourceMissingError, "Requirement Business Logic", resourceId); + BeEcompErrorManager.getInstance().logBeComponentMissingError("Requirement Business Logic", ComponentTypeEnum.RESOURCE.getValue(), resourceId); + log.debug("Couldn't get resource {} from DB", resourceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + // verify that resource is checked-out and the user is the last updater + if (!ComponentValidationUtils.canWorkOnResource(resource, userId)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + // TODO + return null; + } + + private Either getResource(final String resourceId) { + + log.debug("Get resource with id {}", resourceId); + Either status = resourceOperation.getResource(resourceId); + if (status.isRight()) { + log.debug("Resource with id {} was not found", resourceId); + return Either.right(status.right().value()); + } + + Resource resource = status.left().value(); + if (resource == null) { + log.debug("General Error while get resource with id {}", resourceId); + return Either.right(StorageOperationStatus.GENERAL_ERROR); + } + return Either.left(resource); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java new file mode 100644 index 0000000000..ddc03e14e8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceBusinessLogic.java @@ -0,0 +1,5475 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; +import java.util.function.Function; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +import javax.servlet.ServletContext; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperation; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.info.ArtifactTemplateInfo; +import org.openecomp.sdc.be.info.MergedArtifactInfo; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.ComponentParametersView; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GetInputValueInfo; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.HeatParameterDefinition; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.ParsedToscaYamlInfo; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.UploadCapInfo; +import org.openecomp.sdc.be.model.UploadComponentInstanceInfo; +import org.openecomp.sdc.be.model.UploadPropInfo; +import org.openecomp.sdc.be.model.UploadReqInfo; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.heat.HeatParameterType; +import org.openecomp.sdc.be.model.operations.api.IArtifactOperation; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.ICapabilityTypeOperation; +import org.openecomp.sdc.be.model.operations.api.IComponentInstanceOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IHeatParametersOperation; +import org.openecomp.sdc.be.model.operations.api.IInterfaceLifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.IPropertyOperation; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityInstanceOperation; +import org.openecomp.sdc.be.model.operations.impl.CsarOperation; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.GroupOperation; +import org.openecomp.sdc.be.model.operations.impl.InputsOperation; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.resources.data.ResourceMetadataData; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.be.utils.CommonBeUtils; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.context.WebApplicationContext; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.constructor.Constructor; +import org.yaml.snakeyaml.representer.Representer; +import org.yaml.snakeyaml.resolver.Resolver; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +import fj.data.Either; + +@org.springframework.stereotype.Component("resourceBusinessLogic") +public class ResourceBusinessLogic extends ComponentBusinessLogic { + + private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes"; + public static final String INITIAL_VERSION = "0.1"; + + Pattern STR_REPLACE_PATTERN = Pattern.compile("^[ ]*\\{[ ]*" + "str_replace" + "="); + Pattern TOKEN_PATTERN = Pattern.compile("[ ]*\\{[ ]*" + "token" + "="); + Pattern GET_PROPERTY_PATTERN = Pattern.compile("[ ]*\\{[ ]*" + "get_property" + "="); + Pattern CONCAT_PATTERN = Pattern.compile("[ ]*\\{[ ]*" + "concat" + "="); + + private static Logger log = LoggerFactory.getLogger(ResourceBusinessLogic.class.getName()); + + public ResourceBusinessLogic() { + log.debug("ResourceBusinessLogic started"); + } + + @Autowired + private ICapabilityTypeOperation capabilityTypeOperation = null; + + @Autowired + private IInterfaceLifecycleOperation interfaceTypeOperation = null; + + @Autowired + private IComponentInstanceOperation componentInstanceOperation; + + @Autowired + private LifecycleBusinessLogic lifecycleBusinessLogic; + + @Autowired + private IPropertyOperation propertyOperation; + + @Autowired + private CsarOperation csarOperation; + + @Autowired + private VFComponentInstanceBusinessLogic vfComponentInstanceBusinessLogic; + + @Autowired + private ResourceImportManager resourceImportManager; + + @Autowired + private GroupBusinessLogic groupBusinessLogic; + @Autowired + private InputsBusinessLogic inputsBusinessLogic; + + @javax.annotation.Resource + private InputsOperation inputOperation; + + @Autowired + private GroupOperation groupOperation; + + @Autowired + private IHeatParametersOperation heatParametersOperation; + + @Autowired + private IArtifactOperation artifactOperation; + + @Autowired + private CapabilityInstanceOperation capabilityInstanceOperation; + + @Autowired + private CompositionBusinessLogic compositionBusinessLogic; + + @Autowired + private ICacheMangerOperation cacheManagerOperation; + + private Gson gson = new Gson(); + + public CsarOperation getCsarOperation() { + return csarOperation; + } + + public void setCsarOperation(CsarOperation csarOperation) { + this.csarOperation = csarOperation; + } + + public IResourceOperation getResourceOperation() { + return this.resourceOperation; + } + + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + + public LifecycleBusinessLogic getLifecycleBusinessLogic() { + return lifecycleBusinessLogic; + } + + public void setLifecycleManager(LifecycleBusinessLogic lifecycleBusinessLogic) { + this.lifecycleBusinessLogic = lifecycleBusinessLogic; + } + + public IElementOperation getElementDao() { + return elementDao; + } + + public void setElementDao(IElementOperation elementDao) { + this.elementDao = elementDao; + } + + public IUserBusinessLogic getUserAdmin() { + return this.userAdmin; + } + + public void setUserAdmin(UserBusinessLogic userAdmin) { + this.userAdmin = userAdmin; + } + + public ComponentsUtils getComponentsUtils() { + return this.componentsUtils; + } + + public void setComponentsUtils(ComponentsUtils componentsUtils) { + this.componentsUtils = componentsUtils; + } + + public ArtifactsBusinessLogic getArtifactsManager() { + return artifactsBusinessLogic; + } + + public void setArtifactsManager(ArtifactsBusinessLogic artifactsManager) { + this.artifactsBusinessLogic = artifactsManager; + } + + public void setPropertyOperation(IPropertyOperation propertyOperation) { + this.propertyOperation = propertyOperation; + } + + public ApplicationDataTypeCache getApplicationDataTypeCache() { + return applicationDataTypeCache; + } + + public void setApplicationDataTypeCache(ApplicationDataTypeCache applicationDataTypeCache) { + this.applicationDataTypeCache = applicationDataTypeCache; + } + + /** + * the method returns a list of all the resources that are certified, the returned resources are only abstract or only none abstract according to the given param + * + * @param getAbstract + * @param userId + * TODO + * @return + */ + public Either, ResponseFormat> getAllCertifiedResources(boolean getAbstract, HighestFilterEnum highestFilter, String userId) { + Either resp = validateUserExists(userId, "get All Certified Resources", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + IResourceOperation dataModel = getResourceOperation(); + Boolean isHighest = null; + switch (highestFilter) { + case ALL: + break; + case HIGHEST_ONLY: + isHighest = true; + break; + case NON_HIGHEST_ONLY: + isHighest = false; + break; + default: + break; + } + + Either, StorageOperationStatus> dataModelResponse = dataModel.getAllCertifiedResources(getAbstract, isHighest); + + if (dataModelResponse.isLeft()) { + log.debug("Retrived Resource successfully."); + return Either.left(dataModelResponse.left().value()); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value())); + + return Either.right(responseFormat); + } + + public Either, ResponseFormat> validateResourceNameExists(String resourceName, ResourceTypeEnum resourceTypeEnum, String userId) { + + Either resp = validateUserExists(userId, "validate Resource Name Exists", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + IResourceOperation dataModel = getResourceOperation(); + + Either dataModelResponse = dataModel.validateResourceNameExists(resourceName, resourceTypeEnum); + + if (dataModelResponse.isLeft()) { + Map result = new HashMap<>(); + result.put("isValid", dataModelResponse.left().value()); + log.debug("validation was successfully performed."); + return Either.left(result); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value())); + + return Either.right(responseFormat); + } + + public Either createResource(Resource resource, User user, Map csarUIPayload, String payloadName) { + Either createResourceResponse = validateResourceBeforeCreate(resource, user, false); + if (createResourceResponse.isRight()) { + return createResourceResponse; + } + + // Creating resource either by DAO or from CSAR + String csarUUID = null; + if (payloadName == null) { + csarUUID = resource.getCsarUUID(); + } else { + csarUUID = payloadName; + } + if (csarUUID != null && !csarUUID.isEmpty()) { + // check if VF with the same Csar UUID or with he same name already + // exists + Either, StorageOperationStatus> validateCsarUuidUniquenessRes = resourceOperation.validateCsarUuidUniqueness(csarUUID); + if (validateCsarUuidUniquenessRes.isRight()) { + log.debug("Failed to validate uniqueness of CsarUUID {} for resource", csarUUID, resource.getSystemName()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(validateCsarUuidUniquenessRes.right().value()))); + } + + List existingResourceRes = validateCsarUuidUniquenessRes.left().value(); + if (existingResourceRes != null && existingResourceRes.size() > 0) { + log.debug("Failed to create resource {}, csarUUID {} already exist for a different VF {}", resource.getSystemName(), csarUUID, existingResourceRes.get(0).getMetadataDataDefinition().getName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, existingResourceRes.get(0).getMetadataDataDefinition().getName()); + componentsUtils.auditResource(errorResponse, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + return Either.right(errorResponse); + } + + log.debug("CsarUUID is {} - going to create resource from CSAR", csarUUID); + createResourceResponse = createResourceFromCsar(resource, user, AuditingActionEnum.CREATE_RESOURCE, false, Either.left(csarUIPayload), csarUUID); + return createResourceResponse; + } + + return createResourceByDao(resource, user, AuditingActionEnum.CREATE_RESOURCE, false); + } + + public Either validateAndUpdateResourceFromCsar(Resource resource, User user, Map csarUIPayload, String payloadName, String resourceUniqueId) { + Either updateResourceResponse = null; + Either validateResourceResponse = null; + Wrapper responseWrapper = new Wrapper(); + String csarUUID = null; + String csarVersion = null; + if (payloadName == null) { + csarUUID = resource.getCsarUUID(); + csarVersion = resource.getCsarVersion(); + } else { + csarUUID = payloadName; + } + if (csarUUID != null && !csarUUID.isEmpty()) { + Resource oldResource = getResourceByUniqueId(responseWrapper, resourceUniqueId); + if (responseWrapper.isEmpty()) { + validateCsarUuidMatching(responseWrapper, oldResource, resource, csarUUID, resourceUniqueId, user); + } + if (responseWrapper.isEmpty()) { + validateCsarIsNotAlreadyUsed(responseWrapper, oldResource, resource, csarUUID, user); + } + if (responseWrapper.isEmpty()) { + if (oldResource != null && ValidationUtils.hasBeenCertified(oldResource.getVersion())) { + overrideImmutableMetadata(oldResource, resource); + } + validateResourceResponse = validateResourceBeforeCreate(resource, user, false); + if (validateResourceResponse.isRight()) { + responseWrapper.setInnerElement(validateResourceResponse.right().value()); + } + } + if (responseWrapper.isEmpty()) { + String oldCsarVersion = oldResource.getCsarVersion(); + log.debug("CsarUUID is {} - going to update resource with UniqueId {} from CSAR", csarUUID, resourceUniqueId); + // (on boarding flow): If the update includes same csarUUID and + // same csarVersion as already in the VF - no need to import the + // csar (do only metadata changes if there are). + if (csarVersion != null && oldCsarVersion != null && oldCsarVersion.equals(csarVersion)) { + updateResourceResponse = updateResourceMetadata(resourceUniqueId, resource, oldResource, user, false); + } else { + updateResourceResponse = updateResourceFromCsar(oldResource, resource, user, AuditingActionEnum.UPDATE_RESOURCE_METADATA, false, Either.left(csarUIPayload), csarUUID); + } + } + } else { + log.debug("Failed to update resource {}, csarUUID or payload name is missing", resource.getSystemName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CSAR_UUID, resource.getName()); + componentsUtils.auditResource(errorResponse, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + responseWrapper.setInnerElement(errorResponse); + } + if (responseWrapper.isEmpty()) { + return updateResourceResponse; + } + return Either.right(responseWrapper.getInnerElement()); + } + + private void validateCsarIsNotAlreadyUsed(Wrapper responseWrapper, Resource oldResource, Resource resource, String csarUUID, User user) { + // (on boarding flow): If the update includes a csarUUID: verify this + // csarUUID is not in use by another VF, If it is - use same error as + // above: + // "Error: The VSP with UUID %1 was already imported for VF %2. Please + // select another or update the existing VF." %1 - csarUUID, %2 - VF + // name + Either resourceLinkedToCsarRes = resourceOperation.getLatestResourceByCsarOrName(csarUUID, resource.getSystemName()); + if (resourceLinkedToCsarRes.isRight()) { + if (!StorageOperationStatus.NOT_FOUND.equals(resourceLinkedToCsarRes.right().value())) { + log.debug("Failed to find previous resource by CSAR {} and system name {}", csarUUID, resource.getSystemName()); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceLinkedToCsarRes.right().value()))); + } + } else if (!resourceLinkedToCsarRes.left().value().getUniqueId().equals(oldResource.getUniqueId()) && !resourceLinkedToCsarRes.left().value().getName().equals(oldResource.getName())) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.VSP_ALREADY_EXISTS, csarUUID, resourceLinkedToCsarRes.left().value().getName()); + componentsUtils.auditResource(errorResponse, user, resource, "", "", AuditingActionEnum.UPDATE_RESOURCE_METADATA, null); + responseWrapper.setInnerElement(errorResponse); + } + } + + private void validateCsarUuidMatching(Wrapper responseWrapper, Resource resource, Resource oldResource, String csarUUID, String resourceUniqueId, User user) { + // (on boarding flow): If the update includes csarUUID which is + // different from the csarUUID of the VF - fail with + // error: "Error: Resource %1 cannot be updated using since it is linked + // to a different VSP" %1 - VF name + String oldCsarUUID = oldResource.getCsarUUID(); + if (oldCsarUUID != null && !oldCsarUUID.isEmpty() && !csarUUID.equals(oldCsarUUID)) { + log.debug("Failed to update resource with UniqueId {} using Csar {}, since the resource is linked to a different VSP {}", resourceUniqueId, csarUUID, oldCsarUUID); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_LINKED_TO_DIFFERENT_VSP, resource.getName(), csarUUID, oldCsarUUID); + componentsUtils.auditResource(errorResponse, user, resource, "", "", AuditingActionEnum.UPDATE_RESOURCE_METADATA, null); + responseWrapper.setInnerElement(errorResponse); + } + } + + private Resource getResourceByUniqueId(Wrapper responseWrapper, String resourceUniqueId) { + Either oldResourceRes = resourceOperation.getResource(resourceUniqueId); + if (oldResourceRes.isRight()) { + log.debug("Failed to find previous resource by UniqueId {}, status: {}", resourceUniqueId, oldResourceRes.right().value()); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(oldResourceRes.right().value()))); + return null; + } + return oldResourceRes.left().value(); + } + + private void overrideImmutableMetadata(Resource oldRresource, Resource resource) { + resource.setName(oldRresource.getName()); + resource.setIcon(oldRresource.getIcon()); + resource.setTags(oldRresource.getTags()); + resource.setVendorName(oldRresource.getVendorName()); + resource.setCategories(oldRresource.getCategories()); + resource.setDerivedFrom(oldRresource.getDerivedFrom()); + } + + private Either updateResourceFromCsar(Resource oldRresource, Resource newRresource, User user, AuditingActionEnum updateResource, boolean inTransaction, Either, StorageOperationStatus> csarUIPayload, + String csarUUID) { + + // check state + if (LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.equals(oldRresource.getLifecycleState())) { + if (!oldRresource.getLastUpdaterUserId().equals(user.getUserId())) { + log.debug("Current user is not last updater, last updater userId: {}, current user userId: {}", oldRresource.getLastUpdaterUserId(), user.getUserId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + } + String lockedResourceId = oldRresource.getUniqueId(); + List createdArtifacts = new ArrayList(); + + Either, StorageOperationStatus> csar = null; + if (csarUIPayload != null && csarUIPayload.left() != null && csarUIPayload.left().value() != null) { + csar = csarUIPayload; + } else { + csar = csarOperation.getCsar(csarUUID, user); + } + if (csar.isRight()) { + log.debug("Failed to get csar for casrUUID{} ", csarUUID); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(csar.right().value()))); + } + + Either, ResponseFormat> toscaYamlCsarStatus = validateAndParseCsar(newRresource, user, csarUUID, csar); + if (toscaYamlCsarStatus.isRight()) { + return Either.right(toscaYamlCsarStatus.right().value()); + } + Either checksum = CsarValidationUtils.getToscaYamlChecksum(csar.left().value(), csarUUID, componentsUtils); + if (checksum.isRight()) { + log.debug("Failed to calculate checksum for casrUUID{} error {} ", csarUUID, checksum.right().value()); + return Either.right(checksum.right().value()); + } + boolean isUpdateYaml = true; + if (checksum.left().value().equals(oldRresource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum())) { + log.debug("The checksums are equals for csarUUID {}, existing checsum is {}, new one is {} ", csarUUID, oldRresource.getComponentMetadataDefinition().getMetadataDataDefinition().getImportedToscaChecksum(), checksum.left().value()); + if (oldRresource.getLifecycleState().equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) + isUpdateYaml = false; + } else { + oldRresource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(checksum.left().value()); + } + + Either lockResult = lockComponent(lockedResourceId, oldRresource, "update Resource From Csar"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + + Either result = null; + try { + Either, ResponseFormat> prepareForUpdate = null; + Resource preparedResource = null; + if (isUpdateYaml) { + + prepareForUpdate = updateExistingResourceByImport(newRresource, oldRresource, user, true, false); + + if (prepareForUpdate.isRight()) { + log.debug("Failed to prepare resource for update : {}", prepareForUpdate.right().value()); + result = Either.right(prepareForUpdate.right().value()); + return result; + } + preparedResource = prepareForUpdate.left().value().left; + String yamlFileName = toscaYamlCsarStatus.left().value().getKey(); + String yamlFileContents = toscaYamlCsarStatus.left().value().getValue(); + log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContents); + + // Either, ResponseFormat> + // parseNodeTypeInfoYamlEither = + // createResourcesFromYamlNodeTypesList(yamlFileName,preparedResource, + // yamlFileContents, user,false); + + Either, ResponseFormat> parseNodeTypeInfoYamlEither = this.handleNodeTypes(yamlFileName, preparedResource, user, yamlFileContents, csar.left().value(), false); + if (parseNodeTypeInfoYamlEither.isRight()) { + ResponseFormat responseFormat = parseNodeTypeInfoYamlEither.right().value(); + componentsUtils.auditResource(responseFormat, user, preparedResource, "", "", updateResource, null); + result = Either.right(responseFormat); + return result; + } + + Either uploadComponentInstanceInfoMap = parseResourceInfoFromYaml(yamlFileName, preparedResource, yamlFileContents, user); + if (uploadComponentInstanceInfoMap.isRight()) { + ResponseFormat responseFormat = uploadComponentInstanceInfoMap.right().value(); + componentsUtils.auditResource(responseFormat, user, preparedResource, "", "", updateResource, null); + result = Either.right(responseFormat); + return result; + } + + Map inputs = uploadComponentInstanceInfoMap.left().value().getInputs(); + Either createInputsOnResource = createInputsOnResource(preparedResource, user, inputs, true); + if (createInputsOnResource.isRight()) { + log.debug("failed to create resource inputs status is {}", createInputsOnResource.right().value()); + ResponseFormat responseFormat = createInputsOnResource.right().value(); + componentsUtils.auditResource(createInputsOnResource.right().value(), user, preparedResource, "", "", updateResource, null); + result = Either.right(responseFormat); + return result; + } + preparedResource = createInputsOnResource.left().value(); + + Map instances = uploadComponentInstanceInfoMap.left().value().getInstances(); + Either createResourcesInstancesEither = createResourceInstances(user, yamlFileName, preparedResource, instances, true, false, parseNodeTypeInfoYamlEither.left().value()); + if (createResourcesInstancesEither.isRight()) { + log.debug("failed to create resource instances status is {}", createResourcesInstancesEither.right().value()); + ResponseFormat responseFormat = createResourcesInstancesEither.right().value(); + componentsUtils.auditResource(createResourcesInstancesEither.right().value(), user, preparedResource, "", "", updateResource, null); + result = Either.right(responseFormat); + return result; + } + preparedResource = createResourcesInstancesEither.left().value(); + + createResourcesInstancesEither = createResourceInstancesRelations(user, yamlFileName, preparedResource, instances, true, false); + if (createResourcesInstancesEither.isRight()) { + log.debug("failed to create relation between resource instances status is {}", createResourcesInstancesEither.right().value()); + result = Either.right(createResourcesInstancesEither.right().value()); + return result; + } + + preparedResource = createResourcesInstancesEither.left().value(); + + Either, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic.validateUpdateVfGroupNames(uploadComponentInstanceInfoMap.left().value().getGroups(), preparedResource.getSystemName()); + if (validateUpdateVfGroupNamesRes.isRight()) { + + return Either.right(validateUpdateVfGroupNamesRes.right().value()); + } + // add groups to resource + Map groups; + + if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) { + groups = validateUpdateVfGroupNamesRes.left().value(); + } else { + groups = uploadComponentInstanceInfoMap.left().value().getGroups(); + } + Either updatedGroupsOnResource = updateGroupsOnResource(preparedResource, user, groups); + if (updatedGroupsOnResource.isRight()) { + + return updatedGroupsOnResource; + } + preparedResource = updatedGroupsOnResource.left().value(); + + } else { + Either dataModelResponse = updateResourceMetadata(oldRresource.getUniqueId(), newRresource, user, oldRresource, false, true); + if (dataModelResponse.isRight()) { + log.debug("failed to update resource metadata {}", dataModelResponse.right().value()); + result = Either.right(dataModelResponse.right().value()); + return result; + } + + preparedResource = dataModelResponse.left().value(); + + } + + Either createdCsarArtifactsEither = handleCsarArtifacts(preparedResource, user, csarUUID, csar.left().value(), createdArtifacts, ArtifactOperation.Update, false, true); + if (createdCsarArtifactsEither.isRight()) { + + return createdCsarArtifactsEither; + } + preparedResource = createdCsarArtifactsEither.left().value(); + + Either, ResponseFormat> eitherSetPosition = compositionBusinessLogic.setPositionsForComponentInstances(preparedResource, user.getUserId()); + result = eitherSetPosition.isRight() ? Either.right(eitherSetPosition.right().value()) : Either.left(preparedResource); + + return result; + + } finally { + if (result == null || result.isRight()) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + if (!createdArtifacts.isEmpty()) { + StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(createdArtifacts); + if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, oldRresource.getName()); + } + log.debug("component and all its artifacts were deleted, id = {}", oldRresource.getName()); + } + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + log.debug("unlock resource {}", lockedResourceId); + graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource); + } + + } + + public Either createResourceFromCsar(Resource resource, User user, AuditingActionEnum createResource, boolean inTransaction, Either, StorageOperationStatus> csarUIPayload, String csarUUID) { + log.trace("************* created successfully from YAML, resource TOSCA "); + + Either, StorageOperationStatus> csar = null; + if (csarUIPayload != null && csarUIPayload.left() != null && csarUIPayload.left().value() != null) { + csar = csarUIPayload; + } else { + csar = csarOperation.getCsar(csarUUID, user); + } + + Either, ResponseFormat> toscaYamlCsarStatus = validateAndParseCsar(resource, user, csarUUID, csar); + if (toscaYamlCsarStatus.isRight()) { + return Either.right(toscaYamlCsarStatus.right().value()); + } + Either toscaYamlChecksum = CsarValidationUtils.getToscaYamlChecksum(csar.left().value(), csarUUID, componentsUtils); + if (toscaYamlChecksum.isRight()) { + log.debug("Failed to calculate checksum for CSAR {}, error {}", csarUUID, toscaYamlChecksum.right().value()); + return Either.right(toscaYamlChecksum.right().value()); + } + resource.getComponentMetadataDefinition().getMetadataDataDefinition().setImportedToscaChecksum(toscaYamlChecksum.left().value()); + + String yamlFileName = toscaYamlCsarStatus.left().value().getKey(); + String yamlFileContents = toscaYamlCsarStatus.left().value().getValue(); + log.trace("YAML topology file found in CSAR, file name: {}, contents: {}", yamlFileName, yamlFileContents); + Either createResourceFromYaml = createResourceFromYaml(resource, user, yamlFileContents, yamlFileName, csar.left().value(), csarUUID); + if (createResourceFromYaml.isRight()) { + log.debug("Couldn't create resource from YAML"); + return Either.right(createResourceFromYaml.right().value()); + } + + Resource vfResource = createResourceFromYaml.left().value(); + log.trace("*************VF Resource created successfully from YAML, resource TOSCA name: {}", vfResource.getToscaResourceName()); + return Either.left(vfResource); + } + + private Either, ResponseFormat> validateAndParseCsar(Resource resource, User user, String csarUUID, Either, StorageOperationStatus> csar) { + if (csar.isRight()) { + StorageOperationStatus value = csar.right().value(); + log.debug("Error when fetching csar with ID {}, error: {}", csarUUID, value); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(value), csarUUID); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + return Either.right(responseFormat); + } + + Either validateCsarStatus = CsarValidationUtils.validateCsar(csar.left().value(), csarUUID, componentsUtils); + if (validateCsarStatus.isRight()) { + ResponseFormat responseFormat = validateCsarStatus.right().value(); + log.debug("Error when validate csar with ID {}, error: {}", csarUUID, responseFormat); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed"); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + return Either.right(responseFormat); + } + + Either, ResponseFormat> toscaYamlCsarStatus = CsarValidationUtils.getToscaYaml(csar.left().value(), csarUUID, componentsUtils); + + if (toscaYamlCsarStatus.isRight()) { + ResponseFormat responseFormat = toscaYamlCsarStatus.right().value(); + log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed"); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + return Either.right(responseFormat); + } + return toscaYamlCsarStatus; + } + + private Either validateResourceBeforeCreate(Resource resource, User user, boolean inTransaction) { + log.trace("validating resource before create"); + Either eitherCreator = validateUser(user, "Create Resource", resource, AuditingActionEnum.CREATE_RESOURCE, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user.copyData(eitherCreator.left().value()); + + // validate user role + Either validateRes = validateUserRole(user, resource, new ArrayList(), AuditingActionEnum.CREATE_RESOURCE, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + // VF "derivedFrom" should be null (or ignored) + if (!resource.getResourceType().equals(ResourceTypeEnum.VF)) { + Either validateDerivedFromNotEmpty = validateDerivedFromNotEmpty(user, resource, AuditingActionEnum.CREATE_RESOURCE); + if (validateDerivedFromNotEmpty.isRight()) { + return Either.right(validateDerivedFromNotEmpty.right().value()); + } + } + return validateResourceBeforeCreate(resource, user, AuditingActionEnum.CREATE_RESOURCE, inTransaction); + + } + + public Either createResourceFromYaml(Resource resource, User user, String topologyTemplateYaml, String yamlName, Map csar, String csarUUID) { + + List createdArtifacts = new ArrayList(); + log.trace("************* createResourceFromYaml before parse yaml "); + Either parseResourceInfoFromYamlEither = parseResourceInfoFromYaml(yamlName, resource, topologyTemplateYaml, user); + if (parseResourceInfoFromYamlEither.isRight()) { + ResponseFormat responseFormat = parseResourceInfoFromYamlEither.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + log.trace("************* createResourceFromYaml after parse yaml "); + ParsedToscaYamlInfo parsedToscaYamlInfo = parseResourceInfoFromYamlEither.left().value(); + log.debug("The parsed tosca yaml info is {}", parsedToscaYamlInfo); + log.trace("************* createResourceFromYaml before create "); + Either createdResourceResponse = createResourceAndRIsFromYaml(yamlName, resource, user, parsedToscaYamlInfo, AuditingActionEnum.IMPORT_RESOURCE, false, csarUUID, csar, createdArtifacts, topologyTemplateYaml); + log.trace("************* createResourceFromYaml after create "); + if (createdResourceResponse.isRight()) { + ResponseFormat responseFormat = createdResourceResponse.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + + return createdResourceResponse; + + } + + public Either, ResponseFormat> createResourcesFromYamlNodeTypesList(String yamlName, Resource resource, String resourceYml, User user, boolean needLock) { + + Map mappedToscaTemplate = (Map) new Yaml().load(resourceYml); + + Either tosca_version = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION); + if (tosca_version.isRight()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE); + return Either.right(responseFormat); + } + + Either, ResultStatusEnum> eitherNodeTypes = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES); + + Map nodeTypesResources = new HashMap<>(); + Either, ResponseFormat> result = Either.left(nodeTypesResources); + + Map mapToConvert = new HashMap(); + mapToConvert.put(ToscaTagNamesEnum.TOSCA_VERSION.getElementName(), tosca_version.left().value()); + + if (eitherNodeTypes.isLeft()) { + + Iterator> nodesNameValue = eitherNodeTypes.left().value().entrySet().iterator(); + + while (nodesNameValue.hasNext()) { + + Entry nodeType = nodesNameValue.next(); + log.trace("************* Going to create node {}", nodeType.getKey()); + Either, ResponseFormat> resourceCreated = this.createNodeTypeResourceFromYaml(yamlName, nodeType, user, mapToConvert, resource, needLock); + log.trace("************* finished to create node {}", nodeType.getKey()); + if (resourceCreated.isRight()) { + return Either.right(resourceCreated.right().value()); + } + Resource vfcCreated = resourceCreated.left().value().getLeft(); + + nodeTypesResources.put(nodeType.getKey(), vfcCreated); + mapToConvert.remove(ToscaTagNamesEnum.NODE_TYPES.getElementName()); + + } + } + + return result; + } + + private String getNodeTypeActualName(String fullName) { + String nameWithouNamespacePrefix = fullName.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); + String[] findTypes = nameWithouNamespacePrefix.split("\\."); + String resourceType = findTypes[0]; + return nameWithouNamespacePrefix.substring(resourceType.length()); + } + + private Either, ResponseFormat> createNodeTypeResourceFromYaml(String yamlName, Entry nodeNameValue, User user, Map mapToConvert, Resource resourceVf, boolean needLock) { + + Either resourceMetaData = fillResourceMetadata(yamlName, resourceVf, nodeNameValue.getKey(), user); + if (resourceMetaData.isRight()) { + return Either.right(resourceMetaData.right().value()); + } + + // We need to create a Yaml from each node_types in order to create + // resource from each node type using import normative flow. + DumperOptions options = new DumperOptions(); + options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK); + Yaml yaml = new Yaml(options); + + Map singleVfc = new HashMap<>(); + + String actualName = this.getNodeTypeActualName(nodeNameValue.getKey()); + if (!actualName.startsWith(ImportUtils.Constants.ABSTRACT_NODE)) { + actualName = "." + ImportUtils.Constants.ABSTRACT_NODE + actualName; + } + + // Setting tosca name + String toscaResourceName = ImportUtils.Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX + resourceMetaData.left().value().getResourceType().toLowerCase() + '.' + resourceVf.getSystemName() + actualName; + singleVfc.put(toscaResourceName, nodeNameValue.getValue()); + mapToConvert.put(ToscaTagNamesEnum.NODE_TYPES.getElementName(), singleVfc); + + String singleVfcYaml = yaml.dumpAsMap(mapToConvert); + + Either eitherCreator = validateUser(user, "CheckIn Resource", resourceVf, AuditingActionEnum.CHECKIN_RESOURCE, true); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + return this.createResourceFromNodeType(singleVfcYaml, resourceMetaData.left().value(), user, true, needLock); + } + + public Either validateResourceCreationFromNodeType(Resource resource, User creator) { + + Either validateDerivedFromNotEmpty = this.validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE); + if (validateDerivedFromNotEmpty.isRight()) { + return Either.right(validateDerivedFromNotEmpty.right().value()); + } + return Either.left(true); + } + + public Either, ResponseFormat> createResourceFromNodeType(String nodeTypeYaml, UploadResourceInfo resourceMetaData, User creator, boolean isInTransaction, boolean needLock) { + + LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction("certification on import", LifecycleChanceActionEnum.CREATE_FROM_CSAR); + Function> validator = (resource) -> this.validateResourceCreationFromNodeType(resource, creator); + return this.resourceImportManager.importCertifiedResource(nodeTypeYaml, resourceMetaData, creator, validator, lifecycleChangeInfo, isInTransaction, true, needLock); + } + + private Either fillResourceMetadata(String yamlName, Resource resourceVf, String nodeTypeName, User user) { + UploadResourceInfo resourceMetaData = new UploadResourceInfo(); + + // validate nodetype name prefix + if (!nodeTypeName.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX)) { + log.debug("invalid nodeTypeName:{} does not start with {}.", nodeTypeName, Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeTypeName); + return Either.right(responseFormat); + } + + String actualName = this.getNodeTypeActualName(nodeTypeName); + String namePrefix = nodeTypeName.replace(actualName, ""); + String resourceType = namePrefix.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); + + // if we import from csar, the node_type name can be + // org.openecomp.resource.abstract.node_name - in this case we always + // create a vfc + if (resourceType.equals(Constants.ABSTRACT)) { + resourceType = ResourceTypeEnum.VFC.name().toLowerCase(); + } + // validating type + if (!ResourceTypeEnum.contains(resourceType.toUpperCase())) { + log.debug("invalid resourceType:{} the type is not one of the valide types:{}.", resourceType.toUpperCase(), ResourceTypeEnum.values()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, resourceMetaData.getName(), nodeTypeName); + return Either.right(responseFormat); + } + + // Setting name + resourceMetaData.setName(resourceVf.getSystemName() + actualName); + + // Setting type from name + String type = resourceType.toUpperCase(); + resourceMetaData.setResourceType(type); + + resourceMetaData.setDescription(ImportUtils.Constants.INNER_VFC_DESCRIPTION); + resourceMetaData.setIcon(ImportUtils.Constants.DEFAULT_ICON); + resourceMetaData.setContactId(user.getUserId()); + resourceMetaData.setVendorName(resourceVf.getVendorName()); + resourceMetaData.setVendorRelease(resourceVf.getVendorRelease()); + + // Setting tag + List tags = new ArrayList<>(); + tags.add(resourceMetaData.getName()); + resourceMetaData.setTags(tags); + + // Setting category + CategoryDefinition category = new CategoryDefinition(); + category.setName(ImportUtils.Constants.ABSTRACT_CATEGORY_NAME); + SubCategoryDefinition subCategory = new SubCategoryDefinition(); + subCategory.setName(ImportUtils.Constants.ABSTRACT_SUBCATEGORY); + category.addSubCategory(subCategory); + List categories = new ArrayList<>(); + categories.add(category); + resourceMetaData.setCategories(categories); + + return Either.left(resourceMetaData); + } + + private Either createResourceAndRIsFromYaml(String yamlName, Resource resource, User user, ParsedToscaYamlInfo parsedToscaYamlInfo, AuditingActionEnum actionEnum, boolean isNormative, String csarUUID, + Map csar, List createdArtifacts, String topologyTemplateYaml) { + + boolean result = true; + + Either lockResult = lockComponentByName(resource.getSystemName(), resource, "Create Resource"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + return Either.right(responseFormat); + } + log.debug("name is locked {} status = {}", resource.getSystemName(), lockResult); + + try { + log.trace("************* createResourceFromYaml before full create resource {}", yamlName); + Either createResourcesEither = createResourceTransaction(resource, user, actionEnum, isNormative, true); + log.trace("************* createResourceFromYaml after full create resource {}", yamlName); + if (createResourcesEither.isRight()) { + result = false; + return createResourcesEither; + } + resource = createResourcesEither.left().value(); + // add groups to resource + log.trace("************* Going to add inputs from yaml {}", yamlName); + + Map inputs = parsedToscaYamlInfo.getInputs(); + Either createInputsOnResource = createInputsOnResource(resource, user, inputs, true); + if (createInputsOnResource.isRight()) { + result = false; + return createInputsOnResource; + } + resource = createInputsOnResource.left().value(); + log.trace("************* Finish to add inputs from yaml {}", yamlName); + + Map uploadComponentInstanceInfoMap = parsedToscaYamlInfo.getInstances(); + log.trace("************* Going to create nodes, RI's and Relations from yaml {}", yamlName); + createResourcesEither = createRIAndRelationsFromYaml(yamlName, resource, user, uploadComponentInstanceInfoMap, actionEnum, topologyTemplateYaml, csar, csarUUID); + log.trace("************* Finished to create nodes, RI and Relation from yaml {}", yamlName); + if (createResourcesEither.isRight()) { + result = false; + return createResourcesEither; + } + + resource = createResourcesEither.left().value(); + // validate update vf module group names + Either, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic.validateUpdateVfGroupNames(parsedToscaYamlInfo.getGroups(), resource.getSystemName()); + if (validateUpdateVfGroupNamesRes.isRight()) { + result = false; + return Either.right(validateUpdateVfGroupNamesRes.right().value()); + } + // add groups to resource + Map groups; + log.trace("************* Going to add groups from yaml {}", yamlName); + + if (!validateUpdateVfGroupNamesRes.left().value().isEmpty()) { + groups = validateUpdateVfGroupNamesRes.left().value(); + } else { + groups = parsedToscaYamlInfo.getGroups(); + } + Either createGroupsOnResource = createGroupsOnResource(resource, user, groups); + if (createGroupsOnResource.isRight()) { + result = false; + return createGroupsOnResource; + } + resource = createGroupsOnResource.left().value(); + log.trace("************* Finished to add groups from yaml {}", yamlName); + + log.trace("************* Going to add artifacts from yaml {}", yamlName); + Either createdCsarArtifactsEither = this.handleCsarArtifacts(resource, user, csarUUID, csar, createdArtifacts, ArtifactOperation.Create, false, true); + log.trace("************* Finished to add artifacts from yaml {}", yamlName); + if (createdCsarArtifactsEither.isRight()) { + result = false; + return createdCsarArtifactsEither; + } + resource = createdCsarArtifactsEither.left().value(); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + ASDCKpiApi.countCreatedResourcesKPI(); + return Either.left(resource); + + } finally { + if (!result) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + if (!createdArtifacts.isEmpty()) { + StorageOperationStatus deleteFromEsRes = artifactsBusinessLogic.deleteAllComponentArtifactsIfNotOnGraph(createdArtifacts); + if (!deleteFromEsRes.equals(StorageOperationStatus.OK)) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(deleteFromEsRes); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(actionStatus, resource.getName()); + } + log.debug("component and all its artifacts were deleted, id = {}", resource.getName()); + } + + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + + graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource); + + } + + } + + private Either createGroupsOnResource(Resource resource, User user, Map groups) { + if (groups != null && false == groups.isEmpty()) { + Either, ResponseFormat> mergeGroupsUsingResource = updateGroupMembersUsingResource(groups, resource); + + if (mergeGroupsUsingResource.isRight()) { + log.debug("Failed to prepare groups for creation"); + return Either.right(mergeGroupsUsingResource.right().value()); + } + List groupsAsList = mergeGroupsUsingResource.left().value(); + + // Either, ResponseFormat> createGroups = + // groupBusinessLogic.createGroups( + // resource.getUniqueId(), user.getUserId(), + // ComponentTypeEnum.RESOURCE, groupsAsList, false, + // true); + // In this method we assume all instances exists in resource + Either, ResponseFormat> createGroups = groupBusinessLogic.createGroups(resource, user, ComponentTypeEnum.RESOURCE, groupsAsList, true); + if (createGroups.isRight()) { + return Either.right(createGroups.right().value()); + } + } else { + return Either.left(resource); + } + + Either updatedResource = resourceOperation.getResource(resource.getUniqueId(), true); + if (updatedResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resource); + return Either.right(responseFormat); + } + return Either.left(updatedResource.left().value()); + } + + private Either updateGroupsOnResource(Resource resource, User user, Map groups) { + if (groups != null && false == groups.isEmpty()) { + List groupsFromResource = resource.getGroups(); + Either, ResponseFormat> mergeGroupsUsingResource = updateGroupMembersUsingResource(groups, resource); + + if (mergeGroupsUsingResource.isRight()) { + log.debug("Failed to prepare groups for creation"); + return Either.right(mergeGroupsUsingResource.right().value()); + } + List groupsAsList = mergeGroupsUsingResource.left().value(); + List groupsToUpdate = new ArrayList(); + List groupsToDelete = new ArrayList(); + List groupsToCreate = new ArrayList(); + if (groupsFromResource != null && !groupsFromResource.isEmpty()) { + for (GroupDefinition group : groupsAsList) { + Optional op = groupsFromResource.stream().filter(p -> p.getName().equals(group.getName())).findAny(); + if (op.isPresent()) { + GroupDefinition groupToUpdate = op.get(); + groupToUpdate.setMembers(group.getMembers()); + groupsToUpdate.add(groupToUpdate); + } else { + groupsToCreate.add(group); + } + } + for (GroupDefinition group : groupsFromResource) { + Optional op = groupsAsList.stream().filter(p -> p.getName().equals(group.getName())).findAny(); + if (!op.isPresent() && (group.getArtifacts() == null || group.getArtifacts().isEmpty())) { + + groupsToDelete.add(group); + } + + } + } else + groupsToCreate.addAll(groupsAsList); + + if (!groupsToCreate.isEmpty()) { + Either, ResponseFormat> createGroups = groupBusinessLogic.createGroups(resource, user, ComponentTypeEnum.RESOURCE, groupsToCreate, true); + + if (createGroups.isRight()) { + return Either.right(createGroups.right().value()); + } + } + + if (!groupsToDelete.isEmpty()) { + for (GroupDefinition group : groupsToDelete) { + Either deleteGroupEither = groupOperation.deleteGroup(group.getUniqueId(), true); + if (deleteGroupEither.isRight()) { + StorageOperationStatus storageOperationStatus = deleteGroupEither.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus); + log.debug("Failed to delete group {} under component {}, error: {}", group.getUniqueId(), resource.getNormalizedName(), actionStatus.name()); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + } + } + } + if (groupsToUpdate != null && !groupsToUpdate.isEmpty()) { + Either, ResponseFormat> assotiateGroupEither = groupBusinessLogic.associateMembersToGroup(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, groupsToUpdate, false, true); + if (assotiateGroupEither.isRight()) { + log.debug("Failed to associate artifacts to groups. Status is {} ", assotiateGroupEither.right().value()); + return Either.right(assotiateGroupEither.right().value()); + + } + List updatedGroups = assotiateGroupEither.left().value(); + List groupsId = updatedGroups.stream().map(e -> e.getUniqueId()).collect(Collectors.toList()); + + Either, StorageOperationStatus> updateVersionEither = groupBusinessLogic.updateGroupVersion(groupsId, true); + if (updateVersionEither.isRight()) { + log.debug("Failed to update groups version. Status is {} ", updateVersionEither.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(updateVersionEither.right().value()), resource); + return Either.right(responseFormat); + + } + } + + } else { + return Either.left(resource); + } + + Either updatedResource = resourceOperation.getResource(resource.getUniqueId(), true); + if (updatedResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resource); + return Either.right(responseFormat); + } + return Either.left(updatedResource.left().value()); + } + + private Either createInputsOnResource(Resource resource, User user, Map inputs, boolean inTransaction) { + if (inputs != null && false == inputs.isEmpty()) { + List inputsAsList = new ArrayList(); + for (Entry entry : inputs.entrySet()) { + InputDefinition input = entry.getValue(); + input.setName(entry.getKey()); + inputsAsList.add(input); + } + Either, ResponseFormat> createGroups = inputsBusinessLogic.createInputsInGraph(inputsAsList, resource, user, inTransaction); + if (createGroups.isRight()) { + return Either.right(createGroups.right().value()); + } + } else { + return Either.left(resource); + } + + Either updatedResource = resourceOperation.getResource(resource.getUniqueId(), true); + if (updatedResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(updatedResource.right().value()), resource); + return Either.right(responseFormat); + } + return Either.left(updatedResource.left().value()); + } + + private Either, ResponseFormat> updateGroupMembersUsingResource(Map groups, Resource component) { + + List result = new ArrayList<>(); + + List componentInstances = component.getComponentInstances(); + + if (groups != null) { + for (Entry entry : groups.entrySet()) { + String groupName = entry.getKey(); + + GroupDefinition groupDefinition = entry.getValue(); + + GroupDefinition updatedGroupDefinition = new GroupDefinition(groupDefinition); + updatedGroupDefinition.setMembers(null); + + // get the members of the group + Map members = groupDefinition.getMembers(); + if (members != null) { + Set compInstancesNames = members.keySet(); + + if (componentInstances == null || true == componentInstances.isEmpty()) { + String membersAstString = compInstancesNames.stream().collect(Collectors.joining(",")); + log.debug("The members {} in group {} cannot be found in component {}. There are no component instances", membersAstString, groupName, component.getNormalizedName()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName, component.getNormalizedName(), getComponentTypeForResponse(component))); + } + // Find all component instances with the member names + Map memberNames = componentInstances.stream().collect(Collectors.toMap(ComponentInstance::getName, ComponentInstance::getUniqueId)); + memberNames.putAll(groups.keySet().stream().collect(Collectors.toMap(g -> g, g -> ""))); + Map relevantInstances = memberNames.entrySet().stream().filter(n -> compInstancesNames.contains(n.getKey())).collect(Collectors.toMap(n -> n.getKey(), n -> n.getValue())); + + if (relevantInstances == null || relevantInstances.size() != compInstancesNames.size()) { + + List foundMembers = new ArrayList<>(); + if (relevantInstances != null) { + foundMembers = relevantInstances.keySet().stream().collect(Collectors.toList()); + } + compInstancesNames.removeAll(foundMembers); + String membersAstString = compInstancesNames.stream().collect(Collectors.joining(",")); + log.debug("The members {} in group {} cannot be found in component {}", membersAstString, groupName, component.getNormalizedName()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_INVALID_COMPONENT_INSTANCE, membersAstString, groupName, component.getNormalizedName(), getComponentTypeForResponse(component))); + } + + updatedGroupDefinition.setMembers(relevantInstances); + } + + result.add(updatedGroupDefinition); + } + } + return Either.left(result); + } + + private Either createRIAndRelationsFromYaml(String yamlName, Resource resource, User user, Map uploadComponentInstanceInfoMap, AuditingActionEnum actionEnum, + String topologyTemplateYaml, Map csar, String csarUUID) { + + Either result; + Either createResourcesInstancesEither; + log.debug("************* Going to create all nodes {}", yamlName); + Either, ResponseFormat> createdResourcesFromdNodeTypeMap = this.handleNodeTypes(yamlName, resource, user, topologyTemplateYaml, csar, false); + log.debug("************* Finished to create all nodes {}", yamlName); + if (createdResourcesFromdNodeTypeMap.isRight()) { + log.debug("failed to resources from node types status is {}", createdResourcesFromdNodeTypeMap.right().value()); + return Either.right(createdResourcesFromdNodeTypeMap.right().value()); + } + + log.debug("************* Going to create all resource instances {}", yamlName); + createResourcesInstancesEither = createResourceInstances(user, yamlName, resource, uploadComponentInstanceInfoMap, true, false, createdResourcesFromdNodeTypeMap.left().value()); + + log.debug("************* Finished to create all resource instances {}", yamlName); + if (createResourcesInstancesEither.isRight()) { + log.debug("failed to create resource instances status is {}", createResourcesInstancesEither.right().value()); + result = createResourcesInstancesEither; + return createResourcesInstancesEither; + } + resource = createResourcesInstancesEither.left().value(); + log.debug("************* Going to create all relations {}", yamlName); + createResourcesInstancesEither = createResourceInstancesRelations(user, yamlName, resource, uploadComponentInstanceInfoMap, true, false); + + log.debug("************* Finished to create all relations {}", yamlName); + + if (createResourcesInstancesEither.isRight()) { + log.debug("failed to create relation between resource instances status is {}", createResourcesInstancesEither.right().value()); + result = createResourcesInstancesEither; + return result; + } else { + resource = createResourcesInstancesEither.left().value(); + } + + log.debug("************* Going to create positions {}", yamlName); + Either, ResponseFormat> eitherSetPosition = compositionBusinessLogic.setPositionsForComponentInstances(resource, user.getUserId()); + log.debug("************* Finished to set positions {}", yamlName); + result = eitherSetPosition.isRight() ? Either.right(eitherSetPosition.right().value()) : Either.left(resource); + + return result; + } + + private Either, ResponseFormat> handleNodeTypes(String yamlName, Resource resource, User user, String topologyTemplateYaml, Map csar, boolean needLock) { + + Map createdResourcesFromdNodeTypeMap = new HashMap<>(); + Either, ResponseFormat> result = Either.left(createdResourcesFromdNodeTypeMap); + + String yamlFileName = Constants.GLOBAL_SUBSTITUTION_TYPE_SERVICE_TEMPLATE; + + if (csar != null && csar.containsKey(yamlFileName)) { + byte[] yamlFileBytes = csar.get(yamlFileName); + String globalTypesYaml = new String(yamlFileBytes, StandardCharsets.UTF_8); + Either, ResponseFormat> createdNodeTypesFromGlobalTypesTemplateEither = this.createResourcesFromYamlNodeTypesList(yamlFileName, resource, globalTypesYaml, user, needLock); + if (createdNodeTypesFromGlobalTypesTemplateEither.isRight()) { + ResponseFormat responseFormat = createdNodeTypesFromGlobalTypesTemplateEither.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + createdResourcesFromdNodeTypeMap.putAll(createdNodeTypesFromGlobalTypesTemplateEither.left().value()); + } + + Either, ResponseFormat> createdNodeTypeFromMainTemplateEither = createResourcesFromYamlNodeTypesList(yamlName, resource, topologyTemplateYaml, user, needLock); + if (createdNodeTypeFromMainTemplateEither.isRight()) { + ResponseFormat responseFormat = createdNodeTypeFromMainTemplateEither.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + + createdResourcesFromdNodeTypeMap.putAll(createdNodeTypeFromMainTemplateEither.left().value()); + + // add the created node types to the cache although they are not in the + // graph. + createdResourcesFromdNodeTypeMap.values().stream().forEach(p -> cacheManagerOperation.storeComponentInCache(p, NodeTypeEnum.Resource)); + + return result; + } + + private Either handleCsarArtifacts(Resource resource, User user, String csarUUID, Map csar, List createdArtifacts, ArtifactOperation artifactOperation, boolean shouldLock, + boolean inTransaction) { + + if (csar != null) { + String vendorLicenseModelId = null; + String vfLicenseModelId = null; + + if (artifactOperation.equals(ArtifactOperation.Update)) { + Map deploymentArtifactsMap = resource.getDeploymentArtifacts(); + if (deploymentArtifactsMap != null && !deploymentArtifactsMap.isEmpty()) { + for (Entry artifactEntry : deploymentArtifactsMap.entrySet()) { + if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL)) + vendorLicenseModelId = artifactEntry.getValue().getUniqueId(); + if (artifactEntry.getValue().getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) + vfLicenseModelId = artifactEntry.getValue().getUniqueId(); + } + } + + } + createOrUpdateLicenseArtifact(resource, user, csarUUID, csar, Constants.VENDOR_LICENSE_MODEL, ArtifactTypeEnum.VENDOR_LICENSE.getType(), Constants.VENDOR_LICENSE_LABEL, Constants.VENDOR_LICENSE_DISPLAY_NAME, + Constants.VENDOR_LICENSE_DESCRIPTION, vendorLicenseModelId, artifactOperation, shouldLock, inTransaction); + createOrUpdateLicenseArtifact(resource, user, csarUUID, csar, Constants.VF_LICENSE_MODEL, ArtifactTypeEnum.VF_LICENSE.getType(), Constants.VF_LICENSE_LABEL, Constants.VF_LICENSE_DISPLAY_NAME, Constants.VF_LICENSE_DESCRIPTION, + vfLicenseModelId, artifactOperation, shouldLock, inTransaction); + Either, ResponseFormat> artifacsMetaCsarStatus = CsarValidationUtils.getArtifactsMeta(csar, csarUUID, componentsUtils); + if (artifacsMetaCsarStatus.isLeft()) { + + String artifactsFileName = artifacsMetaCsarStatus.left().value().getKey(); + String artifactsContents = artifacsMetaCsarStatus.left().value().getValue(); + Either createArtifactsFromCsar = Either.left(resource); + if (artifactOperation.equals(ArtifactOperation.Create)) + createArtifactsFromCsar = createResourceArtifactsFromCsar(csarUUID, csar, resource, user, artifactsContents, artifactsFileName, createdArtifacts, shouldLock, inTransaction); + else + createArtifactsFromCsar = updateResourceArtifactsFromCsar(csarUUID, csar, resource, user, artifactsContents, artifactsFileName, createdArtifacts, shouldLock, inTransaction); + if (createArtifactsFromCsar.isRight()) { + log.debug("Couldn't create artifacts from artifacts.meta"); + return Either.right(createArtifactsFromCsar.right().value()); + } + + resource = createArtifactsFromCsar.left().value(); + } else { + List groupsToDelete = resource.getGroups(); + + if (groupsToDelete != null && !groupsToDelete.isEmpty()) { + Set artifactsToDelete = new HashSet(); + for (GroupDefinition group : groupsToDelete) { + List artifacts = group.getArtifacts(); + if (artifacts != null) { + artifactsToDelete.addAll(artifacts); + Either deleteGroupEither = groupOperation.deleteGroup(group.getUniqueId(), inTransaction); + if (deleteGroupEither.isRight()) { + StorageOperationStatus storageOperationStatus = deleteGroupEither.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus); + log.debug("Failed to delete group {} under component {}, error: {}", group.getUniqueId(), resource.getNormalizedName(), actionStatus.name()); + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + } + } + } + for (String artifactId : artifactsToDelete) { + Either, ResponseFormat> handleDelete = artifactsBusinessLogic.handleDelete(resource.getUniqueId(), artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, + resource, null, null, shouldLock, inTransaction); + if (handleDelete.isRight()) { + log.debug("Couldn't delete artifact {}", artifactId); + return Either.right(handleDelete.right().value()); + } + + } + Either eitherGerResource = resourceOperation.getResource(resource.getUniqueId(), inTransaction); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + resource = eitherGerResource.left().value(); + } + } + } + return Either.left(resource); + } + + private Either createOrUpdateLicenseArtifact(Resource resource, User user, String csarUUID, Map csar, String artifactFileName, String artifactType, String artifactLabel, String artifactDisplayName, + String artifactDescription, String artifactId, ArtifactOperation operation, boolean shouldLock, boolean inTransaction) { + byte[] artifactFileBytes = null; + + if (csar.containsKey(Constants.ARTIFACTS + artifactFileName)) { + artifactFileBytes = csar.get(Constants.ARTIFACTS + artifactFileName); + } + Either result = Either.left(true); + if (operation.equals(ArtifactOperation.Update)) { + if (artifactId != null && !artifactId.isEmpty() && artifactFileBytes == null) { + Either, ResponseFormat> handleDelete = artifactsBusinessLogic.handleDelete(resource.getUniqueId(), artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, resource, null, + null, shouldLock, inTransaction); + if (handleDelete.isRight()) { + result = Either.right(handleDelete.right().value()); + } + return result; + } + + if ((artifactId == null || artifactId.isEmpty()) && artifactFileBytes != null) { + operation = ArtifactOperation.Create; + } + + } + if (artifactFileBytes != null) { + Map vendorLicenseModelJson = buildJsonForUpdateArtifact(artifactId, artifactFileName, artifactType, artifactLabel, artifactDisplayName, artifactDescription, artifactFileBytes, null); + Either, ResponseFormat> vfLicenceArtifactCreateEither = createOrUpdateCsarArtifactFromJson(resource, user, vendorLicenseModelJson, operation, shouldLock, inTransaction); + + if (vfLicenceArtifactCreateEither.isRight()) { + BeEcompErrorManager.getInstance().logInternalFlowError("UploadLicenseArtifact", "Failed to upload license artifact: " + artifactFileName + "With csar uuid: " + csarUUID, ErrorSeverity.WARNING); + return Either.right(vfLicenceArtifactCreateEither.right().value()); + } + } + return result; + } + + private Either, ResponseFormat> createOrUpdateCsarArtifactFromJson(Resource resource, User user, Map json, ArtifactOperation operation, boolean shoudLock, boolean inTransaction) { + + String jsonStr = gson.toJson(json); + + String origMd5 = GeneralUtility.calculateMD5ByString(jsonStr); + ArtifactDefinition artifactDefinitionFromJson = RepresentationUtils.convertJsonToArtifactDefinition(jsonStr, ArtifactDefinition.class); + + Either, ResponseFormat> uploadArtifactToService = artifactsBusinessLogic.handleArtifactRequest(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, operation, + artifactDefinitionFromJson.getUniqueId(), artifactDefinitionFromJson, origMd5, jsonStr, null, null, null, null, shoudLock, inTransaction); + if (uploadArtifactToService.isRight()) + return Either.right(uploadArtifactToService.right().value()); + + return Either.left(uploadArtifactToService.left().value()); + } + + public Either updateResourceArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, String artifactsMetaFile, String artifactsMetaFileName, List createdNewArtifacts, + boolean shouldLock, boolean inTransaction) { + + Either>, ResponseFormat> parseResourceInfoFromYamlEither = parseResourceArtifactsInfoFromFile(resource, artifactsMetaFile, artifactsMetaFileName, user); + if (parseResourceInfoFromYamlEither.isRight()) { + ResponseFormat responseFormat = parseResourceInfoFromYamlEither.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + + List groups = resource.getGroups(); + Map deplymentArtifact = resource.getDeploymentArtifacts(); + List createdDeplymentArtifactsAfterDelete = new ArrayList(); + if (deplymentArtifact != null && !deplymentArtifact.isEmpty()) { + for (Entry entry : deplymentArtifact.entrySet()) { + createdDeplymentArtifactsAfterDelete.add(entry.getValue()); + } + } + int labelCounter = createdDeplymentArtifactsAfterDelete.size(); + + if (deplymentArtifact == null || deplymentArtifact.isEmpty()) { + if (groups != null && !groups.isEmpty()) { + for (GroupDefinition group : groups) { + if (group.getArtifacts() != null && !group.getArtifacts().isEmpty()) { + log.debug("failed to update artifacts from csar. List of emty but group not empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(responseFormat); + } + } + } + return createResourceArtifacts(csarUUID, csar, resource, user, parseResourceInfoFromYamlEither.left().value(), AuditingActionEnum.CREATE_RESOURCE, createdNewArtifacts, shouldLock, inTransaction); + } + // find artifacts to delete + Set artifactNotInGroupSet = findArtifactsNotInGroupToDelete(groups, createdDeplymentArtifactsAfterDelete); + + // delete all artifacts which not in groups + if (!artifactNotInGroupSet.isEmpty()) { + for (String artifactId : artifactNotInGroupSet) { + Either, ResponseFormat> handleDelete = artifactsBusinessLogic.handleDelete(resource.getUniqueId(), artifactId, user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, resource, null, + null, shouldLock, inTransaction); + if (handleDelete.isRight()) { + return Either.right(handleDelete.right().value()); + } + + } + Either eitherGerResource = resourceOperation.getResource(resource.getUniqueId(), inTransaction); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + + resource = eitherGerResource.left().value(); + deplymentArtifact = resource.getDeploymentArtifacts(); + + createdDeplymentArtifactsAfterDelete.clear(); + if (deplymentArtifact != null && !deplymentArtifact.isEmpty()) { + for (Entry entry : deplymentArtifact.entrySet()) { + createdDeplymentArtifactsAfterDelete.add(entry.getValue()); + } + } + } + + // find master in group + Map>> groupArtifact = findMasterArtifactInGroup(groups, deplymentArtifact); + + ////////////////////////////////////// create set parsed + ////////////////////////////////////// artifacts/////////////////////////////////////////// + Map> parsedArtifactsMap = parseResourceInfoFromYamlEither.left().value(); + Collection> parsedArifactsCollection = parsedArtifactsMap.values(); + Map> parsedGroup = new HashMap>(); + + for (List parsedGroupTemplateList : parsedArifactsCollection) { + for (ArtifactTemplateInfo parsedGroupTemplate : parsedGroupTemplateList) { + parsedGroupTemplate.setGroupName(""); + Set parsedArtifactsNames = new HashSet(); + parsedArtifactsNames.add(parsedGroupTemplate); + List relatedGroupTemplateList = parsedGroupTemplate.getRelatedArtifactsInfo(); + if (relatedGroupTemplateList != null && !relatedGroupTemplateList.isEmpty()) { + createArtifactsGroupSet(parsedGroupTemplateList, parsedArtifactsNames); + } + parsedGroup.put(parsedGroupTemplate, parsedArtifactsNames); + } + } + + ///////////////////////////////// find artifacts to + ///////////////////////////////// delete//////////////////////////////////////////////////// + + Set artifactsToDelete = new HashSet(); + Map> groupToDelete = new HashMap>(); + Map> dissocArtifactFromGroup = new HashMap>(); + + Set jsonMasterArtifacts = parsedGroup.keySet(); + + Map mergedgroup = mergeGroupInUpdateFlow(groupArtifact, parsedGroup, artifactsToDelete, groupToDelete, jsonMasterArtifacts); + + // find artifacts to delete + for (Entry> deleteGroup : groupToDelete.entrySet()) { + + List artifacts = deleteGroup.getValue(); + for (ArtifactDefinition artifact : artifacts) { + findArtifactToDelete(parsedGroup, artifactsToDelete, deleteGroup.getKey(), artifact); + } + + } + + // Set deletedArtifactsName = new HashSet(); + Either, ResponseFormat> deletedArtifactsEither = deleteArtifactsInUpdateCsarFlow(resource, user, shouldLock, inTransaction, artifactsToDelete, groupToDelete); + if (deletedArtifactsEither.isRight()) { + log.debug("Failed to delete artifacts. Status is {} ", deletedArtifactsEither.right().value()); + + return Either.right(deletedArtifactsEither.right().value()); + + } + List deletedArtifacts = deletedArtifactsEither.left().value(); + + // need to update resource if we updated artifacts + if (deletedArtifacts != null && !deletedArtifacts.isEmpty()) { + for (ArtifactDefinition deletedArtifact : deletedArtifacts) { + ArtifactDefinition artToRemove = null; + for (ArtifactDefinition artFromResource : createdDeplymentArtifactsAfterDelete) { + if (deletedArtifact.getUniqueId().equalsIgnoreCase(artFromResource.getUniqueId())) { + artToRemove = artFromResource; + break; + } + } + if (artToRemove != null) + createdDeplymentArtifactsAfterDelete.remove(artToRemove); + + } + } + + ////////////// dissociate, associate or create + ////////////// artifacts//////////////////////////// + Either assDissotiateEither = associateAndDissociateArtifactsToGroup(csarUUID, csar, resource, user, createdNewArtifacts, labelCounter, shouldLock, inTransaction, createdDeplymentArtifactsAfterDelete, + dissocArtifactFromGroup, mergedgroup, deletedArtifacts); + + if (assDissotiateEither.isRight()) { + log.debug("Failed to delete artifacts. Status is {} ", assDissotiateEither.right().value()); + + return Either.right(assDissotiateEither.right().value()); + + } + resource = assDissotiateEither.left().value(); + groups = resource.getGroups(); + List groupToUpdate = new ArrayList<>(); + // update vfModule names + Set groupForAssociateWithMembers = mergedgroup.keySet(); + if (groups != null && !groups.isEmpty()) { + Either, ResponseFormat> validateUpdateVfGroupNamesRes = groupBusinessLogic.validateUpdateVfGroupNamesOnGraph(groups, resource.getSystemName(), inTransaction); + if (validateUpdateVfGroupNamesRes.isRight()) { + return Either.right(validateUpdateVfGroupNamesRes.right().value()); + } + List heatGroups = null; + + // List collect = resources.stream().flatMap( e -> + // e.getArtifacts().stream()).filter(p -> + // relevantArtifactTypes.contains(p.getArtifactType() + // )).collect(Collectors.toList()); + // List heatGroups = createdGroups.stream().filter( + // e -> e.getProperties().stream().filter(p -> + // p.getName().contains(Constants.HEAT_FILE_PROPS))).collect(Collectors.toList()); + heatGroups = groups.stream().filter(e -> e.getMembers() != null).collect(Collectors.toList()); + ; + + for (GroupDefinition updatedGroupDef : groupForAssociateWithMembers) { + GroupDefinition group = null; + Optional opGr = groups.stream().filter(p -> p.getUniqueId().equals(updatedGroupDef.getUniqueId())).findAny(); + if (opGr.isPresent()) { + group = opGr.get(); + groupToUpdate.add(group); + } + if (group != null) { + Map members = new HashMap(); + Set artifactsGroup = new HashSet(); + artifactsGroup.addAll(group.getArtifacts()); + associateMembersTToArtifacts(createdNewArtifacts, createdDeplymentArtifactsAfterDelete, heatGroups, artifactsGroup, members); + if (!members.isEmpty()) { + group.setMembers(members); + + } + } + + } + if (!groupToUpdate.isEmpty()) { + Either, ResponseFormat> assotiateGroupEither = groupBusinessLogic.associateMembersToGroup(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, groupToUpdate, false, true); + if (assotiateGroupEither.isRight()) { + log.debug("Failed to associate artifacts to groups. Status is {} ", assotiateGroupEither.right().value()); + return Either.right(assotiateGroupEither.right().value()); + + } + } + + } + + //////////////// create new artifacts in update + //////////////// flow//////////////////////////// + List newArtifactsGroup = new ArrayList(); + + for (Entry> parsedGroupSetEntry : parsedGroup.entrySet()) { + ArtifactTemplateInfo parsedArtifactMaster = parsedGroupSetEntry.getKey(); + boolean isNewGroup = true; + for (Entry>> groupListEntry : groupArtifact.entrySet()) { + Map> groupArtifacts = groupListEntry.getValue(); + Set group = groupArtifacts.keySet(); + for (ArtifactDefinition artifactInfo : group) { + if (parsedArtifactMaster.getFileName().equalsIgnoreCase(artifactInfo.getArtifactName())) { + parsedArtifactMaster.setGroupName(groupListEntry.getKey().getName()); + isNewGroup = false; + } + } + } + if (isNewGroup) + newArtifactsGroup.add(parsedArtifactMaster); + + } + if (!newArtifactsGroup.isEmpty()) { + Collections.sort(newArtifactsGroup, (art1, art2) -> ArtifactTemplateInfo.compareByGroupName(art1, art2)); + int startGroupCounter = groupBusinessLogic.getNextVfModuleNameCounter(groups); + Either validateGroupNamesRes = groupBusinessLogic.validateGenerateVfModuleGroupNames(newArtifactsGroup, resource.getSystemName(), startGroupCounter); + if (validateGroupNamesRes.isRight()) { + return Either.right(validateGroupNamesRes.right().value()); + } + Either resStatus = createGroupDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, newArtifactsGroup, createdNewArtifacts, createdDeplymentArtifactsAfterDelete, labelCounter, shouldLock, inTransaction); + if (resStatus.isRight()) + return resStatus; + } + + // updatedGroup + if (!groupForAssociateWithMembers.isEmpty()) { + + List groupsId = groupForAssociateWithMembers.stream().map(e -> e.getUniqueId()).collect(Collectors.toList()); + + Either, StorageOperationStatus> updateVersionEither = groupBusinessLogic.updateGroupVersion(groupsId, true); + if (updateVersionEither.isRight()) { + log.debug("Failed to update groups version. Status is {} ", updateVersionEither.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(updateVersionEither.right().value()), resource); + return Either.right(responseFormat); + + } + } + + Either eitherGerResource = resourceOperation.getResource(resource.getUniqueId(), inTransaction); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + return Either.left(eitherGerResource.left().value()); + + } + + private Either, ResponseFormat> deleteArtifactsInUpdateCsarFlow(Resource resource, User user, boolean shouldLock, boolean inTransaction, Set artifactsToDelete, + Map> groupToDelete) { + List deletedArtifacts = new ArrayList(); + + if (!artifactsToDelete.isEmpty()) { + for (ArtifactDefinition artifact : artifactsToDelete) { + + Either, ResponseFormat> handleDelete = artifactsBusinessLogic.handleDelete(resource.getUniqueId(), artifact.getUniqueId(), user, AuditingActionEnum.ARTIFACT_DELETE, ComponentTypeEnum.RESOURCE, + resource, null, null, shouldLock, inTransaction); + if (handleDelete.isRight()) { + return Either.right(handleDelete.right().value()); + } + deletedArtifacts.add(handleDelete.left().value().left().value()); + + } + } + if (!groupToDelete.isEmpty()) { + log.debug("try to delete group"); + for (Entry> deleteGroup : groupToDelete.entrySet()) { + Either deleteGroupEither = groupOperation.deleteGroup(deleteGroup.getKey(), inTransaction); + if (deleteGroupEither.isRight()) { + StorageOperationStatus storageOperationStatus = deleteGroupEither.right().value(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageOperationStatus); + log.debug("Failed to delete group {} under component {}, error: {}", deleteGroup.getKey(), resource.getNormalizedName(), actionStatus.name()); + + return Either.right(componentsUtils.getResponseFormat(actionStatus)); + + } + } + } + return Either.left(deletedArtifacts); + } + + private Either associateAndDissociateArtifactsToGroup(String csarUUID, Map csar, Resource resource, User user, List createdNewArtifacts, int labelCounter, boolean shouldLock, + boolean inTransaction, List createdDeplymentArtifactsAfterDelete, Map> dissocArtifactFromGroup, Map mergedgroup, List deletedArtifacts) { + Map> artifactsToAssotiate = new HashMap>(); + Map>> artifactsToUpdateMap = new HashMap>>(); + Either resEither = Either.left(resource); + for (Entry entry : mergedgroup.entrySet()) { + List dissArtifactsInGroup = entry.getValue().getListToDissotiateArtifactFromGroup(deletedArtifacts); + if (dissArtifactsInGroup != null && !dissArtifactsInGroup.isEmpty()) { + List dissList = new ArrayList(); + for (ArtifactDefinition art : dissArtifactsInGroup) { + dissList.add(art.getUniqueId()); + } + dissocArtifactFromGroup.put(entry.getKey().getUniqueId(), dissList); + } + + List newArtifactsInGroup = entry.getValue().getListToAssociateArtifactToGroup(); + if (newArtifactsInGroup != null && !newArtifactsInGroup.isEmpty()) + artifactsToAssotiate.put(entry.getKey(), newArtifactsInGroup); + + List> artifactsToUpdate = entry.getValue().getListToUpdateArtifactInGroup(); + if (artifactsToUpdate != null && !artifactsToUpdate.isEmpty()) + artifactsToUpdateMap.put(entry.getKey(), artifactsToUpdate); + } + + // Map> dissocArtifactFromGroup = new + // HashMap>(); + List dissotiateArtifactsgroups = new ArrayList(); + for (Entry> dissotiateEntry : dissocArtifactFromGroup.entrySet()) { + + GroupDefinition dissotiateGroup = new GroupDefinition(); + dissotiateGroup.setUniqueId(dissotiateEntry.getKey()); + dissotiateGroup.setArtifacts(dissotiateEntry.getValue()); + dissotiateArtifactsgroups.add(dissotiateGroup); + } + if (!dissotiateArtifactsgroups.isEmpty()) { + log.debug("try to dissociate artifacts from groups "); + Either, ResponseFormat> dissotiateGroupEither = groupBusinessLogic.dissociateArtifactsFromGroup(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, dissotiateArtifactsgroups, shouldLock, + inTransaction); + if (dissotiateGroupEither.isRight()) { + log.debug("Failed to dissociate artifacts from groups. Status is {} ", dissotiateGroupEither.right().value()); + resEither = Either.right(dissotiateGroupEither.right().value()); + return resEither; + + } + } + + if (!artifactsToUpdateMap.isEmpty()) { + List updatedArtifacts = new ArrayList(); + for (Entry>> artifactsToUpdateEntry : artifactsToUpdateMap.entrySet()) { + List> artifactsToUpdateList = artifactsToUpdateEntry.getValue(); + for (ImmutablePair artifact : artifactsToUpdateList) { + Either updateArtifactEither = updateDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, artifact.getKey(), artifact.getValue(), updatedArtifacts, + artifact.getRight().getRelatedArtifactsInfo(), shouldLock, inTransaction); + if (updateArtifactEither.isRight()) { + log.debug("failed to update artifacts. status is {}", updateArtifactEither.right().value()); + resEither = Either.right(updateArtifactEither.right().value()); + return resEither; + + } + + } + } + + } + + List associateArtifactGroup = new ArrayList(); + + for (Entry> associateEntry : artifactsToAssotiate.entrySet()) { + List associatedArtifact = associateEntry.getValue(); + Set arifactsUids = new HashSet(); + for (ArtifactTemplateInfo artifactTemplate : associatedArtifact) { // try + // to + // find + // artifact + // in + // resource + boolean isCreate = true; + for (ArtifactDefinition createdArtifact : createdDeplymentArtifactsAfterDelete) { + if (artifactTemplate.getFileName().equalsIgnoreCase(createdArtifact.getArtifactName())) { + arifactsUids.add(createdArtifact.getUniqueId()); + isCreate = false; + break; + } + + } + if (isCreate) { // check if already created + for (ArtifactDefinition createdNewArtifact : createdNewArtifacts) { + if (artifactTemplate.getFileName().equalsIgnoreCase(createdNewArtifact.getArtifactName())) { + arifactsUids.add(createdNewArtifact.getUniqueId()); + isCreate = false; + break; + } + } + } + + if (isCreate) { + Either createArtifactEither = createDeploymentArtifact(csarUUID, csar, resource, user, artifactTemplate, createdNewArtifacts, labelCounter, shouldLock, inTransaction); + if (createArtifactEither.isRight()) { + resEither = Either.right(createArtifactEither.right().value()); + return resEither; + } + arifactsUids.add(createArtifactEither.left().value().getUniqueId()); + } + + } + if (arifactsUids.size() > 0) { + List artifactsToAssociate = new ArrayList(); + artifactsToAssociate.addAll(arifactsUids); + GroupDefinition assotiateGroup = new GroupDefinition(); + assotiateGroup.setUniqueId(associateEntry.getKey().getUniqueId()); + assotiateGroup.setArtifacts(artifactsToAssociate); + associateArtifactGroup.add(assotiateGroup); + + } + } + + if (!associateArtifactGroup.isEmpty()) { + + log.debug("Try to associate artifacts to groups."); + + Either, ResponseFormat> assotiateGroupEither = groupBusinessLogic.associateArtifactsToGroup(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, associateArtifactGroup, shouldLock, inTransaction); + if (assotiateGroupEither.isRight()) { + log.debug("Failed to associate artifacts to groups. Status is {} ", assotiateGroupEither.right().value()); + resEither = Either.right(assotiateGroupEither.right().value()); + return resEither; + + } + } + + ComponentParametersView parametersView = new ComponentParametersView(); + parametersView.disableAll(); + parametersView.setIgnoreComponentInstances(false); + parametersView.setIgnoreUsers(false); + parametersView.setIgnoreArtifacts(false); + parametersView.setIgnoreGroups(false); + Either eitherGerResource = resourceOperation.getComponent(resource.getUniqueId(), parametersView, inTransaction); + + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + resEither = Either.right(responseFormat); + return resEither; + + } + resEither = Either.left(eitherGerResource.left().value()); + return resEither; + } + + private Map mergeGroupInUpdateFlow(Map>> groupArtifact, Map> parsedGroup, + Set artifactsToDelete, Map> groupToDelete, Set jsonMasterArtifacts) { + Map mergedgroup = new HashMap(); + for (Entry>> groupListEntry : groupArtifact.entrySet()) { + Map> createdArtifactMap = groupListEntry.getValue(); + boolean isNeedToDeleteGroup = true; + List listToDelete = null; + for (ArtifactDefinition maserArtifact : createdArtifactMap.keySet()) { + listToDelete = createdArtifactMap.get(maserArtifact); + for (ArtifactDefinition artToDelete : listToDelete) { + findArtifactToDelete(parsedGroup, artifactsToDelete, groupListEntry.getKey().getUniqueId(), artToDelete); + } + for (ArtifactTemplateInfo jsonMasterArtifact : jsonMasterArtifacts) { + if (maserArtifact.getArtifactName().equalsIgnoreCase(jsonMasterArtifact.getFileName())) { + MergedArtifactInfo mergedGroup = new MergedArtifactInfo(); + mergedGroup.setJsonArtifactTemplate(jsonMasterArtifact); + mergedGroup.setCreatedArtifact(createdArtifactMap.get(maserArtifact)); + mergedgroup.put(groupListEntry.getKey(), mergedGroup); + isNeedToDeleteGroup = false; + + } + } + + } + if (isNeedToDeleteGroup) { + groupToDelete.put(groupListEntry.getKey().getUniqueId(), listToDelete); + } + + } + return mergedgroup; + } + + private Set findArtifactsNotInGroupToDelete(List groups, List createdDeplymentArtifactsAfterDelete) { + Set artifactNotInGroupSet = new HashSet(); + for (ArtifactDefinition artifact : createdDeplymentArtifactsAfterDelete) { + boolean needToDelete = true; + if (artifact.getArtifactName().equalsIgnoreCase(Constants.VENDOR_LICENSE_MODEL) || artifact.getArtifactName().equalsIgnoreCase(Constants.VF_LICENSE_MODEL)) + continue; + if (groups != null) { + for (GroupDefinition group : groups) { + List groupArtifactIds = group.getArtifacts(); + if (groupArtifactIds == null || groupArtifactIds.isEmpty()) { + continue; + } + for (String groupArtifactid : groupArtifactIds) { + if (groupArtifactid.equalsIgnoreCase(artifact.getUniqueId())) + needToDelete = false; + + } + + } + } + if (needToDelete) + artifactNotInGroupSet.add(artifact.getUniqueId()); + } + return artifactNotInGroupSet; + } + + private void findArtifactToDelete(Map> parsedGroup, Set artifactsToDelete, String deleteGroupId, ArtifactDefinition artifact) { + boolean isNeedToDeleteArtifact = true; + for (Entry> parsedGroupSetEntry : parsedGroup.entrySet()) { + Set artifactsNames = parsedGroupSetEntry.getValue(); + for (ArtifactTemplateInfo template : artifactsNames) { + if (artifact.getArtifactName().equalsIgnoreCase(template.getFileName()) && artifact.getArtifactType().equalsIgnoreCase(template.getType())) { + isNeedToDeleteArtifact = false; + + } + } + } + if (isNeedToDeleteArtifact) { + + artifactsToDelete.add(artifact); + + } + } + + private Map>> findMasterArtifactInGroup(List groups, Map deplymentArtifact) { + Map>> groupArtifact = new HashMap>>(); + + for (GroupDefinition group : groups) { + Map> gupsMap = new HashMap>(); + List artifacts = new ArrayList(); + List artifactsList = group.getArtifacts(); + if (artifactsList != null && !artifactsList.isEmpty()) { + + ArtifactDefinition masterArtifact = ArtifactUtils.findMasterArtifact(deplymentArtifact, artifacts, artifactsList); + if (masterArtifact != null) + gupsMap.put(masterArtifact, artifacts); + groupArtifact.put(group, gupsMap); + + } + } + return groupArtifact; + } + + private void createArtifactsGroupSet(List parsedGroupTemplateList, Set parsedArtifactsName) { + + for (ArtifactTemplateInfo parsedGroupTemplate : parsedGroupTemplateList) { + parsedArtifactsName.add(parsedGroupTemplate); + List relatedArtifacts = parsedGroupTemplate.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + createArtifactsGroupSet(relatedArtifacts, parsedArtifactsName); + } + } + } + + public Either createResourceArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, String artifactsMetaFile, String artifactsMetaFileName, List createdArtifacts, + boolean shouldLock, boolean inTransaction) { + + log.debug("parseResourceArtifactsInfoFromFile start"); + Either>, ResponseFormat> parseResourceInfoFromYamlEither = parseResourceArtifactsInfoFromFile(resource, artifactsMetaFile, artifactsMetaFileName, user); + if (parseResourceInfoFromYamlEither.isRight()) { + ResponseFormat responseFormat = parseResourceInfoFromYamlEither.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return Either.right(responseFormat); + } + log.debug("parseResourceArtifactsInfoFromFile end"); + + log.debug("createResourceArtifacts start"); + Either respStatus = createResourceArtifacts(csarUUID, csar, resource, user, parseResourceInfoFromYamlEither.left().value(), AuditingActionEnum.CREATE_RESOURCE, createdArtifacts, shouldLock, inTransaction); + if (respStatus.isRight()) { + return respStatus; + } + log.debug("createResourceArtifacts end"); + log.debug("getResource start"); + Either eitherGerResource = resourceOperation.getResource(resource.getUniqueId(), inTransaction); + log.debug("getResource end"); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + return Either.left(eitherGerResource.left().value()); + + } + + private Either createGroupDeploymentArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, List artifactsTemplateList, + List createdNewArtifacts, List artifactsFromResource, int labelCounter, boolean shouldLock, boolean inTransaction) { + Either resStatus = Either.left(resource); + List createdGroups = resource.getGroups(); + List heatGroups = null; + if (createdGroups != null && !createdGroups.isEmpty()) { + + // List collect = resources.stream().flatMap( e -> + // e.getArtifacts().stream()).filter(p -> + // relevantArtifactTypes.contains(p.getArtifactType() + // )).collect(Collectors.toList()); + // List heatGroups = createdGroups.stream().filter( + // e -> e.getProperties().stream().filter(p -> + // p.getName().contains(Constants.HEAT_FILE_PROPS))).collect(Collectors.toList()); + heatGroups = createdGroups.stream().filter(e -> e.getMembers() != null).collect(Collectors.toList()); + ; + } + + for (ArtifactTemplateInfo groupTemplateInfo : artifactsTemplateList) { + String groupName = groupTemplateInfo.getGroupName(); + Set artifactsGroup = new HashSet(); + + resStatus = createDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, artifactsGroup, groupTemplateInfo, createdNewArtifacts, artifactsFromResource, labelCounter, shouldLock, inTransaction); + if (resStatus.isRight()) + return resStatus; + + Map members = new HashMap(); + associateMembersTToArtifacts(createdNewArtifacts, artifactsFromResource, heatGroups, artifactsGroup, members); + + List artifactsList = new ArrayList(artifactsGroup); + + GroupDefinition groupDefinition = new GroupDefinition(); + groupDefinition.setName(groupName); + groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE); + groupDefinition.setArtifacts(artifactsList); + if (!members.isEmpty()) + groupDefinition.setMembers(members); + + List properties = new ArrayList(); + GroupProperty prop = new GroupProperty(); + prop.setName(Constants.IS_BASE); + prop.setValue(Boolean.toString(groupTemplateInfo.isBase())); + + properties.add(prop); + groupDefinition.setProperties(properties); + Either createGroup = groupBusinessLogic.createGroup(resource.getUniqueId(), user.getUserId(), ComponentTypeEnum.RESOURCE, groupDefinition, inTransaction); + if (createGroup.isRight()) + return Either.right(createGroup.right().value()); + + } + return resStatus; + } + + private Either createDeploymentArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, Set artifactsGroup, ArtifactTemplateInfo artifactTemplateInfo, + List createdArtifacts, List artifactsFromResource, int labelCounter, boolean shoudLock, boolean inTransaction) { + Either resStatus = Either.left(resource); + String artifactFileName = artifactTemplateInfo.getFileName(); + String artifactUid = ""; + boolean alreadyExist = false; + + // check if artifacts already exist + if (artifactsFromResource != null && !artifactsFromResource.isEmpty()) { + for (ArtifactDefinition artifactFromResource : artifactsFromResource) { + if (artifactFromResource.getArtifactName().equals(artifactFileName)) { + artifactUid = artifactFromResource.getUniqueId(); + if (!artifactFromResource.getArtifactType().equalsIgnoreCase(artifactTemplateInfo.getType())) { + log.debug("Artifact with name {} and type {} already exist with type {}", artifactFileName, artifactTemplateInfo.getType(), artifactFromResource.getArtifactType()); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, artifactFileName, artifactTemplateInfo.getType(), artifactFromResource.getArtifactType())); + } + alreadyExist = true; + break; + } + + } + + } + if (!alreadyExist) { + for (ArtifactDefinition createdArtifact : createdArtifacts) { + if (createdArtifact.getArtifactName().equals(artifactFileName)) { + artifactUid = createdArtifact.getUniqueId(); + if (!createdArtifact.getArtifactType().equalsIgnoreCase(artifactTemplateInfo.getType())) { + log.debug("Artifact with name {} and type {} already exist with type {}", artifactFileName, artifactTemplateInfo.getType(), createdArtifact.getArtifactType()); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, artifactFileName, artifactTemplateInfo.getType(), createdArtifact.getArtifactType())); + } + alreadyExist = true; + break; + } + + } + } + // if not exist need to create + if (!alreadyExist) { + + Either newArtifactEither = createDeploymentArtifact(csarUUID, csar, resource, user, artifactTemplateInfo, createdArtifacts, labelCounter, shoudLock, inTransaction); + if (newArtifactEither.isRight()) { + resStatus = Either.right(newArtifactEither.right().value()); + return resStatus; + } + artifactUid = newArtifactEither.left().value().getUniqueId(); + + } + + artifactsGroup.add(artifactUid); + + List relatedArtifacts = artifactTemplateInfo.getRelatedArtifactsInfo(); + if (relatedArtifacts != null) { + for (ArtifactTemplateInfo relatedArtifactTemplateInfo : relatedArtifacts) { + resStatus = createDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, artifactsGroup, relatedArtifactTemplateInfo, createdArtifacts, artifactsFromResource, labelCounter, shoudLock, inTransaction); + if (resStatus.isRight()) + return resStatus; + } + } + return resStatus; + } + + private Either createResourceArtifacts(String csarUUID, Map csar, Resource resource, User user, Map> artifactsMap, AuditingActionEnum createResource, + List createdArtifacts, boolean shouldLock, boolean inTransaction) { + + Either resStatus = Either.left(resource); + + Collection> arifactsCollection = artifactsMap.values(); + + for (List groupTemplateList : arifactsCollection) { + if (groupTemplateList != null) { + resStatus = createGroupDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, groupTemplateList, createdArtifacts, 0, shouldLock, inTransaction); + if (resStatus.isRight()) + return resStatus; + } + } + + return resStatus; + + } + + private Either createGroupDeploymentArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, List artifactsTemplateList, List createdArtifacts, + int labelCounter, boolean shouldLock, boolean inTransaction) { + Either resStatus = Either.left(resource); + List createdGroups = resource.getGroups(); + List heatGroups = null; + if (createdGroups != null && !createdGroups.isEmpty()) { + + // List collect = resources.stream().flatMap( e -> + // e.getArtifacts().stream()).filter(p -> + // relevantArtifactTypes.contains(p.getArtifactType() + // )).collect(Collectors.toList()); + // List heatGroups = createdGroups.stream().filter( + // e -> e.getProperties().stream().filter(p -> + // p.getName().contains(Constants.HEAT_FILE_PROPS))).collect(Collectors.toList()); + heatGroups = createdGroups.stream().filter(e -> e.getMembers() != null).collect(Collectors.toList()); + ; + } + for (ArtifactTemplateInfo groupTemplateInfo : artifactsTemplateList) { + String groupName = groupTemplateInfo.getGroupName(); + Set artifactsGroup = new HashSet(); + + log.debug("createDeploymentArtifactsFromCsar start"); + resStatus = createDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, artifactsGroup, groupTemplateInfo, createdArtifacts, labelCounter, shouldLock, inTransaction); + log.debug("createDeploymentArtifactsFromCsar end"); + if (resStatus.isRight()) + return resStatus; + + Map members = new HashMap(); + associateMembersTToArtifacts(createdArtifacts, null, heatGroups, artifactsGroup, members); + + List artifactsList = new ArrayList(artifactsGroup); + + GroupDefinition groupDefinition = new GroupDefinition(); + groupDefinition.setName(groupName); + groupDefinition.setType(Constants.DEFAULT_GROUP_VF_MODULE); + groupDefinition.setArtifacts(artifactsList); + if (!members.isEmpty()) + groupDefinition.setMembers(members); + List properties = new ArrayList(); + GroupProperty prop = new GroupProperty(); + prop.setName(Constants.IS_BASE); + prop.setValue(Boolean.toString(groupTemplateInfo.isBase())); + + properties.add(prop); + groupDefinition.setProperties(properties); + log.debug("createGroup start"); + // Either createGroup = + // groupBusinessLogic.createGroup(resource.getUniqueId(), + // user.getUserId(), ComponentTypeEnum.RESOURCE, groupDefinition, + // inTransaction); + // Ignore validations and get component + + // Since in these groups we handle only artifacts, then no need to + // fetch component instances + ComponentParametersView componentParametersView = new ComponentParametersView(); + componentParametersView.disableAll(); + componentParametersView.setIgnoreUsers(false); + componentParametersView.setIgnoreArtifacts(false); + componentParametersView.setIgnoreGroups(false); + componentParametersView.setIgnoreComponentInstances(false); + Either component = resourceOperation.getComponent(resource.getUniqueId(), componentParametersView, inTransaction); + if (component.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + Either createGroup = groupBusinessLogic.createGroup(component.left().value(), user, ComponentTypeEnum.RESOURCE, groupDefinition, inTransaction); + log.debug("createGroup end"); + if (createGroup.isRight()) + return Either.right(createGroup.right().value()); + + } + return resStatus; + } + + private void associateMembersTToArtifacts(List createdArtifacts, List artifactsFromResource, List heatGroups, Set artifactsGroup, Map members) { + if (heatGroups != null && !heatGroups.isEmpty()) { + for (GroupDefinition heatGroup : heatGroups) { + List grpoupProps = heatGroup.getProperties(); + if (grpoupProps != null) { + Optional op = grpoupProps.stream().filter(p -> p.getName().equals(Constants.HEAT_FILE_PROPS)).findAny(); + if (op.isPresent()) { + GroupProperty prop = op.get(); + String heatFileNAme = prop.getValue(); + if (null == heatFileNAme || heatFileNAme.isEmpty()) + continue; + List artifacts = new ArrayList(); + for (String artifactId : artifactsGroup) { + Optional opArt = createdArtifacts.stream().filter(p -> p.getUniqueId().equals(artifactId)).findAny(); + if (opArt.isPresent()) { + artifacts.add(opArt.get()); + } + if (artifactsFromResource != null) { + opArt = artifactsFromResource.stream().filter(p -> p.getUniqueId().equals(artifactId)).findAny(); + if (opArt.isPresent()) { + artifacts.add(opArt.get()); + } + } + } + Optional resOp = artifacts.stream().filter(p -> heatFileNAme.contains(p.getArtifactName())).findAny(); + if (resOp.isPresent()) { + members.putAll(heatGroup.getMembers()); + } + } + } + } + + } + } + + private Either createDeploymentArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, Set artifactsGroup, ArtifactTemplateInfo artifactTemplateInfo, + List createdArtifacts, int labelCounter, boolean shoudLock, boolean inTransaction) { + Either resStatus = Either.left(resource); + String artifactFileName = artifactTemplateInfo.getFileName(); + String artifactUid = ""; + boolean alreadyExist = false; + + // check if artifacts already exist + for (ArtifactDefinition createdArtifact : createdArtifacts) { + if (createdArtifact.getArtifactName().equals(artifactFileName)) { + artifactUid = createdArtifact.getUniqueId(); + if (!createdArtifact.getArtifactType().equalsIgnoreCase(artifactTemplateInfo.getType())) { + log.debug("Artifact with name {} and type {} already exist with type {}", artifactFileName, artifactTemplateInfo.getType(), createdArtifact.getArtifactType()); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, artifactFileName, artifactTemplateInfo.getType(), createdArtifact.getArtifactType())); + } + alreadyExist = true; + break; + } + + } + // if not exist need to create + if (!alreadyExist) { + + Either newArtifactEither = createDeploymentArtifact(csarUUID, csar, resource, user, artifactTemplateInfo, createdArtifacts, labelCounter, shoudLock, inTransaction); + if (newArtifactEither.isRight()) { + resStatus = Either.right(newArtifactEither.right().value()); + return resStatus; + } + artifactUid = newArtifactEither.left().value().getUniqueId(); + + } + + artifactsGroup.add(artifactUid); + + List relatedArtifacts = artifactTemplateInfo.getRelatedArtifactsInfo(); + if (relatedArtifacts != null) { + for (ArtifactTemplateInfo relatedArtifactTemplateInfo : relatedArtifacts) { + resStatus = createDeploymentArtifactsFromCsar(csarUUID, csar, resource, user, artifactsGroup, relatedArtifactTemplateInfo, createdArtifacts, labelCounter, shoudLock, inTransaction); + if (resStatus.isRight()) + return resStatus; + } + } + return resStatus; + } + + private Either createDeploymentArtifact(String csarUUID, Map csar, Resource resource, User user, ArtifactTemplateInfo artifactTemplateInfo, List createdArtifacts, + int labelCounter, boolean shoudLock, boolean inTransaction) { + String artifactUid; + Either, ResponseFormat> artifactContententStatus = CsarValidationUtils.getArtifactsContent(csarUUID, csar, artifactTemplateInfo.getFileName(), componentsUtils); + if (artifactContententStatus.isRight()) + return Either.right(artifactContententStatus.right().value()); + labelCounter += createdArtifacts.size(); + + Map json = buildJsonForArtifact(artifactTemplateInfo, artifactContententStatus.left().value().getValue(), labelCounter); + + Either, ResponseFormat> uploadArtifactToService = createOrUpdateCsarArtifactFromJson(resource, user, json, ArtifactOperation.Create, shoudLock, inTransaction); + + if (uploadArtifactToService.isRight()) + return Either.right(uploadArtifactToService.right().value()); + + ArtifactDefinition currentInfo = uploadArtifactToService.left().value().left().value(); + if (currentInfo.getHeatParameters() != null) { + + Either updateEnvEither = updateHeatParamsFromCsar(csarUUID, csar, artifactTemplateInfo, currentInfo); + if (updateEnvEither.isRight()) { + log.debug("failed to update parameters to artifact {}", artifactTemplateInfo.getFileName()); + return Either.right(updateEnvEither.right().value()); + + } + artifactUid = updateEnvEither.left().value().getUniqueId(); + createdArtifacts.add(updateEnvEither.left().value()); + currentInfo = updateEnvEither.left().value(); + } else { + + artifactUid = currentInfo.getUniqueId(); + createdArtifacts.add(currentInfo); + + } + return Either.left(currentInfo); + + } + + private Either updateDeploymentArtifactsFromCsar(String csarUUID, Map csar, Resource resource, User user, ArtifactDefinition oldArtifact, ArtifactTemplateInfo artifactTemplateInfo, + List updatedArtifacts, List updatedRequiredArtifacts, boolean shouldLock, boolean inTransaction) { + + Either resStatus = null; + String artifactFileName = artifactTemplateInfo.getFileName(); + String artifactUid = ""; + + // check if artifacts already exist + for (ArtifactDefinition updatedArtifact : updatedArtifacts) { + if (updatedArtifact.getArtifactName().equals(artifactFileName)) { + artifactUid = updatedArtifact.getUniqueId(); + if (!updatedArtifact.getArtifactType().equalsIgnoreCase(artifactTemplateInfo.getType())) { + log.debug("Artifact with name {} and type {} already updated with type {}", artifactFileName, artifactTemplateInfo.getType(), updatedArtifact.getArtifactType()); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + resStatus = Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR, artifactFileName, artifactTemplateInfo.getType(), updatedArtifact.getArtifactType())); + return resStatus; + } + resStatus = Either.left(updatedArtifact); + return resStatus; + } + + } + + Either, ResponseFormat> artifactContententStatus = CsarValidationUtils.getArtifactsContent(csarUUID, csar, artifactTemplateInfo.getFileName(), componentsUtils); + if (artifactContententStatus.isRight()) { + resStatus = Either.right(artifactContententStatus.right().value()); + return resStatus; + } + + Map json = buildJsonForUpdateArtifact(oldArtifact.getUniqueId(), artifactFileName, oldArtifact.getArtifactType(), oldArtifact.getArtifactLabel(), oldArtifact.getArtifactDisplayName(), oldArtifact.getDescription(), + artifactContententStatus.left().value().getRight(), updatedRequiredArtifacts); + Either, ResponseFormat> uploadArtifactToService = createOrUpdateCsarArtifactFromJson(resource, user, json, ArtifactOperation.Update, shouldLock, inTransaction); + + if (uploadArtifactToService.isRight()) { + resStatus = Either.right(uploadArtifactToService.right().value()); + return resStatus; + } + ArtifactDefinition currentInfo = uploadArtifactToService.left().value().left().value(); + + Either updateEnvEither = updateHeatParamsFromCsar(csarUUID, csar, artifactTemplateInfo, currentInfo); + if (updateEnvEither.isRight()) { + log.debug("failed to update parameters to artifact {}", artifactFileName); + resStatus = Either.right(updateEnvEither.right().value()); + return resStatus; + } + + artifactUid = updateEnvEither.left().value().getUniqueId(); + updatedArtifacts.add(updateEnvEither.left().value()); + resStatus = Either.left(updateEnvEither.left().value()); + + return resStatus; + + } + + private Either updateHeatParamsFromCsar(String csarUUID, Map csar, ArtifactTemplateInfo artifactTemplateInfo, ArtifactDefinition currentInfo) { + Either resStatus = Either.left(currentInfo); + if (artifactTemplateInfo.getEnv() != null && !artifactTemplateInfo.getEnv().isEmpty()) { + + Either, ResponseFormat> artifactparamsStatus = CsarValidationUtils.getArtifactsContent(csarUUID, csar, artifactTemplateInfo.getEnv(), componentsUtils); + if (artifactparamsStatus.isRight()) { + resStatus = Either.right(artifactparamsStatus.right().value()); + return resStatus; + } + Either, ResponseFormat> propsStatus = extractHeatParameters(ArtifactTypeEnum.HEAT_ENV.getType(), artifactTemplateInfo.getEnv(), artifactparamsStatus.left().value().getValue()); + if (propsStatus.isRight()) { + + resStatus = Either.right(propsStatus.right().value()); + return resStatus; + } + List updatedHeatEnvParams = propsStatus.left().value(); + List currentHeatEnvParams = currentInfo.getHeatParameters(); + List newHeatEnvParams = new ArrayList(); + + if (updatedHeatEnvParams != null && !updatedHeatEnvParams.isEmpty() && currentHeatEnvParams != null && !currentHeatEnvParams.isEmpty()) { + + String paramName; + for (HeatParameterDefinition heatEnvParam : updatedHeatEnvParams) { + + paramName = heatEnvParam.getName(); + for (HeatParameterDefinition currHeatParam : currentHeatEnvParams) { + if (paramName.equalsIgnoreCase(currHeatParam.getName())) { + + String updatedParamValue = heatEnvParam.getCurrentValue(); + if (updatedParamValue == null) + updatedParamValue = heatEnvParam.getDefaultValue(); + HeatParameterType paramType = HeatParameterType.isValidType(currHeatParam.getType()); + if (!paramType.getValidator().isValid(updatedParamValue, null)) { + ActionStatus status = ActionStatus.INVALID_HEAT_PARAMETER_VALUE; + ResponseFormat responseFormat = componentsUtils.getResponseFormat(status, ArtifactTypeEnum.HEAT_ENV.getType(), paramType.getType(), paramName); + resStatus = Either.right(responseFormat); + return resStatus; + } + currHeatParam.setCurrentValue(paramType.getConverter().convert(updatedParamValue, null, null)); + newHeatEnvParams.add(currHeatParam); + break; + } + } + } + if (!newHeatEnvParams.isEmpty()) { + StorageOperationStatus operationStatus = heatParametersOperation.updateHeatParameters(currentHeatEnvParams); + + if (operationStatus != StorageOperationStatus.OK) { + log.debug("Failed to update artifact on graph - {}", currentInfo.getUniqueId()); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(operationStatus)); + resStatus = Either.right(responseFormat); + return resStatus; + } + } + } + + } + return resStatus; + } + + private Either, ResponseFormat> extractHeatParameters(String artifactType, String fileName, byte[] content) { + // extract heat parameters + String heatDecodedPayload = GeneralUtility.isBase64Encoded(content) ? new String(Base64.decodeBase64(content)) : new String(content); + Either, ResultStatusEnum> heatParameters = ImportUtils.getHeatParamsWithoutImplicitTypes(heatDecodedPayload, artifactType); + if (heatParameters.isRight()) { + log.debug("File {} is not in expected key-value form in csar ", fileName); + BeEcompErrorManager.getInstance().logInternalDataError("File " + fileName + " is not in expected key-value form in csar ", "CSAR internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_DEPLOYMENT_ARTIFACT_HEAT, fileName)); + + } + return Either.left(heatParameters.left().value()); + + } + + private Map buildJsonForArtifact(ArtifactTemplateInfo artifactTemplateInfo, byte[] artifactContentent, int atrifactLabelCounter) { + + Map json = new HashMap(); + String artifactName = artifactTemplateInfo.getFileName(); + + json.put(Constants.ARTIFACT_NAME, artifactTemplateInfo.getFileName()); + json.put(Constants.ARTIFACT_TYPE, artifactTemplateInfo.getType()); + json.put(Constants.ARTIFACT_DESCRIPTION, "created from csar"); + + /* + * DE250204 + * There is no need to check if base64 encoding. All files that are inside the CSAR are not encoded and need to encoded. The check for isBase64 is not in cases we get files with extension .cert or .key these files are base64 but if do not + * encode them again, when the user download them, the decoded file will return not the encoded file that was upload. + */ + // String encodedPayload = new String(artifactContentent); + // boolean isEncoded = GeneralUtility.isBase64Encoded(artifactContentent); + // if (!isEncoded) { + // log.debug("payload is encoded. perform decode"); + String encodedPayload = Base64.encodeBase64String(artifactContentent); + // } + json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload); + String displayName = artifactName; + if (artifactName.lastIndexOf(".") > 0) + displayName = artifactName.substring(0, artifactName.lastIndexOf(".")); + json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName); + String label = ValidationUtils.normalizeArtifactLabel(artifactTemplateInfo.getType() + atrifactLabelCounter); + json.put(Constants.ARTIFACT_LABEL, label); + json.put(Constants.ARTIFACT_GROUP_TYPE, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + List requiredArtifacts = artifactTemplateInfo.getRelatedArtifactsInfo(); + json.put(Constants.REQUIRED_ARTIFACTS, (requiredArtifacts == null || requiredArtifacts.isEmpty()) ? new ArrayList<>() + : requiredArtifacts.stream().filter(e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType())).map(e -> e.getFileName()).collect(Collectors.toList())); + return json; + } + + private Map buildJsonForUpdateArtifact(String artifactId, String artifactName, String artifactType, String label, String displayName, String description, byte[] artifactContentent, + List updatedRequiredArtifacts) { + + Map json = new HashMap(); + if (artifactId != null && !artifactId.isEmpty()) + json.put(Constants.ARTIFACT_ID, artifactId); + + json.put(Constants.ARTIFACT_NAME, artifactName); + json.put(Constants.ARTIFACT_TYPE, artifactType); + json.put(Constants.ARTIFACT_DESCRIPTION, description); + + String encodedPayload = new String(artifactContentent); + // DE250204 - need to encode all. + //boolean isEncoded = GeneralUtility.isBase64Encoded(artifactContentent); + //if (!isEncoded) { + log.debug("payload is encoded. perform decode"); + encodedPayload = Base64.encodeBase64String(artifactContentent); + //} + + json.put(Constants.ARTIFACT_PAYLOAD_DATA, encodedPayload); + json.put(Constants.ARTIFACT_DISPLAY_NAME, displayName); + json.put(Constants.ARTIFACT_LABEL, label); + json.put(Constants.ARTIFACT_GROUP_TYPE, ArtifactGroupTypeEnum.DEPLOYMENT.getType()); + json.put(Constants.REQUIRED_ARTIFACTS, (updatedRequiredArtifacts == null || updatedRequiredArtifacts.isEmpty()) ? new ArrayList<>() + : updatedRequiredArtifacts.stream().filter(e -> e.getType().equals(ArtifactTypeEnum.HEAT_ARTIFACT.getType()) || e.getType().equals(ArtifactTypeEnum.HEAT_NESTED.getType())).map(e -> e.getFileName()).collect(Collectors.toList())); + return json; + } + + private Either>, ResponseFormat> parseResourceArtifactsInfoFromFile(Resource resource, String artifactsMetaFile, String artifactFileName, User user) { + + try { + JsonObject jsonElement = new JsonObject(); + jsonElement = gson.fromJson(artifactsMetaFile, jsonElement.getClass()); + + JsonElement importStructureElement = jsonElement.get(Constants.IMPORT_STRUCTURE); + if (importStructureElement == null || importStructureElement.isJsonNull()) { + log.debug("Artifact file is not in expected formatr, fileName {}", artifactFileName); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, artifactFileName)); + } + + Map>> artifactTemplateMap = new HashMap>>(); + artifactTemplateMap = componentsUtils.parseJsonToObject(importStructureElement.toString(), HashMap.class); + if (artifactTemplateMap.isEmpty()) { + log.debug("Artifact file is not in expected formatr, fileName {}", artifactFileName); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected formatr, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, artifactFileName)); + } + + Set artifactsTypeKeys = artifactTemplateMap.keySet(); + Map> artifactsMap = new HashMap>(); + List allGroups = new ArrayList<>(); + for (String artifactsTypeKey : artifactsTypeKeys) { + + List> o = artifactTemplateMap.get(artifactsTypeKey); + Either, ResponseFormat> artifactTemplateInfoListPairStatus = createArtifactTemplateInfoModule(artifactsTypeKey, o); + if (artifactTemplateInfoListPairStatus.isRight()) { + log.debug("Artifact file is not in expected formatr, fileName {}", artifactFileName); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected format, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(artifactTemplateInfoListPairStatus.right().value()); + } + List artifactTemplateInfoList = artifactTemplateInfoListPairStatus.left().value(); + if (artifactTemplateInfoList == null) { + log.debug("Artifact file is not in expected formatr, fileName {}", artifactFileName); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected format, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, artifactFileName)); + + } + allGroups.addAll(artifactTemplateInfoList); + artifactsMap.put(artifactsTypeKey, artifactTemplateInfoList); + } + int counter = groupBusinessLogic.getNextVfModuleNameCounter(resource.getGroups()); + Either validateGroupNamesRes = groupBusinessLogic.validateGenerateVfModuleGroupNames(allGroups, resource.getSystemName(), counter); + if (validateGroupNamesRes.isRight()) { + return Either.right(validateGroupNamesRes.right().value()); + } + return Either.left(artifactsMap); + } catch (Exception e) { + log.debug("Artifact file is not in expected format, fileName {}", artifactFileName); + log.debug("failed with exception.", e); + BeEcompErrorManager.getInstance().logInternalDataError("Artifact file is not in expected format, fileName " + artifactFileName, "Artifact internals are invalid", ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID_FORMAT, artifactFileName)); + } + + } + + private Either, ResponseFormat> createArtifactTemplateInfoModule(String artifactsTypeKey, List> jsonObject) { + List artifactTemplateInfoList = new ArrayList(); + for (Map o : jsonObject) { + Either artifacttemplateInfoStatus = ArtifactTemplateInfo.createArtifactTemplateInfoFromJson(componentsUtils, artifactsTypeKey, o, artifactTemplateInfoList, null); + if (artifacttemplateInfoStatus.isRight()) { + return Either.right(artifacttemplateInfoStatus.right().value()); + } + + ArtifactTemplateInfo artifacttemplateInfo = artifacttemplateInfoStatus.left().value(); + if (artifacttemplateInfo != null) { + artifactTemplateInfoList.add(artifacttemplateInfo); + } + + } + return Either.left(artifactTemplateInfoList); + } + + private Either createResourceInstancesRelations(User user, String yamlName, Resource resource, Map uploadResInstancesMap, boolean inTransaction, boolean needLock) { + log.debug("createResourceInstancesRelations try to create relations "); + List componentInstancesList = resource.getComponentInstances(); + if (uploadResInstancesMap == null) { + log.debug("UploadComponentInstanceInfo is empty, fileName {}", yamlName); + BeEcompErrorManager.getInstance().logInternalDataError("UploadComponentInstanceInfo is emty, fileName {}", yamlName, ErrorSeverity.ERROR); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName); + return Either.right(responseFormat); + } + + if (componentInstancesList == null || componentInstancesList.isEmpty()) { + log.debug("componentInstancesList is empty in resource {} ", resource.getUniqueId()); + BeEcompErrorManager.getInstance().logInternalDataError("componentInstancesList is empty in resource {} ", resource.getUniqueId(), ErrorSeverity.ERROR); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName); + return Either.right(responseFormat); + } + + Map> propertiesListPerResource = new HashMap<>(); + + long totalCreateRel = 0; + long totalCreatePropVal = 0; + Iterator> nodesInfoValue = uploadResInstancesMap.entrySet().iterator(); + while (nodesInfoValue.hasNext()) { + Entry uploadComponentInstanceInfoEntry = nodesInfoValue.next(); + UploadComponentInstanceInfo uploadComponentInstanceInfo = uploadComponentInstanceInfoEntry.getValue(); + + ComponentInstance currentCompInstance = null; + for (ComponentInstance compInstance : componentInstancesList) { + if (compInstance.getName().equals(uploadComponentInstanceInfo.getName())) { + currentCompInstance = compInstance; + break; + } + } + + if (currentCompInstance == null) { + log.debug("component instance with name {} in resource {} ", uploadComponentInstanceInfo.getName(), resource.getUniqueId()); + BeEcompErrorManager.getInstance().logInternalDataError("component instance with name " + uploadComponentInstanceInfo.getName() + " in resource {} ", resource.getUniqueId(), ErrorSeverity.ERROR); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName); + return Either.right(responseFormat); + } + String resourceInstanceId = currentCompInstance.getUniqueId(); + + log.debug("************* addPropertyValuesToRi start"); + long startAddProperty = System.currentTimeMillis(); + + ResponseFormat addPropertiesValueToRiRes = addPropertyValuesToRi(uploadComponentInstanceInfo, resource, resourceInstanceId, currentCompInstance, yamlName, propertiesListPerResource); + log.debug("************* addPropertyValuesToRi end"); + totalCreatePropVal += (System.currentTimeMillis() - startAddProperty); + + if (addPropertiesValueToRiRes.getStatus() != 200) { + return Either.right(addPropertiesValueToRiRes); + } + Map> regMap = uploadComponentInstanceInfo.getRequirements(); + if (regMap == null) + continue; + Iterator>> nodesRegValue = regMap.entrySet().iterator(); + + long startAddRelation = System.currentTimeMillis(); + + while (nodesRegValue.hasNext()) { + Entry> nodesRegInfoEntry = nodesRegValue.next(); + + List uploadRegInfoList = nodesRegInfoEntry.getValue(); + for (UploadReqInfo uploadRegInfo : uploadRegInfoList) { + log.debug("Going to create relation {}", uploadRegInfo.getName()); + String regName = uploadRegInfo.getName(); + String nodeCapName = uploadRegInfo.getNode(); + RequirementCapabilityRelDef regCapRelDef = new RequirementCapabilityRelDef(); + regCapRelDef.setFromNode(resourceInstanceId); + log.debug("try to find available requirement {} ", regName); + Either eitherReqStatus = findAviableRequiremen(regName, yamlName, uploadComponentInstanceInfo, currentCompInstance); + if (eitherReqStatus.isRight()) { + log.debug("failed to find available requirement {} status is {}", regName, eitherReqStatus.right().value()); + return Either.right(eitherReqStatus.right().value()); + } + + RequirementDefinition validReq = eitherReqStatus.left().value(); + List reqAndRelationshipPairList = regCapRelDef.getRelationships(); + if (reqAndRelationshipPairList == null) + reqAndRelationshipPairList = new ArrayList(); + RequirementAndRelationshipPair reqAndRelationshipPair = new RequirementAndRelationshipPair(); + reqAndRelationshipPair.setRequirement(regName); + reqAndRelationshipPair.setRequirementOwnerId(validReq.getOwnerId()); + reqAndRelationshipPair.setRequirementUid(validReq.getUniqueId()); + + ComponentInstance currentCapCompInstance = null; + for (ComponentInstance compInstance : componentInstancesList) { + if (compInstance.getName().equals(uploadRegInfo.getNode())) { + currentCapCompInstance = compInstance; + break; + } + } + + if (currentCapCompInstance == null) { + log.debug("component instance with name {} in resource {} ", uploadRegInfo.getNode(), resource.getUniqueId()); + BeEcompErrorManager.getInstance().logInternalDataError("component instance with name " + uploadRegInfo.getNode() + " in resource {} ", resource.getUniqueId(), ErrorSeverity.ERROR); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName); + return Either.right(responseFormat); + } + regCapRelDef.setToNode(currentCapCompInstance.getUniqueId()); + log.debug("try to find aviable Capability req name is {} ", validReq.getName()); + CapabilityDefinition aviableCapForRel = findAvailableCapabilityByTypeOrName(validReq, currentCapCompInstance, uploadRegInfo); + if (aviableCapForRel == null) { + log.debug("aviable capability was not found. req name is {} component instance is {}", validReq.getName(), currentCapCompInstance.getUniqueId()); + BeEcompErrorManager.getInstance().logInternalDataError("aviable capability was not found. req name is " + validReq.getName() + " component instance is " + currentCapCompInstance.getUniqueId(), resource.getUniqueId(), + ErrorSeverity.ERROR); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlName); + return Either.right(responseFormat); + } + reqAndRelationshipPair.setCapability(aviableCapForRel.getName()); + reqAndRelationshipPair.setCapabilityUid(aviableCapForRel.getUniqueId()); + reqAndRelationshipPair.setCapabilityOwnerId(aviableCapForRel.getOwnerId()); + reqAndRelationshipPairList.add(reqAndRelationshipPair); + regCapRelDef.setRelationships(reqAndRelationshipPairList); + ComponentInstanceBusinessLogic componentInstanceBL = getComponentInstanceBL(); + Either eitherRelationRes = componentInstanceBL.associateRIToRIOnGraph(resource.getUniqueId(), regCapRelDef, ComponentTypeEnum.RESOURCE, inTransaction); + log.debug("************* finished to create relation {}", uploadRegInfo.getName()); + if (eitherRelationRes.isRight()) { + log.debug("failed to associate ri {} to ri {}", regCapRelDef.getFromNode(), regCapRelDef.getToNode()); + return Either.right(eitherRelationRes.right().value()); + } + + } + + } + totalCreateRel += (System.currentTimeMillis() - startAddRelation); + } + /* + * List inputs = resource.getInputs(); for(InputDefinition input: inputs){ if(input.getProperties() != null){ this.inputOperation.associatePropertiesToInputOnGraph(input. getUniqueId(), input.getProperties()); } } + */ + + // Either eitherGerResource = + // resourceOperation.getResource(resource.getUniqueId(), inTransaction); + log.debug("************* create relations took : create {}, add property value {}", totalCreateRel, totalCreatePropVal); + log.debug("************* in create relations, getResource start"); + ComponentParametersView parametersView = new ComponentParametersView(); + parametersView.disableAll(); + parametersView.setIgnoreComponentInstances(false); + parametersView.setIgnoreUsers(false); + parametersView.setIgnoreArtifacts(false); + parametersView.setIgnoreGroups(false); + Either eitherGerResource = resourceOperation.getComponent(resource.getUniqueId(), parametersView, inTransaction); + log.debug("************* in create relations, getResource end"); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + return Either.left(eitherGerResource.left().value()); + } + + private ResponseFormat addPropertyValuesToRi(UploadComponentInstanceInfo uploadComponentInstanceInfo, Resource resource, String resourceInstanceId, ComponentInstance currentCompInstance, String yamlName, + Map> propertiesListPerResource) { + + Map> propMap = uploadComponentInstanceInfo.getProperties(); + if (propMap != null && propMap.size() > 0) { + Map currPropertiesMap = new HashMap(); + List propertiesList = new ArrayList(); + Integer index = currentCompInstance.getPropertyValueCounter(); + Integer indexInput = currentCompInstance.getInputValueCounter(); + List listFromMap = propertiesListPerResource.get(currentCompInstance.getComponentUid()); + if (listFromMap != null) { + propertiesList = listFromMap; + } else { + TitanOperationStatus getPropertyRes = ((PropertyOperation) propertyOperation).findAllResourcePropertiesRecursively(currentCompInstance.getComponentUid(), propertiesList); + if (!getPropertyRes.equals(TitanOperationStatus.OK)) { + log.debug("failed to find properties of resource {} status is {}", currentCompInstance.getComponentUid(), getPropertyRes); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(getPropertyRes)), yamlName); + return responseFormat; + } + propertiesListPerResource.put(currentCompInstance.getComponentUid(), propertiesList); + } + if (propertiesList.size() > 0) { + for (PropertyDefinition prop : propertiesList) { + String propName = prop.getName(); + if (!currPropertiesMap.containsKey(propName)) { + currPropertiesMap.put(propName, prop); + } + } + for (List propertyList : propMap.values()) { + UploadPropInfo propertyInfo = propertyList.get(0); + String propName = propertyInfo.getName(); + if (!currPropertiesMap.containsKey(propName)) { + log.debug("failed to find property {} ", propName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND, propName); + return responseFormat; + } + PropertyDefinition curPropertyDef = currPropertiesMap.get(propName); + ComponentInstanceProperty property = null; + ComponentInstanceInput inputValue = null; + // TODO + String value = null; + List getInputs = null; + boolean isValidate = true; + if (propertyInfo.getValue() != null) { + getInputs = propertyInfo.getGet_input(); + isValidate = getInputs == null || getInputs.isEmpty(); + if (isValidate) { + value = ImportUtils.getPropertyJsonStringValue(propertyInfo.getValue(), curPropertyDef.getType()); + } else + value = ImportUtils.getPropertyJsonStringValue(propertyInfo.getValue(), ToscaTagNamesEnum.GET_INPUT.getElementName()); + } + + property = new ComponentInstanceProperty(curPropertyDef, value, null); + + Either result = componentInstanceOperation.addPropertyValueToResourceInstance(property, resourceInstanceId, isValidate, index, true); + if (result.isRight()) { + log.debug("Failed to add property value {} to resource instance {}", property, resourceInstanceId); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(result.right().value()); + return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, currentCompInstance.getName()); + } + Either increaseCounterRes = componentInstanceOperation.increaseAndGetResourceInstanceSpecificCounter(resourceInstanceId, GraphPropertiesDictionary.PROPERTY_COUNTER, true); + if (increaseCounterRes.isRight()) { + log.debug("Failed to increase resource property counter {} to resource instance {}", property, resourceInstanceId); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponseForResourceInstanceProperty(increaseCounterRes.right().value()); + return componentsUtils.getResponseFormatForResourceInstanceProperty(actionStatus, currentCompInstance.getName()); + } + index = increaseCounterRes.left().value(); + if (getInputs != null && !getInputs.isEmpty()) { + for (GetInputValueInfo getInput : getInputs) { + List inputs = resource.getInputs(); + if (inputs == null || inputs.isEmpty()) { + log.debug("Failed to add property {} to resource instance {}. Inputs list is empty ", property, resourceInstanceId); + return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + } + + Optional optional = inputs.stream().filter(p -> p.getName().equals(getInput.getInputName())).findAny(); + if (!optional.isPresent()) { + log.debug("Failed to find input {} ", getInput.getInputName()); + // @@TODO error message + return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + } + InputDefinition input = optional.get(); + TitanOperationStatus status = inputOperation.associatePropertyToInput(resourceInstanceId, input.getUniqueId(), result.left().value(), getInput); + if (status != TitanOperationStatus.OK) { + log.debug("Failed to associate input {} tp property value{} ", getInput.getInputName(), result.left().value().getValueUniqueUid()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status)), yamlName); + return responseFormat; + } + GetInputValueInfo getInputIndex = getInput.getGetInputIndex(); + if (getInputIndex != null) { + optional = inputs.stream().filter(p -> p.getName().equals(getInputIndex.getInputName())).findAny(); + if (!optional.isPresent()) { + log.debug("Failed to find input {} ", getInputIndex.getInputName()); + // @@TODO error message + return componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + } + InputDefinition inputIndex = optional.get(); + status = inputOperation.associatePropertyToInput(resourceInstanceId, inputIndex.getUniqueId(), result.left().value(), getInputIndex); + if (status != TitanOperationStatus.OK) { + log.debug("Failed to associate input {} tp property value{} ", getInput.getInputName(), result.left().value().getValueUniqueUid()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(DaoStatusConverter.convertTitanStatusToStorageStatus(status)), yamlName); + return responseFormat; + } + + } + + } + } + + } + } + } + return componentsUtils.getResponseFormat(ActionStatus.OK); + } + + // US740820 Relate RIs according to capability name + private CapabilityDefinition findAvailableCapabilityByTypeOrName(RequirementDefinition validReq, ComponentInstance currentCapCompInstance, UploadReqInfo uploadReqInfo) { + if (null == uploadReqInfo.getCapabilityName() || validReq.getCapability().equals(uploadReqInfo.getCapabilityName())) {// get + // by + // capability + // type + return findAviableCapability(validReq, currentCapCompInstance); + } + return findAvailableCapability(validReq, currentCapCompInstance, uploadReqInfo); + } + + private CapabilityDefinition findAvailableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance, UploadReqInfo uploadReqInfo) { + Map> capMap = currentCapCompInstance.getCapabilities(); + if (!capMap.containsKey(validReq.getCapability())) { + return null; + } + Optional capByName = capMap.get(validReq.getCapability()).stream().filter(p -> p.getName().equals(uploadReqInfo.getCapabilityName())).findAny(); + if (!capByName.isPresent()) { + return null; + } + CapabilityDefinition cap = capByName.get(); + // TODO temporary fix - remove specific capability node validation - + // String reqNode = validReq.getNode(); + // if (reqNode != null && !reqNode.isEmpty() && + // !cap.getCapabilitySources().contains(reqNode)) { + // return null; + // } + RequirementAndRelationshipPair relationPair = getReqRelPair(cap); + Either eitherStatus = componentInstanceOperation.isAvailableCapabilty(currentCapCompInstance, relationPair); + if (eitherStatus.isRight() || eitherStatus.left().value() == false) { + return null; + } + return cap; + } + + private RequirementAndRelationshipPair getReqRelPair(CapabilityDefinition cap) { + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setCapabilityUid(cap.getUniqueId()); + relationPair.setCapability(cap.getName()); + relationPair.setCapabilityOwnerId(cap.getOwnerId()); + return relationPair; + } + + private CapabilityDefinition findAviableCapability(RequirementDefinition validReq, ComponentInstance currentCapCompInstance) { + CapabilityDefinition aviableCapForRel = null; + Map> capMap = currentCapCompInstance.getCapabilities(); + if (capMap.containsKey(validReq.getCapability())) { + List capList = capMap.get(validReq.getCapability()); + + for (CapabilityDefinition cap : capList) { + // TODO temporary fix - remove specific capability node + // String reqNode = validReq.getNode(); + // if (reqNode != null && !reqNode.isEmpty()) { + // if (!cap.getCapabilitySources().contains(reqNode)) { + // continue; + // } + // } + + RequirementAndRelationshipPair relationPair = getReqRelPair(cap); + Either eitherStatus = componentInstanceOperation.isAvailableCapabilty(currentCapCompInstance, relationPair); + if (eitherStatus.isRight() || eitherStatus.left().value() == false) + continue; + else { + aviableCapForRel = cap; + break; + } + } + } + return aviableCapForRel; + } + + private Either findAviableRequiremen(String regName, String yamlName, UploadComponentInstanceInfo uploadComponentInstanceInfo, ComponentInstance currentCompInstance) { + Map> comInstRegDefMap = currentCompInstance.getRequirements(); + + Iterator>> regListValue = comInstRegDefMap.entrySet().iterator(); + RequirementDefinition validRegDef = null; + while (regListValue.hasNext()) { + Entry> regInfoEntry = regListValue.next(); + + List comInstRegDefList = regInfoEntry.getValue(); + + for (RequirementDefinition comInstRegDef : comInstRegDefList) { + if (!regName.equals(comInstRegDef.getName())) + continue; + RequirementAndRelationshipPair relationPair = new RequirementAndRelationshipPair(); + relationPair.setRequirementUid(comInstRegDef.getUniqueId()); + relationPair.setCapability(comInstRegDef.getCapability()); + relationPair.setRequirementOwnerId(comInstRegDef.getOwnerId()); + Either eitherStatus = componentInstanceOperation.isAvailableRequirement(currentCompInstance, relationPair); + if (eitherStatus.isLeft() && eitherStatus.left().value() == true) { + validRegDef = comInstRegDef; + break; + } + } + if (validRegDef != null) + break; + } + + if (validRegDef == null) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(responseFormat); + } + return Either.left(validRegDef); + } + + public Either parseResourceInfoFromYaml(String yamlFileName, Resource resource, String resourceYml, User user) { + + Map mappedToscaTemplate = (Map) new Yaml().load(resourceYml); + Either toscaElementEither = ImportUtils.findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL); + if (toscaElementEither.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); + return Either.right(responseFormat); + } + + Either, ResponseFormat> createInputsEither = createInputsFromYaml(yamlFileName, mappedToscaTemplate, resource); + if (createInputsEither.isRight()) { + ResponseFormat responseFormat = createInputsEither.right().value(); + return Either.right(responseFormat); + } + + Either, ResponseFormat> uploadResInstancesEither = createResourcesInstanceInfoFromYaml(yamlFileName, mappedToscaTemplate, resource); + if (uploadResInstancesEither.isRight()) { + ResponseFormat responseFormat = uploadResInstancesEither.right().value(); + return Either.right(responseFormat); + } + + Either, ResponseFormat> createGroupsFromYaml = createGroupsFromYaml(yamlFileName, mappedToscaTemplate, resource); + if (createGroupsFromYaml.isRight()) { + ResponseFormat responseFormat = createGroupsFromYaml.right().value(); + return Either.right(responseFormat); + } + + ParsedToscaYamlInfo parsedToscaYamlInfo = new ParsedToscaYamlInfo(); + parsedToscaYamlInfo.setInputs(createInputsEither.left().value()); + parsedToscaYamlInfo.setInstances(uploadResInstancesEither.left().value()); + parsedToscaYamlInfo.setGroups(createGroupsFromYaml.left().value()); + + return Either.left(parsedToscaYamlInfo); + } + + private Either createResourceInstances(User user, String yamlName, Resource resource, Map uploadResInstancesMap, boolean inTransaction, boolean needLock, + Map nodeTypeNamespaceMap) { + log.debug("createResourceInstances is {} - going to create resource instanse from CSAR", yamlName); + if (uploadResInstancesMap == null || uploadResInstancesMap.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); + + return Either.right(responseFormat); + + } + Map existingnodeTypeMap = new HashMap(); + if (nodeTypeNamespaceMap != null && !nodeTypeNamespaceMap.isEmpty()) { + nodeTypeNamespaceMap.entrySet().stream().forEach(x -> existingnodeTypeMap.put(x.getValue().getToscaResourceName(), x.getValue())); + } + + Iterator> nodesInfoValue = uploadResInstancesMap.entrySet().iterator(); + while (nodesInfoValue.hasNext()) { + log.debug("*************Going to create resource instances {}", yamlName); + Entry uploadComponentInstanceInfoEntry = nodesInfoValue.next(); + UploadComponentInstanceInfo uploadComponentInstanceInfo = uploadComponentInstanceInfoEntry.getValue(); + + // updating type if the type is node type name - we need to take the + // updated name + log.debug("*************Going to create resource instances {}", uploadComponentInstanceInfo.getName()); + if (nodeTypeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) { + uploadComponentInstanceInfo.setType(nodeTypeNamespaceMap.get(uploadComponentInstanceInfo.getType()).getToscaResourceName()); + } + + Either eitherResource = validateResourceInstanceBeforeCreate(yamlName, inTransaction, uploadComponentInstanceInfo, existingnodeTypeMap); + if (eitherResource.isRight()) { + return eitherResource; + } + Resource refResource = eitherResource.left().value(); + + ComponentInstance componentInstance = new ComponentInstance(); + + componentInstance.setName(uploadComponentInstanceInfo.getName()); + componentInstance.setComponentUid(refResource.getUniqueId()); + + ComponentTypeEnum containerComponentType = resource.getComponentType(); + NodeTypeEnum containerNodeType = containerComponentType.getNodeType(); + + if (containerNodeType.equals(NodeTypeEnum.Resource) && uploadComponentInstanceInfo.getCapabilities() != null) { + Either>, ResponseFormat> getValidComponentInstanceCapabilitiesRes = getValidComponentInstanceCapabilities(refResource.getCapabilities(), uploadComponentInstanceInfo.getCapabilities()); + if (getValidComponentInstanceCapabilitiesRes.isRight()) { + return Either.right(getValidComponentInstanceCapabilitiesRes.right().value()); + } else { + componentInstance.setCapabilities(getValidComponentInstanceCapabilitiesRes.left().value()); + } + } + if (!existingnodeTypeMap.containsKey(uploadComponentInstanceInfo.getType())) { + log.debug("createResourceInstances - not found lates version for resource instance with name {} and type ", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(responseFormat); + } + Resource origResource = existingnodeTypeMap.get(uploadComponentInstanceInfo.getType()); + ComponentInstanceBusinessLogic componentInstanceBL = getComponentInstanceBL(); + Either eitherCreateCI = componentInstanceBL.createComponentInstanceOnGraph(ComponentTypeEnum.RESOURCE_PARAM_NAME, resource, origResource, componentInstance, user.getUserId(), needLock, inTransaction); + if (eitherCreateCI.isRight()) { + log.debug("createResourceInstances - failed to create resource instance with name {} and type ", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(eitherCreateCI.right().value()); + } + + ComponentInstance createdCI = eitherCreateCI.left().value(); + createdCI.setName(uploadComponentInstanceInfo.getName()); + /* + * updateComponentInstance(String containerComponentParam, org.openecomp.sdc.be.model.Component containerComponent, String componentInstanceId, ComponentInstance componentInstance, boolean inTransaction, boolean needLock) + */ + eitherCreateCI = componentInstanceBL.updateComponentInstance(ComponentTypeEnum.RESOURCE_PARAM_NAME, resource, origResource, createdCI.getUniqueId(), createdCI, needLock, inTransaction); + if (eitherCreateCI.isRight()) { + log.debug("createResourceInstances - failed to update resource instance with name {} and type ", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(eitherCreateCI.right().value()); + } + log.debug("*************finished to create and update resource instances {}", uploadComponentInstanceInfo.getName()); + + } + log.debug("*************Going to get resource {}", resource.getUniqueId()); + ComponentParametersView parametersView = new ComponentParametersView(); + parametersView.disableAll(); + parametersView.setIgnoreComponentInstances(false); + parametersView.setIgnoreUsers(false); + parametersView.setIgnoreInputs(false); // inputs are read when creating + // property values on instances + Either eitherGerResource = resourceOperation.getComponent(resource.getUniqueId(), parametersView, inTransaction); + log.debug("*************finished to get resource {}", resource.getUniqueId()); + if (eitherGerResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(eitherGerResource.right().value()), resource); + + return Either.right(responseFormat); + + } + + if (eitherGerResource.left().value().getComponentInstances() == null || eitherGerResource.left().value().getComponentInstances().isEmpty()) { + + log.debug("Error when create resource inctanse from csar. ComponentInstances list empty"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Error when create resource inctanse from csar. ComponentInstances list empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); + return Either.right(responseFormat); + + } + + return Either.left(eitherGerResource.left().value()); + } + + private Either validateResourceInstanceBeforeCreate(String yamlName, boolean inTransaction, UploadComponentInstanceInfo uploadComponentInstanceInfo, Map nodeTypeNamespaceMap) { + log.debug("validateResourceInstanceBeforeCreate - going to validate resource instance with name {} and type before create", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + Resource refResource = null; + if (nodeTypeNamespaceMap.containsKey(uploadComponentInstanceInfo.getType())) { + refResource = nodeTypeNamespaceMap.get(uploadComponentInstanceInfo.getType()); + } else { + + Either eithervalidateResource = resourceOperation.validateToscaResourceNameExists(uploadComponentInstanceInfo.getType()); + if ((eithervalidateResource.isRight() && eithervalidateResource.right().value() == StorageOperationStatus.NOT_FOUND) || eithervalidateResource.left().value() == true) { + log.debug("validateResourceInstanceBeforeCreate - resource instance with name {} and type not valid", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(responseFormat); + } + Either findResourceEither = resourceOperation.getLatestCertifiedByToscaResourceName(uploadComponentInstanceInfo.getType(), inTransaction); + if (findResourceEither.isRight()) { + log.debug("validateResourceInstanceBeforeCreate - not found lates version for resource instance with name {} and type ", uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findResourceEither.right().value())); + return Either.right(responseFormat); + } + refResource = findResourceEither.left().value(); + nodeTypeNamespaceMap.put(refResource.getToscaResourceName(), refResource); + } + String componentState = refResource.getComponentMetadataDefinition().getMetadataDataDefinition().getState(); + if (componentState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name())) { + log.debug("validateResourceInstanceBeforeCreate - component instance of component {} can not be created because the component is in an illegal state {}.", refResource.getName(), componentState); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.ILLEGAL_COMPONENT_STATE, refResource.getComponentType().getValue(), refResource.getName(), componentState); + return Either.right(responseFormat); + } + ResourceTypeEnum resourceTypeEnum = refResource.getResourceType(); + if (resourceTypeEnum == ResourceTypeEnum.VF) { + log.debug("validateResourceInstanceBeforeCreate - ref resource type is ", resourceTypeEnum); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_NODE_TEMPLATE, yamlName, uploadComponentInstanceInfo.getName(), uploadComponentInstanceInfo.getType()); + return Either.right(responseFormat); + } + return Either.left(refResource); + } + + private Either, ResponseFormat> createResourcesInstanceInfoFromYaml(String yamlFileName, Map toscaJson, Resource resource) { + Map moduleComponentInstances = new HashMap(); + Either, ResponseFormat> result = Either.left(moduleComponentInstances); + Either, ResultStatusEnum> eitherNodesTemlates = ImportUtils.findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TEMPLATES); + if (eitherNodesTemlates.isLeft()) { + Map jsonNodeTemplates = eitherNodesTemlates.left().value(); + + Iterator> nodesNameValue = jsonNodeTemplates.entrySet().iterator(); + while (nodesNameValue.hasNext()) { + Entry nodeNameValue = nodesNameValue.next(); + Either eitherNode = createModuleComponentInstanceInfo(nodeNameValue.getValue()); + if (eitherNode.isRight()) { + log.info("error when creating node template:{}, for resource:{}", nodeNameValue.getKey(), resource.getName()); + return Either.right(eitherNode.right().value()); + } else { + UploadComponentInstanceInfo uploadComponentInstanceInfo = eitherNode.left().value(); + uploadComponentInstanceInfo.setName(nodeNameValue.getKey()); + moduleComponentInstances.put(nodeNameValue.getKey(), uploadComponentInstanceInfo); + } + + } + + } + if (moduleComponentInstances.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE, yamlFileName); + return Either.right(responseFormat); + } + + return result; + } + + private Either createModuleComponentInstanceInfo(Object nodeTemplateJson) { + + UploadComponentInstanceInfo nodeTemplateInfo = new UploadComponentInstanceInfo(); + Either result = Either.left(nodeTemplateInfo); + + try { + if (nodeTemplateJson instanceof String) { + String nodeTemplateJsonString = (String) nodeTemplateJson; + nodeTemplateInfo.setType(nodeTemplateJsonString); + } else if (nodeTemplateJson instanceof Map) { + Map nodeTemplateJsonMap = (Map) nodeTemplateJson; + // Type + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + nodeTemplateInfo.setType((String) nodeTemplateJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName())); + } + + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.REQUIREMENTS.getElementName())) { + Either>, ResponseFormat> regResponse = createReqModuleFromYaml(nodeTemplateInfo, nodeTemplateJsonMap); + if (regResponse.isRight()) + return Either.right(regResponse.right().value()); + if (regResponse.left().value().size() > 0) { + nodeTemplateInfo.setRequirements(regResponse.left().value()); + } + } + + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.CAPABILITIES.getElementName())) { + Either>, ResponseFormat> eitherCapRes = createCapModuleFromYaml(nodeTemplateInfo, nodeTemplateJsonMap); + if (eitherCapRes.isRight()) + return Either.right(eitherCapRes.right().value()); + if (eitherCapRes.left().value().size() > 0) { + nodeTemplateInfo.setCapabilities(eitherCapRes.left().value()); + } + } + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.PROPERTIES.getElementName())) { + Either>, ResponseFormat> regResponse = createPropModuleFromYaml(nodeTemplateJsonMap); + if (regResponse.isRight()) + return Either.right(regResponse.right().value()); + if (regResponse.left().value().size() > 0) { + nodeTemplateInfo.setProperties(regResponse.left().value()); + } + } + } else { + + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE)); + + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Import Resource - create capability"); + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create capability"); + log.debug("error when creating capability, message:{}", e.getMessage(), e); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + } + + return result; + } + + private Either>, ResponseFormat> createPropModuleFromYaml(Map nodeTemplateJsonMap) { + Map> moduleProp = new HashMap>(); + Either>, ResponseFormat> response = Either.left(moduleProp); + Either, ResultStatusEnum> toscaProperties = ImportUtils.findFirstToscaMapElement(nodeTemplateJsonMap, ToscaTagNamesEnum.PROPERTIES); + if (toscaProperties.isLeft()) { + Map jsonProperties = toscaProperties.left().value(); + for (Entry jsonPropObj : jsonProperties.entrySet()) { + // Property + String propName = jsonPropObj.getKey(); + Object propValue = jsonPropObj.getValue(); + + if (valueContainsPattern(STR_REPLACE_PATTERN, propValue)) { + log.debug("Ignore property value {}.", propName); + continue; + } + + if (valueContainsPattern(TOKEN_PATTERN, propValue)) { + log.debug("Ignore property value {}.", propName); + continue; + } + if (valueContainsPattern(GET_PROPERTY_PATTERN, propValue)) { + log.debug("Ignore property value {}.", propName); + continue; + } + + if (valueContainsPattern(CONCAT_PATTERN, propValue)) { + log.debug("Ignore property value {}.", propName); + continue; + } + + UploadPropInfo propertyDef = new UploadPropInfo(); + propertyDef.setValue(propValue); + if (propValue instanceof Map) { + if (((Map) propValue).containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + propertyDef.setType(((Map) propValue).get(ToscaTagNamesEnum.TYPE.getElementName()).toString()); + } + + if (((Map) propValue).containsKey(ToscaTagNamesEnum.GET_INPUT.getElementName()) + || ImportUtils.getPropertyJsonStringValue(propValue, ToscaPropertyType.MAP.getType()).contains(ToscaTagNamesEnum.GET_INPUT.getElementName())) { + createGetInputModuleFromMap(propName, (Map) propValue, propertyDef); + } + + if (((Map) propValue).containsKey(ToscaTagNamesEnum.DESCRIPTION.getElementName())) { + propertyDef.setDescription(((Map) propValue).get(ToscaTagNamesEnum.DESCRIPTION.getElementName()).toString()); + } + if (((Map) propValue).containsKey(ToscaTagNamesEnum.DEFAULT_VALUE.getElementName())) { + propertyDef.setValue(((Map) propValue).get(ToscaTagNamesEnum.DEFAULT_VALUE.getElementName())); + } + if (((Map) propValue).containsKey(ToscaTagNamesEnum.IS_PASSWORD.getElementName())) { + propertyDef.setPassword(Boolean.getBoolean(((Map) propValue).get(ToscaTagNamesEnum.IS_PASSWORD.getElementName()).toString())); + } else { + propertyDef.setValue(propValue); + } + } else if (propValue instanceof List) { + List propValueList = (List) propValue; + + createInputPropList(propertyDef, propValueList); + propertyDef.setValue(propValue); + } + + propertyDef.setName(propName); + if (moduleProp.containsKey(propName)) { + moduleProp.get(propName).add(propertyDef); + } else { + List list = new ArrayList(); + list.add(propertyDef); + moduleProp.put(propName, list); + } + } + } + return response; + } + + private void createInputPropList(UploadPropInfo propertyDef, List propValueList) { + for (Object objValue : propValueList) { + + if (objValue instanceof Map) { + Map objMap = (Map) objValue; + Set keys = objMap.keySet(); + for (String key : keys) { + Object value = objMap.get(key); + if (value instanceof Map) { + createGetInputModuleFromMap(key, (Map) value, propertyDef); + + } else if (value instanceof List) { + List propSubValueList = (List) value; + + createInputPropList(propertyDef, propSubValueList); + } + + } + + } else if (objValue instanceof List) { + List propSubValueList = (List) objValue; + + createInputPropList(propertyDef, propSubValueList); + + } + + } + } + + private void createGetInputModuleFromMap(String propName, Map propValue, UploadPropInfo propertyDef) { + + if (propValue.containsKey(ToscaTagNamesEnum.GET_INPUT.getElementName())) { + Object getInput = propValue.get(ToscaTagNamesEnum.GET_INPUT.getElementName()); + GetInputValueInfo getInputInfo = new GetInputValueInfo(); + List getInputs = propertyDef.getGet_input(); + if (getInputs == null) { + getInputs = new ArrayList(); + } + if (getInput instanceof String) { + + getInputInfo.setInputName((String) getInput); + getInputInfo.setPropName(propName); + + } else if (getInput instanceof List) { + List getInputList = (List) getInput; + getInputInfo.setPropName(propName); + getInputInfo.setInputName((String) getInputList.get(0)); + if (getInputList.size() >= 1) { + Object indexObj = getInputList.get(1); + if (indexObj instanceof Integer) { + getInputInfo.setIndexValue((Integer) indexObj); + } else if (indexObj instanceof Float) { + int index = ((Float) indexObj).intValue(); + getInputInfo.setIndexValue(index); + } else if (indexObj instanceof Map && ((Map) indexObj).containsKey(ToscaTagNamesEnum.GET_INPUT.getElementName())) { + Object index = ((Map) indexObj).get(ToscaTagNamesEnum.GET_INPUT.getElementName()); + GetInputValueInfo getInputInfoIndex = new GetInputValueInfo(); + getInputInfoIndex.setInputName((String) index); + getInputInfoIndex.setPropName(propName); + getInputInfo.setGetInputIndex(getInputInfoIndex); + } + getInputInfo.setList(true); + } + + } + getInputs.add(getInputInfo); + propertyDef.setGet_input(getInputs); + propertyDef.setValue(propValue); + } else { + Set keys = propValue.keySet(); + for (String key : keys) { + Object value = propValue.get(key); + if (value instanceof Map) { + createGetInputModuleFromMap(key, (Map) value, propertyDef); + + } else if (value instanceof List) { + List valueList = (List) value; + for (Object o : valueList) { + if (o instanceof Map) { + createGetInputModuleFromMap(key, (Map) o, propertyDef); + + } + } + + } + + } + + } + } + + /* + * private boolean valueContainsStrReplace(Object propValue) { + * + * log.debug("valueContainsStrReplace value is {}", propValue); boolean result = false; if (propValue != null) { log.debug("valueContainsStrReplace value is {}", propValue.getClass()); Matcher matcher = + * STR_REPLACE_PATTERN.matcher(propValue.toString()); result = matcher.find(); } + * + * return result; } + * + * private boolean valueContainsToken(Object propValue) { + * + * log.debug("valueContainsToken value is {}", propValue); boolean result = false; if (propValue != null) { log.debug("valueContainsToken value is {}", propValue.getClass()); Matcher matcher = TOKEN_PATTERN.matcher(propValue.toString()); result = + * matcher.find(); } + * + * return result; } + */ + + private boolean valueContainsPattern(Pattern pattern, Object propValue) { + + log.debug("valueContainsToken value is {}", propValue); + boolean result = false; + if (propValue != null) { + log.debug("valueContainspattern value is {}", propValue.getClass()); + Matcher matcher = pattern.matcher(propValue.toString()); + result = matcher.find(); + } + + return result; + + } + + private Either>, ResponseFormat> createCapModuleFromYaml(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + Map> moduleCap = new HashMap>(); + Either>, ResponseFormat> response = Either.left(moduleCap); + Either, ResultStatusEnum> toscaRequirements = ImportUtils.findFirstToscaListElement(nodeTemplateJsonMap, ToscaTagNamesEnum.CAPABILITIES); + if (toscaRequirements.isLeft()) { + List jsonCapabilities = toscaRequirements.left().value(); + + for (Object jsonCapObj : jsonCapabilities) { + // Requirement + Map capJsonWrapper = (Map) jsonCapObj; + String capName = capJsonWrapper.keySet().iterator().next(); + Either eitherCap = createModuleNodeTemplateCap(capJsonWrapper.get(capName)); + if (eitherCap.isRight()) { + log.info("error when creating Requirement:{}, for node:{}", capName, nodeTemplateInfo); + return Either.right(eitherCap.right().value()); + } else { + UploadCapInfo requirementDef = eitherCap.left().value(); + requirementDef.setName(capName); + if (moduleCap.containsKey(capName)) { + moduleCap.get(capName).add(requirementDef); + } else { + List list = new ArrayList(); + list.add(requirementDef); + moduleCap.put(capName, list); + } + + } + } + + } + + return response; + } + + private Either>, ResponseFormat> createReqModuleFromYaml(UploadComponentInstanceInfo nodeTemplateInfo, Map nodeTemplateJsonMap) { + Map> moduleRequirements = new HashMap>(); + Either>, ResponseFormat> response = Either.left(moduleRequirements); + Either, ResultStatusEnum> toscaRequirements = ImportUtils.findFirstToscaListElement(nodeTemplateJsonMap, ToscaTagNamesEnum.REQUIREMENTS); + if (toscaRequirements.isLeft()) { + List jsonRequirements = toscaRequirements.left().value(); + + for (Object jsonRequirementObj : jsonRequirements) { + // Requirement + Map requirementJsonWrapper = (Map) jsonRequirementObj; + String requirementName = requirementJsonWrapper.keySet().iterator().next(); + Either eitherRequirement = createModuleNodeTemplateReg(requirementJsonWrapper.get(requirementName)); + if (eitherRequirement.isRight()) { + log.info("error when creating Requirement:{}, for node:{}", requirementName, nodeTemplateInfo); + return Either.right(eitherRequirement.right().value()); + } else { + UploadReqInfo requirementDef = eitherRequirement.left().value(); + requirementDef.setName(requirementName); + if (moduleRequirements.containsKey(requirementName)) { + moduleRequirements.get(requirementName).add(requirementDef); + } else { + List list = new ArrayList(); + list.add(requirementDef); + moduleRequirements.put(requirementName, list); + } + + } + } + + } + return response; + } + + private Either createModuleNodeTemplateCap(Object capObject) { + UploadCapInfo capTemplateInfo = new UploadCapInfo(); + Either result = Either.left(capTemplateInfo); + + if (capObject instanceof String) { + String nodeTemplateJsonString = (String) capObject; + capTemplateInfo.setNode(nodeTemplateJsonString); + } else if (capObject instanceof Map) { + Map nodeTemplateJsonMap = (Map) capObject; + // Type + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.NODE.getElementName())) { + capTemplateInfo.setNode((String) nodeTemplateJsonMap.get(ToscaTagNamesEnum.NODE.getElementName())); + } + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + capTemplateInfo.setType((String) nodeTemplateJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName())); + } + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())) { + Either, ResultStatusEnum> validSourceTypesRes = ImportUtils.findFirstToscaListElement(nodeTemplateJsonMap, ToscaTagNamesEnum.VALID_SOURCE_TYPES); + if (validSourceTypesRes.isLeft()) { + capTemplateInfo.setValidSourceTypes(validSourceTypesRes.left().value().stream().map(o -> o.toString()).collect(Collectors.toList())); + } + } + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.PROPERTIES.getElementName())) { + Either>, ResponseFormat> regResponse = createPropModuleFromYaml(nodeTemplateJsonMap); + if (regResponse.isRight()) + return Either.right(regResponse.right().value()); + if (!regResponse.left().value().isEmpty()) { + List properties = new ArrayList(); + regResponse.left().value().values().forEach(list -> properties.addAll(list)); + if (!properties.isEmpty()) + capTemplateInfo.setProperties(properties); + } + } + } + + return result; + } + + private Either createModuleNodeTemplateReg(Object regObject) { + + UploadReqInfo regTemplateInfo = new UploadReqInfo(); + Either result = Either.left(regTemplateInfo); + + if (regObject instanceof String) { + String nodeTemplateJsonString = (String) regObject; + regTemplateInfo.setNode(nodeTemplateJsonString); + } else if (regObject instanceof Map) { + Map nodeTemplateJsonMap = (Map) regObject; + // Type + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.NODE.getElementName())) { + regTemplateInfo.setNode((String) nodeTemplateJsonMap.get(ToscaTagNamesEnum.NODE.getElementName())); + } + // US740820 Relate RIs according to capability name + if (nodeTemplateJsonMap.containsKey(ToscaTagNamesEnum.CAPABILITY.getElementName())) { + regTemplateInfo.setCapabilityName((String) nodeTemplateJsonMap.get(ToscaTagNamesEnum.CAPABILITY.getElementName())); + } + } + + return result; + } + + public Either propagateStateToCertified(User user, Resource resource, LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean inTransaction, boolean needLock) { + Either result = null; + + // resource updated with checkout. certify the resource + if (resource.getLifecycleState().equals(LifecycleStateEnum.CERTIFIED)) { + Either, ResponseFormat> eitherPopulated = populateToscaArtifacts(resource, user, false, inTransaction, needLock); + result = eitherPopulated.isLeft() ? Either.left(resource) : Either.right(eitherPopulated.right().value()); + return result; + } + try { + result = lifecycleBusinessLogic.changeState(resource.getUniqueId(), user, LifeCycleTransitionEnum.CERTIFICATION_REQUEST, lifecycleChangeInfo, inTransaction, needLock); + if (result.isLeft()) { + resource = result.left().value(); + result = lifecycleBusinessLogic.changeState(resource.getUniqueId(), user, LifeCycleTransitionEnum.START_CERTIFICATION, lifecycleChangeInfo, inTransaction, needLock); + } + if (result.isLeft()) { + resource = result.left().value(); + result = lifecycleBusinessLogic.changeState(resource.getUniqueId(), user, LifeCycleTransitionEnum.CERTIFY, lifecycleChangeInfo, inTransaction, needLock); + } + return result; + } finally { + if (result == null || result.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Change LifecycleState - Certify"); + BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify"); + if (inTransaction == false) { + log.debug("operation failed. do rollback"); + titanGenericDao.rollback(); + } + } else if (inTransaction == false) { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + } + } + + /** + * @deprecated Use {@link #createOrUpdateResourceByImport(Resource,User,boolean, boolean,boolean)} instead + */ + public Either, ResponseFormat> createOrUpdateResourceByImport(Resource resource, User user, AuditingActionEnum auditingEnum, boolean isNormative, boolean needLock) { + return createOrUpdateResourceByImport(resource, user, isNormative, false, needLock); + } + + public Either, ResponseFormat> createOrUpdateResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction, boolean needLock) { + + // check if resource already exist + Either latestByName = resourceOperation.getLatestByName(resource.getName(), true); + Either, ResponseFormat> result = null; + + // create + if (latestByName.isRight() && latestByName.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + + Either latestByToscaName = resourceOperation.getLatestByToscaResourceName(resource.getToscaResourceName(), true); + if (latestByToscaName.isRight() && latestByToscaName.right().value().equals(StorageOperationStatus.NOT_FOUND)) + result = createResourceByImport(resource, user, isNormative, isInTransaction); + + else { + StorageOperationStatus status = latestByName.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeResourceMissingError, "Create / Update resource by import", resource.getName()); + BeEcompErrorManager.getInstance().logBeComponentMissingError("Create / Update resource by import", ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); + log.debug("resource already exist {}. status={}", resource.getName(), status); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + result = Either.right(responseFormat); + } + + } + + // update + else if (latestByName.isLeft()) { + result = updateExistingResourceByImport(resource, latestByName.left().value(), user, isNormative, needLock); + } + + // error + else { + StorageOperationStatus status = latestByName.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeResourceMissingError, "Create / Update resource by import", resource.getName()); + log.debug("failed to get latest version of resource {}. status={}", resource.getName(), status); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(latestByName.right().value()), resource); + componentsUtils.auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + result = Either.right(responseFormat); + } + return result; + + } + + private Either, ResponseFormat> createResourceByImport(Resource resource, User user, boolean isNormative, boolean isInTransaction) { + log.debug("resource with name {} does not exist. create new resource", resource.getName()); + Either response = validateResourceBeforeCreate(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isInTransaction); + if (response.isRight()) { + return Either.right(response.right().value()); + } + Either createResponse = createResourceByDao(resource, user, AuditingActionEnum.IMPORT_RESOURCE, isNormative, isInTransaction); + if (createResponse.isRight()) { + return Either.right(createResponse.right().value()); + } else { + ImmutablePair resourcePair = new ImmutablePair<>(createResponse.left().value(), ActionStatus.CREATED); + ASDCKpiApi.countImportResourcesKPI(); + return Either.left(resourcePair); + + } + } + + public boolean isResourceExist(String resourceName) { + Either latestByName = resourceOperation.getLatestByName(resourceName, false); + return latestByName.isLeft(); + } + + private Either, ResponseFormat> updateExistingResourceByImport(Resource newResource, Resource oldResource, User user, boolean inTransaction, boolean needLock) { + String lockedResourceId = oldResource.getUniqueId(); + log.debug("found resource: name={}, id={}, version={}, state={}", oldResource.getName(), lockedResourceId, oldResource.getVersion(), oldResource.getLifecycleState()); + Either, ResponseFormat> result = null; + try { + if (needLock) { + Either lockResult = lockComponent(lockedResourceId, oldResource, "Update Resource by Import"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + } + + Either prepareResourceForUpdate = prepareResourceForUpdate(oldResource, user, inTransaction, false); + if (prepareResourceForUpdate.isRight()) { + ResponseFormat responseFormat = prepareResourceForUpdate.right().value(); + log.info("resource {} cannot be updated. reason={}", lockedResourceId, responseFormat.getFormattedMessage()); + componentsUtils.auditResource(responseFormat, user, newResource, oldResource.getLifecycleState().name(), oldResource.getVersion(), AuditingActionEnum.IMPORT_RESOURCE, null); + result = Either.right(prepareResourceForUpdate.right().value()); + return result; + } + oldResource = prepareResourceForUpdate.left().value(); + + mergeOldResourceMetadataWithNew(oldResource, newResource); + + Either validateFieldsResponse = validateResourceFieldsBeforeUpdate(oldResource, newResource, inTransaction); + if (validateFieldsResponse.isRight()) { + result = Either.right(validateFieldsResponse.right().value()); + return result; + } + + // contact info normalization + newResource.setContactId(newResource.getContactId().toLowerCase()); + // non-updatable fields + newResource.setCreatorUserId(user.getUserId()); + newResource.setCreatorFullName(user.getFullName()); + newResource.setLastUpdaterUserId(user.getUserId()); + newResource.setLastUpdaterFullName(user.getFullName()); + newResource.setUniqueId(oldResource.getUniqueId()); + newResource.setVersion(oldResource.getVersion()); + newResource.setInvariantUUID(oldResource.getInvariantUUID()); + newResource.setLifecycleState(oldResource.getLifecycleState()); + newResource.setUUID(oldResource.getUUID()); + newResource.setNormalizedName(oldResource.getNormalizedName()); + newResource.setSystemName(oldResource.getSystemName()); + if (oldResource.getCsarUUID() != null) { + newResource.setCsarUUID(oldResource.getCsarUUID()); + } + if (oldResource.getImportedToscaChecksum() != null) { + newResource.setImportedToscaChecksum(oldResource.getImportedToscaChecksum()); + } + newResource.setAbstract(oldResource.isAbstract()); + + if (newResource.getDerivedFrom() == null || newResource.getDerivedFrom().isEmpty()) { + newResource.setDerivedFrom(oldResource.getDerivedFrom()); + } + // TODO rhalili: handle artifacts here (delete from old resource and + // add for new) + // TODO rbetzer: remove after migration - in case of resources + // created without tosca artifacts - add the placeholders + if (newResource.getToscaArtifacts() == null || newResource.getToscaArtifacts().isEmpty()) { + setToscaArtifactsPlaceHolders(newResource, user); + } + Either overrideResource = resourceOperation.overrideResource(newResource, oldResource, true); + + if (overrideResource.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(overrideResource.right().value()), newResource); + componentsUtils.auditResource(responseFormat, user, newResource, newResource.getLifecycleState().name(), newResource.getVersion(), AuditingActionEnum.IMPORT_RESOURCE, null); + result = Either.right(responseFormat); + return result; + } + + log.debug("Resource updated successfully!!!"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + componentsUtils.auditResource(responseFormat, user, newResource, oldResource.getLifecycleState().name(), oldResource.getVersion(), AuditingActionEnum.IMPORT_RESOURCE, null); + + ImmutablePair resourcePair = new ImmutablePair<>(overrideResource.left().value(), ActionStatus.OK); + result = Either.left(resourcePair); + return result; + } finally { + if (result == null || result.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Change LifecycleState - Certify"); + BeEcompErrorManager.getInstance().logBeSystemError("Change LifecycleState - Certify"); + log.debug("operation failed. do rollback"); + titanGenericDao.rollback(); + } else if (inTransaction == false) { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + if (needLock == true) { + log.debug("unlock resource {}", lockedResourceId); + graphLockOperation.unlockComponent(lockedResourceId, NodeTypeEnum.Resource); + } + } + + } + + /** + * Merge old resource with new. Keep old category and vendor name without change + * + * @param oldResource + * @param newResource + */ + private void mergeOldResourceMetadataWithNew(Resource oldResource, Resource newResource) { + + // keep old category and vendor name without change + // merge the rest of the resource metadata + if (newResource.getTags() == null || newResource.getTags().isEmpty()) { + newResource.setTags(oldResource.getTags()); + } + + if (newResource.getDescription() == null) { + newResource.setDescription(oldResource.getDescription()); + } + + if (newResource.getVendorRelease() == null) { + newResource.setVendorRelease(oldResource.getVendorRelease()); + } + + if (newResource.getContactId() == null) { + newResource.setContactId(oldResource.getContactId()); + } + + newResource.setCategories(oldResource.getCategories()); + newResource.setVendorName(oldResource.getVendorName()); + } + + private Either prepareResourceForUpdate(Resource latestResource, User user, boolean inTransaction, boolean needLock) { + + Either result = Either.left(latestResource); + // check if user can edit resource + if (!ComponentValidationUtils.canWorkOnResource(latestResource, user.getUserId())) { + // checkout + Either changeState = lifecycleBusinessLogic.changeState(latestResource.getUniqueId(), user, LifeCycleTransitionEnum.CHECKOUT, new LifecycleChangeInfoWithAction("update by import"), inTransaction, needLock); + result = changeState; + } + + return result; + } + + public Either validateResourceBeforeCreate(Resource resource, User user, AuditingActionEnum actionEnum, boolean inTransaction) { + + Either eitherValidation = validateResourceFieldsBeforeCreate(user, getResourceOperation(), resource, actionEnum, inTransaction); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + + eitherValidation = validateCapabilityTypesCreate(user, getCapabilityTypeOperation(), resource, actionEnum, inTransaction); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + eitherValidation = validateLifecycleTypesCreate(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + eitherValidation = validateResourceType(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + + resource.setCreatorUserId(user.getUserId()); + resource.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + resource.setContactId(resource.getContactId().toLowerCase()); + if (resource.getResourceType().equals(ResourceTypeEnum.VF)) { + resource.setToscaResourceName(CommonBeUtils.generateToscaResourceName(ResourceTypeEnum.VF.name(), resource.getSystemName())); + } + + // Generate invariant UUID - must be here and not in operation since it + // should stay constant during clone + String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + resource.setInvariantUUID(invariantUUID); + + return Either.left(resource); + } + + private Either validateResourceType(User user, Resource resource, AuditingActionEnum actionEnum) { + Either eitherResult = Either.left(true); + if (resource.getResourceType() == null) { + log.debug("Invalid resource type for resource"); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + eitherResult = Either.right(errorResponse); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + } + return eitherResult; + } + + private Either validateLifecycleTypesCreate(User user, Resource resource, AuditingActionEnum actionEnum) { + Either eitherResult = Either.left(true); + if (resource.getInterfaces() != null && resource.getInterfaces().size() > 0) { + log.debug("validate interface lifecycle Types Exist"); + Iterator intItr = resource.getInterfaces().values().iterator(); + while (intItr.hasNext() && eitherResult.isLeft()) { + InterfaceDefinition interfaceDefinition = intItr.next(); + String intType = interfaceDefinition.getUniqueId(); + Either eitherCapTypeFound = interfaceTypeOperation.getInterface(intType); + if (eitherCapTypeFound.isRight()) { + if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInterfaceMissingError, "Create Resource - validateLifecycleTypesCreate", intType); + BeEcompErrorManager.getInstance().logBeGraphObjectMissingError("Create Resource - validateLifecycleTypesCreate", "Interface", intType); + log.debug("Lifecycle Type: {} is required by resource: {} but does not exist in the DB", intType, resource.getName()); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Create Resource - validateLifecycleTypesCreate"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateLifecycleTypesCreate"); + log.debug("request to data model failed with error: {}", eitherCapTypeFound.right().value().name()); + } + + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_LIFECYCLE_TYPE, intType); + eitherResult = Either.right(errorResponse); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + } + + } + } + return eitherResult; + } + + private Either validateCapabilityTypesCreate(User user, ICapabilityTypeOperation capabilityTypeOperation, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) { + + Either eitherResult = Either.left(true); + if (resource.getCapabilities() != null && resource.getCapabilities().size() > 0) { + log.debug("validate capability Types Exist - capabilities section"); + + for (String type : resource.getCapabilities().keySet()) { + + eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, type, inTransaction); + if (eitherResult.isRight()) { + return Either.right(eitherResult.right().value()); + } + } + } + + if (resource.getRequirements() != null && resource.getRequirements().size() > 0) { + log.debug("validate capability Types Exist - requirements section"); + + for (String type : resource.getRequirements().keySet()) { + + eitherResult = validateCapabilityTypeExists(user, capabilityTypeOperation, resource, actionEnum, eitherResult, type, inTransaction); + if (eitherResult.isRight()) { + return Either.right(eitherResult.right().value()); + } + } + } + + return eitherResult; + } + + private Either validateCapabilityTypeExists(User user, ICapabilityTypeOperation capabilityTypeOperation, Resource resource, AuditingActionEnum actionEnum, Either eitherResult, String type, + boolean inTransaction) { + Either eitherCapTypeFound = capabilityTypeOperation.getCapabilityType(type, inTransaction); + if (eitherCapTypeFound.isRight()) { + if (eitherCapTypeFound.right().value() == StorageOperationStatus.NOT_FOUND) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeCapabilityTypeMissingError, "Create Resource - validateCapabilityTypesCreate", type); + BeEcompErrorManager.getInstance().logBeGraphObjectMissingError("Create Resource - validateCapabilityTypesCreate", "Capability Type", type); + log.debug("Capability Type: {} is required by resource: {} but does not exist in the DB", type, resource.getName()); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateCapabilityTypesCreate"); + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Create Resource - validateCapabilityTypesCreate"); + log.debug("Trying to get capability type {} failed with error: {}", type, eitherCapTypeFound.right().value().name()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, type); + eitherResult = Either.right(errorResponse); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + } + return eitherResult; + } + + public Either createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative) { + return createResourceByDao(resource, user, actionEnum, isNormative, false); + } + + public Either createResourceByDao(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) { + // create resource + + // lock new resource name in order to avoid creation resource with same + // name + if (inTransaction == false) { + Either lockResult = lockComponentByName(resource.getSystemName(), resource, "Create Resource"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + + log.debug("name is locked {}. status = {}", resource.getSystemName(), lockResult); + } + try { + Either respStatus = createResourceTransaction(resource, user, actionEnum, isNormative, inTransaction); + if (respStatus.isLeft()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + ASDCKpiApi.countCreatedResourcesKPI(); + } else + componentsUtils.auditResource(respStatus.right().value(), user, resource, "", "", actionEnum, null); + return respStatus; + + } finally { + if (inTransaction == false) { + // graphLockOperation.unlockComponent(resource.getSystemName(), + // NodeTypeEnum.Resource); + graphLockOperation.unlockComponentByName(resource.getSystemName(), resource.getUniqueId(), NodeTypeEnum.Resource); + } + } + } + + private Either createResourceTransaction(Resource resource, User user, AuditingActionEnum actionEnum, boolean isNormative, boolean inTransaction) { + // validate resource name uniqueness + log.debug("validate resource name"); + Either eitherValidation = validateResourceNameExists(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + + log.debug("send resource {} to dao for create", resource.getName()); + + createArtifactsPlaceHolderData(resource, user); + + // + if (!isNormative) { + // enrich object + log.debug("enrich resource with creator, version and state"); + resource.setLifecycleState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + resource.setVersion(INITIAL_VERSION); + resource.setHighestVersion(true); + resource.setAbstract(false); + } + + Either dataModelResponse = resourceOperation.createResource(resource, inTransaction); + + // Resource created successfully!!! + if (dataModelResponse.isLeft()) { + log.debug("Resource created successfully!!!"); + + return Either.left(dataModelResponse.left().value()); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), resource); + + return Either.right(responseFormat); + } + + private void createArtifactsPlaceHolderData(Resource resource, User user) { + // create mandatory artifacts + + // TODO it must be removed after that artifact uniqueId creation will be + // moved to ArtifactOperation + // String resourceUniqueId = + // UniqueIdBuilder.buildResourceUniqueId(resource.getResourceName(), + // resource.getResourceVersion()); + + setInformationalArtifactsPlaceHolder(resource, user); + setDeploymentArtifactsPlaceHolder(resource, user); + setToscaArtifactsPlaceHolders(resource, user); + } + + @SuppressWarnings("unchecked") + @Override + public void setDeploymentArtifactsPlaceHolder(Component component, User user) { + Resource resource = (Resource) component; + Map artifactMap = resource.getDeploymentArtifacts(); + if (artifactMap == null) { + artifactMap = new HashMap(); + } + Map deploymentResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getDeploymentResourceArtifacts(); + if (deploymentResourceArtifacts != null) { + Iterator> iterator = deploymentResourceArtifacts.entrySet().iterator(); + while (iterator.hasNext()) { + Entry currEntry = iterator.next(); + boolean shouldCreateArtifact = true; + Map artifactDetails = (Map) currEntry.getValue(); + Object object = artifactDetails.get(PLACE_HOLDER_RESOURCE_TYPES); + if (object != null) { + List artifactTypes = (List) object; + if (!artifactTypes.contains(resource.getResourceType().name())) { + shouldCreateArtifact = false; + continue; + } + } else { + log.info("resource types for artifact placeholder {} were not defined. default is all resources", currEntry.getKey()); + } + if (shouldCreateArtifact) { + if (artifactsBusinessLogic != null) { + ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(resource.getUniqueId(), currEntry.getKey(), (Map) currEntry.getValue(), user, ArtifactGroupTypeEnum.DEPLOYMENT); + if (artifactDefinition != null && !artifactMap.containsKey(artifactDefinition.getArtifactLabel())) + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + } + } + } + } + resource.setDeploymentArtifacts(artifactMap); + } + + private void setInformationalArtifactsPlaceHolder(Resource resource, User user) { + Map artifactMap = resource.getArtifacts(); + if (artifactMap == null) { + artifactMap = new HashMap(); + } + String resourceUniqueId = resource.getUniqueId(); + List exludeResourceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeResourceCategory(); + Map informationalResourceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalResourceArtifacts(); + List categories = resource.getCategories(); + boolean isCreateArtifact = true; + if (exludeResourceCategory != null) { + String category = categories.get(0).getName(); + for (String exlude : exludeResourceCategory) { + if (exlude.equalsIgnoreCase(category)) { + isCreateArtifact = false; + break; + } + } + + } + + if (informationalResourceArtifacts != null && isCreateArtifact) { + Set keys = informationalResourceArtifacts.keySet(); + for (String informationalResourceArtifactName : keys) { + Map artifactInfoMap = (Map) informationalResourceArtifacts.get(informationalResourceArtifactName); + ArtifactDefinition artifactDefinition = artifactsBusinessLogic.createArtifactPlaceHolderInfo(resourceUniqueId, informationalResourceArtifactName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + + } + } + resource.setArtifacts(artifactMap); + } + + /** + * deleteResource + * + * @param resourceId + * @param user + * @return + */ + public ResponseFormat deleteResource(String resourceId, User user) { + ResponseFormat responseFormat; + Either eitherCreator = validateUserExists(user, "Delete Resource", false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + + Either resourceStatus = resourceOperation.getResource(resourceId); + if (resourceStatus.isRight()) { + log.debug("failed to get resource {}", resourceId); + return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), ""); + } + + Resource resource = resourceStatus.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + Either lockResult = lockComponent(resourceId, resource, "Mark resource to delete"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + + try { + + result = markComponentToDelete(resource); + if (result.equals(StorageOperationStatus.OK)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName()); + } + return responseFormat; + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(resourceId, NodeTypeEnum.Resource); + } + + } + + public ResponseFormat deleteResourceByNameAndVersion(String resourceName, String version, User user) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + Either eitherCreator = validateUserExists(user, "Delete Resource", false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + + // Resource resource = null; + List resourcesList = null; + StorageOperationStatus result = StorageOperationStatus.OK; + try { + + Either, StorageOperationStatus> resourceStatus = resourceOperation.getResourceByNameAndVersion(resourceName, version, true); + if (resourceStatus.isRight()) { + log.debug("failed to get resource {} version {}", resourceName, version); + return componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(resourceStatus.right().value()), resourceName); + } + + resourcesList = resourceStatus.left().value(); + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resourceName); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + } + for (Resource resource : resourcesList) { + Either lockResult = lockComponent(resource.getUniqueId(), resource, "Delete Resource"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + try { + result = markComponentToDelete(resource); + if (!result.equals(StorageOperationStatus.OK)) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, resource.getName()); + return responseFormat; + } + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(resource.getUniqueId(), NodeTypeEnum.Resource); + } + } + return responseFormat; + } + + public Either getResource(String resourceId, User user) { + + if (user != null) { + Either eitherCreator = validateUserExists(user, "Create Resource", false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + } + + IResourceOperation dataModel = getResourceOperation(); + Either storageStatus = dataModel.getResource(resourceId); + + if (storageStatus.isRight()) { + log.debug("failed to get resource by id {}", resourceId); + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), "")); + } + return Either.left(storageStatus.left().value()); + + } + + public Either, ResponseFormat> getResourceByNameAndVersion(String resourceName, String resourceVersion, String userId) { + + Either resp = validateUserExists(userId, "get Resource By Name And Version", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either, StorageOperationStatus> getResource = resourceOperation.getResourceByNameAndVersion(resourceName, resourceVersion, false); + if (getResource.isRight()) { + log.debug("failed to get resource by name {} and version {}", resourceName, resourceVersion); + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(getResource.right().value()), resourceName)); + } + return Either.left(getResource.left().value()); + } + + /** + * updateResourceMetadata + * + * @param user + * - modifier data (userId) + * @param inTransaction + * TODO + * @param resourceIdToUpdate + * - the resource identifier + * @param newResource + * + * @return Either + */ + public Either updateResourceMetadata(String resourceIdToUpdate, Resource newResource, Resource currentResource, User user, boolean inTransaction) { + + Either resp = validateUserExists(user.getUserId(), "update Resource Metadata", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + IResourceOperation dataModel = getResourceOperation(); + log.debug("Get resource with id {}", resourceIdToUpdate); + boolean needToUnlock = false; + boolean rollbackNeeded = true; + + try { + // Either storageStatus = + // dataModel.getResource_tx(resourceIdToUpdate, false); + if (currentResource == null) { + Either storageStatus = dataModel.getResource(resourceIdToUpdate, false); + if (storageStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus.right().value()), "")); + } + + currentResource = storageStatus.left().value(); + } + // verify that resource is checked-out and the user is the last + // updater + if (!ComponentValidationUtils.canWorkOnResource(currentResource, user.getUserId())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + // lock resource + StorageOperationStatus lockResult = graphLockOperation.lockComponent(resourceIdToUpdate, NodeTypeEnum.Resource); + if (!lockResult.equals(StorageOperationStatus.OK)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeFailedLockObjectError, "Upload Artifact - lock " + resourceIdToUpdate + ": " + NodeTypeEnum.Resource); + BeEcompErrorManager.getInstance().logBeFailedLockObjectError("Upload Artifact - lock ", NodeTypeEnum.Resource.getName(), resourceIdToUpdate); + log.debug("Failed to lock resource {} error - {}", resourceIdToUpdate, lockResult); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(lockResult)); + return Either.right(responseFormat); + } + + needToUnlock = true; + + // critical section starts here + // convert json to object + + // Update and updated resource must have a non-empty "derivedFrom" + // list + // This code is not called from import resources, because of root + // VF "derivedFrom" should be null (or ignored) + if (!currentResource.getResourceType().equals(ResourceTypeEnum.VF)) { + Either derivedFromNotEmptyEither = validateDerivedFromNotEmpty(null, newResource, null); + if (derivedFromNotEmptyEither.isRight()) { + log.debug("for updated resource {}, derived from field is empty", newResource.getName()); + return Either.right(derivedFromNotEmptyEither.right().value()); + } + + derivedFromNotEmptyEither = validateDerivedFromNotEmpty(null, currentResource, null); + if (derivedFromNotEmptyEither.isRight()) { + log.debug("for current resource {}, derived from field is empty", currentResource.getName()); + return Either.right(derivedFromNotEmptyEither.right().value()); + } + } else { + newResource.setDerivedFrom(null); + } + + Either dataModelResponse = updateResourceMetadata(resourceIdToUpdate, newResource, user, currentResource, false, true); + if (dataModelResponse.isRight()) { + log.debug("failed to update resource metadata!!!"); + rollbackNeeded = true; + return Either.right(dataModelResponse.right().value()); + } + + log.debug("Resource metadata updated successfully!!!"); + rollbackNeeded = false; + return Either.left(dataModelResponse.left().value()); + + } finally { + if (!inTransaction) { + if (rollbackNeeded) { + titanGenericDao.rollback(); + } else { + titanGenericDao.commit(); + } + } + + if (needToUnlock) { + graphLockOperation.unlockComponent(resourceIdToUpdate, NodeTypeEnum.Resource); + } + } + } + + private Either updateResourceMetadata(String resourceIdToUpdate, Resource newResource, User user, Resource currentResource, boolean shouldLock, boolean inTransaction) { + + IResourceOperation dataModel = getResourceOperation(); + Either validateResourceFields = validateResourceFieldsBeforeUpdate(currentResource, newResource, inTransaction); + if (validateResourceFields.isRight()) { + return Either.right(validateResourceFields.right().value()); + } + // Setting last updater and uniqueId + newResource.setContactId(newResource.getContactId().toLowerCase()); + newResource.setLastUpdaterUserId(user.getUserId()); + newResource.setUniqueId(resourceIdToUpdate); + // Cannot set highest version through UI + newResource.setHighestVersion(null); + newResource.setCreationDate(currentResource.getCreationDate()); + + Either processUpdateOfDerivedFrom = processUpdateOfDerivedFrom(currentResource, newResource, user.getUserId(), shouldLock, inTransaction); + + if (processUpdateOfDerivedFrom.isRight()) { + log.debug("Couldn't update derived from for resource {}", resourceIdToUpdate); + return Either.right(processUpdateOfDerivedFrom.right().value()); + } + + log.debug("send resource {} to dao for update", newResource.getUniqueId()); + Either dataModelResponse = dataModel.updateResource(newResource, inTransaction); + + if (dataModelResponse.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), newResource); + return Either.right(responseFormat); + } else if (dataModelResponse.left().value() == null) { + log.debug("No response from updateResource"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return Either.left(dataModelResponse.left().value()); + } + + /** + * validateResourceFieldsBeforeCreate + * + * @param user + * - modifier data (userId) + * @param dataModel + * - IResourceOperation for resource crud + * @param resource + * - Resource object to validate + * @return Either + */ + private Either validateResourceFieldsBeforeCreate(User user, IResourceOperation dataModel, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) { + Either componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, resource, actionEnum); + if (componentsFieldsValidation.isRight()) { + return componentsFieldsValidation; + } + + // validate name + + /* + * log.debug("validate resource name"); Either eitherValidation = validateComponentName(user, resource, actionEnum); if (eitherValidation.isRight()) { return eitherValidation; } + * + * // validate description log.debug("validate description"); eitherValidation = validateDescriptionAndCleanup(user, resource, actionEnum); if (eitherValidation.isRight()) { return eitherValidation; } + */ + + // validate icon + /* + * log.debug("validate icon"); eitherValidation = validateIcon(user, resource, actionEnum); if (eitherValidation.isRight()) { return eitherValidation; } + */ + + // validate tags + /* + * log.debug("validate tags"); eitherValidation = validateTagsListAndRemoveDuplicates(user, resource, actionEnum); if (eitherValidation.isRight()) { return eitherValidation; } + */ + + // validate category + log.debug("validate category"); + Either eitherValidation = validateCategory(user, resource, actionEnum, inTransaction); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // validate vendor name & release + log.debug("validate vendor name"); + eitherValidation = validateVendorName(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate vendor release"); + eitherValidation = validateVendorReleaseName(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // validate cost + log.debug("validate cost"); + eitherValidation = validateCost(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // validate licenseType + log.debug("validate licenseType"); + eitherValidation = validateLicenseType(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // validate template (derived from) + log.debug("validate derived from"); + if (resource.getResourceType().equals(ResourceTypeEnum.VF)) { + resource.setDerivedFrom(null); + } + eitherValidation = validateDerivedFromExist(user, resource, actionEnum); + if (eitherValidation.isRight()) { + return Either.right(eitherValidation.right().value()); + } + + // warn about non-updatable fields + checkComponentFieldsForOverrideAttempt(resource); + String currentCreatorFullName = resource.getCreatorFullName(); + if (currentCreatorFullName != null) { + log.warn("Resource Creator fullname is automatically set and cannot be updated"); + } + + String currentLastUpdaterFullName = resource.getLastUpdaterFullName(); + if (currentLastUpdaterFullName != null) { + log.warn("Resource LastUpdater fullname is automatically set and cannot be updated"); + } + + Long currentLastUpdateDate = resource.getLastUpdateDate(); + if (currentLastUpdateDate != null) { + log.warn("Resource last update date is automatically set and cannot be updated"); + } + + Boolean currentAbstract = resource.isAbstract(); + if (currentAbstract != null) { + log.warn("Resource abstract is automatically set and cannot be updated"); + } + + return Either.left(true); + } + + /** + * validateResourceFieldsBeforeUpdate + * + * @param currentResource + * - Resource object to validate + * @return Either + */ + private Either validateResourceFieldsBeforeUpdate(Resource currentResource, Resource updateInfoResource, boolean inTransaction) { + + boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentResource.getVersion()); + + // validate resource name + log.debug("validate resource name before update"); + Either eitherValidation = validateResourceName(currentResource, updateInfoResource, hasBeenCertified); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // validate description + log.debug("validate description before update"); + eitherValidation = validateDescriptionAndCleanup(null, updateInfoResource, null); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate icon before update"); + eitherValidation = validateIcon(currentResource, updateInfoResource, hasBeenCertified); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate tags before update"); + eitherValidation = validateTagsListAndRemoveDuplicates(null, updateInfoResource, null); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate vendor name before update"); + eitherValidation = validateVendorName(currentResource, updateInfoResource, hasBeenCertified); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate vendor release before update"); + eitherValidation = validateVendorReleaseName(null, updateInfoResource, null); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate contact info before update"); + eitherValidation = validateContactId(null, updateInfoResource, null); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate derived before update"); + eitherValidation = validateDerivedFromDuringUpdate(currentResource, updateInfoResource, hasBeenCertified); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + log.debug("validate category before update"); + eitherValidation = validateCategory(currentResource, updateInfoResource, hasBeenCertified, inTransaction); + if (eitherValidation.isRight()) { + return eitherValidation; + } + + // warn about non-updatable fields + String currentResourceVersion = currentResource.getVersion(); + String updatedResourceVersion = updateInfoResource.getVersion(); + + if ((updatedResourceVersion != null) && (!updatedResourceVersion.equals(currentResourceVersion))) { + log.warn("Resource version is automatically set and cannot be updated"); + } + + String currentCreatorUserId = currentResource.getCreatorUserId(); + String updatedCreatorUserId = updateInfoResource.getCreatorUserId(); + + if ((updatedCreatorUserId != null) && (!updatedCreatorUserId.equals(currentCreatorUserId))) { + log.warn("Resource Creator User id is automatically set and cannot be updated"); + } + + String currentCreatorFullName = currentResource.getCreatorFullName(); + String updatedCreatorFullName = updateInfoResource.getCreatorFullName(); + + if ((updatedCreatorFullName != null) && (!updatedCreatorFullName.equals(currentCreatorFullName))) { + log.warn("Resource Creator fullname is automatically set and cannot be updated"); + } + + String currentLastUpdaterUserId = currentResource.getLastUpdaterUserId(); + String updatedLastUpdaterUserId = updateInfoResource.getLastUpdaterUserId(); + + if ((updatedLastUpdaterUserId != null) && (!updatedLastUpdaterUserId.equals(currentLastUpdaterUserId))) { + log.warn("Resource LastUpdater userId is automatically set and cannot be updated"); + } + + String currentLastUpdaterFullName = currentResource.getLastUpdaterFullName(); + String updatedLastUpdaterFullName = updateInfoResource.getLastUpdaterFullName(); + + if ((updatedLastUpdaterFullName != null) && (!updatedLastUpdaterFullName.equals(currentLastUpdaterFullName))) { + log.warn("Resource LastUpdater fullname is automatically set and cannot be updated"); + } + + Long currentCreationDate = currentResource.getCreationDate(); + Long updatedCreationDate = updateInfoResource.getCreationDate(); + + if ((updatedCreationDate != null) && (!updatedCreationDate.equals(currentCreationDate))) { + log.warn("Resource Creation date is automatically set and cannot be updated"); + } + + Long currentLastUpdateDate = currentResource.getLastUpdateDate(); + Long updatedLastUpdateDate = updateInfoResource.getLastUpdateDate(); + + if ((updatedLastUpdateDate != null) && (!updatedLastUpdateDate.equals(currentLastUpdateDate))) { + log.warn("Resource last update date is automatically set and cannot be updated"); + } + + LifecycleStateEnum currentLifecycleState = currentResource.getLifecycleState(); + LifecycleStateEnum updatedLifecycleState = updateInfoResource.getLifecycleState(); + + if ((updatedLifecycleState != null) && (!updatedLifecycleState.equals(currentLifecycleState))) { + log.warn("Resource lifecycle state date is automatically set and cannot be updated"); + } + + Boolean currentAbstract = currentResource.isAbstract(); + Boolean updatedAbstract = updateInfoResource.isAbstract(); + + if ((updatedAbstract != null) && (!updatedAbstract.equals(currentAbstract))) { + log.warn("Resource abstract is automatically set and cannot be updated"); + } + + Boolean currentHighestVersion = currentResource.isHighestVersion(); + Boolean updatedHighestVersion = updateInfoResource.isHighestVersion(); + + if ((updatedHighestVersion != null) && (!updatedHighestVersion.equals(currentHighestVersion))) { + log.warn("Resource highest version is automatically set and cannot be updated"); + } + + String currentUuid = currentResource.getUUID(); + String updatedUuid = updateInfoResource.getUUID(); + + if ((updatedUuid != null) && (!updatedUuid.equals(currentUuid))) { + log.warn("Resource UUID is automatically set and cannot be updated"); + } + + ResourceTypeEnum currentResourceType = currentResource.getResourceType(); + ResourceTypeEnum updatedResourceType = updateInfoResource.getResourceType(); + + if ((updatedResourceType != null) && (!updatedResourceType.equals(currentResourceType))) { + log.warn("Resource Type cannot be updated"); + + } + updateInfoResource.setResourceType(currentResource.getResourceType()); + + String currentInvariantUuid = currentResource.getInvariantUUID(); + String updatedInvariantUuid = updateInfoResource.getInvariantUUID(); + + if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) { + log.warn("Resource invariant UUID is automatically set and cannot be updated"); + updateInfoResource.setInvariantUUID(currentInvariantUuid); + } + return Either.left(true); + } + + /* + * private Either validateResourceName(User user, Resource resource, AuditingActionEnum actionEnum) { log.debug("validate resource name is not empty"); String resourceName = resource.getResourceName(); + * + * if (!ValidationUtils.validateStringNotEmpty(resourceName)) { log.debug("Resource name is empty"); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_COMPONENT_NAME, ComponentTypeEnum.RESOURCE.getValue()); + * componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); return Either.right(responseFormat); } + * + * if (!ValidationUtils.validateResourceNameLength(resourceName)) { log.debug("Resource name is exceeds max length {} ", ValidationUtils.RESOURCE_NAME_MAX_LENGTH); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus. + * COMPONENT_NAME_EXCEEDS_LIMIT, ComponentTypeEnum.RESOURCE.getValue(), "" + ValidationUtils.RESOURCE_NAME_MAX_LENGTH); componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); return Either.right(responseFormat); + * } + * + * if (!ValidationUtils.validateResourceName(resourceName)) { log.debug("Resource name {} has invalid format", resourceName); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPONENT_NAME, + * ComponentTypeEnum.RESOURCE.getValue()); componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); return Either.right(responseFormat); } resource.setNormalizedName(ValidationUtils.normaliseComponentName( + * resourceName)); resource.setSystemName(ValidationUtils.convertToSystemName(resourceName)) ; + * + * return Either.left(true); } + */ + + private Either validateResourceName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) { + String resourceNameUpdated = updateInfoResource.getName(); + String resourceNameCurrent = currentResource.getName(); + if (!resourceNameCurrent.equals(resourceNameUpdated)) { + if (!hasBeenCertified) { + Either validateResourceNameResponse = validateComponentName(null, updateInfoResource, null); + if (validateResourceNameResponse.isRight()) { + ResponseFormat errorResponse = validateResourceNameResponse.right().value(); + return Either.right(errorResponse); + } + validateResourceNameResponse = validateResourceNameExists(null, updateInfoResource, null); + if (validateResourceNameResponse.isRight()) { + ResponseFormat errorResponse = validateResourceNameResponse.right().value(); + return Either.right(errorResponse); + } + currentResource.setName(resourceNameUpdated); + currentResource.setNormalizedName(ValidationUtils.normaliseComponentName(resourceNameUpdated)); + currentResource.setSystemName(ValidationUtils.convertToSystemName(resourceNameUpdated)); + + } else { + log.info("Resource name {} cannot be updated once the resource has been certified once.", resourceNameUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_NAME_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateIcon(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) { + String iconUpdated = updateInfoResource.getIcon(); + String iconCurrent = currentResource.getIcon(); + if (!iconCurrent.equals(iconUpdated)) { + if (!hasBeenCertified) { + Either validateIcon = validateIcon(null, updateInfoResource, null); + if (validateIcon.isRight()) { + ResponseFormat errorResponse = validateIcon.right().value(); + return Either.right(errorResponse); + } + } else { + log.info("Icon {} cannot be updated once the resource has been certified once.", iconUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_ICON_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateVendorName(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) { + String vendorNameUpdated = updateInfoResource.getVendorName(); + String vendorNameCurrent = currentResource.getVendorName(); + if (!vendorNameCurrent.equals(vendorNameUpdated)) { + if (!hasBeenCertified) { + Either validateVendorName = validateVendorName(null, updateInfoResource, null); + if (validateVendorName.isRight()) { + ResponseFormat errorResponse = validateVendorName.right().value(); + return Either.right(errorResponse); + } + } else { + log.info("Vendor name {} cannot be updated once the resource has been certified once.", vendorNameUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateCategory(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified, boolean inTransaction) { + Either validateCategoryName = validateCategory(null, updateInfoResource, null, inTransaction); + if (validateCategoryName.isRight()) { + ResponseFormat errorResponse = validateCategoryName.right().value(); + return Either.right(errorResponse); + } + if (hasBeenCertified) { + CategoryDefinition currentCategory = currentResource.getCategories().get(0); + SubCategoryDefinition currentSubCategory = currentCategory.getSubcategories().get(0); + CategoryDefinition updateCategory = updateInfoResource.getCategories().get(0); + SubCategoryDefinition updtaeSubCategory = updateCategory.getSubcategories().get(0); + if (!currentCategory.getName().equals(updateCategory.getName()) || !currentSubCategory.getName().equals(updtaeSubCategory.getName())) { + log.info("Category {} cannot be updated once the resource has been certified once.", currentResource.getCategories()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CATEGORY_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateDerivedFromDuringUpdate(Resource currentResource, Resource updateInfoResource, boolean hasBeenCertified) { + + List currentDerivedFrom = currentResource.getDerivedFrom(); + List updatedDerivedFrom = updateInfoResource.getDerivedFrom(); + if (currentDerivedFrom == null || currentDerivedFrom.isEmpty() || updatedDerivedFrom == null || updatedDerivedFrom.isEmpty()) { + log.trace("Update normative types"); + return Either.left(true); + } + + String derivedFromCurrent = currentDerivedFrom.get(0); + String derivedFromUpdated = updatedDerivedFrom.get(0); + + if (!derivedFromCurrent.equals(derivedFromUpdated)) { + if (!hasBeenCertified) { + Either validateDerivedFromExistsEither = validateDerivedFromExist(null, updateInfoResource, null); + if (validateDerivedFromExistsEither.isRight()) { + return validateDerivedFromExistsEither; + } + } else { + log.debug("Derived from cannot be updated once the resource has been certified once."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_DERIVED_FROM_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } else { + // For derived from, we must know whether it was actually changed, + // otherwise we must do no action. + // Due to changes it inflicts on data model (remove artifacts, + // properties...), it's not like a flat field which can be + // overwritten if not changed. + // So we must indicate that derived from is not changed + updateInfoResource.setDerivedFrom(null); + } + return Either.left(true); + } + + private Either validateDerivedFromExist(User user, Resource resource, AuditingActionEnum actionEnum) { + + if (resource.getDerivedFrom() == null || resource.getDerivedFrom().isEmpty()) { + return Either.left(true); + } + + IResourceOperation resourceOperation = getResourceOperation(); + + String templateName = resource.getDerivedFrom().get(0); + + Either dataModelResponse = resourceOperation.validateToscaResourceNameExists(templateName); + if (dataModelResponse.isRight()) { + StorageOperationStatus storageStatus = dataModelResponse.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Create Resource - validateDerivedFromExist"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Create Resource - validateDerivedFromExist"); + log.debug("request to data model failed with error: {}", storageStatus.name()); + ResponseFormat responseFormat = componentsUtils.getResponseFormatByResource(componentsUtils.convertFromStorageResponse(storageStatus), resource); + log.trace("audit before sending response"); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + + if (dataModelResponse.left().value()) { + log.info("resource template with name {} does not exists", templateName); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.PARENT_RESOURCE_NOT_FOUND); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + + return Either.right(responseFormat); + + } + return Either.left(true); + } + + public Either validateDerivedFromNotEmpty(User user, Resource resource, AuditingActionEnum actionEnum) { + log.debug("validate resource derivedFrom field"); + if ((resource.getDerivedFrom() == null) || (resource.getDerivedFrom().isEmpty()) || (resource.getDerivedFrom().get(0)) == null || (resource.getDerivedFrom().get(0).trim().isEmpty())) { + log.info("derived from (template) field is missing for the resource"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_DERIVED_FROM_TEMPLATE); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + + return Either.right(responseFormat); + } + return Either.left(true); + } + + private Either validateResourceNameExists(User user, Resource resource, AuditingActionEnum actionEnum) { + + IResourceOperation resourceOperation = getResourceOperation(); + Either resourceOperationResponse = resourceOperation.validateResourceNameExists(resource.getName(), resource.getResourceType()); + if (resourceOperationResponse.isLeft()) { + if (resourceOperationResponse.left().value()) { + return Either.left(true); + } else { + log.debug("resource with name {} already exists", resource.getName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + return Either.right(errorResponse); + } + } + log.debug("error while validateResourceNameExists for resource: {}", resource.getName()); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(resourceOperationResponse.right().value())); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + return Either.right(errorResponse); + } + + /* + * private Either validateTagsListAndRemoveDuplicates(User user, Resource resource, AuditingActionEnum actionEnum) { List tagsList = resource.getTags(); + * + * Either validateTags = validateResourceTags(tagsList, resource.getResourceName()); if (validateTags.isRight()) { ResponseFormat responseFormat = validateTags.right().value(); + * componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); return Either.right(responseFormat); } ValidationUtils.removeDuplicateFromList(tagsList); return Either.left(true); + * + * } + * + * private Either validateResourceTags(List tags, String resourceName) { log.debug("validate resource tags"); boolean includesResourceName = false; int tagListSize = 0; if (tags != null && !tags.isEmpty()) { for + * (String tag : tags) { if (!ValidationUtils.validateTagLength(tag)) { log.debug("tag length exceeds limit {}", ValidationUtils.TAG_MAX_LENGTH); return Either.right(componentsUtils.getResponseFormat(ActionStatus. + * COMPONENT_SINGLE_TAG_EXCEED_LIMIT, "" + ValidationUtils.TAG_MAX_LENGTH)); } if (ValidationUtils.validateComponentNamePattern(tag)) { if (!includesResourceName) { includesResourceName = resourceName.equals(tag); } } else { + * log.debug("invalid tag {}", tag); return Either.right(componentsUtils.getResponseFormat(ActionStatus. COMPONENT_INVALID_TAG)); } tagListSize += tag.length() + 1; } if (!includesResourceName) { log.debug( "tags must include resource name"); + * return Either.right(componentsUtils.getResponseFormat(ActionStatus. COMPONENT_INVALID_TAGS_NO_COMP_NAME)); } if (!ValidationUtils.validateTagListLength(tagListSize)) { log.debug( "overall tags length {}, exceeds limit {}", tagListSize, + * ValidationUtils.TAG_LIST_MAX_LENGTH); return Either.right(componentsUtils.getResponseFormat(ActionStatus. COMPONENT_TAGS_EXCEED_LIMIT, "" + ValidationUtils.TAG_LIST_MAX_LENGTH)); } return Either.left(true); } + * + * return Either.right(componentsUtils.getResponseFormat(ActionStatus. COMPONENT_MISSING_TAGS)); } + */ + + private Either validateCategory(User user, Resource resource, AuditingActionEnum actionEnum, boolean inTransaction) { + + List categories = resource.getCategories(); + if (categories == null || categories.size() == 0) { + log.debug("Resource category is empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + if (categories.size() > 1) { + log.debug("Must be only one category for resource"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.RESOURCE.getValue()); + return Either.right(responseFormat); + } + CategoryDefinition category = categories.get(0); + List subcategories = category.getSubcategories(); + if (subcategories == null || subcategories.size() == 0) { + log.debug("Missinig subcategory for resource"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY); + return Either.right(responseFormat); + } + if (subcategories.size() > 1) { + log.debug("Must be only one sub ategory for resource"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_TOO_MUCH_SUBCATEGORIES); + return Either.right(responseFormat); + } + + SubCategoryDefinition subcategory = subcategories.get(0); + + if (!ValidationUtils.validateStringNotEmpty(category.getName())) { + log.debug("Resource category is empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.RESOURCE.getValue()); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + if (!ValidationUtils.validateStringNotEmpty(subcategory.getName())) { + log.debug("Resource category is empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_SUBCATEGORY, ComponentTypeEnum.RESOURCE.getValue()); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + + Either validateCategory = validateCategoryListed(category, subcategory, inTransaction); + if (validateCategory.isRight()) { + ResponseFormat responseFormat = validateCategory.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + return Either.right(responseFormat); + } + + return Either.left(true); + } + + private Either validateCategoryListed(CategoryDefinition category, SubCategoryDefinition subcategory, boolean inTransaction) { + if (category != null && subcategory != null) { + log.debug("validating resource category {} against valid categories list", category); + Either, ActionStatus> categories = elementDao.getAllCategories(NodeTypeEnum.ResourceNewCategory, inTransaction); + if (categories.isRight()) { + log.debug("failed to retrive resource categories from Titan"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(categories.right().value()); + return Either.right(responseFormat); + } + List categoryList = categories.left().value(); + for (CategoryDefinition cat : categoryList) { + if (cat.getName().equals(category.getName())) { + for (SubCategoryDefinition subcat : cat.getSubcategories()) { + if (subcat.getName().equals(subcategory.getName())) { + return Either.left(true); + } + } + log.debug("SubCategory {} is not part of resource category group. Resource subcategory valid values are {}", subcategory, cat.getSubcategories()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); + } + } + log.debug("Category {} is not part of resource category group. Resource category valid values are {}", category, categoryList); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.RESOURCE.getValue())); + } + return Either.left(false); + } + + public Either validateVendorReleaseName(User user, Resource resource, AuditingActionEnum actionEnum) { + String vendorRelease = resource.getVendorRelease(); + + log.debug("validate vendor relese name"); + if (!ValidationUtils.validateStringNotEmpty(vendorRelease)) { + log.info("vendor relese name is missing."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_RELEASE); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + return Either.right(errorResponse); + } + + Either validateVendorReleaseResponse = validateVendorReleaseName(vendorRelease); + if (validateVendorReleaseResponse.isRight()) { + ResponseFormat responseFormat = validateVendorReleaseResponse.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + } + return validateVendorReleaseResponse; + } + + public Either validateVendorReleaseName(String vendorRelease) { + if (vendorRelease != null) { + if (!ValidationUtils.validateVendorReleaseLength(vendorRelease)) { + log.info("vendor release exceds limit."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.VENDOR_RELEASE_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_RELEASE_MAX_LENGTH); + return Either.right(errorResponse); + } + + if (!ValidationUtils.validateVendorRelease(vendorRelease)) { + log.info("vendor release is not valid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_RELEASE); + return Either.right(errorResponse); + } + return Either.left(true); + } + return Either.left(false); + + } + + private Either validateVendorName(User user, Resource resource, AuditingActionEnum actionEnum) { + String vendorName = resource.getVendorName(); + if (!ValidationUtils.validateStringNotEmpty(vendorName)) { + log.info("vendor name is missing."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.MISSING_VENDOR_NAME); + componentsUtils.auditResource(errorResponse, user, resource, "", "", actionEnum, null); + return Either.right(errorResponse); + } + + Either validateVendorNameResponse = validateVendorName(vendorName); + if (validateVendorNameResponse.isRight()) { + ResponseFormat responseFormat = validateVendorNameResponse.right().value(); + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + } + return validateVendorNameResponse; + + } + + private Either validateVendorName(String vendorName) { + if (vendorName != null) { + if (!ValidationUtils.validateVendorNameLength(vendorName)) { + log.info("vendor name exceds limit."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.VENDOR_NAME_EXCEEDS_LIMIT, "" + ValidationUtils.VENDOR_NAME_MAX_LENGTH); + return Either.right(errorResponse); + } + + if (!ValidationUtils.validateVendorName(vendorName)) { + log.info("vendor name is not valid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_VENDOR_NAME); + return Either.right(errorResponse); + } + return Either.left(true); + + } + return Either.left(false); + + } + + private Either validateCost(User user, Resource resource, AuditingActionEnum actionEnum) { + String cost = resource.getCost(); + if (cost != null) { + + if (!ValidationUtils.validateCost(cost)) { + log.debug("resource cost is invalid."); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateLicenseType(User user, Resource resource, AuditingActionEnum actionEnum) { + log.debug("validate licenseType"); + String licenseType = resource.getLicenseType(); + if (licenseType != null) { + List licenseTypes = ConfigurationManager.getConfigurationManager().getConfiguration().getLicenseTypes(); + if (!licenseTypes.contains(licenseType)) { + log.debug("License type {} isn't configured"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + if (actionEnum != null) { + // In update case, no audit is required + componentsUtils.auditResource(responseFormat, user, resource, "", "", actionEnum, null); + } + return Either.right(responseFormat); + } + } + return Either.left(true); + } + + private Either processUpdateOfDerivedFrom(Resource currentResource, Resource updatedResource, String userId, boolean shouldLock, boolean inTransaction) { + Either deleteArtifactByInterface = null; + if (updatedResource.getDerivedFrom() != null) { + log.debug("Starting derived from update for resource {}", updatedResource.getUniqueId()); + log.debug("1. Removing interface artifacts from graph"); + // Remove all interface artifacts of resource + String resourceId = updatedResource.getUniqueId(); + Map interfaces = currentResource.getInterfaces(); + + if (interfaces != null) { + Collection values = interfaces.values(); + for (InterfaceDefinition interfaceDefinition : values) { + String interfaceType = interfaceTypeOperation.getShortInterfaceName(interfaceDefinition); + + log.trace("Starting interface artifacts removal for interface type {}", interfaceType); + Map operations = interfaceDefinition.getOperations(); + if (operations != null) { + for (Entry operationEntry : operations.entrySet()) { + Operation operation = operationEntry.getValue(); + ArtifactDefinition implementation = operation.getImplementation(); + if (implementation != null) { + String uniqueId = implementation.getUniqueId(); + log.debug("Removing interface artifact definition {}, operation {}, interfaceType {}", uniqueId, operationEntry.getKey(), interfaceType); + // only thing that transacts and locks here + deleteArtifactByInterface = artifactsBusinessLogic.deleteArtifactByInterface(resourceId, interfaceType, operationEntry.getKey(), userId, uniqueId, null, shouldLock, true); + if (deleteArtifactByInterface.isRight()) { + log.debug("Couldn't remove artifact definition with id {}", uniqueId); + if (!inTransaction) { + titanGenericDao.rollback(); + } + return Either.right(deleteArtifactByInterface.right().value()); + } + } else { + log.trace("No implementation found for operation {} - nothing to delete", operationEntry.getKey()); + } + } + } else { + log.trace("No operations found for interface type {}", interfaceType); + } + } + } + log.debug("2. Removing properties"); + Either, StorageOperationStatus> findPropertiesOfNode = propertyOperation.deleteAllPropertiesAssociatedToNode(NodeTypeEnum.Resource, resourceId); + + if (findPropertiesOfNode.isRight() && !findPropertiesOfNode.right().value().equals(StorageOperationStatus.OK)) { + log.debug("Failed to remove all properties of resource"); + if (!inTransaction) + titanGenericDao.rollback(); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(findPropertiesOfNode.right().value()))); + } + + } else { + log.debug("Derived from wasn't changed during update"); + } + + if (!inTransaction) + titanGenericDao.commit(); + return Either.left(true); + + } + + /**** Auditing *******************/ + + protected static IElementOperation getElementDao(Class class1, ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + + return webApplicationContext.getBean(class1); + } + + public ICapabilityTypeOperation getCapabilityTypeOperation() { + return capabilityTypeOperation; + } + + public void setCapabilityTypeOperation(ICapabilityTypeOperation capabilityTypeOperation) { + this.capabilityTypeOperation = capabilityTypeOperation; + } + + public Either validatePropertiesDefaultValues(Resource resource) { + log.debug("validate resource properties default values"); + Either eitherResult = Either.left(true); + List properties = resource.getProperties(); + String type = null; + String innerType = null; + if (properties != null) { + for (PropertyDefinition property : properties) { + if (!propertyOperation.isPropertyTypeValid(property)) { + log.info("Invalid type for property"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_TYPE, property.getType(), property.getName()); + eitherResult = Either.right(responseFormat); + break; + } + + Either, ResponseFormat> allDataTypes = getAllDataTypes(applicationDataTypeCache); + if (allDataTypes.isRight()) { + return Either.right(allDataTypes.right().value()); + } + + type = property.getType(); + if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) { + ImmutablePair propertyInnerTypeValid = propertyOperation.isPropertyInnerTypeValid(property, allDataTypes.left().value()); + innerType = propertyInnerTypeValid.getLeft(); + if (!propertyInnerTypeValid.getRight().booleanValue()) { + log.info("Invalid inner type for property"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_PROPERTY_INNER_TYPE, innerType, property.getName()); + eitherResult = Either.right(responseFormat); + break; + } + } + + if (!propertyOperation.isPropertyDefaultValueValid(property, allDataTypes.left().value())) { + log.info("Invalid default value for property"); + ResponseFormat responseFormat; + if (type.equals(ToscaPropertyType.LIST.getType()) || type.equals(ToscaPropertyType.MAP.getType())) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_COMPLEX_DEFAULT_VALUE, property.getName(), type, innerType, property.getDefaultValue()); + } else { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_DEFAULT_VALUE, property.getName(), type, property.getDefaultValue()); + } + eitherResult = Either.right(responseFormat); + break; + + } + } + } + return eitherResult; + } + + @Override + public Either, ResponseFormat> deleteMarkedComponents() { + return deleteMarkedComponents(ComponentTypeEnum.RESOURCE); + } + + @Override + public ComponentInstanceBusinessLogic getComponentInstanceBL() { + return vfComponentInstanceBusinessLogic; + } + + private String getComponentTypeForResponse(Component component) { + String componentTypeForResponse = "SERVICE"; + if (component instanceof Resource) { + componentTypeForResponse = ((Resource) component).getResourceType().name(); + } + return componentTypeForResponse; + } + + private Either, ResponseFormat> createGroupsFromYaml(String yamlFileName, Map toscaJson, Resource resource) { + + Map groups = new HashMap(); + Either, ResponseFormat> result = Either.left(groups); + + Either, ResultStatusEnum> eitherNodesTemlates = ImportUtils.findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.GROUPS); + if (eitherNodesTemlates.isLeft()) { + Map jsonNodeTemplates = eitherNodesTemlates.left().value(); + + if (jsonNodeTemplates != null && false == jsonNodeTemplates.isEmpty()) { + Iterator> nodesNameValue = jsonNodeTemplates.entrySet().iterator(); + while (nodesNameValue.hasNext()) { + Entry groupNameValue = nodesNameValue.next(); + + String groupName = groupNameValue.getKey(); + Either eitherNode = createGroupInfo(groupName, groupNameValue.getValue()); + if (eitherNode.isRight()) { + String message = "Failed when creating group: " + groupNameValue.getKey() + " for resource:" + resource.getName(); + BeEcompErrorManager.getInstance().logInternalFlowError("ImportResource", message, ErrorSeverity.INFO); + return Either.right(eitherNode.right().value()); + } else { + GroupDefinition groupDefinition = eitherNode.left().value(); + groups.put(groupName, groupDefinition); + } + } + } + } + + return result; + } + + private Either, ResponseFormat> createInputsFromYaml(String yamlFileName, Map toscaJson, Resource resource) { + + Either, ResultStatusEnum> inputs = ImportUtils.getInputs(toscaJson); + if (inputs.isRight()) { + String message = "Failed when creating inputs: for resource:" + resource.getName(); + BeEcompErrorManager.getInstance().logInternalFlowError("ImportResource", message, ErrorSeverity.INFO); + Map resultMap = new HashMap(); + return Either.left(resultMap); + + } + + Either, ResponseFormat> result = Either.left(inputs.left().value()); + + return result; + } + + private Either createGroupInfo(String groupName, Object groupTemplateJson) { + + GroupDefinition groupInfo = new GroupDefinition(); + groupInfo.setName(groupName); + Either result = Either.left(groupInfo); + + try { + if (groupTemplateJson != null && groupTemplateJson instanceof Map) { + Map groupTemplateJsonMap = (Map) groupTemplateJson; + // Type + String groupType = null; + if (groupTemplateJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + groupType = (String) groupTemplateJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName()); + groupInfo.setType(groupType); + } else { + log.debug("The 'type' member is not found under group {}", groupName); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE)); + } + + if (groupTemplateJsonMap.containsKey(ToscaTagNamesEnum.DESCRIPTION.getElementName())) { + groupInfo.setDescription((String) groupTemplateJsonMap.get(ToscaTagNamesEnum.DESCRIPTION.getElementName())); + } + + if (groupTemplateJsonMap.containsKey(ToscaTagNamesEnum.MEMBERS.getElementName())) { + Object members = groupTemplateJsonMap.get(ToscaTagNamesEnum.MEMBERS.getElementName()); + if (members != null) { + if (members instanceof List) { + Map membersLoaded = new HashMap<>(); + List membersAsList = (List) members; + for (Object member : membersAsList) { + membersLoaded.put(member.toString(), ""); + } + groupInfo.setMembers(membersLoaded); + } else { + log.debug("The 'type' member is not found under group {}", groupName); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE)); + } + } + } + + if (groupTemplateJsonMap.containsKey(ToscaTagNamesEnum.PROPERTIES.getElementName())) { + Object properties = groupTemplateJsonMap.get(ToscaTagNamesEnum.PROPERTIES.getElementName()); + + Either, ResponseFormat> regResponse = createPropertiesValueModuleFromYaml(properties, groupName, groupType); + if (regResponse.isRight()) + return Either.right(regResponse.right().value()); + if (regResponse.left().value().size() > 0) { + groupInfo.setProperties(regResponse.left().value()); + } + } + + } else { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE)); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create group"); + log.debug("error when creating group, message:{}", e.getMessage(), e); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + } + + return result; + } + + private Either, ResponseFormat> createPropertiesValueModuleFromYaml(Object properties, String groupName, String groupType) { + + List result = new ArrayList<>(); + + if (properties == null) { + return Either.left(result); + } + + Either groupTypeRes = groupTypeOperation.getLatestGroupTypeByType(groupType, true); + + if (groupTypeRes.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_MISSING_GROUP_TYPE, groupType)); + } + + Map gtProperties = new HashMap<>(); + GroupTypeDefinition groupTypeDefinition = groupTypeRes.left().value(); + + List propertiesDef = groupTypeDefinition.getProperties(); + + if (propertiesDef != null) { + gtProperties = propertiesDef.stream().collect(Collectors.toMap(p -> p.getName(), p -> p)); + } + + if (properties != null) { + + if (properties instanceof Map) { + + Map props = (Map) properties; + for (Entry entry : props.entrySet()) { + + String propName = entry.getKey(); + Object value = entry.getValue(); + + PropertyDefinition gtDefinition = gtProperties.get(propName); + if (gtDefinition == null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GROUP_PROPERTY_NOT_FOUND, propName, groupName, groupType)); + } + + ToscaPropertyType type = ToscaPropertyType.isValidType(gtDefinition.getType()); + + String convertedValue = null; + if (value != null) { + if (type == null || value instanceof Map || value instanceof List) { + convertedValue = gson.toJson(value); + } else { + convertedValue = value.toString(); + } + } + + GroupProperty groupProperty = new GroupProperty(); + groupProperty.setValue(convertedValue); + groupProperty.setName(propName); + + log.debug("After building group property {}", groupProperty); + + result.add(groupProperty); + } + + } + + } + + return Either.left(result); + } + + public Either getLatestResourceFromCsarUuid(String csarUuid, User user) { + + // validate user + if (user != null) { + Either userValidation = validateUserExists(user, "Get resource from csar UUID", false); + if (userValidation.isRight()) { + return Either.right(userValidation.right().value()); + } + } + + // get resource from csar uuid + Either either = resourceOperation.getLatestResourceByCsarOrName(csarUuid, ""); + if (either.isRight()) { + ResponseFormat resp = componentsUtils.getResponseFormat(ActionStatus.RESOURCE_FROM_CSAR_NOT_FOUND, csarUuid); + return Either.right(resp); + } + + return Either.left(either.left().value()); + } + + @Override + public Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + return null; + } + + private Either>, ResponseFormat> getValidComponentInstanceCapabilities(Map> defaultCapabilities, Map> uploadedCapabilities) { + ResponseFormat responseFormat; + Map> validCapabilitiesMap = new HashMap<>(); + + for (Entry> uploadedCapabilitiesEntry : uploadedCapabilities.entrySet()) { + String capabilityType = uploadedCapabilitiesEntry.getValue().get(0).getType(); + if (!defaultCapabilities.containsKey(capabilityType)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_CAPABILITY_TYPE, capabilityType); + return Either.right(responseFormat); + } else { + CapabilityDefinition delaultCapability = defaultCapabilities.get(capabilityType).get(0); + Either validationRes = validateUniquenessUpdateUploadedComponentInstanceCapability(delaultCapability, uploadedCapabilitiesEntry.getValue().get(0)); + if (validationRes.isRight()) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NAME_ALREADY_EXISTS, validationRes.right().value()); + return Either.right(responseFormat); + } + List validCapabilityList = new ArrayList<>(); + validCapabilityList.add(delaultCapability); + validCapabilitiesMap.put(uploadedCapabilitiesEntry.getKey(), validCapabilityList); + } + } + return Either.left(validCapabilitiesMap); + } + + private Either validateUniquenessUpdateUploadedComponentInstanceCapability(CapabilityDefinition defaultCapability, UploadCapInfo uploadedCapability) { + List validProperties = new ArrayList<>(); + Map defaultProperties = defaultCapability.getProperties().stream().collect(Collectors.toMap(PropertyDefinition::getName, Function.identity())); + List uploadedProperties = uploadedCapability.getProperties(); + for (UploadPropInfo property : uploadedProperties) { + String propertyName = property.getName().toLowerCase(); + String propertyType = property.getType(); + ComponentInstanceProperty validProperty; + if (defaultProperties.containsKey(propertyName)) { + if (propertyType != null && !defaultProperties.get(propertyName).getType().equals(propertyType)) { + return Either.right(propertyName); + } + } + validProperty = new ComponentInstanceProperty(); + validProperty.setName(propertyName); + if (property.getValue() != null) + validProperty.setValue(property.getValue().toString()); + validProperty.setDescription(property.getDescription()); + validProperty.setPassword(property.isPassword()); + validProperties.add(validProperty); + } + defaultCapability.setProperties(validProperties); + return Either.left(true); + } + + public ICacheMangerOperation getCacheManagerOperation() { + return cacheManagerOperation; + } + + public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) { + this.cacheManagerOperation = cacheManagerOperation; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java new file mode 100644 index 0000000000..329481a546 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResourceImportManager.java @@ -0,0 +1,921 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.servlet.ServletContext; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.auditing.api.IAuditingManager; +import org.openecomp.sdc.be.components.impl.ImportUtils.Constants; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.InterfaceDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityTypeOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.WebApplicationContext; +import org.yaml.snakeyaml.Yaml; + +import fj.data.Either; + +@Component("resourceImportManager") +public class ResourceImportManager { + + private ServletContext servletContext; + + @Autowired + private IAuditingManager auditingManager; + + @Autowired + private ResourceBusinessLogic resourceBusinessLogic; + + @Autowired + private IGraphLockOperation graphLockOperation; + + @Autowired + protected ComponentsUtils componentsUtils; + + @Autowired + protected ResourceOperation resourceOperation; + + @Autowired + protected CapabilityTypeOperation capabilityTypeOperation; + + private ResponseFormatManager responseFormatManager; + + private static Logger log = LoggerFactory.getLogger(ResourceImportManager.class.getName()); + + public Either, ResponseFormat> importNormativeResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator, boolean createNewVersion, boolean needLock) { + + LifecycleChangeInfoWithAction lifecycleChangeInfo = new LifecycleChangeInfoWithAction(); + lifecycleChangeInfo.setUserRemarks("certification on import"); + Function> validator = (resource) -> resourceBusinessLogic.validatePropertiesDefaultValues(resource); + + return importCertifiedResource(resourceYml, resourceMetaData, creator, validator, lifecycleChangeInfo, false, createNewVersion, needLock); + } + + public Either, ResponseFormat> importCertifiedResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator, Function> validationFunction, + LifecycleChangeInfoWithAction lifecycleChangeInfo, boolean isInTransaction, boolean createNewVersion, boolean needLock) { + Resource resource = new Resource(); + ImmutablePair responsePair = new ImmutablePair(resource, ActionStatus.CREATED); + Either, ResponseFormat> response = Either.left(responsePair); + + String latestCertifiedResourceId = null; + try { + setConstantMetaData(resource); + setMetaDataFromJson(resourceMetaData, resource); + + Either validateResourceFromYaml = populateResourceFromYaml(resourceYml, resource, isInTransaction); + if (validateResourceFromYaml.isRight()) { + ResponseFormat validationErrorResponse = validateResourceFromYaml.right().value(); + auditErrorImport(resourceMetaData, creator, validationErrorResponse, true); + return Either.right(validationErrorResponse); + + } + + Either isValidResource = validationFunction.apply(resource); + if (isValidResource.isLeft()) { + // The flag createNewVersion if false doesn't create new version + if (!createNewVersion) { + Either latestByName = resourceOperation.getLatestByName(resource.getName(), isInTransaction); + if (latestByName.isLeft()) { + return Either.right(componentsUtils.getResponseFormatByResource(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, resource)); + } + } + + response = resourceBusinessLogic.createOrUpdateResourceByImport(resource, creator, true, isInTransaction, needLock); + if (response.isLeft()) { + resource = response.left().value().left; + latestCertifiedResourceId = getLatestCertifiedResourceId(resource); + Either certificationResponse = resourceBusinessLogic.propagateStateToCertified(creator, resource, lifecycleChangeInfo, isInTransaction, needLock); + if (certificationResponse.isRight()) { + response = Either.right(certificationResponse.right().value()); + } else { + responsePair = new ImmutablePair(certificationResponse.left().value(), response.left().value().right); + response = Either.left(responsePair); + } + } + } else { + ResponseFormat validationErrorResponse = isValidResource.right().value(); + auditErrorImport(resourceMetaData, creator, validationErrorResponse, true); + response = Either.right(validationErrorResponse); + } + + } catch (RuntimeException e) { + ResponseFormat exceptionResponse = handleImportResourceExecption(resourceMetaData, creator, true, e); + response = Either.right(exceptionResponse); + } finally { + if (latestCertifiedResourceId != null && needLock) { + log.debug("unlock resource {}", latestCertifiedResourceId); + graphLockOperation.unlockComponent(latestCertifiedResourceId, NodeTypeEnum.Resource); + } + } + + return response; + } + + private String getLatestCertifiedResourceId(Resource resource) { + Map allVersions = resource.getAllVersions(); + Double latestCertifiedVersion = 0.0; + if (allVersions != null) { + for (String version : allVersions.keySet()) { + Double dVersion = Double.valueOf(version); + if ((dVersion > latestCertifiedVersion) && (version.endsWith(".0"))) { + latestCertifiedVersion = dVersion; + } + } + return allVersions.get(String.valueOf(latestCertifiedVersion)); + } else { + return null; + } + } + + public Either, ResponseFormat> importUserDefinedResource(String resourceYml, UploadResourceInfo resourceMetaData, User creator, boolean isReusable, boolean isInTransaction) { + + Resource resource = new Resource(); + ImmutablePair responsePair = new ImmutablePair(resource, ActionStatus.CREATED); + Either, ResponseFormat> response = Either.left(responsePair); + + try { + setMetaDataFromJson(resourceMetaData, resource); + + Either validateResourceFromYaml = populateResourceFromYaml(resourceYml, resource, isInTransaction); + if (validateResourceFromYaml.isRight()) { + ResponseFormat validationErrorResponse = validateResourceFromYaml.right().value(); + auditErrorImport(resourceMetaData, creator, validationErrorResponse, false); + return Either.right(validationErrorResponse); + + } + + // currently import VF isn't supported. In future will be supported + // import VF only with CSER file!! + if (ResourceTypeEnum.VF.equals(resource.getResourceType())) { + log.debug("Now import VF isn't supported. It will be supported in future with CSER file only"); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + Either validateDerivedFromNotEmpty = resourceBusinessLogic.validateDerivedFromNotEmpty(creator, resource, AuditingActionEnum.CREATE_RESOURCE); + if (validateDerivedFromNotEmpty.isRight()) { + return Either.right(validateDerivedFromNotEmpty.right().value()); + } + + Either validatePropertiesTypes = resourceBusinessLogic.validatePropertiesDefaultValues(resource); + + if (validatePropertiesTypes.isLeft()) { + response = resourceBusinessLogic.createOrUpdateResourceByImport(resource, creator, false, isInTransaction, true); + } else { + ResponseFormat validationErrorResponse = validatePropertiesTypes.right().value(); + auditErrorImport(resourceMetaData, creator, validationErrorResponse, false); + response = Either.right(validationErrorResponse); + } + + } catch (RuntimeException e) { + ResponseFormat exceptionResponse = handleImportResourceExecption(resourceMetaData, creator, false, e); + response = Either.right(exceptionResponse); + } + + return response; + + } + + private Either populateResourceFromYaml(String resourceYml, Resource resource, boolean inTransaction) { + @SuppressWarnings("unchecked") + Either eitherResult = Either.left(true); + Map toscaJsonAll = (Map) new Yaml().load(resourceYml); + Map toscaJson = toscaJsonAll; + + // Checks if exist and builds the node_types map + if (toscaJsonAll.containsKey(ToscaTagNamesEnum.NODE_TYPES.getElementName())) { + toscaJson = new HashMap(); + toscaJson.put(ToscaTagNamesEnum.NODE_TYPES.getElementName(), toscaJsonAll.get(ToscaTagNamesEnum.NODE_TYPES.getElementName())); + } + // Derived From + Either setDerivedFrom = setDerivedFrom(toscaJson, resource, inTransaction); + if (setDerivedFrom.isRight()) { + return Either.right(setDerivedFrom.right().value()); + } + Resource parentResource = setDerivedFrom.left().value(); + setToscaResourceName(toscaJson, resource); + setAttributes(toscaJson, resource); + eitherResult = setCapabilities(toscaJson, resource, parentResource); + if (eitherResult.isRight()) + return eitherResult; + setProperties(toscaJson, resource); + eitherResult = setRequirements(toscaJson, resource, parentResource); + if (eitherResult.isRight()) + return eitherResult; + setInterfaceLifecycle(toscaJson, resource); + + return eitherResult; + } + + private void setToscaResourceName(Map toscaJson, Resource resource) { + Either, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.NODE_TYPES); + if (toscaElement.isLeft() || toscaElement.left().value().size() == 1) { + String toscaResourceName = toscaElement.left().value().keySet().iterator().next(); + resource.setToscaResourceName(toscaResourceName); + } + } + + private void setInterfaceLifecycle(Map toscaJson, Resource resource) { + Either, ResultStatusEnum> toscaInterfaces = ImportUtils.findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.INTERFACES); + if (toscaInterfaces.isLeft()) { + Map jsonInterfaces = toscaInterfaces.left().value(); + Map moduleInterfaces = new HashMap(); + Iterator> interfacesNameValue = jsonInterfaces.entrySet().iterator(); + while (interfacesNameValue.hasNext()) { + Entry interfaceNameValue = interfacesNameValue.next(); + Either eitherInterface = createModuleInterface(interfaceNameValue.getValue()); + if (eitherInterface.isRight()) { + log.info("error when creating interface:{}, for resource:{}", interfaceNameValue.getKey(), resource.getName()); + } else { + moduleInterfaces.put(interfaceNameValue.getKey(), eitherInterface.left().value()); + } + + } + if (moduleInterfaces.size() > 0) { + resource.setInterfaces(moduleInterfaces); + } + } + } + + private Either createModuleInterface(Object interfaceJson) { + InterfaceDefinition interf = new InterfaceDefinition(); + Either result = Either.left(interf); + + try { + if (interfaceJson instanceof String) { + String requirementJsonString = (String) interfaceJson; + interf.setType(requirementJsonString); + } else if (interfaceJson instanceof Map) { + Map requirementJsonMap = (Map) interfaceJson; + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + String type = (String) requirementJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName()); + interf.setType(type); + interf.setUniqueId(type.toLowerCase()); + } + } else { + result = Either.right(ResultStatusEnum.GENERAL_ERROR); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Import Resource- create interface"); + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource- create interface"); + log.debug("error when creating interface, message:{}", e.getMessage(), e); + result = Either.right(ResultStatusEnum.GENERAL_ERROR); + } + + return result; + } + + private Either setRequirements(Map toscaJson, Resource resource, Resource parentResource) {// Note that parentResource can be null + Either eitherResult = Either.left(true); + Either, ResultStatusEnum> toscaRequirements = ImportUtils.findFirstToscaListElement(toscaJson, ToscaTagNamesEnum.REQUIREMENTS); + if (toscaRequirements.isLeft()) { + List jsonRequirements = toscaRequirements.left().value(); + Map> moduleRequirements = new HashMap>(); + // Checking for name duplication + Set reqNames = new HashSet<>(); + // Getting flattened list of capabilities of parent node - cap name + // to cap type + Either, ResponseFormat> reqName2Type = getReqName2Type(parentResource); + if (reqName2Type.isRight()) { + ResponseFormat responseFormat = reqName2Type.right().value(); + log.debug("Error during setting requirements of imported resource: {}", responseFormat); + return Either.right(responseFormat); + } + Map reqName2TypeMap = reqName2Type.left().value(); + for (Object jsonRequirementObj : jsonRequirements) { + // Requirement + Map requirementJsonWrapper = (Map) jsonRequirementObj; + String requirementName = requirementJsonWrapper.keySet().iterator().next(); + String reqNameLowerCase = requirementName.toLowerCase(); + if (reqNames.contains(reqNameLowerCase)) { + log.debug("More than one requirement with same name {} (case-insensitive) in imported TOSCA file is invalid", reqNameLowerCase); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME, "requirement", reqNameLowerCase)); + } + reqNames.add(reqNameLowerCase); + Either eitherRequirement = createRequirementFromImportFile(requirementJsonWrapper.get(requirementName)); + if (eitherRequirement.isRight()) { + log.info("error when creating Requirement:{}, for resource:{}", requirementName, resource.getName()); + return Either.right(eitherRequirement.right().value()); + } + RequirementDefinition requirementDef = eitherRequirement.left().value(); + requirementDef.setName(requirementName); + if (moduleRequirements.containsKey(requirementDef.getCapability())) { + moduleRequirements.get(requirementDef.getCapability()).add(requirementDef); + } else { + List list = new ArrayList(); + list.add(requirementDef); + moduleRequirements.put(requirementDef.getCapability(), list); + } + + // Validating against req/cap of "derived from" node + Either validateVsParentCap = validateCapNameVsDerived(reqName2TypeMap, requirementDef.getCapability(), requirementDef.getName()); + if (validateVsParentCap.isRight()) { + return Either.right(validateVsParentCap.right().value()); + } + if (!validateVsParentCap.left().value()) { + log.debug("Requirement with name {} already exists in parent {}", requirementDef.getName(), parentResource.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED, "requirement", requirementDef.getName().toLowerCase(), parentResource.getName()); + return Either.right(responseFormat); + } + } + if (moduleRequirements.size() > 0) { + resource.setRequirements(moduleRequirements); + } + + } + return eitherResult; + + } + + private Either createRequirementFromImportFile(Object requirementJson) { + RequirementDefinition requirement = new RequirementDefinition(); + Either result = Either.left(requirement); + + try { + if (requirementJson instanceof String) { + String requirementJsonString = (String) requirementJson; + requirement.setCapability(requirementJsonString); + } else if (requirementJson instanceof Map) { + Map requirementJsonMap = (Map) requirementJson; + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.CAPABILITY.getElementName())) { + requirement.setCapability((String) requirementJsonMap.get(ToscaTagNamesEnum.CAPABILITY.getElementName())); + } + + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.NODE.getElementName())) { + requirement.setNode((String) requirementJsonMap.get(ToscaTagNamesEnum.NODE.getElementName())); + } + + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.RELATIONSHIP.getElementName())) { + requirement.setRelationship((String) requirementJsonMap.get(ToscaTagNamesEnum.RELATIONSHIP.getElementName())); + } + if (requirementJsonMap.containsKey(ToscaTagNamesEnum.OCCURRENCES.getElementName())) { + List occurrencesList = (List) requirementJsonMap.get(ToscaTagNamesEnum.OCCURRENCES.getElementName()); + Either validateAndSetOccurrencesStatus = validateOccurrences(occurrencesList); + if (validateAndSetOccurrencesStatus.isRight()) { + result = Either.right(validateAndSetOccurrencesStatus.right().value()); + return result; + } + if (validateAndSetOccurrencesStatus.left().value() == true) { + requirement.setMinOccurrences(occurrencesList.get(0).toString()); + requirement.setMaxOccurrences(occurrencesList.get(1).toString()); + } + + } + } else { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Import Resource - create Requirement"); + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create Requirement"); + log.debug("error when creating requirement, message:{}", e.getMessage(), e); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + } + + return result; + } + + private ResultStatusEnum setProperties(Map toscaJson, Resource resource) { + Map reducedToscaJson = new HashMap<>(toscaJson); + ImportUtils.removeElementFromJsonMap(reducedToscaJson, "capabilities"); + ResultStatusEnum result = ResultStatusEnum.OK; + Either, ResultStatusEnum> properties = ImportUtils.getProperties(reducedToscaJson); + if (properties.isLeft()) { + List propertiesList = new ArrayList<>(); + Map value = properties.left().value(); + if (value != null) { + for (Entry entry : value.entrySet()) { + String name = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + propertyDefinition.setName(name); + propertiesList.add(propertyDefinition); + } + } + resource.setProperties(propertiesList); + } else { + result = properties.right().value(); + } + return result; + } + + private ResultStatusEnum setAttributes(Map toscaJson, Resource resource) { + ResultStatusEnum result = ResultStatusEnum.OK; + Either, ResultStatusEnum> attributes = ImportUtils.getAttributes(toscaJson); + if (attributes.isLeft()) { + List attributeList = new ArrayList<>(); + Map value = attributes.left().value(); + if (value != null) { + for (Entry entry : value.entrySet()) { + String name = entry.getKey(); + AttributeDefinition attributeDef = entry.getValue(); + attributeDef.setName(name); + attributeList.add(attributeDef); + } + } + resource.setAttributes(attributeList); + } else { + result = attributes.right().value(); + } + return result; + } + + private Either setDerivedFrom(Map toscaJson, Resource resource, boolean inTransaction) { + Either toscaDerivedFromElement = ImportUtils.findFirstToscaStringElement(toscaJson, ToscaTagNamesEnum.DERIVED_FROM); + Resource derivedFromResource = null; + if (toscaDerivedFromElement.isLeft()) { + String derivedFrom = toscaDerivedFromElement.left().value(); + log.debug("Derived from TOSCA name is {}", derivedFrom); + resource.setDerivedFrom(Arrays.asList(new String[] { derivedFrom })); + Either latestByToscaResourceName = resourceOperation.getLatestByToscaResourceName(derivedFrom, inTransaction); + if (latestByToscaResourceName.isRight()) { + StorageOperationStatus operationStatus = latestByToscaResourceName.right().value(); + if (operationStatus.equals(StorageOperationStatus.NOT_FOUND)) { + operationStatus = StorageOperationStatus.PARENT_RESOURCE_NOT_FOUND; + } + log.debug("Error when fetching parent resource {}, error: {}", derivedFrom, operationStatus); + ActionStatus convertFromStorageResponse = componentsUtils.convertFromStorageResponse(operationStatus); + BeEcompErrorManager.getInstance().logBeComponentMissingError("Import TOSCA YAML", "resource", derivedFrom); + return Either.right(componentsUtils.getResponseFormat(convertFromStorageResponse, derivedFrom)); + } + derivedFromResource = latestByToscaResourceName.left().value(); + } + return Either.left(derivedFromResource); + } + + private Either setCapabilities(Map toscaJson, Resource resource, Resource parentResource) {// Note that parentResource can be null + Either eitherResult = Either.left(true); + Either, ResultStatusEnum> toscaCapabilities = ImportUtils.findFirstToscaMapElement(toscaJson, ToscaTagNamesEnum.CAPABILITIES); + if (toscaCapabilities.isLeft()) { + Map jsonCapabilities = toscaCapabilities.left().value(); + Map> moduleCapabilities = new HashMap>(); + Iterator> capabilitiesNameValue = jsonCapabilities.entrySet().iterator(); + Set capNames = new HashSet<>(); + // Getting flattened list of capabilities of parent node - cap name + // to cap type + Either, ResponseFormat> capName2Type = getCapName2Type(parentResource); + if (capName2Type.isRight()) { + ResponseFormat responseFormat = capName2Type.right().value(); + log.debug("Error during setting capabilities of imported resource: {}", responseFormat); + return Either.right(responseFormat); + } + Map capName2TypeMap = capName2Type.left().value(); + while (capabilitiesNameValue.hasNext()) { + Entry capabilityNameValue = capabilitiesNameValue.next(); + + // Validating that no req/cap duplicates exist in imported YAML + String capNameLowerCase = capabilityNameValue.getKey().toLowerCase(); + if (capNames.contains(capNameLowerCase)) { + log.debug("More than one capability with same name {} (case-insensitive) in imported TOSCA file is invalid", capNameLowerCase); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.IMPORT_DUPLICATE_REQ_CAP_NAME, "capability", capNameLowerCase)); + } + capNames.add(capNameLowerCase); + + Either eitherCapability = createCapabilityFromImportFile(capabilityNameValue.getValue()); + if (eitherCapability.isRight()) { + log.debug("error when creating capability:{}, for resource:{}", capabilityNameValue.getKey(), resource.getName()); + return Either.right(eitherCapability.right().value()); + } + + CapabilityDefinition capabilityDef = eitherCapability.left().value(); + capabilityDef.setName(capabilityNameValue.getKey()); + if (moduleCapabilities.containsKey(capabilityDef.getType())) { + moduleCapabilities.get(capabilityDef.getType()).add(capabilityDef); + } else { + List list = new ArrayList(); + list.add(capabilityDef); + moduleCapabilities.put(capabilityDef.getType(), list); + } + + // Validating against req/cap of "derived from" node + Either validateVsParentCap = validateCapNameVsDerived(capName2TypeMap, capabilityDef.getType(), capabilityDef.getName()); + if (validateVsParentCap.isRight()) { + return Either.right(validateVsParentCap.right().value()); + } + if (!validateVsParentCap.left().value()) { + // Here parentResource is for sure not null, so it's + // null-safe + log.debug("Capability with name {} already exists in parent {}", capabilityDef.getName(), parentResource.getName()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED, "capability", capabilityDef.getName().toLowerCase(), parentResource.getName()); + return Either.right(responseFormat); + } + } + if (moduleCapabilities.size() > 0) { + resource.setCapabilities(moduleCapabilities); + } + } + + return eitherResult; + + } + + private Either, ResponseFormat> getCapName2Type(Resource parentResource) { + Map capName2type = new HashMap<>(); + if (parentResource != null) { + Map> capabilities = parentResource.getCapabilities(); + if (capabilities != null) { + for (List capDefinitions : capabilities.values()) { + for (CapabilityDefinition capDefinition : capDefinitions) { + String nameLowerCase = capDefinition.getName().toLowerCase(); + if (capName2type.get(nameLowerCase) != null) { + String parentResourceName = parentResource.getName(); + log.debug("Resource with name {} has more than one capability with name {}, ignoring case", parentResourceName, nameLowerCase); + BeEcompErrorManager.getInstance().logInternalDataError("Import resource", "Parent resource " + parentResourceName + " of imported resource has one or more capabilities with name " + nameLowerCase, ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + capName2type.put(nameLowerCase, capDefinition.getType()); + } + } + } + } + return Either.left(capName2type); + } + + private Either, ResponseFormat> getReqName2Type(Resource parentResource) { + Map reqName2type = new HashMap<>(); + if (parentResource != null) { + Map> requirements = parentResource.getRequirements(); + if (requirements != null) { + for (List reqDefinitions : requirements.values()) { + for (RequirementDefinition reqDefinition : reqDefinitions) { + String nameLowerCase = reqDefinition.getName().toLowerCase(); + if (reqName2type.get(nameLowerCase) != null) { + String parentResourceName = parentResource.getName(); + log.debug("Resource with name {} has more than one requirement with name {}, ignoring case", parentResourceName, nameLowerCase); + BeEcompErrorManager.getInstance().logInternalDataError("Import resource", "Parent resource " + parentResourceName + " of imported resource has one or more requirements with name " + nameLowerCase, ErrorSeverity.ERROR); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + reqName2type.put(nameLowerCase, reqDefinition.getCapability()); + } + } + } + } + return Either.left(reqName2type); + } + + private Either validateCapNameVsDerived(Map parentCapName2Type, String childCapabilityType, String reqCapName) { + String capNameLowerCase = reqCapName.toLowerCase(); + log.trace("Validating capability {} vs parent resource", capNameLowerCase); + String parentCapType = parentCapName2Type.get(capNameLowerCase); + if (parentCapType != null) { + if (childCapabilityType.equals(parentCapType)) { + log.debug("Capability with name {} is of same type {} for imported resource and its parent - this is OK", capNameLowerCase, childCapabilityType); + return Either.left(true); + } + Either capabilityTypeDerivedFrom = capabilityTypeOperation.isCapabilityTypeDerivedFrom(childCapabilityType, parentCapType); + if (capabilityTypeDerivedFrom.isRight()) { + log.debug("Couldn't check whether imported resource capability derives from its parent's capability"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(capabilityTypeDerivedFrom.right().value())); + return Either.right(responseFormat); + } + return Either.left(capabilityTypeDerivedFrom.left().value()); + } + return Either.left(true); + } + + private Either createCapabilityFromImportFile(Object capabilityJson) { + + CapabilityDefinition capabilityDefinition = new CapabilityDefinition(); + Either result = Either.left(capabilityDefinition); + + try { + if (capabilityJson instanceof String) { + String capabilityJsonString = (String) capabilityJson; + capabilityDefinition.setType(capabilityJsonString); + } else if (capabilityJson instanceof Map) { + Map capabilityJsonMap = (Map) capabilityJson; + // Type + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.TYPE.getElementName())) { + capabilityDefinition.setType((String) capabilityJsonMap.get(ToscaTagNamesEnum.TYPE.getElementName())); + } + // ValidSourceTypes + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())) { + capabilityDefinition.setValidSourceTypes((List) capabilityJsonMap.get(ToscaTagNamesEnum.VALID_SOURCE_TYPES.getElementName())); + } + // ValidSourceTypes + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.DESCRIPTION.getElementName())) { + capabilityDefinition.setDescription((String) capabilityJsonMap.get(ToscaTagNamesEnum.DESCRIPTION.getElementName())); + } + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.OCCURRENCES.getElementName())) { + List occurrencesList = (List) capabilityJsonMap.get(ToscaTagNamesEnum.OCCURRENCES.getElementName()); + Either validateAndSetOccurrencesStatus = validateOccurrences(occurrencesList); + if (validateAndSetOccurrencesStatus.isRight()) { + result = Either.right(validateAndSetOccurrencesStatus.right().value()); + return result; + } + if (validateAndSetOccurrencesStatus.left().value() == true) { + capabilityDefinition.setMinOccurrences(occurrencesList.get(0).toString()); + capabilityDefinition.setMaxOccurrences(occurrencesList.get(1).toString()); + } + } + if (capabilityJsonMap.containsKey(ToscaTagNamesEnum.PROPERTIES.getElementName())) { + + Either, ResultStatusEnum> propertiesRes = ImportUtils.getProperties(capabilityJsonMap); + if (propertiesRes.isRight()) { + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.PROPERTY_NOT_FOUND)); + return result; + } else { + propertiesRes.left().value().entrySet().stream().forEach(e -> e.getValue().setName(e.getKey().toLowerCase())); + List capabilityProperties = propertiesRes.left().value().values().stream().map(p -> new ComponentInstanceProperty(p, p.getDefaultValue(), null)).collect(Collectors.toList()); + capabilityDefinition.setProperties(capabilityProperties); + } + } + } else { + + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Import Resource - create capability"); + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource - create capability"); + log.debug("error when creating capability, message:{}", e.getMessage(), e); + result = Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_YAML)); + } + + return result; + } + + private ResponseFormat handleImportResourceExecption(UploadResourceInfo resourceMetaData, User user, boolean isNormative, RuntimeException e) { + String payloadName = (resourceMetaData != null) ? resourceMetaData.getPayloadName() : ""; + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Import Resource " + payloadName); + BeEcompErrorManager.getInstance().logBeSystemError("Import Resource " + payloadName); + + log.debug("Error when importing resource from payload:{} Exception text: {}", payloadName, e.getMessage(), e); + ResponseFormat errorResponseWrapper = getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR); + auditErrorImport(resourceMetaData, user, errorResponseWrapper, isNormative); + return errorResponseWrapper; + } + + private void auditErrorImport(UploadResourceInfo resourceMetaData, User user, ResponseFormat errorResponseWrapper, boolean isNormative) { + EnumMap auditingFields = new EnumMap<>(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, AuditingActionEnum.IMPORT_RESOURCE.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceMetaData.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, ComponentTypeEnum.RESOURCE.getValue()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, user.getUserId()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, errorResponseWrapper.getStatus()); + String message = ""; + if (errorResponseWrapper.getMessageId() != null) { + message = errorResponseWrapper.getMessageId() + ": "; + } + message += errorResponseWrapper.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, user.getFirstName() + " " + user.getLastName()); + + String version, lifeCycleState; + if (isNormative) { + version = Constants.FIRST_CERTIFIED_VERSION_VERSION; + lifeCycleState = LifecycleStateEnum.CERTIFIED.name(); + } else { + version = ""; + lifeCycleState = LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name(); + + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, version); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, lifeCycleState); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TOSCA_NODE_TYPE, ""); + + getAuditingManager().auditEvent(auditingFields); + } + + private void setMetaDataFromJson(UploadResourceInfo resourceMetaData, Resource resource) { + resource.setTags(resourceMetaData.getTags()); + List categories = resourceMetaData.getCategories(); + resource.setCategories(categories); + resource.setDescription(resourceMetaData.getDescription()); + resource.setIcon(resourceMetaData.getResourceIconPath()); + resource.setName(resourceMetaData.getName()); + if (categories != null && !categories.isEmpty()) { + CategoryDefinition categoryDef = categories.get(0); + resource.setAbstract(false); + if (categoryDef != null && categoryDef.getName() != null && categoryDef.getName().equals(Constants.ABSTRACT_CATEGORY_NAME)) { + SubCategoryDefinition subCategoryDef = categoryDef.getSubcategories().get(0); + if (subCategoryDef != null && subCategoryDef.getName().equals(Constants.ABSTRACT_SUBCATEGORY)) { + resource.setAbstract(true); + } + } + } + resource.setContactId(resourceMetaData.getContactId()); + resource.setCreatorUserId(resourceMetaData.getContactId()); + + if (resourceMetaData.getVendorName() != null) { + resource.setVendorName(resourceMetaData.getVendorName()); + } + + if (resourceMetaData.getVendorRelease() != null) { + resource.setVendorRelease(resourceMetaData.getVendorRelease()); + } + + resource.setResourceType(ResourceTypeEnum.valueOf(resourceMetaData.getResourceType())); + + } + + private void setConstantMetaData(Resource resource) { + resource.setVersion(ImportUtils.Constants.FIRST_CERTIFIED_VERSION_VERSION); + ; + resource.setLifecycleState(ImportUtils.Constants.NORMATIVE_TYPE_LIFE_CYCLE); + resource.setHighestVersion(ImportUtils.Constants.NORMATIVE_TYPE_HIGHEST_VERSION); + resource.setVendorName(ImportUtils.Constants.VENDOR_NAME); + resource.setVendorRelease(ImportUtils.Constants.VENDOR_RELEASE); + + } + + private Either validateOccurrences(List occurrensesList) { + + if (!ValidationUtils.validateListNotEmpty(occurrensesList)) { + log.debug("Occurrenses list empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + + if (occurrensesList.size() < 2) { + log.debug("Occurrenses list size not 2"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + Object minObj = occurrensesList.get(0); + Object maxObj = occurrensesList.get(1); + Integer minOccurrences = null; + Integer maxOccurrences = null; + if (minObj instanceof Integer) + minOccurrences = (Integer) minObj; + else { + log.debug("Invalid occurrenses format. low_bound occurrense must be Integer {}", minObj); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + if (minOccurrences < 0) { + log.debug("Invalid occurrenses format.low_bound occurrense negative {}", minOccurrences); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + + if (maxObj instanceof String) { + if (maxObj.equals("UNBOUNDED")) { + return Either.left(true); + } else { + log.debug("Invalid occurrenses format. Max occurrence is {}", maxObj); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + } else { + if (maxObj instanceof Integer) + maxOccurrences = (Integer) maxObj; + else { + log.debug("Invalid occurrenses format. Max occurrence is {}", maxObj); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + + if (maxOccurrences <= 0 || maxOccurrences < minOccurrences) { + log.debug("Invalid occurrenses format. min occurrence is {}. Max occurrence is {}", minOccurrences, maxOccurrences); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_OCCURRENCES); + return Either.right(responseFormat); + } + } + + return Either.left(true); + + } + + public void init(ServletContext servletContext) { + if (this.servletContext == null) { + synchronized (this) { + if (this.servletContext == null) { + this.servletContext = servletContext; + responseFormatManager = ResponseFormatManager.getInstance(); + resourceBusinessLogic = getResourceBL(servletContext); + } + } + } + } + + public boolean isResourceExist(String resourceName) { + return resourceBusinessLogic.isResourceExist(resourceName); + } + + private ResourceBusinessLogic getResourceBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(org.openecomp.sdc.common.api.Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ResourceBusinessLogic resourceBl = webApplicationContext.getBean(ResourceBusinessLogic.class); + return resourceBl; + } + + public ServletContext getServletContext() { + return servletContext; + } + + public IAuditingManager getAuditingManager() { + return auditingManager; + } + + public ResponseFormatManager getResponseFormatManager() { + return responseFormatManager; + } + + public void setResponseFormatManager(ResponseFormatManager responseFormatManager) { + this.responseFormatManager = responseFormatManager; + } + + public ResourceBusinessLogic getResourceBusinessLogic() { + return resourceBusinessLogic; + } + + public void setResourceBusinessLogic(ResourceBusinessLogic resourceBusinessLogic) { + this.resourceBusinessLogic = resourceBusinessLogic; + } + + public Logger getLog() { + return log; + } + + public static void setLog(Logger log) { + ResourceImportManager.log = log; + } + + public IGraphLockOperation getGraphLockOperation() { + return graphLockOperation; + } + + public void setGraphLockOperation(IGraphLockOperation graphLockOperation) { + this.graphLockOperation = graphLockOperation; + } + + public void setServletContext(ServletContext servletContext) { + this.servletContext = servletContext; + } + + public void setAuditingManager(IAuditingManager auditingManager) { + this.auditingManager = auditingManager; + } + + public void setResourceOperation(ResourceOperation resourceOperation) { + this.resourceOperation = resourceOperation; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResponseFormatManager.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResponseFormatManager.java new file mode 100644 index 0000000000..e8c0bf3d8a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ResponseFormatManager.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.ErrorConfiguration; +import org.openecomp.sdc.be.config.ErrorInfo; +import org.openecomp.sdc.be.config.ErrorInfo.ErrorInfoType; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.OkResponseInfo; +import org.openecomp.sdc.exception.PolicyException; +import org.openecomp.sdc.exception.ResponseFormat; +import org.openecomp.sdc.exception.ServiceException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ResponseFormatManager { + + private volatile static ResponseFormatManager instance; + private static ConfigurationManager configurationManager; + private static Logger log = LoggerFactory.getLogger(ResponseFormatManager.class.getName()); + + public static ResponseFormatManager getInstance() { + if (instance == null) { + + instance = init(); + } + return instance; + } + + private static synchronized ResponseFormatManager init() { + if (instance == null) { + instance = new ResponseFormatManager(); + configurationManager = ConfigurationManager.getConfigurationManager(); + } + return instance; + } + + public ResponseFormat getResponseFormat(ActionStatus responseEnum, String... variables) { + ErrorConfiguration errorConfiguration = configurationManager.getErrorConfiguration(); + ErrorInfo errorInfo = errorConfiguration.getErrorInfo(responseEnum.name()); + if (errorInfo == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.EcompErrorNotFound, "ResponseFormatManager", responseEnum.name()); + log.debug("failed to locate {} in error configuration", responseEnum.name()); + errorInfo = errorConfiguration.getErrorInfo(ActionStatus.GENERAL_ERROR.name()); + } + ResponseFormat errorResponseWrapper = new ResponseFormat(errorInfo.getCode()); + String errorMessage = errorInfo.getMessage(); + String errorMessageId = errorInfo.getMessageId(); + ErrorInfoType errorInfoType = errorInfo.getErrorInfoType(); + if (errorInfoType.equals(ErrorInfoType.SERVICE_EXCEPTION)) { + errorResponseWrapper.setServiceException(new ServiceException(errorMessageId, errorMessage, variables)); + } else if (errorInfoType.equals(ErrorInfoType.POLICY_EXCEPTION)) { + errorResponseWrapper.setPolicyException(new PolicyException(errorMessageId, errorMessage, variables)); + } else if (errorInfoType.equals(ErrorInfoType.OK)) { + errorResponseWrapper.setOkResponseInfo(new OkResponseInfo(errorMessageId, errorMessage, variables)); + } + return errorResponseWrapper; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java new file mode 100644 index 0000000000..6bbe88f30c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceBusinessLogic.java @@ -0,0 +1,1768 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; +import java.util.function.Function; +import java.util.stream.Collectors; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.collections.CollectionUtils; +import org.apache.commons.collections.MapUtils; +import org.openecomp.sdc.be.components.distribution.engine.IDistributionEngine; +import org.openecomp.sdc.be.components.distribution.engine.INotificationData; +import org.openecomp.sdc.be.components.distribution.engine.VfModuleArtifactPayload; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.AuditCassandraDao; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.GroupTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.DistributionTransitionEnum; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IElementOperation; +import org.openecomp.sdc.be.model.operations.api.IServiceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.utils.ComponentValidationUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.resources.data.auditing.AuditingGenericEvent; +import org.openecomp.sdc.be.resources.data.auditing.DistributionDeployEvent; +import org.openecomp.sdc.be.resources.data.auditing.DistributionNotificationEvent; +import org.openecomp.sdc.be.resources.data.auditing.ResourceAdminEvent; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@org.springframework.stereotype.Component("serviceBusinessLogic") +public class ServiceBusinessLogic extends ComponentBusinessLogic { + + private static final String STATUS_SUCCESS_200 = "200"; + + private static final String STATUS_DEPLOYED = "DEPLOYED"; + + @Autowired + private IElementOperation elementDao; + + @Autowired + private IDistributionEngine distributionEngine; + + // @Autowired + // private AuditingDao auditingDao; + + @Autowired + private AuditCassandraDao auditCassandraDao; + + @Autowired + private ServiceComponentInstanceBusinessLogic serviceComponentInstanceBusinessLogic; + + @Autowired + private ICacheMangerOperation cacheManagerOperation; + + private static Logger log = LoggerFactory.getLogger(ServiceBusinessLogic.class.getName()); + private static final String INITIAL_VERSION = "0.1"; + + public ServiceBusinessLogic() { + log.debug("ServiceBusinessLogic started"); + } + + public Either changeServiceDistributionState(String serviceId, String state, LifecycleChangeInfoWithAction commentObj, User user) { + + Either resp = validateUserExists(user.getUserId(), "change Service Distribution State", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.debug("check request state"); + Either validateEnum = validateTransitionEnum(state, user); + if (validateEnum.isRight()) { + return Either.right(validateEnum.right().value()); + } + DistributionTransitionEnum distributionTransition = validateEnum.left().value(); + AuditingActionEnum auditAction = (distributionTransition == DistributionTransitionEnum.APPROVE ? AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_APPROV : AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REJECT); + Either commentResponse = validateComment(commentObj, user, auditAction); + if (commentResponse.isRight()) { + return Either.right(commentResponse.right().value()); + } + String comment = commentResponse.left().value(); + + Either validateService = validateServiceDistributionChange(user, serviceId, auditAction, comment); + if (validateService.isRight()) { + return Either.right(validateService.right().value()); + } + Service service = validateService.left().value(); + DistributionStatusEnum initState = service.getDistributionStatus(); + + Either validateUser = validateUserDistributionChange(user, service, auditAction, comment); + if (validateUser.isRight()) { + return Either.right(validateUser.right().value()); + } + user = validateUser.left().value(); + + // lock resource + /* + * StorageOperationStatus lockResult = graphLockOperation.lockComponent(serviceId, NodeTypeEnum.Service); if (!lockResult.equals(StorageOperationStatus.OK)) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. + * BeFailedLockObjectError, "ChangeServiceDistributionState"); log.debug("Failed to lock service {} error - {}", serviceId, lockResult); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, + * service.getVersion(), service.getServiceName()); + * + * createAudit(user, auditAction, comment, service, responseFormat); return Either.right(componentsUtils.getResponseFormat(ActionStatus. GENERAL_ERROR)); } + */ + Either lockResult = lockComponent(serviceId, service, "ChangeServiceDistributionState"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(responseFormat); + } + + try { + + DistributionStatusEnum newState; + if (distributionTransition == DistributionTransitionEnum.APPROVE) { + newState = DistributionStatusEnum.DISTRIBUTION_APPROVED; + } else { + newState = DistributionStatusEnum.DISTRIBUTION_REJECTED; + } + Either result = serviceOperation.updateDestributionStatus(service, user, newState); + if (result.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "ChangeServiceDistributionState"); + BeEcompErrorManager.getInstance().logBeSystemError("ChangeServiceDistributionState"); + log.debug("service {} is change destribuation status failed", service.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR, service.getVersion(), service.getName()); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + Service updatedService = result.left().value(); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, updatedService.getDistributionStatus().name()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, initState.name()); + createAudit(user, auditAction, comment, updatedService, responseFormat, auditingFields); + return Either.left(result.left().value()); + + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + + } + + public Either>, ResponseFormat> getComponentAuditRecords(String componentVersion, String componentUUID, String userId) { + Either resp = validateUserExists(userId, "get Component Audit Records", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either>, ActionStatus> result; + try { + + // Certified Version + if (componentVersion.endsWith(".0")) { + Either, ActionStatus> eitherAuditingForCertified = auditCassandraDao.getByServiceInstanceId(componentUUID); + if (eitherAuditingForCertified.isLeft()) { + result = Either.left(getAuditingFieldsList(eitherAuditingForCertified.left().value())); + } else { + result = Either.right(eitherAuditingForCertified.right().value()); + } + } + // Uncertified Version + else { + result = getAuditRecordsForUncertifiedComponent(componentUUID, componentVersion); + } + } catch (Exception e) { + log.debug("get Audit Records failed with exception {}", e); + result = Either.right(ActionStatus.GENERAL_ERROR); + } + + if (result.isRight()) { + return Either.right(componentsUtils.getResponseFormat(result.right().value())); + } else { + return Either.left(result.left().value()); + } + + } + + private Either>, ActionStatus> getAuditRecordsForUncertifiedComponent(String componentUUID, String componentVersion) { + // First Query + Either, ActionStatus> eitherprevVerAudit = auditCassandraDao.getAuditByServiceIdAndPrevVersion(componentUUID, componentVersion); + + if (eitherprevVerAudit.isRight()) { + return Either.right(eitherprevVerAudit.right().value()); + } + + // Second Query + Either, ActionStatus> eitherCurrVerAudit = auditCassandraDao.getAuditByServiceIdAndCurrVersion(componentUUID, componentVersion); + if (eitherCurrVerAudit.isRight()) { + return Either.right(eitherCurrVerAudit.right().value()); + } + + List> prevVerAuditList = getAuditingFieldsList(eitherprevVerAudit.left().value()); + List> currVerAuditList = getAuditingFieldsList(eitherCurrVerAudit.left().value()); + + List> duplicateElements = new ArrayList>(); + duplicateElements.addAll(prevVerAuditList); + duplicateElements.retainAll(currVerAuditList); + + List> joinedNonDuplicatedList = new ArrayList>(); + joinedNonDuplicatedList.addAll(prevVerAuditList); + joinedNonDuplicatedList.removeAll(duplicateElements); + joinedNonDuplicatedList.addAll(currVerAuditList); + + return Either.left(joinedNonDuplicatedList); + } + + private List> getAuditingFieldsList(List prevVerAuditList) { + + List> prevVerAudit = new ArrayList>(); + for (AuditingGenericEvent auditEvent : prevVerAuditList) { + auditEvent.fillFields(); + prevVerAudit.add(auditEvent.getFields()); + } + return prevVerAudit; + } + + /** + * createService + * + * @param service + * - Service + * @param user + * - modifier data (userId) + * @return Either + */ + public Either createService(Service service, User user) { + + // get user details + Either eitherCreator = validateUser(user, "Create Service", service, AuditingActionEnum.CREATE_RESOURCE, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either validateRes = validateUserRole(user, service, new ArrayList(), AuditingActionEnum.CREATE_RESOURCE, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + service.setCreatorUserId(user.getUserId()); + + // warn on overridden fields + checkFieldsForOverideAttampt(service); + // enrich object + log.debug("enrich service with version and state"); + service.setState(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT); + service.setVersion(INITIAL_VERSION); + service.setDistributionStatus(DistributionStatusEnum.DISTRIBUTION_NOT_APPROVED); + + Either createServiceResponse = validateServiceBeforeCreate(service, user, AuditingActionEnum.CREATE_RESOURCE); + if (createServiceResponse.isRight()) { + return createServiceResponse; + } + return createServiceByDao(service, AuditingActionEnum.CREATE_RESOURCE, serviceOperation, user); + } + + private void checkFieldsForOverideAttampt(Service service) { + checkComponentFieldsForOverrideAttempt(service); + if ((service.getDistributionStatus() != null)) { + log.info("Distribution Status cannot be defined by user. This field will be overridden by the application"); + } + } + + private Either createServiceByDao(Service service, AuditingActionEnum actionEnum, IServiceOperation dataModel, User user) { + log.debug("send service {} to dao for create", service.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + + Either lockResult = lockComponentByName(service.getSystemName(), service, "Create Service"); + if (lockResult.isRight()) { + ResponseFormat responseFormat = lockResult.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + log.debug("System name locked is {}, status = {}", service.getSystemName(), lockResult); + + try { + + createMandatoryArtifactsData(service, user); + createServiceApiArtifactsData(service, user); + setToscaArtifactsPlaceHolders(service, user); + + Either dataModelResponse = dataModel.createService(service); + + // service created successfully!!! + if (dataModelResponse.isLeft()) { + log.debug("Service created successfully!!!"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + ASDCKpiApi.countCreatedServicesKPI(); + + Service createdService = dataModelResponse.left().value(); + // //add service to cache + // cacheManagerOperation.updateComponentInCache(createdService.getUniqueId(), + // createdService.getLastUpdateDate(), NodeTypeEnum.Service); + + return Either.left(dataModelResponse.left().value()); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormatByComponent(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value()), service, ComponentTypeEnum.SERVICE); + log.debug("audit before sending response"); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + + } finally { + graphLockOperation.unlockComponentByName(service.getSystemName(), service.getUniqueId(), NodeTypeEnum.Service); + } + } + + private void createServiceApiArtifactsData(Service service, User user) { + // create mandatory artifacts + + // TODO it must be removed after that artifact uniqueId creation will be + // moved to ArtifactOperation + // String serviceUniqueId = + // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), + // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion()); + String serviceUniqueId = service.getUniqueId(); + Map artifactMap = service.getArtifacts(); + if (artifactMap == null) + artifactMap = new HashMap(); + + Map serviceApiArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceApiArtifacts(); + List exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory(); + + List categories = service.getCategories(); + boolean isCreateArtifact = true; + if (categories != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) { + for (String exlude : exludeServiceCategory) { + if (exlude.equalsIgnoreCase(categories.get(0).getName())) { + isCreateArtifact = false; + break; + } + } + + } + + if (serviceApiArtifacts != null && isCreateArtifact) { + Set keys = serviceApiArtifacts.keySet(); + for (String serviceApiArtifactName : keys) { + Map artifactInfoMap = (Map) serviceApiArtifacts.get(serviceApiArtifactName); + ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, serviceApiArtifactName, artifactInfoMap, user, true); + artifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.SERVICE_API); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + } + + service.setArtifacts(artifactMap); + } + } + + private Either validateServiceBeforeCreate(Service service, User user, AuditingActionEnum actionEnum) { + + Either validationResponse = validateServiceFieldsBeforeCreate(user, service, actionEnum); + if (validationResponse.isRight()) { + return Either.right(validationResponse.right().value()); + } + service.setCreatorFullName(user.getFirstName() + " " + user.getLastName()); + service.setContactId(service.getContactId().toLowerCase()); + + // Generate invariant UUID - must be here and not in operation since it + // should stay constant during clone + String invariantUUID = UniqueIdBuilder.buildInvariantUUID(); + service.setInvariantUUID(invariantUUID); + + return Either.left(service); + } + + private Either validateServiceFieldsBeforeCreate(User user, Service service, AuditingActionEnum actionEnum) { + Either componentsFieldsValidation = validateComponentFieldsBeforeCreate(user, service, actionEnum); + if (componentsFieldsValidation.isRight()) { + return componentsFieldsValidation; + } + + // validate service name uniqueness + log.debug("validate service name uniqueness"); + Either serviceNameUniquenessValidation = validateComponentNameUnique(user, service, actionEnum); + if (serviceNameUniquenessValidation.isRight()) { + return serviceNameUniquenessValidation; + } + + // validate category + log.debug("validate category"); + Either categoryValidation = validateServiceCategory(user, service, actionEnum); + if (categoryValidation.isRight()) { + return categoryValidation; + } + + log.debug("validate projectName"); + Either projectCodeValidation = validateProjectCode(user, service, actionEnum); + if (projectCodeValidation.isRight()) { + return projectCodeValidation; + } + + return Either.left(true); + + } + + private Either validateServiceCategory(User user, Service service, AuditingActionEnum actionEnum) { + log.debug("validate Service category"); + + if (service.getCategories() == null || service.getCategories().size() == 0) { + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue()); + componentsUtils.auditComponentAdmin(errorResponse, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(errorResponse); + } + + Either validatCategory = validateServiceCategory(service.getCategories()); + if (validatCategory.isRight()) { + ResponseFormat responseFormat = validatCategory.right().value(); + componentsUtils.auditComponentAdmin(responseFormat, user, service, "", "", actionEnum, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + return Either.left(true); + } + + public Either, ResponseFormat> validateServiceNameExists(String serviceName, String userId) { + + Either resp = validateUserExists(userId, "validate Service Name Exists", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + Either dataModelResponse = serviceOperation.validateServiceNameExists(serviceName); + + if (dataModelResponse.isLeft()) { + Map result = new HashMap<>(); + result.put("isValid", dataModelResponse.left().value()); + log.debug("validation was successfully performed."); + return Either.left(result); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(dataModelResponse.right().value())); + + return Either.right(responseFormat); + } + + public void setElementDao(IElementOperation elementDao) { + this.elementDao = elementDao; + } + + public void setServiceOperation(ServiceOperation serviceOperation) { + this.serviceOperation = serviceOperation; + } + + public void setCassandraAuditingDao(AuditCassandraDao auditingDao) { + this.auditCassandraDao = auditingDao; + } + + /* + * public void setUserAdmin(UserAdminBuisinessLogic userAdmin) { this.userAdmin = userAdmin; } + * + * public void setComponentsUtils(ComponentsUtils componentsUtils) { this.componentsUtils = componentsUtils; } + * + * public void setGraphLockOperation(IGraphLockOperation graphLockOperation) { this.graphLockOperation = graphLockOperation; } + */ + + public ArtifactsBusinessLogic getArtifactBl() { + return artifactsBusinessLogic; + } + + public void setArtifactBl(ArtifactsBusinessLogic artifactBl) { + this.artifactsBusinessLogic = artifactBl; + } + + public Either updateServiceMetadata(String serviceId, Service serviceUpdate, User user) { + Either eitherCreator = validateUser(user, "updateServiceMetadata", serviceUpdate, null, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + Either validateRes = validateUserRole(user, serviceUpdate, new ArrayList(), null, null); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + + Either storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), "")); + } + + Service currentService = storageStatus.left().value(); + + if (!ComponentValidationUtils.canWorkOnService(currentService.getUniqueId(), serviceOperation, user.getUserId())) { + log.info("Restricted operation for user {} on service {}", user.getUserId(), currentService.getCreatorUserId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION)); + } + + Either validationRsponse = validateAndUpdateServiceMetadata(user, currentService, serviceUpdate); + if (validationRsponse.isRight()) { + log.info("service update metadata: validations field."); + return validationRsponse; + } + Service serviceToUpdate = validationRsponse.left().value(); + // lock resource + + Either lockResult = lockComponent(serviceId, currentService, "Update Service Metadata"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either updateResponse = serviceOperation.updateService(serviceToUpdate, true); + if (updateResponse.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Update Service Metadata"); + BeEcompErrorManager.getInstance().logBeSystemError("Update Service Metadata"); + log.debug("failed to update sevice {}", serviceToUpdate.getUniqueId()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + return Either.left(updateResponse.left().value()); + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + private Either validateAndUpdateServiceMetadata(User user, Service currentService, Service serviceUpdate) { + + boolean hasBeenCertified = ValidationUtils.hasBeenCertified(currentService.getVersion()); + Either response = validateAndUpdateCategory(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + String creatorUserIdUpdated = serviceUpdate.getCreatorUserId(); + String creatorUserIdCurrent = currentService.getCreatorUserId(); + if (creatorUserIdUpdated != null && !creatorUserIdCurrent.equals(creatorUserIdUpdated)) { + log.info("update srvice: recived request to update creatorUserId to {} the field is not updatable ignoring.", creatorUserIdUpdated); + } + + String creatorFullNameUpdated = serviceUpdate.getCreatorFullName(); + String creatorFullNameCurrent = currentService.getCreatorFullName(); + if (creatorFullNameUpdated != null && !creatorFullNameCurrent.equals(creatorFullNameUpdated)) { + log.info("update srvice: recived request to update creatorFullName to {} the field is not updatable ignoring.", creatorFullNameUpdated); + } + + String lastUpdaterUserIdUpdated = serviceUpdate.getLastUpdaterUserId(); + String lastUpdaterUserIdCurrent = currentService.getLastUpdaterUserId(); + if (lastUpdaterUserIdUpdated != null && !lastUpdaterUserIdCurrent.equals(lastUpdaterUserIdUpdated)) { + log.info("update srvice: recived request to update lastUpdaterUserId to {} the field is not updatable ignoring.", lastUpdaterUserIdUpdated); + } + + String lastUpdaterFullNameUpdated = serviceUpdate.getLastUpdaterFullName(); + String lastUpdaterFullNameCurrent = currentService.getLastUpdaterFullName(); + if (lastUpdaterFullNameUpdated != null && !lastUpdaterFullNameCurrent.equals(lastUpdaterFullNameUpdated)) { + log.info("update srvice: recived request to update lastUpdaterFullName to {} the field is not updatable ignoring.", lastUpdaterFullNameUpdated ); + } + + response = validateAndUpdateServiceName(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + DistributionStatusEnum distributionStatusUpdated = serviceUpdate.getDistributionStatus(); + DistributionStatusEnum distributionStatusCurrent = currentService.getDistributionStatus(); + if (distributionStatusUpdated != null && !distributionStatusUpdated.name().equals((distributionStatusCurrent != null ? distributionStatusCurrent.name() : null))) { + log.info("update srvice: recived request to update distributionStatus to {} the field is not updatable ignoring.", distributionStatusUpdated); + } + + if (serviceUpdate.getProjectCode() != null) { + response = validateAndUpdateProjectCode(user, currentService, serviceUpdate, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + } + + response = validateAndUpdateIcon(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + Long creationDateUpdated = serviceUpdate.getCreationDate(); + Long creationDateCurrent = currentService.getCreationDate(); + if (creationDateUpdated != null && !creationDateCurrent.equals(creationDateUpdated)) { + log.info("update srvice: recived request to update creationDate to {} the field is not updatable ignoring.", creationDateUpdated); + } + + String versionUpdated = serviceUpdate.getVersion(); + String versionCurrent = currentService.getVersion(); + if (versionUpdated != null && !versionCurrent.equals(versionUpdated)) { + log.info("update srvice: recived request to update version to {} the field is not updatable ignoring.", versionUpdated); + } + + response = validateAndUpdateDescription(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateTags(user, currentService, serviceUpdate, hasBeenCertified, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + response = validateAndUpdateContactId(user, currentService, serviceUpdate, null); + if (response.isRight()) { + ResponseFormat errorResponse = response.right().value(); + return Either.right(errorResponse); + } + + Long lastUpdateDateUpdated = serviceUpdate.getLastUpdateDate(); + Long lastUpdateDateCurrent = currentService.getLastUpdateDate(); + if (lastUpdateDateUpdated != null && !lastUpdateDateCurrent.equals(lastUpdateDateUpdated)) { + log.info("update srvice: recived request to update lastUpdateDate to {} the field is not updatable ignoring.", lastUpdateDateUpdated); + } + + LifecycleStateEnum lifecycleStateUpdated = serviceUpdate.getLifecycleState(); + LifecycleStateEnum lifecycleStateCurrent = currentService.getLifecycleState(); + if (lifecycleStateUpdated != null && !lifecycleStateCurrent.name().equals(lifecycleStateUpdated.name())) { + log.info("update srvice: recived request to update lifecycleState to {} the field is not updatable ignoring.", lifecycleStateUpdated); + } + + Boolean isHighestVersionUpdated = serviceUpdate.isHighestVersion(); + Boolean isHighestVersionCurrent = currentService.isHighestVersion(); + if (isHighestVersionUpdated != null && !isHighestVersionCurrent.equals(isHighestVersionUpdated)) { + log.info("update srvice: recived request to update isHighestVersion to {} the field is not updatable ignoring.", isHighestVersionUpdated); + } + + String uuidUpdated = serviceUpdate.getUUID(); + String uuidCurrent = currentService.getUUID(); + if (!uuidCurrent.equals(uuidUpdated)) { + log.info("update srvice: recived request to update uuid to {} the field is not updatable ignoring.", uuidUpdated); + } + + String currentInvariantUuid = currentService.getInvariantUUID(); + String updatedInvariantUuid = serviceUpdate.getInvariantUUID(); + + if ((updatedInvariantUuid != null) && (!updatedInvariantUuid.equals(currentInvariantUuid))) { + log.warn("Product invariant UUID is automatically set and cannot be updated"); + serviceUpdate.setInvariantUUID(currentInvariantUuid); + } + return Either.left(currentService); + + } + + private Either validateAndUpdateContactId(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) { + String contactIdUpdated = serviceUpdate.getContactId(); + String contactIdCurrent = currentService.getContactId(); + if (!contactIdCurrent.equals(contactIdUpdated)) { + Either validatContactId = validateContactId(user, serviceUpdate, audatingAction); + if (validatContactId.isRight()) { + ResponseFormat errorRespons = validatContactId.right().value(); + return Either.right(errorRespons); + } + currentService.setContactId(contactIdUpdated.toLowerCase()); + } + return Either.left(true); + } + + private Either validateAndUpdateTags(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + List tagsUpdated = serviceUpdate.getTags(); + List tagsCurrent = currentService.getTags(); + if (tagsUpdated == null || tagsUpdated.isEmpty()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_TAGS); + componentsUtils.auditComponentAdmin(responseFormat, user, serviceUpdate, "", "", audatingAction, ComponentTypeEnum.SERVICE); + return Either.right(responseFormat); + } + + if (!(tagsCurrent.containsAll(tagsUpdated) && tagsUpdated.containsAll(tagsCurrent))) { + Either validatResponse = validateTagsListAndRemoveDuplicates(user, serviceUpdate, audatingAction); + if (validatResponse.isRight()) { + ResponseFormat errorRespons = validatResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setTags(tagsUpdated); + } + return Either.left(true); + } + + private Either validateAndUpdateDescription(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String descriptionUpdated = serviceUpdate.getDescription(); + String descriptionCurrent = currentService.getDescription(); + if (!descriptionCurrent.equals(descriptionUpdated)) { + Either validateDescriptionResponse = validateDescriptionAndCleanup(user, serviceUpdate, audatingAction); + if (validateDescriptionResponse.isRight()) { + ResponseFormat errorRespons = validateDescriptionResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setDescription(serviceUpdate.getDescription()); + } + return Either.left(true); + } + + private Either validateAndUpdateProjectCode(User user, Service currentService, Service serviceUpdate, AuditingActionEnum audatingAction) { + String projectCodeUpdated = serviceUpdate.getProjectCode(); + String projectCodeCurrent = currentService.getProjectCode(); + if (!projectCodeCurrent.equals(projectCodeUpdated)) { + Either validatProjectCodeResponse = validateProjectCode(user, serviceUpdate, audatingAction); + if (validatProjectCodeResponse.isRight()) { + ResponseFormat errorRespons = validatProjectCodeResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setProjectCode(projectCodeUpdated); + } + return Either.left(true); + } + + private Either validateAndUpdateIcon(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String iconUpdated = serviceUpdate.getIcon(); + String iconCurrent = currentService.getIcon(); + if (!iconCurrent.equals(iconUpdated)) { + if (!hasBeenCertified) { + Either validatIconResponse = validateIcon(user, serviceUpdate, audatingAction); + if (validatIconResponse.isRight()) { + ResponseFormat errorRespons = validatIconResponse.right().value(); + return Either.right(errorRespons); + } + currentService.setIcon(iconUpdated); + } else { + log.info("icon {} cannot be updated once the service has been certified once.", iconUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_ICON_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateAndUpdateServiceName(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + String serviceNameUpdated = serviceUpdate.getName(); + String serviceNameCurrent = currentService.getName(); + if (!serviceNameCurrent.equals(serviceNameUpdated)) { + if (!hasBeenCertified) { + Either validatServiceNameResponse = validateComponentName(user, serviceUpdate, audatingAction); + if (validatServiceNameResponse.isRight()) { + ResponseFormat errorRespons = validatServiceNameResponse.right().value(); + return Either.right(errorRespons); + } + + Either serviceNameUniquenessValidation = validateComponentNameUnique(user, serviceUpdate, audatingAction); + if (serviceNameUniquenessValidation.isRight()) { + return serviceNameUniquenessValidation; + } + currentService.setName(serviceNameUpdated); + currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setNormalizedName(ValidationUtils.normaliseComponentName(serviceNameUpdated)); + currentService.getComponentMetadataDefinition().getMetadataDataDefinition().setSystemName(ValidationUtils.convertToSystemName(serviceNameUpdated)); + + } else { + log.info("service name {} cannot be updated once the service has been certified once.", serviceNameUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NAME_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + } + + private Either validateAndUpdateCategory(User user, Service currentService, Service serviceUpdate, boolean hasBeenCertified, AuditingActionEnum audatingAction) { + List categoryUpdated = serviceUpdate.getCategories(); + List categoryCurrent = currentService.getCategories(); + Either validatCategoryResponse = validateServiceCategory(user, serviceUpdate, audatingAction); + if (validatCategoryResponse.isRight()) { + ResponseFormat errorRespons = validatCategoryResponse.right().value(); + return Either.right(errorRespons); + } + if (!categoryCurrent.get(0).getName().equals(categoryUpdated.get(0).getName())) { + if (!hasBeenCertified) { + currentService.setCategories(categoryUpdated); + } else { + log.info("category {} cannot be updated once the service has been certified once.", categoryUpdated); + ResponseFormat errorResponse = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CATEGORY_CANNOT_BE_CHANGED); + return Either.right(errorResponse); + } + } + return Either.left(true); + + } + + public Either validateServiceCategory(List list) { + if (list != null) { + if (list.size() > 1) { + log.debug("Must be only one category for service"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_TOO_MUCH_CATEGORIES, ComponentTypeEnum.SERVICE.getValue()); + return Either.right(responseFormat); + } + CategoryDefinition category = list.get(0); + if (category.getSubcategories() != null) { + log.debug("Subcategories cannot be defined for service"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_CANNOT_CONTAIN_SUBCATEGORY); + return Either.right(responseFormat); + } + if (!ValidationUtils.validateStringNotEmpty(category.getName())) { + log.debug("Resource category is empty"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.COMPONENT_MISSING_CATEGORY, ComponentTypeEnum.SERVICE.getValue()); + return Either.right(responseFormat); + } + + log.debug("validating service category {} against valid categories list", list); + Either, ActionStatus> categorys = elementDao.getAllServiceCategories(); + if (categorys.isRight()) { + log.debug("failed to retrive service categories from Titan"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(categorys.right().value()); + return Either.right(responseFormat); + } + List categoryList = categorys.left().value(); + for (CategoryDefinition value : categoryList) { + if (value.getName().equals(category.getName())) { + return Either.left(true); + } + } + log.debug("Category {} is not part of service category group. Service category valid values are {}", list, categoryList); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.COMPONENT_INVALID_CATEGORY, ComponentTypeEnum.SERVICE.getValue())); + } + return Either.left(false); + } + + public ResponseFormat deleteService(String serviceId, User user) { + ResponseFormat responseFormat; + String ecompErrorContext = "delete service"; + + Either eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + user = eitherCreator.left().value(); + + Either serviceStatus = serviceOperation.getService(serviceId); + if (serviceStatus.isRight()) { + log.debug("failed to get service {}", serviceId); + return componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceStatus.right().value()), ""); + } + + Service service = serviceStatus.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + Either lockResult = lockComponent(service, "Mark service to delete"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + + try { + + result = markComponentToDelete(service); + if (result.equals(StorageOperationStatus.OK)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName()); + } + return responseFormat; + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + BeEcompErrorManager.getInstance().logBeSystemError("Delete Service"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + public ResponseFormat deleteServiceByNameAndVersion(String serviceName, String version, User user) { + ResponseFormat responseFormat; + String ecompErrorContext = "delete service"; + Either validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return validateEmptyResult.right().value(); + } + + Either eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return eitherCreator.right().value(); + } + user = eitherCreator.left().value(); + + Either getResult = getServiceByNameAndVersion(serviceName, version, user.getUserId()); + if (getResult.isRight()) { + return getResult.right().value(); + } + Service service = getResult.left().value(); + + StorageOperationStatus result = StorageOperationStatus.OK; + Either lockResult = lockComponent(service, "Mark service to delete"); + if (lockResult.isRight()) { + result = StorageOperationStatus.GENERAL_ERROR; + return componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + + try { + result = markComponentToDelete(service); + if (result.equals(StorageOperationStatus.OK)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.NO_CONTENT); + } else { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(result); + responseFormat = componentsUtils.getResponseFormatByResource(actionStatus, service.getName()); + } + return responseFormat; + + } finally { + if (result == null || !result.equals(StorageOperationStatus.OK)) { + log.warn("operation failed. do rollback"); + BeEcompErrorManager.getInstance().logBeSystemError("Delete Service"); + titanGenericDao.rollback(); + } else { + log.debug("operation success. do commit"); + titanGenericDao.commit(); + } + graphLockOperation.unlockComponent(service.getUniqueId(), NodeTypeEnum.Service); + } + } + + public Either getService(String serviceId, User user) { + String ecompErrorContext = "Get service"; + Either validateEmptyResult = validateUserNotEmpty(user, ecompErrorContext); + if (validateEmptyResult.isRight()) { + return Either.right(validateEmptyResult.right().value()); + } + + Either eitherCreator = validateUserExists(user, ecompErrorContext, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + Either storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + log.debug("failed to get service by id {}", serviceId); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceId)); + } + // Service service = + // createServiceApiArtifactLIst(storageStatus.left().value()); + Service service = storageStatus.left().value(); + return Either.left(service); + } + + public Either getServiceByNameAndVersion(String serviceName, String serviceVersion, String userId) { + Either resp = validateUserExists(userId, "get Service By Name And Version", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + Either storageStatus = serviceOperation.getServiceByNameAndVersion(serviceName, serviceVersion, null, false); + if (storageStatus.isRight()) { + log.debug("failed to get service by name {} and version {}", serviceName, serviceVersion); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(storageStatus.right().value(), ComponentTypeEnum.SERVICE), serviceName)); + } + Service service = storageStatus.left().value(); + return Either.left(service); + } + + private void createMandatoryArtifactsData(Service service, User user) { + // create mandatory artifacts + + // TODO it must be removed after that artifact uniqueId creation will be + // moved to ArtifactOperation + // String serviceUniqueId = + // UniqueIdBuilder.buildServiceUniqueId(service.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), + // service.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion()); + String serviceUniqueId = service.getUniqueId(); + Map artifactMap = service.getArtifacts(); + if (artifactMap == null) + artifactMap = new HashMap(); + + Map informationalServiceArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getInformationalServiceArtifacts(); + List exludeServiceCategory = ConfigurationManager.getConfigurationManager().getConfiguration().getExcludeServiceCategory(); + + String category = service.getCategories().get(0).getName(); + boolean isCreateArtifact = true; + if (category != null && exludeServiceCategory != null && !exludeServiceCategory.isEmpty()) { + for (String exlude : exludeServiceCategory) { + if (exlude.equalsIgnoreCase(category)) { + isCreateArtifact = false; + break; + } + } + + } + + if (informationalServiceArtifacts != null && isCreateArtifact) { + Set keys = informationalServiceArtifacts.keySet(); + for (String informationalServiceArtifactName : keys) { + Map artifactInfoMap = (Map) informationalServiceArtifacts.get(informationalServiceArtifactName); + ArtifactDefinition artifactDefinition = createArtifactDefinition(serviceUniqueId, informationalServiceArtifactName, artifactInfoMap, user, false); + artifactMap.put(artifactDefinition.getArtifactLabel(), artifactDefinition); + + } + + service.setArtifacts(artifactMap); + } + } + + private ArtifactDefinition createArtifactDefinition(String serviceId, String logicalName, Map artifactInfoMap, User user, Boolean isServiceApi) { + + ArtifactDefinition artifactInfo = artifactsBusinessLogic.createArtifactPlaceHolderInfo(serviceId, logicalName, artifactInfoMap, user, ArtifactGroupTypeEnum.INFORMATIONAL); + + if (isServiceApi) { + artifactInfo.setMandatory(false); + artifactInfo.setServiceApi(true); + } + return artifactInfo; + } + + private Either validateTransitionEnum(String distributionTransition, User user) { + DistributionTransitionEnum transitionEnum = null; + + transitionEnum = DistributionTransitionEnum.getFromDisplayName(distributionTransition); + if (transitionEnum == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeSystemError("Change Service Distribution"); + log.info("state operation is not valid. operations allowed are: {}", DistributionTransitionEnum.valuesAsString()); + ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(error); + } + + return Either.left(transitionEnum); + } + + private Either validateComment(LifecycleChangeInfoWithAction comment, User user, AuditingActionEnum auditAction) { + String data = comment.getUserRemarks(); + + if (data == null || data.trim().isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution"); + log.debug("user comment cannot be empty or null."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + data = ValidationUtils.removeNoneUtf8Chars(data); + data = ValidationUtils.removeHtmlTags(data); + data = ValidationUtils.normaliseWhitespace(data); + data = ValidationUtils.stripOctets(data); + + if (!ValidationUtils.validateLength(data, ValidationUtils.COMMENT_MAX_LENGTH)) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "Change Service Distribution"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("Change Service Distribution"); + log.debug("user comment exceeds limit."); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, "comment", String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH))); + } + if (!ValidationUtils.validateIsEnglish(data)) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + return Either.left(data); + } + + private Either validateServiceDistributionChange(User user, String serviceId, AuditingActionEnum auditAction, String comment) { + Either storageStatus = serviceOperation.getService(serviceId); + if (storageStatus.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_FOUND, serviceId); + createAudit(user, auditAction, comment, responseFormat); + return Either.right(responseFormat); + } + Service service = storageStatus.left().value(); + + if (service.getLifecycleState() != LifecycleStateEnum.CERTIFIED) { + log.info("service {} is not available for distribution. Should be in certified state", service.getUniqueId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION, service.getVersion(), service.getName()); + createAudit(user, auditAction, comment, service, responseFormat); + return Either.right(responseFormat); + } + return Either.left(service); + } + + private Either validateUserDistributionChange(User user, Service service, AuditingActionEnum auditAction, String comment) { + log.debug("get user from DB"); + /* + * Either eitherCreator = userAdmin.getUser(user.getUserId());s if (eitherCreator.isRight() || eitherCreator.left().value() == null) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeUserMissingError, + * "Activate Distribution", user.getUserId()); log. debug("changeServiceDistributionState method - user is not listed. userId=" + user.getUserId()); ResponseFormat responseFormat = + * componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND); createAudit(user, auditAction, comment, responseFormat); return Either.right(responseFormat); } user = eitherCreator.left().value(); log.debug("validate user role"); if + * (!validateUserTemp(user, Role.ADMIN, Role.GOVERNOR)) { log.info("role {} is not allowed to perform this action", user.getRole()); ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + * createAudit(user, auditAction, comment, service, responseFormat); return Either.right(responseFormat); } + */ + // get user details + Either eitherCreator = validateUser(user, "Activate Distribution", service, auditAction, false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + user = eitherCreator.left().value(); + + // validate user role + List roles = new ArrayList<>(); + roles.add(Role.ADMIN); + roles.add(Role.GOVERNOR); + Either validateRes = validateUserRole(user, service, roles, auditAction, comment); + if (validateRes.isRight()) { + return Either.right(validateRes.right().value()); + } + return Either.left(user); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, ResponseFormat responseFormat) { + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + + createAudit(user, auditAction, comment, null, responseFormat, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat) { + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, component.getDistributionStatus().name()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, component.getDistributionStatus().name()); + createAudit(user, auditAction, comment, component, component.getLifecycleState().name(), component.getVersion(), responseFormat, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, ResponseFormat responseFormat, EnumMap auditingFields) { + log.debug("audit before sending response"); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment); + componentsUtils.auditComponent(responseFormat, user, component, null, null, auditAction, ComponentTypeEnum.SERVICE, auditingFields); + } + + private void createAudit(User user, AuditingActionEnum auditAction, String comment, Service component, String prevState, String prevVersion, ResponseFormat responseFormat, EnumMap auditingFields) { + log.debug("audit before sending response"); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, comment); + componentsUtils.auditComponent(responseFormat, user, component, prevState, prevVersion, auditAction, ComponentTypeEnum.SERVICE, auditingFields); + } + + public Either activateDistribution(String serviceId, String envName, User modifier, HttpServletRequest request) { + + Either eitherCreator = validateUserExists(modifier.getUserId(), "activate Distribution", false); + if (eitherCreator.isRight()) { + return Either.right(eitherCreator.right().value()); + } + + User user = eitherCreator.left().value(); + + Either result = null; + ResponseFormat response = null; + Service updatedService = null; + String did = ThreadLocalsHolder.getUuid(); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, did); + // DE194021 + String configuredEnvName = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration().getEnvironments().get(0); + if (configuredEnvName != null && false == envName.equals(configuredEnvName)) { + log.trace("Update environment name to be {} instead of {}", configuredEnvName, envName); + envName = configuredEnvName; + } + // DE194021 + + ServletContext servletContext = request.getSession().getServletContext(); + boolean isDistributionEngineUp = getHealthCheckBL(servletContext).isDistributionEngineUp(request.getSession().getServletContext()); // DE + if (!isDistributionEngineUp) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Distribution Engine is DOWN"); + BeEcompErrorManager.getInstance().logBeSystemError("Distribution Engine is DOWN"); + log.debug("Distribution Engine is DOWN"); + response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(response); + } + + Either serviceRes = serviceOperation.getService(serviceId); + if (serviceRes.isRight()) { + log.debug("failed retrieving service"); + response = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(serviceRes.right().value(), ComponentTypeEnum.SERVICE), serviceId); + componentsUtils.auditComponent(response, user, null, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields); + return Either.right(response); + } + Service service = serviceRes.left().value(); + String dcurrStatus = service.getDistributionStatus().name(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DPREV_STATUS, dcurrStatus); + + Either readyForDistribution = distributionEngine.isReadyForDistribution(service, did, envName); + if (readyForDistribution.isLeft()) { + INotificationData notificationData = readyForDistribution.left().value(); + StorageOperationStatus notifyServiceResponse = distributionEngine.notifyService(did, service, notificationData, envName, user.getUserId(), user.getFullName()); + if (notifyServiceResponse == StorageOperationStatus.OK) { + Either updateStateRes = updateDistributionStatusForActivation(service, user, DistributionStatusEnum.DISTRIBUTED); + if (updateStateRes.isLeft() && updateStateRes.left().value() != null) { + updatedService = updateStateRes.left().value(); + dcurrStatus = updatedService.getDistributionStatus().name(); + } else { + // The response is not relevant + updatedService = service; + } + ASDCKpiApi.countActivatedDistribution(); + response = componentsUtils.getResponseFormat(ActionStatus.OK); + result = Either.left(updatedService); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Activate Distribution - send notification"); + BeEcompErrorManager.getInstance().logBeSystemError("Activate Distribution - send notification"); + log.debug("distributionEngine.notifyService response is: {}", notifyServiceResponse); + response = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + result = Either.right(response); + } + } else { + StorageOperationStatus distEngineValidationResponse = readyForDistribution.right().value(); + response = componentsUtils.getResponseFormatByDE(componentsUtils.convertFromStorageResponse(distEngineValidationResponse), service.getName(), envName); + result = Either.right(response); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_DCURR_STATUS, dcurrStatus); + componentsUtils.auditComponent(response, user, service, null, null, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST, ComponentTypeEnum.SERVICE, auditingFields); + return result; + } + + // convert to private after deletion of temp url + public Either updateDistributionStatusForActivation(Service service, User user, DistributionStatusEnum state) { + + Either resp = validateUserExists(user.getUserId(), "update Distribution Status For Activation", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + String serviceId = service.getUniqueId(); + Either lockResult = lockComponent(serviceId, service, "updateDistributionStatusForActivation"); + if (lockResult.isRight()) { + return Either.right(lockResult.right().value()); + } + try { + Either result = serviceOperation.updateDestributionStatus(service, user, state); + if (result.isRight()) { + titanGenericDao.rollback(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "updateDistributionStatusForActivation"); + BeEcompErrorManager.getInstance().logBeSystemError("updateDistributionStatusForActivation"); + log.debug("service {} change distribution status failed", serviceId); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + titanGenericDao.commit(); + return Either.left(result.left().value()); + } finally { + graphLockOperation.unlockComponent(serviceId, NodeTypeEnum.Service); + } + } + + public Either markDistributionAsDeployed(String serviceId, String did, User user) { + + Either resp = validateUserExists(user.getUserId(), "mark Distribution As Deployed", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + log.debug("mark distribution deployed"); + + AuditingActionEnum auditAction = AuditingActionEnum.DISTRIBUTION_DEPLOY; + Either getServiceResponse = serviceOperation.getService(serviceId); + if (getServiceResponse.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeServiceMissingError, "markDistributionAsDeployed", serviceId); + BeEcompErrorManager.getInstance().logBeComponentMissingError("markDistributionAsDeployed", ComponentTypeEnum.SERVICE.getValue(), serviceId); + log.debug("service {} not found", serviceId); + ResponseFormat responseFormat = auditDeployError(did, user, auditAction, null, componentsUtils.convertFromStorageResponse(getServiceResponse.right().value(), ComponentTypeEnum.SERVICE), ""); + + return Either.right(responseFormat); + } + + Service service = getServiceResponse.left().value(); + + Either validateRoleForDeploy = validateRoleForDeploy(did, user, auditAction, service); + if (validateRoleForDeploy.isRight()) { + return Either.right(validateRoleForDeploy.right().value()); + } + user = validateRoleForDeploy.left().value(); + + return checkDistributionAndDeploy(did, user, auditAction, service); + + } + + public Either generateVfModuleArtifacts(Service service, User modifier, boolean shouldLock) { + Function>> artifactTaskGeneratorCreator = ri -> + // Only one VF Module Artifact per instance - add it to a list of one + Arrays.asList(new VfModuleArtifacGenerator(modifier, ri, service, shouldLock)); + + return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator); + + } + + private List collectGroupsForCompInstance(ComponentInstance currVF, Wrapper responseWrapper) { + List relevantGroups = new ArrayList<>(); + Either, StorageOperationStatus> eitherGroups = groupOperation.getAllGroups(currVF.getComponentUid(), NodeTypeEnum.Resource); + + if (eitherGroups.isRight()) { + final StorageOperationStatus storageStatus = eitherGroups.right().value(); + if (storageStatus != StorageOperationStatus.NOT_FOUND && storageStatus != StorageOperationStatus.OK) { + ActionStatus actionStatus = componentsUtils.convertFromStorageResponse(storageStatus); + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(actionStatus)); + } + + } else { + relevantGroups = eitherGroups.left().value().stream().filter(p -> GroupTypeEnum.VF_MODULE.getGroupTypeName().equals(p.getType())).collect(Collectors.toList()); + } + return relevantGroups; + } + + private ArtifactDefinition getVfModuleArtifactForCompInstance(ComponentInstance currVF, Service service, User modifier, List groupsForCurrVF, Wrapper payloadWrapper, Wrapper responseWrapper) { + ArtifactDefinition vfModuleAertifact = null; + + Optional optionalVfModuleArtifact = currVF.getDeploymentArtifacts().values().stream().filter(p -> p.getArtifactType().equals(ArtifactTypeEnum.VF_MODULES_METADATA.name())).findAny(); + if (optionalVfModuleArtifact.isPresent()) { + vfModuleAertifact = optionalVfModuleArtifact.get(); + } else { + Either createVfModuleArtifact = createVfModuleArtifact(modifier, currVF, service, payloadWrapper.getInnerElement()); + if (createVfModuleArtifact.isLeft()) { + vfModuleAertifact = createVfModuleArtifact.left().value(); + } else { + responseWrapper.setInnerElement(createVfModuleArtifact.right().value()); + } + } + return vfModuleAertifact; + } + + private void fillVfModuleHeatEnvPayload(List groupsForCurrVF, ComponentInstance currVFInstance, Wrapper payloadWrapper) { + // Converts GroupDefinition to VfModuleArtifactPayload which is the + // format used in the payload + + List vfModulePayloadForCurrVF = groupsForCurrVF.stream().map(group -> new VfModuleArtifactPayload(group)).collect(Collectors.toList()); + Collections.sort(vfModulePayloadForCurrVF, (art1, art2) -> VfModuleArtifactPayload.compareByGroupName(art1, art2)); + // Update Payload With Heat Env + vfModulePayloadForCurrVF.stream().forEach(e -> addHeatEnvArtifactsToVFModulePayload(e, currVFInstance)); + + final Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + String vfModulePayloadString = gson.toJson(vfModulePayloadForCurrVF); + payloadWrapper.setInnerElement(vfModulePayloadString); + + } + + private void addHeatEnvArtifactsToVFModulePayload(VfModuleArtifactPayload vfModulePayload, ComponentInstance currVFInstance) { + List originalModuleArtifacts = vfModulePayload.getArtifacts(); + if (!MapUtils.isEmpty(currVFInstance.getDeploymentArtifacts()) && !CollectionUtils.isEmpty(originalModuleArtifacts)) { + + final Collection depInsArtifacts = currVFInstance.getDeploymentArtifacts().values(); + // All Heat_ENV + List heatEnvArtifacts = depInsArtifacts.stream().filter(art -> art.getArtifactType().equals(ArtifactTypeEnum.HEAT_ENV.getType())).collect(Collectors.toList()); + // Unique Id Of Artifacts In the vf module + List moduleArtUniqueId = depInsArtifacts.stream().filter(art -> originalModuleArtifacts.contains(art.getArtifactUUID())).map(art -> art.getUniqueId()).collect(Collectors.toList()); + // Collect Only Heat Artifatcs that are Generated from artifacts in + // the module + List relevantHeatEnvUUID = heatEnvArtifacts.stream().filter(heatEnv -> moduleArtUniqueId.contains(heatEnv.getGeneratedFromId())).map(heatEnv -> heatEnv.getArtifactUUID()).collect(Collectors.toList()); + + List fullArtifactList = new ArrayList<>(); + fullArtifactList.addAll(originalModuleArtifacts); + fullArtifactList.addAll(relevantHeatEnvUUID); + + vfModulePayload.setArtifacts(fullArtifactList); + } + } + + private Either generateVfModuleArtifact(User modifier, ComponentInstance currVFInstance, Service service, boolean shouldLock) { + ArtifactDefinition vfModuleAertifact = null; + Wrapper responseWrapper = new Wrapper<>(); + Wrapper payloadWrapper = new Wrapper<>(); + List groupsForCurrVF = collectGroupsForCompInstance(currVFInstance, responseWrapper); + if (responseWrapper.isEmpty()) { + fillVfModuleHeatEnvPayload(groupsForCurrVF, currVFInstance, payloadWrapper); + } + if (responseWrapper.isEmpty()) { + vfModuleAertifact = getVfModuleArtifactForCompInstance(currVFInstance, service, modifier, groupsForCurrVF, payloadWrapper, responseWrapper); + } + if (responseWrapper.isEmpty() && vfModuleAertifact != null) { + vfModuleAertifact = fillVfModulePayload(modifier, currVFInstance, vfModuleAertifact, shouldLock, payloadWrapper, responseWrapper); + } + + Either result; + if (responseWrapper.isEmpty()) { + result = Either.left(vfModuleAertifact); + } else { + result = Either.right(responseWrapper.getInnerElement()); + } + + return result; + } + + private ArtifactDefinition fillVfModulePayload(User modifier, ComponentInstance currVF, ArtifactDefinition vfModuleAertifact, boolean shouldLock, Wrapper payloadWrapper, Wrapper responseWrapper) { + ArtifactDefinition result = null; + final Either eitherResource = resourceOperation.getResource(currVF.getComponentUid()); + if (eitherResource.isRight()) { + responseWrapper.setInnerElement(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(eitherResource.right().value()))); + } else { + Resource resource = eitherResource.left().value(); + Either eitherPayload = artifactsBusinessLogic.generateArtifactPayload(vfModuleAertifact, resource, currVF.getName(), modifier, shouldLock, () -> System.currentTimeMillis(), + () -> Either.left(artifactsBusinessLogic.createEsArtifactData(vfModuleAertifact, payloadWrapper.getInnerElement().getBytes(StandardCharsets.UTF_8)))); + if (eitherPayload.isLeft()) { + result = eitherPayload.left().value(); + } else { + responseWrapper.setInnerElement(eitherPayload.right().value()); + } + } + + return result; + } + + private Either createVfModuleArtifact(User modifier, ComponentInstance currVF, Service service, String vfModulePayloadString) { + + ArtifactDefinition vfModuleArtifactDefinition = new ArtifactDefinition(); + + vfModuleArtifactDefinition.setDescription("Auto-generated VF Modules information artifact"); + vfModuleArtifactDefinition.setArtifactDisplayName("Vf Modules Metadata"); + vfModuleArtifactDefinition.setArtifactType(ArtifactTypeEnum.VF_MODULES_METADATA.getType()); + vfModuleArtifactDefinition.setArtifactGroupType(ArtifactGroupTypeEnum.DEPLOYMENT); + vfModuleArtifactDefinition.setArtifactLabel("vfModulesMetadata"); + vfModuleArtifactDefinition.setTimeout(0); + vfModuleArtifactDefinition.setArtifactName(currVF.getNormalizedName() + "_modules.json"); + vfModuleArtifactDefinition.setPayloadData(vfModulePayloadString); + + Either addArifactToComponent = artifactOperation.addArifactToComponent(vfModuleArtifactDefinition, currVF.getUniqueId(), NodeTypeEnum.ResourceInstance, true, true); + + Either result; + if (addArifactToComponent.isLeft()) { + result = Either.left(addArifactToComponent.left().value()); + } else { + result = Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addArifactToComponent.right().value()))); + } + + return result; + } + + public Either generateHeatEnvArtifacts(Service service, User modifier, boolean shouldLock) { + + Function>> artifactTaskGeneratorCreator = resourceInstance -> + // Get All Deployment Artifacts + service.getComponentInstances().stream().filter(ri -> ri != null && ri == resourceInstance).filter(ri -> ri.getDeploymentArtifacts() != null).flatMap(ri -> ri.getDeploymentArtifacts().values().stream()). + // Filter in Only Heat Env + filter(depArtifact -> ArtifactTypeEnum.HEAT_ENV.getType().equals(depArtifact.getArtifactType())). + // Create ArtifactGenerator from those Artifacts + map(depArtifact -> new HeatEnvArtifactGenerator(depArtifact, service, resourceInstance.getName(), modifier, shouldLock)).collect(Collectors.toList()); + + return generateDeploymentArtifacts(service, modifier, artifactTaskGeneratorCreator); + + } + + private Either generateDeploymentArtifacts(Service service, User modifier, Function>> artifactTaskGeneratorCreator) { + + List>> allFutures = new ArrayList<>(); + + // Get Flat List of (Callable) ArtifactGenerator for all the RI in the + // service + if (service.getComponentInstances() != null) { + List> artifactGenList = service.getComponentInstances().stream().flatMap(ri -> artifactTaskGeneratorCreator.apply(ri).stream()).collect(Collectors.toList()); + if (artifactGenList != null && !artifactGenList.isEmpty()) { + ExecutorService executor = Executors.newFixedThreadPool(artifactGenList.size()); + + artifactGenList.stream().forEach(e -> allFutures.add(executor.submit(e))); + + boolean isSuccess = true; + ResponseFormat firstError = null; + for (Future> entry : allFutures) { + try { + Either actionStatus = entry.get(20, TimeUnit.SECONDS); + if (actionStatus.isRight()) { + isSuccess = false; + if (firstError == null) { + firstError = actionStatus.right().value(); + } + log.debug("Failed to generate artifact error : {}", actionStatus.right().value()); + } + } catch (Exception e) { + log.debug("Failed to collect result from artifact generator ", e); + isSuccess = false; + firstError = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + } + } + executor.shutdown(); + if (!isSuccess) { + return Either.right(firstError); + } + } + + } + return Either.left(service); + } + + abstract class ArtifactGenerator implements Callable> { + + } + + class HeatEnvArtifactGenerator extends ArtifactGenerator { + ArtifactDefinition artifactDefinition; + Service service; + String resourceInstanceName; + User modifier; + boolean shouldLock; + + HeatEnvArtifactGenerator(ArtifactDefinition artifactDefinition, Service service, String resourceInstanceName, User modifier, boolean shouldLock) { + this.artifactDefinition = artifactDefinition; + this.service = service; + this.resourceInstanceName = resourceInstanceName; + this.modifier = modifier; + this.shouldLock = shouldLock; + } + + @Override + public Either call() throws Exception { + return artifactsBusinessLogic.generateHeatEnvArtifact(artifactDefinition, service, resourceInstanceName, modifier, shouldLock); + } + + public ArtifactDefinition getArtifactDefinition() { + return artifactDefinition; + } + + } + + class VfModuleArtifacGenerator extends ArtifactGenerator { + private User user; + private ComponentInstance componentInstance; + private Service service; + boolean shouldLock; + + @Override + public Either call() throws Exception { + return generateVfModuleArtifact(user, componentInstance, service, shouldLock); + } + + private VfModuleArtifacGenerator(User user, ComponentInstance componentInstance, Service service, boolean shouldLock) { + super(); + this.user = user; + this.componentInstance = componentInstance; + this.service = service; + this.shouldLock = shouldLock; + } + + } + + private synchronized Either checkDistributionAndDeploy(String did, User user, AuditingActionEnum auditAction, Service service) { + boolean isDeployed = isDistributionDeployed(did, service); + if (isDeployed) { + return Either.left(service); + } + Either distributionSuccess = checkDistributionSuccess(did, user, auditAction, service); + if (distributionSuccess.isRight()) { + return Either.right(distributionSuccess.right().value()); + } + + log.debug("mark distribution {} as deployed - success", did); + componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, STATUS_DEPLOYED, "OK", user); + return Either.left(service); + } + + private boolean isDistributionDeployed(String did, Service service) { + Either, ActionStatus> alreadyDeployed = auditCassandraDao.getDistributionDeployByStatus(did, AuditingActionEnum.DISTRIBUTION_DEPLOY.getName(), STATUS_DEPLOYED); + + boolean isDeployed = false; + if (alreadyDeployed.isLeft() && !alreadyDeployed.left().value().isEmpty()) { + // already deployed + log.debug("distribution {} is already deployed", did); + isDeployed = true; + } + return isDeployed; + } + + protected Either checkDistributionSuccess(String did, User user, AuditingActionEnum auditAction, Service service) { + + log.trace("checkDistributionSuccess"); + // get all "DRequest" records for this distribution + // Either, ActionStatus> distRequestsResponse = + // auditingDao.getListOfDistributionByAction(did, + // AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName(), "", + // ResourceAdminEvent.class); + Either, ActionStatus> distRequestsResponse = auditCassandraDao.getDistributionRequest(did, AuditingActionEnum.DISTRIBUTION_STATE_CHANGE_REQUEST.getName()); + if (distRequestsResponse.isRight()) { + ResponseFormat error = auditDeployError(did, user, auditAction, service, distRequestsResponse.right().value()); + return Either.right(error); + } + + List distributionRequests = distRequestsResponse.left().value(); + if (distributionRequests.isEmpty()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionMissingError, "markDistributionAsDeployed", did); + BeEcompErrorManager.getInstance().logBeDistributionMissingError("markDistributionAsDeployed", did); + log.info("distribution {} is not found", did); + ResponseFormat error = auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_NOT_FOUND); + return Either.right(error); + } + boolean isRequestSucceeded = false; + for (ResourceAdminEvent event : distributionRequests) { + String eventStatus = event.getStatus(); + if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) { + isRequestSucceeded = true; + break; + } + } + + // get all "DNotify" records for this distribution + // Either, ActionStatus> + // distNotificationsResponse = + // auditingDao.getListOfDistributionByAction(did, + // AuditingActionEnum.DISTRIBUTION_NOTIFY.getName(), "", + // DistributionNotificationEvent.class); + Either, ActionStatus> distNotificationsResponse = auditCassandraDao.getDistributionNotify(did, AuditingActionEnum.DISTRIBUTION_NOTIFY.getName()); + if (distNotificationsResponse.isRight()) { + ResponseFormat error = auditDeployError(did, user, auditAction, service, distNotificationsResponse.right().value()); + return Either.right(error); + } + + List distributionNotifications = distNotificationsResponse.left().value(); + boolean isNotificationsSucceeded = false; + for (DistributionNotificationEvent event : distributionNotifications) { + String eventStatus = event.getStatus(); + if (eventStatus != null && eventStatus.equals(STATUS_SUCCESS_200)) { + isNotificationsSucceeded = true; + break; + } + } + + // if request failed OR there are notifications that failed + if (!(isRequestSucceeded && isNotificationsSucceeded)) { + + log.info("distribution {} has failed", did); + ResponseFormat error = componentsUtils.getResponseFormat(ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did); + auditDeployError(did, user, auditAction, service, ActionStatus.DISTRIBUTION_REQUESTED_FAILED, did); + return Either.right(error); + } + return Either.left(true); + } + + private ResponseFormat auditDeployError(String did, User user, AuditingActionEnum auditAction, Service service, ActionStatus status, String... params) { + + ResponseFormat error = componentsUtils.getResponseFormat(status, params); + String message = ""; + if (error.getMessageId() != null) { + message = error.getMessageId() + ": "; + } + message += error.getFormattedMessage(); + + if (service != null) { + componentsUtils.auditServiceDistributionDeployed(auditAction, service.getName(), service.getVersion(), service.getUUID(), did, error.getStatus().toString(), message, user); + } else { + componentsUtils.auditServiceDistributionDeployed(auditAction, "", "", "", did, error.getStatus().toString(), message, user); + } + return error; + } + + private Either validateRoleForDeploy(String did, User user, AuditingActionEnum auditAction, Service service) { + Either eitherCreator = userAdmin.getUser(user.getUserId(), false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, "Deploy Service", user.getUserId()); + BeEcompErrorManager.getInstance().logBeUserMissingError("Deploy Service", user.getUserId()); + log.debug("validateRoleForDeploy method - user is not listed. userId={}", user.getUserId()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, user.getUserId()); + auditDeployError(did, user, auditAction, service, ActionStatus.USER_NOT_FOUND); + return Either.right(responseFormat); + } + user = eitherCreator.left().value(); + log.debug("validate user role"); + List roles = new ArrayList<>(); + roles.add(Role.ADMIN); + roles.add(Role.OPS); + Either validateRes = validateUserRole(user, service, roles, auditAction, null); + if (validateRes.isRight()) { + log.info("role {} is not allowed to perform this action", user.getRole()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + auditDeployError(did, user, auditAction, service, ActionStatus.RESTRICTED_OPERATION); + return Either.right(responseFormat); + } + return Either.left(user); + + } + + @Override + public void setDeploymentArtifactsPlaceHolder(Component component, User user) { + // TODO Auto-generated method stub + + } + + @Override + public Either, ResponseFormat> deleteMarkedComponents() { + return deleteMarkedComponents(ComponentTypeEnum.SERVICE); + } + + private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class); + return healthCheckBl; + } + + @Override + public ComponentInstanceBusinessLogic getComponentInstanceBL() { + return serviceComponentInstanceBusinessLogic; + } + + @Override + public Either, ResponseFormat> getComponentInstancesFilteredByPropertiesAndInputs(String componentId, ComponentTypeEnum componentTypeEnum, String userId, String searchText) { + + Either resp = validateUserExists(userId, "Get Component Instances", false); + if (resp.isRight()) { + return Either.right(resp.right().value()); + } + + ComponentOperation componentOperation = getComponentOperation(componentTypeEnum); + + Either, StorageOperationStatus> componentInstancesResponse = componentOperation.getAllComponentInstncesMetadata(componentId, componentTypeEnum.getNodeType()); + if (componentInstancesResponse.isRight()) { + + if (componentInstancesResponse.right().value().equals(StorageOperationStatus.NOT_FOUND)) { + return Either.left(new ArrayList()); + } + ResponseFormat responseFormat = componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(componentInstancesResponse.right().value())); + return Either.right(responseFormat); + } + + List componentInstances = componentInstancesResponse.left().value(); + componentInstances = componentInstances.stream().filter(instance -> instance.getOriginType().equals(OriginTypeEnum.VF)).collect(Collectors.toList()); + + return Either.left(componentInstances); + } + + public ICacheMangerOperation getCacheManagerOperation() { + return cacheManagerOperation; + } + + public void setCacheManagerOperation(ICacheMangerOperation cacheManagerOperation) { + this.cacheManagerOperation = cacheManagerOperation; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceComponentInstanceBusinessLogic.java new file mode 100644 index 0000000000..c42cf004ff --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/ServiceComponentInstanceBusinessLogic.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("serviceComponentInstanceBusinessLogic") +public class ServiceComponentInstanceBusinessLogic extends ComponentInstanceBusinessLogic { + + @Override + protected Either validateAllowedToContainCompInstances(org.openecomp.sdc.be.model.Component containerComponent) { + return Either.left(true); + } + + @Override + protected NodeTypeEnum getNodeTypeOfComponentInstanceOrigin() { + return NodeTypeEnum.Resource; + } + + @Override + protected ComponentOperation getContainerComponentOperation() { + return serviceOperation; + } + + @Override + protected ComponentOperation getCompInstOriginComponentOperation() { + return resourceOperation; + } + + @Override + protected ComponentTypeEnum getComponentTypeOfComponentInstance() { + return ComponentTypeEnum.RESOURCE_INSTANCE; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/VFComponentInstanceBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/VFComponentInstanceBusinessLogic.java new file mode 100644 index 0000000000..3e42897c79 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/impl/VFComponentInstanceBusinessLogic.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.impl; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.operations.impl.ComponentOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("vfComponentInstanceBusinessLogic") +public class VFComponentInstanceBusinessLogic extends ComponentInstanceBusinessLogic { + + private static Logger log = LoggerFactory.getLogger(VFComponentInstanceBusinessLogic.class.getName()); + + @Override + protected Either validateAllowedToContainCompInstances(org.openecomp.sdc.be.model.Component containerComponent) { + Resource resource = (Resource) containerComponent; + ResourceTypeEnum resourceType = resource.getResourceType(); + if (ResourceTypeEnum.VF != resourceType) { + log.debug("Cannot attach resource instances to container resource of type {}", resourceType); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES, resourceType.getValue())); + } + return Either.left(true); + } + + @Override + protected NodeTypeEnum getNodeTypeOfComponentInstanceOrigin() { + return NodeTypeEnum.Resource; + } + + @Override + protected ComponentOperation getContainerComponentOperation() { + return resourceOperation; + } + + @Override + protected ComponentOperation getCompInstOriginComponentOperation() { + return resourceOperation; + } + + @Override + protected ComponentTypeEnum getComponentTypeOfComponentInstance() { + return ComponentTypeEnum.RESOURCE_INSTANCE; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java new file mode 100644 index 0000000000..445b3a9750 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationChangeTransition.java @@ -0,0 +1,209 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.Arrays; +import java.util.List; + +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CertificationChangeTransition extends LifeCycleTransition { + + private static Logger log = LoggerFactory.getLogger(CertificationChangeTransition.class.getName()); + + private LifecycleStateEnum nextState; + private LifeCycleTransitionEnum name; + private AuditingActionEnum auditingAction; + private ArtifactsBusinessLogic artifactsManager; + + public CertificationChangeTransition(LifeCycleTransitionEnum name, ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + super(componentUtils, lifecycleOperation); + + this.name = name; + + // authorized roles + Role[] certificationChangeRoles = { Role.ADMIN, Role.TESTER }; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(certificationChangeRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(certificationChangeRoles)); + // TODO to be later defined for product + + switch (this.name) { + case CERTIFY: + this.auditingAction = AuditingActionEnum.CERTIFICATION_SUCCESS_RESOURCE; + this.nextState = LifecycleStateEnum.CERTIFIED; + break; + case FAIL_CERTIFICATION: + this.auditingAction = AuditingActionEnum.FAIL_CERTIFICATION_RESOURCE; + nextState = LifecycleStateEnum.NOT_CERTIFIED_CHECKIN; + break; + case CANCEL_CERTIFICATION: + this.auditingAction = AuditingActionEnum.CANCEL_CERTIFICATION_RESOURCE; + nextState = LifecycleStateEnum.READY_FOR_CERTIFICATION; + break; + default: + break; + } + + } + + @Override + public LifeCycleTransitionEnum getName() { + return name; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return auditingAction; + } + + public ArtifactsBusinessLogic getArtifactsManager() { + return artifactsManager; + } + + public void setArtifactsManager(ArtifactsBusinessLogic artifactsManager) { + this.artifactsManager = artifactsManager; + } + + private ResponseFormat formatCertificationError(Component component, StorageOperationStatus response, ComponentTypeEnum componentType) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Change LifecycleState - Certify failed on graph"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Change LifecycleState - Certify failed on graph"); + log.debug("certification change failed on graph"); + + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(response); + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return responseFormat; + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before certification change. resource name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + if (!oldState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_READY_FOR_CERTIFICATION, componentName, componentType.name().toLowerCase()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS) && !modifier.equals(owner) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + return Either.left(true); + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + + log.info("start performing certification change for resource {}", component.getUniqueId()); + Either result = null; + NodeTypeEnum nodeType = componentType.getNodeType(); + + try { + Either certificationChangeResult = Either.right(StorageOperationStatus.GENERAL_ERROR); + if (nextState.equals(LifecycleStateEnum.CERTIFIED)) { + certificationChangeResult = lifeCycleOperation.certifyComponent(nodeType, component, modifier, owner, true); + } else { + certificationChangeResult = lifeCycleOperation.cancelOrFailCertification(nodeType, component, modifier, owner, nextState, true); + } + + if (certificationChangeResult.isRight()) { + ResponseFormat responseFormat = formatCertificationError(component, certificationChangeResult.right().value(), componentType); + result = Either.right(responseFormat); + return result; + } + + if (nextState.equals(LifecycleStateEnum.CERTIFIED)) { + Either deleteOldComponentVersions = lifeCycleOperation.deleteOldComponentVersions(nodeType, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), + component.getComponentMetadataDefinition().getMetadataDataDefinition().getUUID(), true); + if (deleteOldComponentVersions.isRight()) { + ResponseFormat responseFormat = formatCertificationError(component, deleteOldComponentVersions.right().value(), componentType); + result = Either.right(responseFormat); + return result; + } + } + + result = Either.left(certificationChangeResult.left().value()); + return result; + } finally { + if (result == null || result.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Change LifecycleState"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Change LifecycleState"); + if (inTransaction == false) { + log.debug("operation failed. do rollback"); + lifeCycleOperation.getResourceOperation().getTitanGenericDao().rollback(); + } + } else { + if (inTransaction == false) { + log.debug("operation success. do commit"); + lifeCycleOperation.getResourceOperation().getTitanGenericDao().commit(); + } + } + } + + } + + public StorageOperationStatus deleteOldVersion(List artifactsToDelete, Resource resourceToDelete) { + ResourceOperation resourceOperation = lifeCycleOperation.getResourceOperation(); + + Either, StorageOperationStatus> artifactsRes = resourceOperation.getComponentArtifactsForDelete(resourceToDelete.getUniqueId(), NodeTypeEnum.Resource, true); + if (artifactsRes.isRight()) { + return artifactsRes.right().value(); + } + Either deleteResourceRes = resourceOperation.deleteResource(resourceToDelete.getUniqueId(), true); + if (deleteResourceRes.isRight()) { + return deleteResourceRes.right().value(); + } + artifactsToDelete.addAll(artifactsRes.left().value()); + + return StorageOperationStatus.OK; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationRequestTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationRequestTransition.java new file mode 100644 index 0000000000..69a9cbdb24 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CertificationRequestTransition.java @@ -0,0 +1,409 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Optional; +import java.util.Set; + +import org.openecomp.sdc.be.components.distribution.engine.ServiceDistributionArtifactsBuilder; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.OriginTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.tosca.ToscaExportHandler; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CertificationRequestTransition extends LifeCycleTransition { + + private static Logger log = LoggerFactory.getLogger(CertificationRequestTransition.class.getName()); + + private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder; + private ResourceOperation resourceOperation; + private CapabilityOperation capabilityOperation; + private ServiceBusinessLogic serviceBusinessLogic; + private ToscaExportHandler toscaExportUtils; + + public CertificationRequestTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation, ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder, ServiceBusinessLogic serviceBusinessLogic, + CapabilityOperation capabilityOperation, ToscaExportHandler toscaExportUtils) { + super(componentUtils, lifecycleOperation); + + // authorized roles + Role[] resourceServiceCheckoutRoles = { Role.ADMIN, Role.DESIGNER }; + // Role[] productCheckoutRoles = {Role.ADMIN, Role.PRODUCT_MANAGER, + // Role.PRODUCT_STRATEGIST}; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(resourceServiceCheckoutRoles)); + // TODO to be later defined for product + // addAuthorizedRoles(ComponentTypeEnum.PRODUCT, + // Arrays.asList(productCheckoutRoles)); + + this.serviceDistributionArtifactsBuilder = serviceDistributionArtifactsBuilder; + if (lifeCycleOperation != null) + this.resourceOperation = lifeCycleOperation.getResourceOperation(); + this.serviceBusinessLogic = serviceBusinessLogic; + this.capabilityOperation = capabilityOperation; + this.toscaExportUtils = toscaExportUtils; + } + + @Override + public LifeCycleTransitionEnum getName() { + return LifeCycleTransitionEnum.CERTIFICATION_REQUEST; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return AuditingActionEnum.CERTIFICATION_REQUEST_RESOURCE; + } + + protected Either validateAllResourceInstanceCertified(Component component) { + Either eitherResult = Either.left(true); + + List resourceInstance = component.getComponentInstances(); + if (resourceInstance != null) { + Optional nonCertifiedRIOptional = resourceInstance.stream().filter(p -> !ValidationUtils.validateCertifiedVersion(p.getComponentVersion())).findAny(); + // Uncertified Resource Found + if (nonCertifiedRIOptional.isPresent()) { + ComponentInstance nonCertifiedRI = nonCertifiedRIOptional.get(); + ResponseFormat resFormat = getRelevantResponseFormatUncertifiedRI(nonCertifiedRI, component.getComponentType()); + eitherResult = Either.right(resFormat); + } + } + return eitherResult; + } + + private ResponseFormat getRelevantResponseFormatUncertifiedRI(ComponentInstance nonCertifiedRI, ComponentTypeEnum componentType) { + + ResponseFormat responseFormat; + Either eitherResource = resourceOperation.getResource(nonCertifiedRI.getComponentUid()); + if (eitherResource.isRight()) { + + responseFormat = componentUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + + } else { + ActionStatus actionStatus; + Resource resource = eitherResource.left().value(); + Either, StorageOperationStatus> status = resourceOperation.findLastCertifiedResourceByUUID(resource); + + if (ValidationUtils.validateMinorVersion(nonCertifiedRI.getComponentVersion())) { + if (status.isRight() || status.left().value() == null || status.left().value().isEmpty()) { + actionStatus = ActionStatus.VALIDATED_RESOURCE_NOT_FOUND; + } else { + actionStatus = ActionStatus.FOUND_ALREADY_VALIDATED_RESOURCE; + } + } else { + if (status.isRight() || status.left().value() == null || status.left().value().isEmpty()) + actionStatus = ActionStatus.FOUND_LIST_VALIDATED_RESOURCES; + else { + actionStatus = ActionStatus.FOUND_ALREADY_VALIDATED_RESOURCE; + } + + } + String compType = (componentType == ComponentTypeEnum.RESOURCE) ? "VF" : "service"; + responseFormat = componentUtils.getResponseFormat(actionStatus, compType, resource.getName()); + } + return responseFormat; + } + + private Either> validateMandatoryArtifactsSupplied(Map artifacts) { + + if (artifacts == null || true == artifacts.isEmpty()) { + return Either.left(ActionStatus.OK); + } + + Map invalidArtifacts = new HashMap(); + for (Entry artifact : artifacts.entrySet()) { + + ArtifactDefinition artifactDefinition = artifact.getValue(); + if (true == artifactDefinition.getMandatory()) { + String artifactEsId = artifactDefinition.getEsId(); + if (artifactEsId == null || true == artifactEsId.isEmpty()) { + invalidArtifacts.put(artifact.getKey(), artifactDefinition); + } + } + } + + if (true == invalidArtifacts.isEmpty()) { + return Either.left(ActionStatus.OK); + } else { + return Either.right(invalidArtifacts); + } + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + + log.debug("start performing certification request for resource {}", component.getUniqueId()); + + // Either> + // validateMandatoryArtifacts = + // validateMandatoryArtifactsSupplied(component.getArtifacts()); + // log.debug("After checking mandatory artifacts were populated. Result + // is " + validateMandatoryArtifacts); + // if (validateMandatoryArtifacts.isRight()) { + // ResponseFormat responseFormat = componentUtils + // .getResponseFormatByMissingArtifacts( + // componentType, + // validateMandatoryArtifacts.right().value()); + // return Either.right(responseFormat); + // } + ActionStatus actionStatus = null; + ResponseFormat responseFormat = null; + + if (componentType == ComponentTypeEnum.SERVICE || (componentType == ComponentTypeEnum.RESOURCE && ((Resource) component).getResourceType() == ResourceTypeEnum.VF)) { + + Either statusCert = validateAllResourceInstanceCertified(component); + if (statusCert.isRight()) { + return Either.right(statusCert.right().value()); + } + + statusCert = validateConfiguredAtomicReqCapSatisfied(component); + if (statusCert.isRight()) { + return Either.right(statusCert.right().value()); + } + } + if (componentType == ComponentTypeEnum.SERVICE) { + Either status = validateDeloymentArtifactSupplied((Service) component); + if (status.isRight()) { + StorageOperationStatus operationStatus = status.right().value(); + actionStatus = componentUtils.convertFromStorageResponse(operationStatus); + } else { + Boolean isDeploymentArtifactExists = status.left().value(); + if (isDeploymentArtifactExists == null || isDeploymentArtifactExists.booleanValue() == false) { + actionStatus = ActionStatus.SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND; + } else { + Either generateHeatEnvResult = serviceBusinessLogic.generateHeatEnvArtifacts((Service) component, modifier, shouldLock); + if (generateHeatEnvResult.isRight()) { + return Either.right(generateHeatEnvResult.right().value()); + } + Either generateVfModuleResult = serviceBusinessLogic.generateVfModuleArtifacts((Service) component, modifier, shouldLock); + if (generateVfModuleResult.isRight()) { + return Either.right(generateVfModuleResult.right().value()); + } + } + } + + if (actionStatus != null) { + responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return Either.right(responseFormat); + } + + } + + Either, ResponseFormat> eitherPopulated = componentBl.populateToscaArtifacts(component, modifier, true, inTransaction, shouldLock); + if (eitherPopulated != null && eitherPopulated.isRight()) { + return Either.right(eitherPopulated.right().value()); + } + + NodeTypeEnum nodeType = (componentType.equals(ComponentTypeEnum.SERVICE)) ? NodeTypeEnum.Service : NodeTypeEnum.Resource; + Either certificationRequestResult = lifeCycleOperation.requestCertificationComponent(nodeType, component, modifier, owner, inTransaction); + if (certificationRequestResult.isRight()) { + log.debug("checkout failed on graph"); + StorageOperationStatus response = certificationRequestResult.right().value(); + actionStatus = componentUtils.convertFromStorageResponse(response); + + if (response.equals(StorageOperationStatus.ENTITY_ALREADY_EXISTS)) { + actionStatus = ActionStatus.COMPONENT_VERSION_ALREADY_EXIST; + } + responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return Either.right(responseFormat); + } + + return Either.left(certificationRequestResult.left().value()); + } + + private Either validateConfiguredAtomicReqCapSatisfied(Component component) { + log.debug("Submit for testing validation - Start validating configured req/cap satisfied for inner atomic instances, component id:{}", component.getUniqueId()); + List componentInstances = component.getComponentInstances(); + if (componentInstances != null) { + // Prepare relationships data structures + // Better make it list than set in case we need to count req/cap + // occurrences in the future + Map> reqName2Ids = new HashMap<>(); + Map> capName2Ids = new HashMap<>(); + parseRelationsForReqCapVerification(component, reqName2Ids, capName2Ids); + Map> requirementsToFulfillBeforeCert = configurationManager.getConfiguration().getRequirementsToFulfillBeforeCert(); + Map> capabilitiesToConsumeBeforeCert = configurationManager.getConfiguration().getCapabilitiesToConsumeBeforeCert(); + for (ComponentInstance compInst : componentInstances) { + String compInstId = compInst.getUniqueId(); + OriginTypeEnum originType = compInst.getOriginType(); + if (originType == null) { + log.error("Origin type is not set for component instance {} - it shouldn't happen. Skipping this component instance...", compInst.getUniqueId()); + continue; + } + String compInstType = originType.getValue(); + // Validating configured requirements fulfilled + if (null != requirementsToFulfillBeforeCert) { + Set reqToFulfillForType = requirementsToFulfillBeforeCert.get(compInstType); + if (reqToFulfillForType != null) { + for (String reqNameToFulfill : reqToFulfillForType) { + List reqNameList = reqName2Ids.get(reqNameToFulfill); + if (reqNameList == null || !reqNameList.contains(compInstId)) { + log.debug("Requirement {} wasn't fulfilled for component instance {} of type {}", reqNameToFulfill, compInstId, compInstType); + ComponentTypeEnum componentType = component.getComponentType(); + String compParam = (componentType == ComponentTypeEnum.RESOURCE) ? "VF" : componentType.getValue().toLowerCase(); + ResponseFormat responseFormat = componentUtils.getResponseFormat(ActionStatus.REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION, component.getName(), compParam, originType.getDisplayValue(), compInst.getName(), "requirement", + reqNameToFulfill, "fulfilled"); + return Either.right(responseFormat); + } + } + } + } + // Validating configured capabilities consumed + if (null != capabilitiesToConsumeBeforeCert) { + Set capToConsumeForType = capabilitiesToConsumeBeforeCert.get(compInstType); + if (capToConsumeForType != null) { + for (String capNameToConsume : capToConsumeForType) { + List capNameList = capName2Ids.get(capNameToConsume); + if (capNameList == null || !capNameList.contains(compInstId)) { + log.debug("Capability {} wasn't consumed for component instance {} of type {}", capNameToConsume, compInstId, compInstType); + ComponentTypeEnum componentType = component.getComponentType(); + String compParam = (componentType == ComponentTypeEnum.RESOURCE) ? "VF" : componentType.getValue().toLowerCase(); + ResponseFormat responseFormat = componentUtils.getResponseFormat(ActionStatus.REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION, component.getName(), compParam, originType.getDisplayValue(), compInst.getName(), "capability", + capNameToConsume, "consumed"); + return Either.right(responseFormat); + } + } + } + } + } + } + log.debug("Submit for testing validation - validating configured req/cap satisfied for inner atomic instances finished successfully, component id:{}", component.getUniqueId()); + return Either.left(true); + } + + private Either parseRelationsForReqCapVerification(Component component, Map> reqName2Ids, Map> capName2Ids) { + log.debug("Submit for testing validation - Preparing relations for inner atomic instances validation"); + List componentInstancesRelations = component.getComponentInstancesRelations(); + if (componentInstancesRelations != null) { + for (RequirementCapabilityRelDef reqCapRelDef : componentInstancesRelations) { + List relationships = reqCapRelDef.getRelationships(); + if (relationships != null) { + for (RequirementAndRelationshipPair reqRelPair : relationships) { + String capUniqueId = reqRelPair.getCapabilityUid(); + Either capability = capabilityOperation.getCapability(capUniqueId); + if (capability.isRight()) { + log.error("Couldn't fetch capability by id {}", capUniqueId); + return Either.right(componentUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + String reqCapType = capability.left().value().getType(); + String capabilityOwnerId = reqRelPair.getCapabilityOwnerId(); + String requirementOwnerId = reqRelPair.getRequirementOwnerId(); + // Update req + List reqIds = reqName2Ids.get(reqCapType); + if (reqIds == null) { + reqIds = new ArrayList<>(); + reqName2Ids.put(reqCapType, reqIds); + } + reqIds.add(requirementOwnerId); + // Update cap + List capIds = capName2Ids.get(reqCapType); + if (capIds == null) { + capIds = new ArrayList<>(); + capName2Ids.put(reqCapType, capIds); + } + capIds.add(capabilityOwnerId); + } + } + } + log.debug("Parsed req for validation: {}, parsed cap for validation: {}", reqName2Ids, capName2Ids); + } else { + log.debug("There are no relations found for component {}", component.getUniqueId()); + } + return Either.left(true); + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before certification request. resource name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + // case of "atomic" checkin and certification request - modifier must be + // the owner + if (oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) && !modifier.equals(owner) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_CHECKOUT_BY_ANOTHER_USER, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + // other states + if (oldState.equals(LifecycleStateEnum.CERTIFIED)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_ALREADY_CERTIFIED, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + if (oldState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + if (oldState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_SENT_FOR_CERTIFICATION, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + return Either.left(true); + } + + private Either validateDeloymentArtifactSupplied(Service service) { + + Either serviceContainsDeploymentArtifacts = this.serviceDistributionArtifactsBuilder.isServiceContainsDeploymentArtifacts(service); + + return serviceContainsDeploymentArtifacts; + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckinTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckinTransition.java new file mode 100644 index 0000000000..28227285f1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckinTransition.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.Arrays; + +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CheckinTransition extends LifeCycleTransition { + + private static Logger log = LoggerFactory.getLogger(CheckinTransition.class.getName()); + + public CheckinTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + super(componentUtils, lifecycleOperation); + + // authorized roles + Role[] resourceServiceCheckoutRoles = { Role.ADMIN, Role.DESIGNER }; + Role[] productCheckoutRoles = { Role.ADMIN, Role.PRODUCT_MANAGER }; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.PRODUCT, Arrays.asList(productCheckoutRoles)); + + } + + @Override + public LifeCycleTransitionEnum getName() { + return LifeCycleTransitionEnum.CHECKIN; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return AuditingActionEnum.CHECKIN_RESOURCE; + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + log.debug("start performing checkin for {} {}", componentType.name(), component.getUniqueId()); + + NodeTypeEnum nodeType = componentType.getNodeType(); + Either checkinResourceResult = lifeCycleOperation.checkinComponent(nodeType, component, modifier, owner, inTransaction); + if (checkinResourceResult.isRight()) { + log.debug("checkout failed on graph"); + StorageOperationStatus response = checkinResourceResult.right().value(); + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(response); + + if (response.equals(StorageOperationStatus.ENTITY_ALREADY_EXISTS)) { + actionStatus = ActionStatus.COMPONENT_VERSION_ALREADY_EXIST; + } + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return Either.right(responseFormat); + } + + return Either.left(checkinResourceResult.left().value()); + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before checkin. component name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + if (!oldState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION) && !oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_ALREADY_CHECKED_IN, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT) && !modifier.equals(owner) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_CHECKOUT_BY_ANOTHER_USER, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION) && !modifier.equals(owner) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_SENT_FOR_CERTIFICATION, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + return Either.left(true); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java new file mode 100644 index 0000000000..a4e6bdb86c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/CheckoutTransition.java @@ -0,0 +1,141 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.Arrays; + +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CheckoutTransition extends LifeCycleTransition { + + private static final String PLACE_HOLDER_RESOURCE_TYPES = "validForResourceTypes"; + + private static Logger log = LoggerFactory.getLogger(CheckoutTransition.class.getName()); + + public CheckoutTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + super(componentUtils, lifecycleOperation); + + // authorized roles + Role[] resourceServiceCheckoutRoles = { Role.ADMIN, Role.DESIGNER }; + Role[] productCheckoutRoles = { Role.ADMIN, Role.PRODUCT_MANAGER }; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.PRODUCT, Arrays.asList(productCheckoutRoles)); + + } + + @Override + public LifeCycleTransitionEnum getName() { + return LifeCycleTransitionEnum.CHECKOUT; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return AuditingActionEnum.CHECKOUT_RESOURCE; + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + + log.debug("start performing {} for resource {}", getName().name(), component.getUniqueId()); + + if (componentBl != null) + componentBl.setDeploymentArtifactsPlaceHolder(component, modifier); + NodeTypeEnum nodeType = componentType.getNodeType(); + Either checkoutResourceResult = lifeCycleOperation.checkoutComponent(nodeType, component, modifier, owner, inTransaction); + + if (checkoutResourceResult.isRight()) { + log.debug("checkout failed on graph"); + StorageOperationStatus response = checkoutResourceResult.right().value(); + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(response); + + if (response.equals(StorageOperationStatus.ENTITY_ALREADY_EXISTS)) { + actionStatus = ActionStatus.COMPONENT_VERSION_ALREADY_EXIST; + } + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return Either.right(responseFormat); + } + + return Either.left(checkoutResourceResult.left().value()); + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before checkout. resource name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + // Disabled as of 1604 patch after discussing with Ella/Eli/Michael + + /* + * if (componentType == ComponentTypeEnum.PRODUCT){ Either productContactsEither = productContactsValidation((Product)component, modifier); if (productContactsEither.isRight()){ return productContactsEither; } } + */ + + // check resource is not locked by another user + if (oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_IN_CHECKOUT_STATE, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.READY_FOR_CERTIFICATION)) { + if (!modifier.getRole().equals(Role.DESIGNER.name()) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_SENT_FOR_CERTIFICATION, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + } + return Either.left(true); + } + + /* + * private Either productContactsValidation(Product product, User modifier) { // validate user Either eitherResponse = Either.left(true); String role = modifier.getRole(); if + * (UserRoleEnum.PRODUCT_MANAGER.getName().equals(role) || UserRoleEnum.PRODUCT_STRATEGIST.getName().equals(role)){ String userId = modifier.getUserId(); if (!product.getContacts().contains(userId)){ log. + * debug("User with userId {} cannot checkout product. userId not found in product contacts list" , userId); ResponseFormat responseFormat = componentUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); return Either.right(responseFormat); + * } else { log. trace("Found user userId {} in product contacts - checkout request validated" ); } } return eitherResponse; } + */ + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifeCycleTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifeCycleTransition.java new file mode 100644 index 0000000000..49d94dc80b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifeCycleTransition.java @@ -0,0 +1,160 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction.LifecycleChanceActionEnum; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.exception.ResponseFormat; + +import fj.data.Either; + +public abstract class LifeCycleTransition { + + protected ConfigurationManager configurationManager; + protected ILifecycleOperation lifeCycleOperation; + protected ComponentsUtils componentUtils; + + protected Map> authorizedRoles; + + protected LifeCycleTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + + // configurationManager = (ConfigurationManager) + // context.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR); + // lifeCycleOperation = LifecycleOperation.getInstance(); + this.configurationManager = ConfigurationManager.getConfigurationManager(); + this.lifeCycleOperation = lifecycleOperation; + this.componentUtils = componentUtils; + this.authorizedRoles = new HashMap<>(); + + } + + public abstract LifeCycleTransitionEnum getName(); + + public abstract AuditingActionEnum getAuditingAction(); + + public ConfigurationManager getConfigurationManager() { + return configurationManager; + } + + public void setConfigurationManager(ConfigurationManager configurationManager) { + this.configurationManager = configurationManager; + } + + public ILifecycleOperation getLifeCycleOperation() { + return lifeCycleOperation; + } + + public void setLifeCycleOperation(ILifecycleOperation lifeCycleOperation) { + this.lifeCycleOperation = lifeCycleOperation; + } + + public List getAuthorizedRoles(ComponentTypeEnum componentType) { + return authorizedRoles.get(componentType); + } + + public void addAuthorizedRoles(ComponentTypeEnum componentType, List authorizedRoles) { + this.authorizedRoles.put(componentType, authorizedRoles); + } + + // + // public Either + // changeState(ComponentTypeEnum componentType, Component component, + // ComponentBusinessLogic componentBl, User modifier, User owner){ + // return changeState(componentType, component, componentBl, modifier, + // owner, false); + // } + + public abstract Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean needLock, boolean inTransaction); + + public abstract Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo); + + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState) { + + return this.validateBeforeTransition(component, componentType, modifier, owner, oldState, null); + } + + /** + * getComponentOwner + * + * @param resource + * @return + */ + protected Either getComponentOwner(Component component, ComponentTypeEnum componentType) { + + return getComponentOwner(component, componentType, false); + } + + protected Either getComponentOwner(Component component, ComponentTypeEnum componentType, boolean inTransaction) { + + NodeTypeEnum nodeType = componentType.getNodeType(); + Either resourceOwnerResult = getLifeCycleOperation().getComponentOwner(component.getUniqueId(), nodeType, inTransaction); + if (resourceOwnerResult.isRight()) { + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(componentUtils.convertFromStorageResponse(resourceOwnerResult.right().value()), component, componentType); + return Either.right(responseFormat); + } + return Either.left(resourceOwnerResult.left().value()); + } + + /** + * isUserValidForRequest + * + * @param modifier + * @param action + * TODO + * @return + */ + protected Either userRoleValidation(User modifier, ComponentTypeEnum componentType, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + + // validate user + if (getAuthorizedRoles(componentType).contains(Role.valueOf(modifier.getRole()))) { + return Either.left(true); + } + + // this is only when creating vfc/cp when import vf from csar - when we + // create resources from node type, we create need to change the state + // to certified + if (lifecycleChangeInfo != null && lifecycleChangeInfo.getAction() != null && lifecycleChangeInfo.getAction() == LifecycleChanceActionEnum.CREATE_FROM_CSAR) { + return Either.left(true); + } + + ResponseFormat responseFormat = componentUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + return Either.right(responseFormat); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java new file mode 100644 index 0000000000..27709bb332 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleBusinessLogic.java @@ -0,0 +1,572 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import javax.annotation.PostConstruct; + +import org.openecomp.sdc.be.components.distribution.engine.ServiceDistributionArtifactsBuilder; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ICacheMangerOperation; +import org.openecomp.sdc.be.model.operations.api.IGraphLockOperation; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.CapabilityOperation; +import org.openecomp.sdc.be.model.operations.impl.ProductOperation; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.tosca.ToscaExportHandler; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +@org.springframework.stereotype.Component("lifecycleBusinessLogic") +public class LifecycleBusinessLogic { + + private static final String COMMENT = "comment"; + + @Autowired + private IGraphLockOperation graphLockOperation = null; + + @Autowired + private ArtifactsBusinessLogic artifactsBusinessLogic; + + @Autowired + private ResourceOperation resourceOperation; + + @Autowired + private ServiceOperation serviceOperation; + + @Autowired + private ProductOperation productOperation; + + @Autowired + private CapabilityOperation capabilityOperation; + + private static Logger log = LoggerFactory.getLogger(LifecycleBusinessLogic.class.getName()); + + @javax.annotation.Resource + private ComponentsUtils componentUtils; + + @javax.annotation.Resource + private ILifecycleOperation lifecycleOperation; + @javax.annotation.Resource + ArtifactsBusinessLogic artifactsManager; + + @javax.annotation.Resource + private ServiceDistributionArtifactsBuilder serviceDistributionArtifactsBuilder; + + @javax.annotation.Resource + private ServiceBusinessLogic serviceBusinessLogic; + + @javax.annotation.Resource + private ResourceBusinessLogic resourceBusinessLogic; + + @javax.annotation.Resource + private ProductBusinessLogic productBusinessLogic; + + @Autowired + private ToscaExportHandler toscaExportUtils; + + @Autowired + ICacheMangerOperation cacheManagerOperation; + + private Map stateTransitions; + private static volatile boolean isInitialized = false; + + @PostConstruct + public void init() { + // init parameters + if (!isInitialized) { + synchronized (this) { + if (!isInitialized) { + initStateOperations(); + isInitialized = true; + } + } + } + } + + private void initStateOperations() { + stateTransitions = new HashMap(); + + LifeCycleTransition checkoutOp = new CheckoutTransition(componentUtils, lifecycleOperation); + stateTransitions.put(checkoutOp.getName().name(), checkoutOp); + + UndoCheckoutTransition undoCheckoutOp = new UndoCheckoutTransition(componentUtils, lifecycleOperation); + undoCheckoutOp.setArtifactsBusinessLogic(artifactsBusinessLogic); + stateTransitions.put(undoCheckoutOp.getName().name(), undoCheckoutOp); + + LifeCycleTransition checkinOp = new CheckinTransition(componentUtils, lifecycleOperation); + stateTransitions.put(checkinOp.getName().name(), checkinOp); + + LifeCycleTransition certificationRequest = new CertificationRequestTransition(componentUtils, lifecycleOperation, serviceDistributionArtifactsBuilder, serviceBusinessLogic, capabilityOperation, toscaExportUtils); + stateTransitions.put(certificationRequest.getName().name(), certificationRequest); + + LifeCycleTransition startCertification = new StartCertificationTransition(componentUtils, lifecycleOperation); + stateTransitions.put(startCertification.getName().name(), startCertification); + + LifeCycleTransition failCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.FAIL_CERTIFICATION, componentUtils, lifecycleOperation); + stateTransitions.put(failCertification.getName().name(), failCertification); + + LifeCycleTransition cancelCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CANCEL_CERTIFICATION, componentUtils, lifecycleOperation); + stateTransitions.put(cancelCertification.getName().name(), cancelCertification); + + CertificationChangeTransition successCertification = new CertificationChangeTransition(LifeCycleTransitionEnum.CERTIFY, componentUtils, lifecycleOperation); + successCertification.setArtifactsManager(artifactsBusinessLogic); + stateTransitions.put(successCertification.getName().name(), successCertification); + } + + public LifeCycleTransition getLifecycleTransition(LifeCycleTransitionEnum transitionEnum) { + return stateTransitions.get(transitionEnum.name()); + } + + public Either changeServiceState(String serviceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) { + return (Either) changeComponentState(ComponentTypeEnum.SERVICE, serviceId, modifier, transitionEnum, changeInfo, inTransaction, needLock); + } + + // TODO: rhalili - should use changeComponentState when possible + public Either changeState(String resourceId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, boolean needLock) { + return (Either) changeComponentState(ComponentTypeEnum.RESOURCE, resourceId, modifier, transitionEnum, changeInfo, inTransaction, needLock); + + // LifeCycleTransition lifeCycleTransition = + // stateTransitions.get(transitionEnum.name()); + // if (lifeCycleTransition == null) { + // log.debug("state operation is not valid. operations allowed are: {}", + // LifeCycleTransitionEnum.valuesAsString()); + // ResponseFormat error = + // componentUtils.getInvalidContentErrorAndAudit(modifier, + // AuditingActionEnum.CHECKOUT_RESOURCE); + // return Either.right(error); + // } + // + // Either operationResult; + // Resource resource = null; + // boolean needToUnlockResource = false; + // + // log.debug("get resource from graph"); + // ResponseFormat errorResponse; + // Either eitherResourceResponse = + // getResourceForChange(resourceId, modifier, lifeCycleTransition); + // if (eitherResourceResponse.isRight()) { + // return eitherResourceResponse; + // } + // resource = eitherResourceResponse.left().value(); + // String resourceCurrVersion = resource.getResourceVersion(); + // LifecycleStateEnum resourceCurrState = resource.getLifecycleState(); + // + // if (inTransaction == false) { + // // lock resource + // Either eitherLockResource = + // lockResource(resource); + // if (eitherLockResource.isRight()) { + // errorResponse = eitherLockResource.right().value(); + // componentUtils.auditResource(errorResponse, modifier, resource, + // resourceCurrState.name(), resourceCurrVersion, + // lifeCycleTransition.getAuditingAction(), null); + // return Either.right(errorResponse); + // } + // needToUnlockResource = true; + // } + // + // try { + // Either resourceNotDeleted = + // validateResourceNotDeleted(modifier, lifeCycleTransition, resource, + // resourceCurrVersion); + // if (resourceNotDeleted.isRight()) { + // return Either.right(resourceNotDeleted.right().value()); + // } + // + // Either validateHighestVersion = + // validateHighestVersion(modifier, lifeCycleTransition, resource, + // resourceCurrVersion); + // if (validateHighestVersion.isRight()) { + // return Either.right(validateHighestVersion.right().value()); + // } + // + // Either ownerResult = + // lifeCycleTransition.getResourceOwner(resource); + // if (ownerResult.isRight()) { + // return Either.right(ownerResult.right().value()); + // } + // User owner = ownerResult.left().value(); + // log.debug("owner of resource {} is {}", resource.getUniqueId(), + // owner.getUserId()); + // + // LifecycleStateEnum oldState = resource.getLifecycleState(); + // + // Either commentValidationResult = + // validateComment(changeInfo, transitionEnum); + // if (commentValidationResult.isRight()) { + // errorResponse = commentValidationResult.right().value(); + // EnumMap auditingFields = new + // EnumMap(AuditingFieldsKeysEnum.class); + // auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, + // changeInfo.getUserRemarks()); + // componentUtils.auditResource(errorResponse, modifier, resource, + // resourceCurrState.name(), resourceCurrVersion, + // lifeCycleTransition.getAuditingAction(), auditingFields); + // return Either.right(errorResponse); + // } + // changeInfo.setUserRemarks(commentValidationResult.left().value()); + // + // Either stateValidationResult = + // lifeCycleTransition.validateResourceBeforeTransition(resource.getResourceName(), + // ComponentTypeEnum.RESOURCE, modifier, owner, oldState); + // if (stateValidationResult.isRight()) { + // errorResponse = stateValidationResult.right().value(); + // componentUtils.auditResource(errorResponse, modifier, resource, + // resourceCurrState.name(), resourceCurrVersion, + // lifeCycleTransition.getAuditingAction(), null); + // return Either.right(errorResponse); + // } + // + // operationResult = lifeCycleTransition.changeStateOperation(resource, + // modifier, owner, inTransaction); + // + // if (operationResult.isRight()) { + // errorResponse = operationResult.right().value(); + // log.debug("audit before sending response"); + // componentUtils.auditResource(errorResponse, modifier, resource, + // resourceCurrState.name(), resourceCurrVersion, + // lifeCycleTransition.getAuditingAction(), null); + // + // return Either.right(errorResponse); + // } + // Resource resourceAfterOperation = operationResult.left().value(); + // EnumMap auditingFields = new + // EnumMap(AuditingFieldsKeysEnum.class); + // auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, + // changeInfo.getUserRemarks()); + // componentUtils.auditResource(componentUtils.getResponseFormat(ActionStatus.OK), + // modifier, resourceAfterOperation, resourceCurrState.name(), + // resourceCurrVersion, lifeCycleTransition.getAuditingAction(), + // auditingFields); + // return operationResult; + // + // } finally { + // log.debug("unlock resource {}", resourceId); + // if (needToUnlockResource && resource != null) { + // resource.setUniqueId(resourceId); + // graphLockOperation.unlockResource(resource); + // } + // } + + } + + public Either changeComponentState(ComponentTypeEnum componentType, String componentId, User modifier, LifeCycleTransitionEnum transitionEnum, LifecycleChangeInfoWithAction changeInfo, boolean inTransaction, + boolean needLock) { + + LifeCycleTransition lifeCycleTransition = stateTransitions.get(transitionEnum.name()); + if (lifeCycleTransition == null) { + log.debug("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString()); + ResponseFormat error = componentUtils.getInvalidContentErrorAndAudit(modifier, AuditingActionEnum.CHECKOUT_RESOURCE); + return Either.right(error); + } + ComponentBusinessLogic bl = getComponentBL(componentType); + + Either operationResult = null; + Component component = null; + // boolean needToUnlockResource = false; + log.debug("get resource from graph"); + ResponseFormat errorResponse; + + Either eitherResourceResponse = getComponentForChange(componentType, componentId, modifier, lifeCycleTransition, changeInfo); + if (eitherResourceResponse.isRight()) { + return eitherResourceResponse; + } + component = eitherResourceResponse.left().value(); + String resourceCurrVersion = component.getVersion(); + LifecycleStateEnum resourceCurrState = component.getLifecycleState(); + + // lock resource + if (inTransaction == false && needLock) { + Either eitherLockResource = lockComponent(componentType, component); + if (eitherLockResource.isRight()) { + errorResponse = eitherLockResource.right().value(); + componentUtils.auditComponent(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, null); + return Either.right(errorResponse); + } + // needToUnlockResource = true; + } + try { + Either commentValidationResult = validateComment(changeInfo, transitionEnum); + if (commentValidationResult.isRight()) { + errorResponse = commentValidationResult.right().value(); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks()); + componentUtils.auditComponent(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields); + return Either.right(errorResponse); + } + changeInfo.setUserRemarks(commentValidationResult.left().value()); + + Either validateHighestVersion = validateHighestVersion(modifier, lifeCycleTransition, component, resourceCurrVersion, componentType); + if (validateHighestVersion.isRight()) { + return Either.right(validateHighestVersion.right().value()); + } + + Either ownerResult = lifeCycleTransition.getComponentOwner(component, componentType, inTransaction); + if (ownerResult.isRight()) { + return Either.right(ownerResult.right().value()); + } + User owner = ownerResult.left().value(); + log.debug("owner of resource {} is {}", component.getUniqueId(), owner.getUserId()); + + LifecycleStateEnum oldState = component.getLifecycleState(); + + Either stateValidationResult = lifeCycleTransition.validateBeforeTransition(component, componentType, modifier, owner, oldState, changeInfo); + if (stateValidationResult.isRight()) { + errorResponse = stateValidationResult.right().value(); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks()); + componentUtils.auditComponent(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields); + return Either.right(errorResponse); + + } + + operationResult = lifeCycleTransition.changeState(componentType, component, bl, modifier, owner, false, inTransaction); + + if (operationResult.isRight()) { + errorResponse = operationResult.right().value(); + log.debug("audit before sending response"); + componentUtils.auditComponentAdmin(errorResponse, modifier, component, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType); + + return Either.right(errorResponse); + } + Component resourceAfterOperation = operationResult.left().value(); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks()); + componentUtils.auditComponent(componentUtils.getResponseFormat(ActionStatus.OK), modifier, resourceAfterOperation, resourceCurrState.name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType, auditingFields); + return operationResult; + + } finally { + log.debug("unlock component {}", componentId); + if (inTransaction == false && needLock && component != null) { + component.setUniqueId(componentId); + NodeTypeEnum nodeType = componentType.getNodeType(); + + // Handle component change in the cache of the side affect of + // the operation + if (operationResult != null && operationResult.isLeft()) { + Component componentAfterOpertion = operationResult.left().value(); + String uniqueId = componentAfterOpertion.getUniqueId(); + if (false == componentId.equals(uniqueId)) { + log.debug("During change state, another component {} has been created/updated", uniqueId); + if (uniqueId != null) { + cacheManagerOperation.updateComponentInCache(uniqueId, componentAfterOpertion.getLastUpdateDate(), nodeType); + } + } + } + + graphLockOperation.unlockComponent(componentId, nodeType); + + } + } + + } + + private Either getComponentForChange(ComponentTypeEnum componentType, String componentId, User modifier, LifeCycleTransition lifeCycleTransition, LifecycleChangeInfoWithAction changeInfo) { + + Either eitherResourceResponse = Either.right(StorageOperationStatus.GENERAL_ERROR); + switch (componentType) { + case SERVICE: + eitherResourceResponse = serviceOperation.getComponent(componentId, true); + break; + case PRODUCT: + eitherResourceResponse = productOperation.getComponent(componentId, true); + break; + case RESOURCE: + eitherResourceResponse = resourceOperation.getComponent(componentId, true); + break; + default: + break; + } + + ResponseFormat errorResponse = null; + if (eitherResourceResponse.isRight()) { + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(eitherResourceResponse.right().value(), componentType); + errorResponse = componentUtils.getResponseFormat(actionStatus, Constants.EMPTY_STRING); + log.debug("audit before sending response"); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_COMMENT, changeInfo.getUserRemarks()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, componentId); + componentUtils.auditComponent(errorResponse, modifier, null, Constants.EMPTY_STRING, Constants.EMPTY_STRING, lifeCycleTransition.getAuditingAction(), componentType, auditingFields); + + return Either.right(errorResponse); + } + return Either.left(eitherResourceResponse.left().value()); + } + + private Either validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Resource resource, String resourceCurrVersion) { + ResponseFormat errorResponse; + if (!resource.isHighestVersion()) { + log.debug("resource version {} is not the last version of resource {}", resource.getVersion(), resource.getName()); + errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, resource.getName(), ComponentTypeEnum.RESOURCE.name().toLowerCase()); + componentUtils.auditResource(errorResponse, modifier, resource, resource.getLifecycleState().name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), null); + return Either.right(errorResponse); + } + return Either.left(true); + } + + private Either validateResourceNotDeleted(User modifier, LifeCycleTransition lifeCycleTransition, Resource resource, String resourceCurrVersion) { + + ResponseFormat errorResponse; + if ((resource.getIsDeleted() != null) && (resource.getIsDeleted() == true)) { + ActionStatus actionStatus = ActionStatus.RESOURCE_NOT_FOUND; + errorResponse = componentUtils.getResponseFormatByResource(actionStatus, resource.getName()); + log.debug("resource {} {} is marked for delete", resource.getName(), resource.getVersion()); + componentUtils.auditResource(errorResponse, modifier, null, "", "", lifeCycleTransition.getAuditingAction(), null); + + return Either.right(errorResponse); + } + return Either.left(true); + } + + private Either validateHighestVersion(User modifier, LifeCycleTransition lifeCycleTransition, Component component, String resourceCurrVersion, ComponentTypeEnum componentType) { + ResponseFormat errorResponse; + if (!component.isHighestVersion()) { + log.debug("Component version {} is not the last version of component {}", component.getComponentMetadataDefinition().getMetadataDataDefinition().getVersion(), + component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + errorResponse = componentUtils.getResponseFormat(ActionStatus.COMPONENT_HAS_NEWER_VERSION, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(), componentType.getValue().toLowerCase()); + componentUtils.auditComponentAdmin(errorResponse, modifier, component, component.getLifecycleState().name(), resourceCurrVersion, lifeCycleTransition.getAuditingAction(), componentType); + return Either.right(errorResponse); + } + return Either.left(true); + } + + private Either lockComponent(ComponentTypeEnum componentType, Component component) { + NodeTypeEnum nodeType = componentType.getNodeType(); + StorageOperationStatus lockResourceStatus = graphLockOperation.lockComponent(component.getUniqueId(), nodeType); + + if (lockResourceStatus.equals(StorageOperationStatus.OK)) { + return Either.left(true); + } else { + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(lockResourceStatus); + ResponseFormat responseFormat = componentUtils.getResponseFormat(actionStatus, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + return Either.right(responseFormat); + } + + } + + private Either getResourceForChange(String resourceId, User modifier, LifeCycleTransition lifeCycleTransition) { + Either eitherResourceResponse = resourceOperation.getResource(resourceId, true); + + ResponseFormat errorResponse = null; + if (eitherResourceResponse.isRight()) { + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(eitherResourceResponse.right().value()); + errorResponse = componentUtils.getResponseFormatByResource(actionStatus, ""); + log.debug("audit before sending response"); + // For audit of not found, resourceName should be uniqueID according + // to Ella + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceId); + componentUtils.auditResource(errorResponse, modifier, null, "", "", lifeCycleTransition.getAuditingAction(), null); + + return Either.right(errorResponse); + } + Resource resource = eitherResourceResponse.left().value(); + + return Either.left(resource); + + } + + private Either validateComment(LifecycleChangeInfoWithAction changeInfo, LifeCycleTransitionEnum transitionEnum) { + String comment = changeInfo.getUserRemarks(); + if (LifeCycleTransitionEnum.CANCEL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CERTIFY == transitionEnum || LifeCycleTransitionEnum.FAIL_CERTIFICATION == transitionEnum || LifeCycleTransitionEnum.CHECKIN == transitionEnum + || LifeCycleTransitionEnum.CERTIFICATION_REQUEST == transitionEnum + // import? + ) { + + if (!ValidationUtils.validateStringNotEmpty(comment)) { + log.debug("user comment cannot be empty or null."); + ResponseFormat errorResponse = componentUtils.getResponseFormat(ActionStatus.MISSING_DATA, COMMENT); + return Either.right(errorResponse); + } + + comment = ValidationUtils.removeNoneUtf8Chars(comment); + comment = ValidationUtils.removeHtmlTags(comment); + comment = ValidationUtils.normaliseWhitespace(comment); + comment = ValidationUtils.stripOctets(comment); + + if (!ValidationUtils.validateLength(comment, ValidationUtils.COMMENT_MAX_LENGTH)) { + log.debug("user comment exceeds limit."); + return Either.right(componentUtils.getResponseFormat(ActionStatus.EXCEEDS_LIMIT, COMMENT, String.valueOf(ValidationUtils.COMMENT_MAX_LENGTH))); + } + if (!ValidationUtils.validateIsEnglish(comment)) { + return Either.right(componentUtils.getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + return Either.left(comment); + } + + private ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum) { + ComponentBusinessLogic businessLogic; + switch (componentTypeEnum) { + case RESOURCE: { + businessLogic = this.resourceBusinessLogic; + break; + } + case SERVICE: { + businessLogic = this.serviceBusinessLogic; + break; + } + case PRODUCT: { + businessLogic = this.productBusinessLogic; + break; + } + + default: { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "getComponentBL"); + throw new IllegalArgumentException("Illegal component type:" + componentTypeEnum.getValue()); + } + } + return businessLogic; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoBase.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoBase.java new file mode 100644 index 0000000000..0c35caf41b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoBase.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +public class LifecycleChangeInfoBase { + + public LifecycleChangeInfoBase() { + } + + public LifecycleChangeInfoBase(String userRemarks) { + super(); + this.userRemarks = userRemarks; + } + + private String userRemarks; + + public String getUserRemarks() { + return userRemarks; + } + + public void setUserRemarks(String userRemarks) { + this.userRemarks = userRemarks; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoWithAction.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoWithAction.java new file mode 100644 index 0000000000..170e187f15 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/LifecycleChangeInfoWithAction.java @@ -0,0 +1,50 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +public class LifecycleChangeInfoWithAction extends LifecycleChangeInfoBase { + + public enum LifecycleChanceActionEnum { + CREATE_FROM_CSAR, UPDATE_FROM_EXTERNAL_API + }; + + private LifecycleChanceActionEnum action; + + public LifecycleChangeInfoWithAction() { + } + + public LifecycleChangeInfoWithAction(String userRemarks) { + super(userRemarks); + } + + public LifecycleChangeInfoWithAction(String userRemarks, LifecycleChanceActionEnum action) { + super(userRemarks); + this.action = action; + } + + public LifecycleChanceActionEnum getAction() { + return action; + } + + public void setAction(LifecycleChanceActionEnum action) { + this.action = action; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/StartCertificationTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/StartCertificationTransition.java new file mode 100644 index 0000000000..918140b0af --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/StartCertificationTransition.java @@ -0,0 +1,119 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.Arrays; + +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class StartCertificationTransition extends LifeCycleTransition { + + private static Logger log = LoggerFactory.getLogger(StartCertificationTransition.class.getName()); + + public StartCertificationTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + super(componentUtils, lifecycleOperation); + + // authorized roles + Role[] rsrcServiceStartCertificationRoles = { Role.ADMIN, Role.TESTER }; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(rsrcServiceStartCertificationRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(rsrcServiceStartCertificationRoles)); + // TODO to be later defined for product + } + + @Override + public LifeCycleTransitionEnum getName() { + return LifeCycleTransitionEnum.START_CERTIFICATION; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return AuditingActionEnum.START_CERTIFICATION_RESOURCE; + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + + log.debug("start performing certification test for resource {}", component.getUniqueId()); + + NodeTypeEnum nodeType = (componentType.equals(ComponentTypeEnum.SERVICE)) ? NodeTypeEnum.Service : NodeTypeEnum.Resource; + Either stateChangeResult = lifeCycleOperation.startComponentCertification(nodeType, component, modifier, owner, inTransaction); + if (stateChangeResult.isRight()) { + log.debug("start certification failed on graph"); + StorageOperationStatus response = stateChangeResult.right().value(); + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(response); + + if (response.equals(StorageOperationStatus.ENTITY_ALREADY_EXISTS)) { + actionStatus = ActionStatus.COMPONENT_VERSION_ALREADY_EXIST; + } + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + return Either.right(responseFormat); + } + + return Either.left(stateChangeResult.left().value()); + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before start certification test. resource name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + if (oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKIN) || oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_NOT_READY_FOR_CERTIFICATION, componentName, componentType.name().toLowerCase()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.CERTIFIED)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_ALREADY_CERTIFIED, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (oldState.equals(LifecycleStateEnum.CERTIFICATION_IN_PROGRESS)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_IN_CERT_IN_PROGRESS_STATE, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + return Either.left(true); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/UndoCheckoutTransition.java b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/UndoCheckoutTransition.java new file mode 100644 index 0000000000..fcb211bc3e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/components/lifecycle/UndoCheckoutTransition.java @@ -0,0 +1,170 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.components.lifecycle; + +import java.util.Arrays; +import java.util.List; + +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.ILifecycleOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class UndoCheckoutTransition extends LifeCycleTransition { + private static Logger log = LoggerFactory.getLogger(CheckoutTransition.class.getName()); + private ArtifactsBusinessLogic artifactsManager; + + public UndoCheckoutTransition(ComponentsUtils componentUtils, ILifecycleOperation lifecycleOperation) { + super(componentUtils, lifecycleOperation); + + // authorized roles + Role[] resourceServiceCheckoutRoles = { Role.ADMIN, Role.DESIGNER }; + Role[] productCheckoutRoles = { Role.ADMIN, Role.PRODUCT_MANAGER }; + addAuthorizedRoles(ComponentTypeEnum.RESOURCE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.SERVICE, Arrays.asList(resourceServiceCheckoutRoles)); + addAuthorizedRoles(ComponentTypeEnum.PRODUCT, Arrays.asList(productCheckoutRoles)); + + } + + @Override + public LifeCycleTransitionEnum getName() { + return LifeCycleTransitionEnum.UNDO_CHECKOUT; + } + + @Override + public AuditingActionEnum getAuditingAction() { + return AuditingActionEnum.UNDO_CHECKOUT_RESOURCE; + } + + public ArtifactsBusinessLogic getArtifactsBusinessLogic() { + return artifactsManager; + } + + public void setArtifactsBusinessLogic(ArtifactsBusinessLogic artifactsBusinessLogic) { + this.artifactsManager = artifactsBusinessLogic; + } + + @Override + public Either validateBeforeTransition(Component component, ComponentTypeEnum componentType, User modifier, User owner, LifecycleStateEnum oldState, LifecycleChangeInfoWithAction lifecycleChangeInfo) { + String componentName = component.getComponentMetadataDefinition().getMetadataDataDefinition().getName(); + log.debug("validate before undo checkout. resource name={}, oldState={}, owner userId={}", componentName, oldState, owner.getUserId()); + + // validate user + Either userValidationResponse = userRoleValidation(modifier, componentType, lifecycleChangeInfo); + if (userValidationResponse.isRight()) { + return userValidationResponse; + } + + // check resource is not locked by another user + if (!oldState.equals(LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_ALREADY_CHECKED_IN, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + if (!modifier.equals(owner) && !modifier.getRole().equals(Role.ADMIN.name())) { + ResponseFormat error = componentUtils.getResponseFormat(ActionStatus.COMPONENT_CHECKOUT_BY_ANOTHER_USER, componentName, componentType.name().toLowerCase(), owner.getFirstName(), owner.getLastName(), owner.getUserId()); + return Either.right(error); + } + + return Either.left(true); + } + + @Override + public Either changeState(ComponentTypeEnum componentType, Component component, ComponentBusinessLogic componentBl, User modifier, User owner, boolean shouldLock, boolean inTransaction) { + + Either result = null; + log.debug("start performing undo-checkout for resource {}", component.getUniqueId()); + + Either, StorageOperationStatus> artifactsRes = lifeCycleOperation.getComponentOperation(componentType.getNodeType()).getComponentArtifactsForDelete(component.getUniqueId(), componentType.getNodeType(), true); + if (artifactsRes.isRight()) { + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(artifactsRes.right().value()); + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + result = Either.right(responseFormat); + return result; + } + // TODO - start transaction + try { + NodeTypeEnum nodeType = componentType.getNodeType(); + + // 1. perform undo checkout on graph (update status and delete + // current version) + Either undoCheckoutResourceResult = lifeCycleOperation.undoCheckout(nodeType, component, modifier, owner, true); + + if (undoCheckoutResourceResult.isRight()) { + log.debug("checkout failed on graph"); + StorageOperationStatus response = undoCheckoutResourceResult.right().value(); + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(response); + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + result = Either.right(responseFormat); + return result; + } + + // 2. delete unrelated artifacts + // use artifacts API to delete artifacts from swift / elasticsearch + + if (artifactsRes.left().value() != null) { + List artifacts = artifactsRes.left().value(); + StorageOperationStatus deleteAllResourceArtifacts = artifactsManager.deleteAllComponentArtifactsIfNotOnGraph(artifacts); + + if (!deleteAllResourceArtifacts.equals(StorageOperationStatus.OK)) { + ActionStatus actionStatus = componentUtils.convertFromStorageResponse(deleteAllResourceArtifacts); + ResponseFormat responseFormat = componentUtils.getResponseFormatByComponent(actionStatus, component, componentType); + result = Either.right(responseFormat); + return result; + } + } + + result = Either.left(undoCheckoutResourceResult.left().value()); + } finally { + if (result == null || result.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDaoSystemError, "Change LifecycleState - Undo Checkout failed on graph"); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Change LifecycleState - Undo Checkout failed on graph"); + + log.debug("operation failed. do rollback"); + lifeCycleOperation.getResourceOperation().getTitanGenericDao().rollback(); + } else { + log.debug("operation success. do commit"); + lifeCycleOperation.getResourceOperation().getTitanGenericDao().commit(); + } + } + + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/CategoryTypeEnum.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/CategoryTypeEnum.java new file mode 100644 index 0000000000..edfe56ebfa --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/CategoryTypeEnum.java @@ -0,0 +1,39 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.datamodel.api; + +import java.io.Serializable; + +public enum CategoryTypeEnum implements Serializable { + + CATEGORY("category"), SUBCATEGORY("sub-category"), GROUPING("grouping"); + + private String value; + + CategoryTypeEnum(String value) { + this.value = value; + } + + public String getValue() { + return value; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/HighestFilterEnum.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/HighestFilterEnum.java new file mode 100644 index 0000000000..42ff4c900a --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/api/HighestFilterEnum.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.datamodel.api; + +public enum HighestFilterEnum { + + ALL, HIGHEST_ONLY, NON_HIGHEST_ONLY; + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ArtifactUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ArtifactUtils.java new file mode 100644 index 0000000000..9f66911461 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/ArtifactUtils.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.datamodel.utils; + +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; + +public class ArtifactUtils { + public static ArtifactDefinition findMasterArtifact(Map deplymentArtifact, List artifacts, List artifactsList) { + for (String artifactUid : artifactsList) { + for (Entry entry : deplymentArtifact.entrySet()) { + ArtifactDefinition artifact = entry.getValue(); + if (artifactUid.equalsIgnoreCase(artifact.getUniqueId())) { + artifacts.add(artifact); + } + + } + } + if (artifacts.size() == 1) { + return artifacts.get(0); + } + ArtifactDefinition masterArtifact = null; + for (ArtifactDefinition artifactInfo : artifacts) { + String atrifactType = artifactInfo.getArtifactType(); + if (atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType()) || atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType())) { + masterArtifact = artifactInfo; + continue; + } + if (atrifactType.equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + masterArtifact = artifactInfo; + break; + } + } + return masterArtifact; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/NodeTypeConvertUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/NodeTypeConvertUtils.java new file mode 100644 index 0000000000..ab71508e62 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/datamodel/utils/NodeTypeConvertUtils.java @@ -0,0 +1,76 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.datamodel.utils; + +import org.openecomp.sdc.be.datamodel.api.CategoryTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; + +public class NodeTypeConvertUtils { + public static NodeTypeEnum getCategoryNodeTypeByComponentParam(ComponentTypeEnum componentTypeEnum, CategoryTypeEnum categoryType) { + NodeTypeEnum res = null; + if (componentTypeEnum != null) { + switch (componentTypeEnum) { + case SERVICE: + switch (categoryType) { + case CATEGORY: + res = NodeTypeEnum.ServiceNewCategory; + break; + + default: + // doesn't support subcategories or grouping + break; + } + break; + case RESOURCE: + switch (categoryType) { + case CATEGORY: + res = NodeTypeEnum.ResourceNewCategory; + break; + case SUBCATEGORY: + res = NodeTypeEnum.ResourceSubcategory; + break; + default: + // doesn't support grouping + break; + } + break; + case PRODUCT: + switch (categoryType) { + case CATEGORY: + res = NodeTypeEnum.ProductCategory; + break; + case SUBCATEGORY: + res = NodeTypeEnum.ProductSubcategory; + break; + case GROUPING: + res = NodeTypeEnum.ProductGrouping; + break; + } + break; + default: + break; + } + } + return res; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java new file mode 100644 index 0000000000..0cc415c80d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/AuditHandler.java @@ -0,0 +1,65 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution; + +import org.openecomp.sdc.be.components.distribution.engine.CambriaErrorResponse; +import org.openecomp.sdc.be.components.distribution.engine.SubscriberTypeEnum; +import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; + +public class AuditHandler { + ComponentsUtils componentsUtils; + String instanceID; + private RegistrationRequest registrationRequest; + + public AuditHandler(ComponentsUtils componentsUtils, String instanceID, RegistrationRequest registrationRequest) { + super(); + this.componentsUtils = componentsUtils; + this.instanceID = instanceID; + this.registrationRequest = registrationRequest; + } + + public void auditRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole) { + + String topicName = (subscriberRole == SubscriberTypeEnum.CONSUMER) ? DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()) + : DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName()); + componentsUtils.auditTopicACLKeys(AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL, registrationRequest.getDistrEnvName(), topicName, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); + } + + public void auditUnRegisterACL(CambriaErrorResponse registerResponse, SubscriberTypeEnum subscriberRole) { + String topicName = (subscriberRole == SubscriberTypeEnum.CONSUMER) ? DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()) + : DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName()); + componentsUtils.auditTopicACLKeys(AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL, registrationRequest.getDistrEnvName(), topicName, subscriberRole.name(), registrationRequest.getApiPublicKey(), String.valueOf(registerResponse.getHttpCode())); + + } + + public void auditRegisterRequest(CambriaErrorResponse registerResponse) { + componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), + registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); + + } + + public void auditUnRegisterRequest(CambriaErrorResponse registerResponse) { + componentsUtils.auditRegisterOrUnRegisterEvent(AuditingActionEnum.DISTRIBUTION_UN_REGISTER, instanceID, registrationRequest.getApiPublicKey(), registrationRequest.getDistrEnvName(), String.valueOf(registerResponse.getHttpCode()), + registerResponse.getOperationStatus().name(), DistributionBusinessLogic.getNotificationTopicName(registrationRequest.getDistrEnvName()), DistributionBusinessLogic.getStatusTopicName(registrationRequest.getDistrEnvName())); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java new file mode 100644 index 0000000000..ae1de21ea8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/DistributionBusinessLogic.java @@ -0,0 +1,243 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution; + +import java.util.List; + +import javax.annotation.Resource; +import javax.ws.rs.core.Response; + +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.components.distribution.engine.CambriaErrorResponse; +import org.openecomp.sdc.be.components.distribution.engine.CambriaHandler; +import org.openecomp.sdc.be.components.distribution.engine.DistributionEngine; +import org.openecomp.sdc.be.components.distribution.engine.DistributionEngineInitTask; +import org.openecomp.sdc.be.components.distribution.engine.SubscriberTypeEnum; +import org.openecomp.sdc.be.components.impl.ResponseFormatManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.DistributionEngineConfiguration; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.distribution.api.client.CambriaOperationStatus; +import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; +import org.openecomp.sdc.be.distribution.api.client.ServerListResponse; +import org.openecomp.sdc.be.distribution.api.client.TopicRegistrationResponse; +import org.openecomp.sdc.be.distribution.api.client.TopicUnregistrationResponse; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@Component("distributionBusinessLogic") +public class DistributionBusinessLogic { + public static final String REGISTER_IN_DISTRIBUTION_ENGINE = "registerInDistributionEngine"; + public static final String UN_REGISTER_IN_DISTRIBUTION_ENGINE = "unregisterInDistributionEngine"; + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + private static Logger log = LoggerFactory.getLogger(DistributionBusinessLogic.class.getName()); + @Resource + private DistributionEngine distributionEngine; + + private ResponseFormatManager responseFormatManager = ResponseFormatManager.getInstance(); + private CambriaHandler cambriaHandler; + + public Either getUebServerList() { + + DistributionEngineConfiguration distributionEngineConfiguration = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + + List serverList = distributionEngineConfiguration.getUebServers(); + + if (serverList != null && !serverList.isEmpty()) { + + ServerListResponse serverListResponse = new ServerListResponse(); + + serverListResponse.setUebServerList(serverList); + + return Either.left(serverListResponse); + } else { + ResponseFormat errorResponseWrapper = getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(errorResponseWrapper); + } + + } + + public void handleRegistration(Wrapper responseWrapper, RegistrationRequest registrationRequest, AuditHandler auditHandler) { + CambriaErrorResponse registerResponse = null; + try { + registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, SubscriberTypeEnum.PRODUCER); + auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.PRODUCER); + + if (responseWrapper.isEmpty()) { + registerResponse = registerDistributionClientToTopic(responseWrapper, registrationRequest, SubscriberTypeEnum.CONSUMER); + auditHandler.auditRegisterACL(registerResponse, SubscriberTypeEnum.CONSUMER); + // Second Register failed - unregister the first + if (!responseWrapper.isEmpty()) { + CambriaErrorResponse unRegisterResponse = unRegisterDistributionClientFromTopic(registrationRequest, SubscriberTypeEnum.PRODUCER); + auditHandler.auditUnRegisterACL(unRegisterResponse, SubscriberTypeEnum.PRODUCER); + } + } + + if (responseWrapper.isEmpty()) { + TopicRegistrationResponse okTopicResponse = buildTopicResponse(registrationRequest); + responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(okTopicResponse).build()); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, REGISTER_IN_DISTRIBUTION_ENGINE, "registration of subscriber to topic"); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, "registration of subscriber to topic"); + Response errorResponse = buildErrorResponse(getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + } finally { + auditHandler.auditRegisterRequest(registerResponse); + } + } + + public void handleUnRegistration(Wrapper responseWrapper, RegistrationRequest unRegistrationRequest, AuditHandler auditHandler) { + Wrapper cambriaResponseWrapper = new Wrapper<>(); + try { + CambriaErrorResponse unregisterClientProducerTopicResponse = unRegisterDistributionClientFromTopic(unRegistrationRequest, SubscriberTypeEnum.PRODUCER); + auditHandler.auditUnRegisterACL(unregisterClientProducerTopicResponse, SubscriberTypeEnum.PRODUCER); + updateResponseWrapper(cambriaResponseWrapper, unregisterClientProducerTopicResponse); + + CambriaErrorResponse unregisterClientConsumerTopicResponse = unRegisterDistributionClientFromTopic(unRegistrationRequest, SubscriberTypeEnum.CONSUMER); + auditHandler.auditUnRegisterACL(unregisterClientConsumerTopicResponse, SubscriberTypeEnum.CONSUMER); + updateResponseWrapper(cambriaResponseWrapper, unregisterClientConsumerTopicResponse); + + // Success unregister both topics + TopicUnregistrationResponse unregisterResponse = new TopicUnregistrationResponse(getNotificationTopicName(unRegistrationRequest.getDistrEnvName()), getStatusTopicName(unRegistrationRequest.getDistrEnvName()), + unregisterClientConsumerTopicResponse.getOperationStatus(), unregisterClientProducerTopicResponse.getOperationStatus()); + + if (cambriaResponseWrapper.getInnerElement().getOperationStatus() == CambriaOperationStatus.OK) { + responseWrapper.setInnerElement(Response.status(HttpStatus.SC_OK).entity(unregisterResponse).build()); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration failed"); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration failed"); + responseWrapper.setInnerElement(Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(unregisterResponse).build()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration of subscriber to topic"); + Response errorResponse = buildErrorResponse(getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + + } finally { + auditHandler.auditUnRegisterRequest(cambriaResponseWrapper.getInnerElement()); + } + } + + private void updateResponseWrapper(Wrapper cambriaResponseWrapper, CambriaErrorResponse currentResponse) { + if (cambriaResponseWrapper.isEmpty()) { + cambriaResponseWrapper.setInnerElement(currentResponse); + } else if (currentResponse.getOperationStatus() != CambriaOperationStatus.OK) { + cambriaResponseWrapper.setInnerElement(currentResponse); + + } + + } + + public static String getNotificationTopicName(String envName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + return DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), envName); + + } + + public static String getStatusTopicName(String envName) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + return DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), envName); + + } + + protected CambriaErrorResponse unRegisterDistributionClientFromTopic(RegistrationRequest unRegistrationRequest, SubscriberTypeEnum subscriberType) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + String topicName; + if (subscriberType == SubscriberTypeEnum.PRODUCER) { + topicName = getStatusTopicName(unRegistrationRequest.getDistrEnvName()); + } else { + topicName = getNotificationTopicName(unRegistrationRequest.getDistrEnvName()); + + } + log.debug("unregistering client as {} , from topic: {}", subscriberType.name(), topicName); + return getCambriaHandler().unRegisterFromTopic(config.getUebServers(), topicName, config.getUebPublicKey(), config.getUebSecretKey(), unRegistrationRequest.getApiPublicKey(), subscriberType); + } + + private TopicRegistrationResponse buildTopicResponse(RegistrationRequest registrationRequest) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + String statusTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), registrationRequest.getDistrEnvName()); + String notificationTopicName = DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), registrationRequest.getDistrEnvName()); + + TopicRegistrationResponse topicResponse = new TopicRegistrationResponse(); + topicResponse.setDistrNotificationTopicName(notificationTopicName); + topicResponse.setDistrStatusTopicName(statusTopicName); + return topicResponse; + } + + protected CambriaErrorResponse registerDistributionClientToTopic(Wrapper responseWrapper, RegistrationRequest registrationRequest, SubscriberTypeEnum subscriberType) { + DistributionEngineConfiguration config = ConfigurationManager.getConfigurationManager().getDistributionEngineConfiguration(); + String topicName, errorMsg; + + // Register for notifications as consumer + if (subscriberType == SubscriberTypeEnum.CONSUMER) { + topicName = DistributionEngineInitTask.buildTopicName(config.getDistributionNotifTopicName(), registrationRequest.getDistrEnvName()); + errorMsg = "registration of subscriber to topic:" + topicName + " as consumer failed"; + } + // Register for status as producer + else { + topicName = DistributionEngineInitTask.buildTopicName(config.getDistributionStatusTopicName(), registrationRequest.getDistrEnvName()); + errorMsg = "registration of subscriber to topic:" + topicName + " as producer failed"; + } + log.debug("registering client as {} , from topic: {}", subscriberType.name(), topicName); + CambriaErrorResponse registerToTopic = getCambriaHandler().registerToTopic(config.getUebServers(), topicName, config.getUebPublicKey(), config.getUebSecretKey(), registrationRequest.getApiPublicKey(), subscriberType); + + if (registerToTopic.getOperationStatus() != CambriaOperationStatus.OK) { + Response failedRegistrationResponse = buildErrorResponse(getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, REGISTER_IN_DISTRIBUTION_ENGINE, errorMsg); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(REGISTER_IN_DISTRIBUTION_ENGINE, errorMsg); + responseWrapper.setInnerElement(failedRegistrationResponse); + } + return registerToTopic; + } + + protected Response buildErrorResponse(ResponseFormat requestErrorWrapper) { + Response response = Response.status(requestErrorWrapper.getStatus()).entity(gson.toJson(requestErrorWrapper.getRequestError())).build(); + return response; + } + + public ResponseFormatManager getResponseFormatManager() { + return responseFormatManager; + } + + public DistributionEngine getDistributionEngine() { + return distributionEngine; + } + + public CambriaHandler getCambriaHandler() { + if (cambriaHandler == null) { + cambriaHandler = new CambriaHandler(); + } + return cambriaHandler; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/CambriaOperationStatus.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/CambriaOperationStatus.java new file mode 100644 index 0000000000..a6a6602cb0 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/CambriaOperationStatus.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.api.client; + +public enum CambriaOperationStatus { + OK, CONNNECTION_ERROR, NOT_FOUND, TOPIC_ALREADY_EXIST, OBJECT_NOT_FOUND, INTERNAL_SERVER_ERROR, AUTHENTICATION_ERROR, UNKNOWN_HOST_ERROR, +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/RegistrationRequest.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/RegistrationRequest.java new file mode 100644 index 0000000000..ef14efe4f8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/RegistrationRequest.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.api.client; + +public class RegistrationRequest { + String apiPublicKey; + String distrEnvName; + + public RegistrationRequest(String apiPublicKey, String distrEnvName) { + this.apiPublicKey = apiPublicKey; + this.distrEnvName = distrEnvName; + } + + public String getApiPublicKey() { + return apiPublicKey; + } + + public String getDistrEnvName() { + return distrEnvName; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/ServerListResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/ServerListResponse.java new file mode 100644 index 0000000000..267a691e29 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/ServerListResponse.java @@ -0,0 +1,36 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.api.client; + +import java.util.List; + +public class ServerListResponse { + + private List uebServerList; + + public List getUebServerList() { + return uebServerList; + } + + public void setUebServerList(List uebServerList) { + this.uebServerList = uebServerList; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicRegistrationResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicRegistrationResponse.java new file mode 100644 index 0000000000..e2a34a19d5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicRegistrationResponse.java @@ -0,0 +1,42 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.api.client; + +public class TopicRegistrationResponse { + String distrNotificationTopicName; + String distrStatusTopicName; + + public void setDistrNotificationTopicName(String distrNotificationTopicName) { + this.distrNotificationTopicName = distrNotificationTopicName; + } + + public void setDistrStatusTopicName(String distrStatusTopicName) { + this.distrStatusTopicName = distrStatusTopicName; + } + + public String getDistrNotificationTopicName() { + return distrNotificationTopicName; + } + + public String getDistrStatusTopicName() { + return distrStatusTopicName; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicUnregistrationResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicUnregistrationResponse.java new file mode 100644 index 0000000000..ffb9f9352f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/api/client/TopicUnregistrationResponse.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.api.client; + +public class TopicUnregistrationResponse { + String distrNotificationTopicName; + String distrStatusTopicName; + CambriaOperationStatus notificationUnregisterResult; + CambriaOperationStatus statusUnregisterResult; + + public TopicUnregistrationResponse(String distrNotificationTopicName, String distrStatusTopicName, CambriaOperationStatus notificationUnregisterResult, CambriaOperationStatus statusUnregisterResult) { + super(); + this.distrNotificationTopicName = distrNotificationTopicName; + this.distrStatusTopicName = distrStatusTopicName; + this.notificationUnregisterResult = notificationUnregisterResult; + this.statusUnregisterResult = statusUnregisterResult; + } + + public String getDistrNotificationTopicName() { + return distrNotificationTopicName; + } + + public String getDistrStatusTopicName() { + return distrStatusTopicName; + } + + public CambriaOperationStatus getNotificationUnregisterResult() { + return notificationUnregisterResult; + } + + public CambriaOperationStatus getStatusUnregisterResult() { + return statusUnregisterResult; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java new file mode 100644 index 0000000000..a5d1093648 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionCatalogServlet.java @@ -0,0 +1,230 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.servlet; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Singleton +public class DistributionCatalogServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(DistributionCatalogServlet.class.getName()); + + // ******************************************************* + // Download (GET) artifacts + // **********************************************************/ + + @GET + @Path("/services/{serviceName}/{serviceVersion}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadServiceArtifact(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @PathParam("artifactName") final String artifactName, + @Context final HttpServletRequest request) { + Response response = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.DISTRIBUTION_ARTIFACT_DOWNLOAD; + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("Missing X-ECOMP-InstanceID header"); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either downloadRsrcArtifactEither = artifactsLogic.downloadServiceArtifactByNames(serviceName, serviceVersion, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "download Murano package artifact for service - external API"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download Murano package artifact for service - external API"); + log.debug("download artifact failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/services/{serviceName}/{serviceVersion}/resources/{resourceName}/{resourceVersion}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download resource artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadResourceArtifact(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @PathParam("resourceName") final String resourceName, + @PathParam("resourceVersion") final String resourceVersion, @PathParam("artifactName") final String artifactName, @Context final HttpServletRequest request) { + Response response = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.DISTRIBUTION_ARTIFACT_DOWNLOAD; + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("Missing X-ECOMP-InstanceID header"); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either downloadRsrcArtifactEither = artifactsLogic.downloadRsrcArtifactByNames(serviceName, serviceVersion, resourceName, resourceVersion, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + // Returning 64-encoded as it was received during upload + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "download interface artifact for resource - external API"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); + log.debug("download artifact failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // -------------------------------- + + @GET + @Path("/services/{serviceName}/{serviceVersion}/resourceInstances/{resourceInstanceName}/artifacts/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download resource artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadResourceInstanceArtifact(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @PathParam("resourceInstanceName") final String resourceInstanceName, + @PathParam("artifactName") final String artifactName, @Context final HttpServletRequest request) { + Response response = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.DISTRIBUTION_ARTIFACT_DOWNLOAD; + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); + + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("Missing X-ECOMP-InstanceID header"); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either downloadRsrcArtifactEither = artifactsLogic.downloadRsrcInstArtifactByNames(serviceName, serviceVersion, resourceInstanceName, artifactName); + if (downloadRsrcArtifactEither.isRight()) { + ResponseFormat responseFormat = downloadRsrcArtifactEither.right().value(); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = downloadRsrcArtifactEither.left().value(); + // Returning 64-encoded as it was received during upload + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(artifactName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditDistributionDownload(responseFormat, auditingActionEnum, additionalParam); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "download interface artifact for resource - external API"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("download interface artifact for resource - external API"); + log.debug("download artifact failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // -------------------------------- +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java new file mode 100644 index 0000000000..b1556bafc3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/distribution/servlet/DistributionServlet.java @@ -0,0 +1,279 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.distribution.servlet; + +import javax.annotation.Resource; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.distribution.AuditHandler; +import org.openecomp.sdc.be.distribution.DistributionBusinessLogic; +import org.openecomp.sdc.be.distribution.api.client.RegistrationRequest; +import org.openecomp.sdc.be.distribution.api.client.ServerListResponse; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.HttpUtil; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1") +@Singleton +public class DistributionServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(DistributionServlet.class.getName()); + @Resource + private DistributionBusinessLogic distributionLogic; + + @GET + @Path("/distributionUebCluster") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getUebServerList(@Context final HttpServletRequest request, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, @HeaderParam(value = Constants.ACCEPT_HEADER) String accept) { + init(request); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + ResponseFormat responseFormat = null; + if (instanceId == null) { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + response = buildErrorResponse(responseFormat); + getComponentsUtils().auditMissingInstanceId(AuditingActionEnum.GET_UEB_CLUSTER, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + return response; + } + try { + Either actionResponse = distributionLogic.getUebServerList(); + + if (actionResponse.isRight()) { + responseFormat = actionResponse.right().value(); + response = buildErrorResponse(responseFormat); + } else { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + } + + getComponentsUtils().auditGetUebCluster(AuditingActionEnum.GET_UEB_CLUSTER, instanceId, null, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "failed to get ueb serbver list from cofiguration"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("failed to get ueb serbver list from cofiguration"); + log.debug("failed to get ueb serbver list from cofiguration", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + getComponentsUtils().auditGetUebCluster(AuditingActionEnum.GET_UEB_CLUSTER, instanceId, null, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + response = buildErrorResponse(responseFormat); + return response; + } + + } + + /** + * Returns list of valid artifact types for validation done in the distribution client.
+ * The list is the representation of the values of the enum ArtifactTypeEnum. + * + * @param request + * @param instanceId + * @param requestId + * @param authorization + * @param accept + * @return + */ + @GET + @Path("/artifactTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getValidArtifactTypes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.X_ECOMP_INSTANCE_ID_HEADER) String instanceId, @HeaderParam(value = Constants.X_ECOMP_REQUEST_ID_HEADER) String requestId, + @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization, @HeaderParam(value = Constants.ACCEPT_HEADER) String accept) { + init(request); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + + Wrapper responseWrapper = new Wrapper<>(); + + validateHeaders(responseWrapper, request, AuditingActionEnum.GET_VALID_ARTIFACT_TYPES); + if (responseWrapper.isEmpty()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), ArtifactTypeEnum.values()); + } else { + response = responseWrapper.getInnerElement(); + } + return response; + } + + @POST + @Path("/registerForDistribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response registerForDistribution(@Context final HttpServletRequest request, String requestJson) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + init(request); + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper registrationRequestWrapper = new Wrapper<>(); + + validateHeaders(responseWrapper, request, AuditingActionEnum.ADD_KEY_TO_TOPIC_ACL); + + if (responseWrapper.isEmpty()) { + validateJson(responseWrapper, registrationRequestWrapper, requestJson); + } + if (responseWrapper.isEmpty()) { + validateEnv(responseWrapper, registrationRequestWrapper.getInnerElement().getDistrEnvName()); + } + + if (responseWrapper.isEmpty()) { + distributionLogic.handleRegistration(responseWrapper, registrationRequestWrapper.getInnerElement(), buildAuditHandler(request, registrationRequestWrapper.getInnerElement())); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, DistributionBusinessLogic.REGISTER_IN_DISTRIBUTION_ENGINE, "registration validation failed"); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.REGISTER_IN_DISTRIBUTION_ENGINE, "registration validation failed"); + } + + return responseWrapper.getInnerElement(); + } + + @POST + @Path("/unRegisterForDistribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response unRegisterForDistribution(@Context final HttpServletRequest request, String requestJson) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + init(request); + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper unRegistrationRequestWrapper = new Wrapper<>(); + + validateHeaders(responseWrapper, request, AuditingActionEnum.REMOVE_KEY_FROM_TOPIC_ACL); + + if (responseWrapper.isEmpty()) { + validateJson(responseWrapper, unRegistrationRequestWrapper, requestJson); + } + if (responseWrapper.isEmpty()) { + validateEnv(responseWrapper, unRegistrationRequestWrapper.getInnerElement().getDistrEnvName()); + } + if (responseWrapper.isEmpty()) { + distributionLogic.handleUnRegistration(responseWrapper, unRegistrationRequestWrapper.getInnerElement(), buildAuditHandler(request, unRegistrationRequestWrapper.getInnerElement())); + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeDistributionEngineSystemError, DistributionBusinessLogic.UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration validation failed"); + BeEcompErrorManager.getInstance().logBeDistributionEngineSystemError(DistributionBusinessLogic.UN_REGISTER_IN_DISTRIBUTION_ENGINE, "unregistration validation failed"); + } + + return responseWrapper.getInnerElement(); + } + + private void validateEnv(Wrapper responseWrapper, String distrEnvName) { + + // DE194021 + StorageOperationStatus environmentStatus = distributionLogic.getDistributionEngine().isEnvironmentAvailable(); + // DE194021 + // StorageOperationStatus environmentStatus = + // distributionLogic.getDistributionEngine().isEnvironmentAvailable(distrEnvName); + if (environmentStatus != StorageOperationStatus.OK) { + if (environmentStatus == StorageOperationStatus.DISTR_ENVIRONMENT_NOT_FOUND) { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.DISTRIBUTION_ENV_DOES_NOT_EXIST)); + responseWrapper.setInnerElement(missingHeaderResponse); + } else { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(missingHeaderResponse); + } + } + + } + + private void init(HttpServletRequest request) { + if (distributionLogic == null) { + distributionLogic = getDistributionBL(request.getSession().getServletContext()); + } + } + + private void validateHeaders(Wrapper responseWrapper, HttpServletRequest request, AuditingActionEnum auditingAction) { + if (request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER) == null) { + Response missingHeaderResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID)); + responseWrapper.setInnerElement(missingHeaderResponse); + // Audit + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditMissingInstanceId(auditingAction, responseFormat.getStatus().toString(), responseFormat.getFormattedMessage()); + + } + + } + + private void validateJson(Wrapper responseWrapper, Wrapper registrationRequestWrapper, String requestJson) { + if (requestJson == null || requestJson.isEmpty()) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); + responseWrapper.setInnerElement(missingBodyResponse); + } else { + Either eitherRegistration = HttpUtil.convertJsonStringToObject(requestJson, RegistrationRequest.class); + if (eitherRegistration.isLeft()) { + RegistrationRequest registrationRequest = eitherRegistration.left().value(); + if (registrationRequest.getApiPublicKey() == null) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_PUBLIC_KEY)); + responseWrapper.setInnerElement(missingBodyResponse); + + } else if (registrationRequest.getDistrEnvName() == null) { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_ENV_NAME)); + responseWrapper.setInnerElement(missingBodyResponse); + } else { + registrationRequestWrapper.setInnerElement(registrationRequest); + } + } else { + Response missingBodyResponse = buildErrorResponse(distributionLogic.getResponseFormatManager().getResponseFormat(ActionStatus.MISSING_BODY)); + responseWrapper.setInnerElement(missingBodyResponse); + } + } + + } + + private DistributionBusinessLogic getDistributionBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + return webApplicationContext.getBean(DistributionBusinessLogic.class); + } + + private AuditHandler buildAuditHandler(HttpServletRequest request, RegistrationRequest registrationRequest) { + return new AuditHandler(getComponentsUtils(), request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER), registrationRequest); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/EcompIntImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/EcompIntImpl.java new file mode 100644 index 0000000000..5670239ef7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/EcompIntImpl.java @@ -0,0 +1,376 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.ecomp; + +import java.util.LinkedList; +import java.util.List; + +import javax.servlet.http.HttpServletRequest; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.ecomp.converters.EcompRoleConverter; +import org.openecomp.sdc.be.ecomp.converters.EcompUserConverter; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationContext; +import org.springframework.web.context.ContextLoader; + +import org.openecomp.portalsdk.core.onboarding.crossapi.IPortalRestAPIService; +import org.openecomp.portalsdk.core.onboarding.crossapi.PortalAPIException; +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +import fj.data.Either; + +/* + * PortalAPIException(String message, Throwable cause); + */ +public class EcompIntImpl implements IPortalRestAPIService { + private static Logger log = LoggerFactory.getLogger(EcompIntImpl.class.getName()); + + public EcompIntImpl() { + log.debug("EcompIntImpl Class Instantiated"); + } + + @Override + public void pushUser(EcompUser user) throws PortalAPIException { + log.debug("Start handle request of ECOMP pushUser"); + try { + if (user == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("PushUser", "Recieved null for argument user", ErrorSeverity.INFO); + log.debug("Recieved null for argument user"); + throw new PortalAPIException("Recieved null for argument user"); + } + + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + final String modifierAttId = "jh0003"; + User modifier = new User(); + modifier.setUserId(modifierAttId); + log.debug("modifier id is {}", modifierAttId); + + Either newASDCUser = EcompUserConverter.convertEcompUserToUser(user); + if (newASDCUser.isRight()) { + BeEcompErrorManager.getInstance().logInvalidInputError("PushUser", "Failed to convert user", ErrorSeverity.INFO); + log.debug("Failed to create user {}",user.toString()); + throw new PortalAPIException("Failed to create user " + newASDCUser.right().value()); + } else if (newASDCUser.left().value() == null) { + BeEcompErrorManager.getInstance().logInvalidInputError("PushUser", "NULL pointer returned from user converter", ErrorSeverity.INFO); + log.debug("Failed to create user {}", user.toString()); + throw new PortalAPIException("Failed to create user " + newASDCUser.right().value()); + } + + User convertedAsdcUser = newASDCUser.left().value(); + Either createUserResponse = userBusinessLogic.createUser(modifier, convertedAsdcUser); + + // ALREADY EXIST ResponseFormat + final String ALREADY_EXISTS_RESPONSE_ID = "SVC4006"; + + if (createUserResponse.isRight()) { + if (!createUserResponse.right().value().getMessageId().equals(ALREADY_EXISTS_RESPONSE_ID)) { + log.debug("Failed to create user {}", user.toString()); + BeEcompErrorManager.getInstance().logInvalidInputError("PushUser", "Failed to create user", ErrorSeverity.ERROR); + throw new PortalAPIException("Failed to create user" + createUserResponse.right()); + } + log.debug("User already exist {}", user.toString()); + } + log.debug("User created {}", user.toString()); + } catch (Exception e) { + log.debug("Failed to create user {}", user, e); + BeEcompErrorManager.getInstance().logInvalidInputError("PushUser", "Failed to create user", ErrorSeverity.ERROR); + throw new PortalAPIException("Failed to create user", e); + } + } + + /* + * (non-Javadoc) + * + * + * loginId - equals to userId + * + */ + @Override + public void editUser(String loginId, EcompUser user) throws PortalAPIException { + log.debug("Start handle request of ECOMP editUser"); + + try { + if (user == null) { + log.debug("Recieved null for argument user"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "Recieved null for argument user", ErrorSeverity.INFO); + throw new PortalAPIException("Recieved null for argument user"); + } else if (loginId == null) { + log.debug("Recieved null for argument loginId"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "Recieved null for argument loginId", ErrorSeverity.INFO); + throw new PortalAPIException("Recieved null for argument loginId"); + } + + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + if (user.getLoginId() != null && !user.getLoginId().equals(loginId)) { + log.debug("loginId and user loginId not equal"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "loginId and user loginId not equal", ErrorSeverity.INFO); + throw new PortalAPIException("loginId not equals to the user loginId field"); + } else if (user.getLoginId() == null) { + user.setLoginId(loginId); + } + + Either asdcUser = EcompUserConverter.convertEcompUserToUser(user); + if (asdcUser.isRight()) { + log.debug("Failed to convert user"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "Failed to convert user", ErrorSeverity.INFO); + throw new PortalAPIException(asdcUser.right().value()); + } else if (asdcUser.left().value() == null) { + log.debug("NULL pointer returned from user converter"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "NULL pointer returned from user converter", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to edit user"); + } + + Either updateUserCredentialsResponse = userBusinessLogic.updateUserCredentials(asdcUser.left().value()); + + if (updateUserCredentialsResponse.isRight()) { + log.debug("Failed to updateUserCredentials"); + BeEcompErrorManager.getInstance().logInvalidInputError("EditUser", "Failed to updateUserCredentials", ErrorSeverity.ERROR); + throw new PortalAPIException("Failed to edit user" + updateUserCredentialsResponse.right().value()); + } + } catch (Exception e) { + log.debug("Failed to updateUserCredentials"); + throw new PortalAPIException("Failed to edit user", e); + } + + } + + @Override + public EcompUser getUser(String loginId) throws PortalAPIException { + log.debug("Start handle request of ECOMP getUser"); + + try { + + if (loginId == null) { + log.debug("Recieved null for argument loginId"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUser", "Recieved null for argument loginId", ErrorSeverity.INFO); + throw new PortalAPIException("Recieved null for argument loginId"); + } + + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + Either getUserResponse = userBusinessLogic.getUser(loginId, false); + + if (getUserResponse.isRight()) { + log.debug("Failed to get User"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUser", "Failed to get User", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get User" + getUserResponse.right()); + } else { + if (getUserResponse.left().value() != null) { + Either ecompUser = EcompUserConverter.convertUserToEcompUser(getUserResponse.left().value()); + if (ecompUser.isLeft() && ecompUser.left().value() != null) { + return ecompUser.left().value(); + } else { + log.debug("Failed to get User"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUser", "Failed to get User", ErrorSeverity.INFO); + throw new PortalAPIException(ecompUser.right().value()); + } + } else { + log.debug("Failed to get User"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUser", "Failed to get User", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get User" + getUserResponse.right()); + } + } + } catch (Exception e) { + log.debug("Failed to get User"); + throw new PortalAPIException("Failed to get User", e); + } + } + + @Override + public List getUsers() throws PortalAPIException { + log.debug("Start handle request of ECOMP getUsers"); + + try { + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + final String modifierAttId = "jh0003"; + + Either, ResponseFormat> getUsersResponse = userBusinessLogic.getUsersList(modifierAttId, null, null); + + if (getUsersResponse.isRight()) { + log.debug("Failed to get Users"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUsers", "Failed to get users", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get Users" + getUsersResponse.right()); + } else { + if (getUsersResponse.left().value() != null) { + List ecompUserList = new LinkedList<>(); + for (User user : getUsersResponse.left().value()) { + Either ecompUser = EcompUserConverter.convertUserToEcompUser(user); + if (ecompUser.isRight()) { + log.debug("Failed to convert User {}", user); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUsers", "Failed to convert User" + user.toString(), ErrorSeverity.WARNING); + continue; + } else if (ecompUser.left().value() == null) { + log.debug("Failed to convert User {}", user); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUsers", "Failed to convert User" + user.toString(), ErrorSeverity.WARNING); + continue; + } + ecompUserList.add(ecompUser.left().value()); + } + return ecompUserList; + } else { + log.debug("Failed to get users"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUsers", "Failed to get users", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get Users" + getUsersResponse.right()); + } + } + } catch (Exception e) { + log.debug("Failed to get users"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUsers", "Failed to get users", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get Users", e); + } + } + + @Override + public List getAvailableRoles() throws PortalAPIException { + log.debug("Start handle request of ECOMP getAvailableRoles"); + try { + List ecompRolesList = new LinkedList<>(); + for (Role role : Role.values()) { + EcompRole ecompRole = new EcompRole(); + ecompRole.setId(new Long(role.ordinal())); + ecompRole.setName(role.name()); + ecompRolesList.add(ecompRole); + } + + if (ecompRolesList.isEmpty()) { + throw new PortalAPIException(); + } + + return ecompRolesList; + } catch (Exception e) { + log.debug("Failed to fetch roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetAvailableRoles", "Failed to fetch roles", ErrorSeverity.INFO); + throw new PortalAPIException("Roles fetching failed", e); + } + + } + + /** + * The user role updated through this method only + */ + @Override + public void pushUserRole(String loginId, List roles) throws PortalAPIException { + log.debug("Start handle request of ECOMP pushUserRole"); + + final String modifierAttId = "jh0003"; + User modifier = new User(); + modifier.setUserId(modifierAttId); + log.debug("modifier id is {}", modifierAttId); + + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + String updatedRole = null; + + if (roles == null) { + throw new PortalAPIException("Error: Recieved null for roles"); + } else if (roles.iterator().hasNext()) { + EcompRole ecompRole = roles.iterator().next(); + updatedRole = EcompRoleConverter.convertEcompRoleToRole(ecompRole); + log.debug("pushing role: {} to user: {}", updatedRole, loginId); + } else { + log.debug("Error: No roles in List"); + BeEcompErrorManager.getInstance().logInvalidInputError("PushUserRole", "Failed to fetch roles", ErrorSeverity.INFO); + throw new PortalAPIException("Error: No roles in List"); + } + + Either updateUserRoleResponse = userBusinessLogic.updateUserRole(modifier, loginId, updatedRole); + if (updateUserRoleResponse.isRight()) { + log.debug("Error: Failed to update role"); + BeEcompErrorManager.getInstance().logInvalidInputError("PushUserRole", "Failed to update role", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to update role" + updateUserRoleResponse.right().value().toString()); + } + } + + @Override + public List getUserRoles(String loginId) throws PortalAPIException { + try { + log.debug("Start handle request of ECOMP getUserRoles"); + + UserBusinessLogic userBusinessLogic = getUserBusinessLogic(); + + Either getUserResponse = userBusinessLogic.getUser(loginId, false); + + if (getUserResponse.isRight()) { + log.debug("Error: Failed to get Roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUserRoles", "Failed to get Roles", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get Roles" + getUserResponse.right()); + } else { + if (getUserResponse.left().value() != null) { + Either ecompUser = EcompUserConverter.convertUserToEcompUser(getUserResponse.left().value()); + if (ecompUser.isRight()) { + log.debug("Error: Failed to convert Roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUserRoles", "Failed to convert Roles", ErrorSeverity.ERROR); + throw new PortalAPIException(ecompUser.right().value()); + } else if (ecompUser.left().value() == null) { + log.debug("Error: Failed to convert Roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUserRoles", "Failed to convert Roles", ErrorSeverity.ERROR); + throw new PortalAPIException(); + } + + return new LinkedList<>(ecompUser.left().value().getRoles()); + } else { + log.debug("Error: Failed to get Roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUserRoles", "Failed to get Roles", ErrorSeverity.ERROR); + throw new PortalAPIException("Failed to get Roles" + getUserResponse.right()); + } + } + } catch (Exception e) { + log.debug("Error: Failed to get Roles"); + BeEcompErrorManager.getInstance().logInvalidInputError("GetUserRoles", "Failed to get Roles", ErrorSeverity.INFO); + throw new PortalAPIException("Failed to get Roles", e); + } + } + + @Override + public boolean isAppAuthenticated(HttpServletRequest request) throws PortalAPIException { + // TODO Validation should be changed completely + final String USERNAME = request.getHeader("username"); + final String PASSWORD = request.getHeader("password"); + + if (USERNAME != null && PASSWORD != null) { + if (!USERNAME.equals("") && !PASSWORD.equals("")) { + log.debug("User authenticated - Username: {} Password: {}", USERNAME, PASSWORD); + return true; + } + } + + log.debug("User authentication failed"); + return false; + } + + private UserBusinessLogic getUserBusinessLogic() { + ApplicationContext ctx = ContextLoader.getCurrentWebApplicationContext(); + UserBusinessLogic userBusinessLogic = (UserBusinessLogic) ctx.getBean("userBusinessLogic"); + return userBusinessLogic; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompRoleConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompRoleConverter.java new file mode 100644 index 0000000000..ca970ce45f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompRoleConverter.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.ecomp.converters; + +import org.openecomp.sdc.be.user.Role; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.openecomp.portalsdk.core.restful.domain.EcompRole; + +public final class EcompRoleConverter { + + private static Logger log = LoggerFactory.getLogger(EcompRoleConverter.class.getName()); + + private EcompRoleConverter() { + } + + // TODO Add Either or Exception in case of convertation failure + public static String convertEcompRoleToRole(EcompRole ecompRole) { + + log.debug("converting role"); + if (ecompRole == null) { + log.debug("recieved null for roles"); + return null; + } + + for (Role role : Role.values()) { + if (role.ordinal() == ecompRole.getId()) { + return role.name(); + } + } + log.debug("no roles converted"); + return null; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompUserConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompUserConverter.java new file mode 100644 index 0000000000..e83b53c2a4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/ecomp/converters/EcompUserConverter.java @@ -0,0 +1,118 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.ecomp.converters; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.user.Role; + +import org.openecomp.portalsdk.core.restful.domain.EcompRole; +import org.openecomp.portalsdk.core.restful.domain.EcompUser; + +import fj.data.Either; + +public final class EcompUserConverter { + + private EcompUserConverter() { + } + + // private static final EcompUserConverter instance = new + // EcompUserConverter(); + + /* + * public static EcompUserConverter getInsatnce() { return instance; } + */ + + public static Either convertUserToEcompUser(User asdcUser) { + EcompUser convertedUser = new EcompUser(); + + if (asdcUser == null) { + return Either.right("User is null"); + } + + convertedUser.setFirstName(asdcUser.getFirstName()); + convertedUser.setLastName(asdcUser.getLastName()); + convertedUser.setLoginId(asdcUser.getUserId()); + convertedUser.setOrgUserId(asdcUser.getUserId()); + convertedUser.setEmail(asdcUser.getEmail()); + + if (asdcUser.getStatus().equals(UserStatusEnum.ACTIVE)) { + convertedUser.setActive(true); + } else if (asdcUser.getStatus().equals(UserStatusEnum.INACTIVE)) { + convertedUser.setActive(false); + } + + EcompRole convertedRole = new EcompRole(); + for (Role role : Role.values()) { + if (role.name().equals(asdcUser.getRole()) || role.toString().equals(asdcUser.getRole())) { + convertedRole.setName(role.name()); + convertedRole.setId(new Long(role.ordinal())); + break; + } + } + + Set convertedRoleSet = new HashSet<>(); + convertedRoleSet.add(convertedRole); + convertedUser.setRoles(convertedRoleSet); + + return Either.left(convertedUser); + } + + public static Either convertEcompUserToUser(EcompUser ecompUser) { + User convertedUser = new User(); + + if (ecompUser == null) { + return Either.right("EcompUser is null"); + } + + convertedUser.setFirstName(ecompUser.getFirstName()); + convertedUser.setLastName(ecompUser.getLastName()); + + if (!ecompUser.getLoginId().isEmpty()) { + convertedUser.setUserId(ecompUser.getLoginId()); + } else { + convertedUser.setUserId(ecompUser.getOrgUserId()); + } + + convertedUser.setEmail(ecompUser.getEmail()); + + if (ecompUser.getRoles() != null) { + Iterator iter = ecompUser.getRoles().iterator(); + + if (iter.hasNext()) { + String updatedRole = EcompRoleConverter.convertEcompRoleToRole(iter.next()); + convertedUser.setRole(updatedRole); + } + } + + if (ecompUser.isActive()) { + convertedUser.setStatus(UserStatusEnum.ACTIVE); + } else { + convertedUser.setStatus(UserStatusEnum.INACTIVE); + } + + return Either.left(convertedUser); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java new file mode 100644 index 0000000000..ecdce79b29 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/ArtifactExternalServlet.java @@ -0,0 +1,646 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * This Servlet serves external users operations on artifacts. + * + * @author mshitrit + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Singleton +public class ArtifactExternalServlet extends BeGenericServlet { + + @Context + private HttpServletRequest request; + + private static Logger log = LoggerFactory.getLogger(ArtifactExternalServlet.class.getName()); + + /** + * Uploads an artifact to resource or service + * + * @param assetType + * @param uuid + * @return + */ + @POST + @Path("/{assetType}/{uuid}/artifacts") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "uploads of artifact to a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact uploaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response uploadArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @ApiParam(value = "json describe the artifact", required = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("uploadArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.uploadArtifactToComponentByUUID(data, request, componentType, uuid, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to upload artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to upload artifact to a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * Uploads an artifact to resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @return + */ + @POST + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "uploads an artifact to a resource instance", httpMethod = "POST", notes = "uploads an artifact to a resource instance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact uploaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response uploadArtifactToInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, + @ApiParam(value = "json describe the artifact", required = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("uploadArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("uploadArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("uploadArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.uploadArtifactToRiByUUID(data, request, componentType, uuid, resourceInstanceName, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to upload artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalUploadArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to upload artifact to a resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * updates an artifact on a resource or service + * + * @param assetType + * @param uuid + * @param artifactUUID + * @return + */ + @POST + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "updates an artifact on a resource or service", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Updated"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response updateArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID, + @ApiParam(value = "json describe the artifact", required = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("updateArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + // Mandatory + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.updateArtifactOnComponentByUUID(data, request, componentType, uuid, artifactUUID, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to update artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to update artifact on a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * updates an artifact on a resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @param artifactUUID + * @return + */ + @POST + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "updates an artifact on a resource instance", httpMethod = "POST", notes = "uploads of artifact to a resource or service", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Updated"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response updateArtifactOnResourceInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, + @PathParam("artifactUUID") final String artifactUUID, @ApiParam(value = "json describe the artifact", required = true) String data) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("updateArtifactOnResourceInstance: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("updateArtifactOnResourceInstance: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("updateArtifactOnResourceInstance: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.updateArtifactOnRiByUUID(data, request, componentType, uuid, resourceInstanceName, artifactUUID, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to update artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalUpdateArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to update artifact on resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * deletes an artifact of a resource or service + * + * @param assetType + * @param uuid + * @param artifactUUID + * @return + */ + @DELETE + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "deletes an artifact of a resource or service", httpMethod = "DELETE", notes = "deletes an artifact of a resource or service", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response deleteArtifact(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("deleteArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("deleteArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("deleteArtifact: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.deleteArtifactOnComponentByUUID(request, componentType, uuid, artifactUUID, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to delete artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to delete an artifact of a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * deletes an artifact of a resource instance + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @return + */ + @DELETE + @Path("{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "deletes an artifact of a resource insatnce", httpMethod = "DELETE", notes = "deletes an artifact of a resource insatnce", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact Deleted"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response deleteArtifactOnResourceInstance(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, + @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String userId = request.getHeader(Constants.USER_ID_HEADER); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("deleteArtifactOnResourceInsatnce: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParams = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("deleteArtifactOnResourceInsatnce: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty() && (userId == null || userId.isEmpty())) { + log.debug("deleteArtifactOnResourceInsatnce: Missing USER_ID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.COMPONENT_MISSING_CONTACT); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either uploadArtifactEither = artifactsLogic.deleteArtifactOnRiByUUID(request, componentType, uuid, resourceInstanceName, artifactUUID, additionalParams); + if (uploadArtifactEither.isRight()) { + log.debug("failed to delete artifact"); + responseFormat = uploadArtifactEither.right().value(); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + Object representation = RepresentationUtils.toRepresentation(uploadArtifactEither.left().value()); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByString((String) representation)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalDeleteArtifact(responseFormat, componentType.getValue(), request, additionalParams); + responseWrapper.setInnerElement(buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation, headers)); + } + } catch (Exception e) { + final String message = "failed to delete an artifact of a resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * downloads an artifact of a component (either a service or a resource) by artifactUUID + * + * @param assetType + * @param uuid + * @param artifactUUID + * @return + */ + @GET + @Path("/{assetType}/{uuid}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download component artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadComponentArtifact( + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, + @PathParam("uuid") final String uuid, @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("downloadComponentArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParam = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("downloadComponentArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either downloadComponentArtifactEither = artifactsLogic.downloadComponentArtifactByUUIDs(componentType, uuid, artifactUUID, additionalParam); + if (downloadComponentArtifactEither.isRight()) { + responseFormat = downloadComponentArtifactEither.right().value(); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + byte[] value = downloadComponentArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByByteArray(value)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); + } + } catch (Exception e) { + final String message = "failed to download an artifact of a resource or service"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } + + /** + * downloads an artifact of a resource instance of a component (either a service or a resource) by artifactUUID + * + * @param assetType + * @param uuid + * @param resourceInstanceName + * @param artifactUUID + * @return + */ + @GET + @Path("/{assetType}/{uuid}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID}") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download resource instance artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadResourceInstanceArtifact( + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, + @PathParam("uuid") final String uuid, @PathParam("resourceInstanceName") final String resourceInstanceName, @PathParam("artifactUUID") final String artifactUUID) { + + Wrapper responseWrapper = new Wrapper<>(); + ResponseFormat responseFormat; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + if (componentType == null) { + log.debug("downloadResourceInstanceArtifact: assetType parameter {} is not valid", assetType); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + EnumMap additionalParam = new EnumMap<>(AuditingFieldsKeysEnum.class); + + if (responseWrapper.isEmpty() && (instanceIdHeader == null || instanceIdHeader.isEmpty())) { + log.debug("downloadResourceInstanceArtifact: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } + if (responseWrapper.isEmpty()) { + try { + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either downloadResourceArtifactEither = artifactsLogic.downloadResourceInstanceArtifactByUUIDs(componentType, uuid, resourceInstanceName, artifactUUID, additionalParam); + if (downloadResourceArtifactEither.isRight()) { + responseFormat = downloadResourceArtifactEither.right().value(); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildErrorResponse(responseFormat)); + } else { + byte[] value = downloadResourceArtifactEither.left().value(); + InputStream is = new ByteArrayInputStream(value); + Map headers = new HashMap<>(); + headers.put(Constants.MD5_HEADER, GeneralUtility.calculateMD5ByByteArray(value)); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalDownloadArtifact(responseFormat, componentType.getValue(), request, additionalParam); + responseWrapper.setInnerElement(buildOkResponse(responseFormat, is, headers)); + } + } catch (Exception e) { + final String message = "failed to download an artifact of a resource instance"; + BeEcompErrorManager.getInstance().logBeRestApiGeneralError(message); + log.debug(message, e); + responseWrapper.setInnerElement(buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR))); + } + } + return responseWrapper.getInnerElement(); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetMetadataConverter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetMetadataConverter.java new file mode 100644 index 0000000000..20eac081c9 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetMetadataConverter.java @@ -0,0 +1,381 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet; + +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.distribution.servlet.DistributionCatalogServlet; +import org.openecomp.sdc.be.externalapi.servlet.representation.ArtifactMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceAssetDetailedMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceAssetMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.ResourceInstanceMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceAssetDetailedMetadata; +import org.openecomp.sdc.be.externalapi.servlet.representation.ServiceAssetMetadata; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.ResourceOperation; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import fj.data.Either; + +@org.springframework.stereotype.Component("asset-metadata-utils") +public class AssetMetadataConverter { + private static Logger log = LoggerFactory.getLogger(DistributionCatalogServlet.class.getName()); + + @Autowired + private ComponentsUtils componentsUtils; + @Autowired + private ResourceOperation resourceOperation; + + /* + * Relative asset’s URL. Should be used in REST GET API to download the asset’s CSAR. https://{serverBaseURL}/{csarPath} can be obtained from (HttpServletRequest)request.getServerName() + */ + public Either, ResponseFormat> convertToAssetMetadata(List componentList, String serverBaseURL, boolean detailed) { + if (componentList == null || componentList.isEmpty()) { + return Either.left(new LinkedList<>()); + } + + List retResList = new LinkedList<>(); + Component component = componentList.iterator().next(); + ComponentTypeEnum componentType = component.getComponentType(); + + for (Component curr : componentList) { + + Either resMetaData = convertToMetadata(componentType, serverBaseURL, detailed, curr); + + if (resMetaData.isRight()) { + return Either.right(resMetaData.right().value()); + } + + retResList.add(resMetaData.left().value()); + } + + return Either.left(retResList); + + } + + private Either convertToMetadata(ComponentTypeEnum componentType, String serverBaseURL, boolean detailed, Component curr) { + + switch (componentType) { + + case RESOURCE: + + return generateResourceMeatdata(serverBaseURL, detailed, curr); + + case SERVICE: + + return generateServiceMetadata(serverBaseURL, detailed, curr); + + // For future US's that include product + /* + * case PRODUCT: if (component instanceof Product) { List retResList = new LinkedList<>(); for (Component curr : componentList) { retResList.add(convertToProductAssetMetadata((Product) curr, serverBaseURL)); } return + * Either.left(retResList); + */ + default: + + ResponseFormat responseFormat = componentsUtils.getResponseFormatAdditionalProperty(ActionStatus.COMPONENT_INVALID_CATEGORY); + return Either.right(responseFormat); + } + } + + private Either generateResourceMeatdata(String serverBaseURL, boolean detailed, Component curr) { + AssetMetadata metaData; + metaData = createMetadaObject(detailed, curr.getComponentType()); + metaData = convertToResourceMetadata((ResourceAssetMetadata) metaData, (Resource) curr, serverBaseURL, detailed); + + if (detailed) { + Either converted = convertToResourceDetailedMetadata((ResourceAssetDetailedMetadata) metaData, (Resource) curr, serverBaseURL); + if (converted.isRight()) { + ActionStatus storageResponse = componentsUtils.convertFromStorageResponse(converted.right().value(), ComponentTypeEnum.RESOURCE); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(storageResponse); + return Either.right(responseFormat); + } + } + + return Either.left(metaData); + } + + private AssetMetadata createMetadaObject(boolean detailed, ComponentTypeEnum type) { + AssetMetadata metaData = null; + switch (type) { + case SERVICE: + if (!detailed) { + metaData = new ServiceAssetMetadata(); + } else { + metaData = new ServiceAssetDetailedMetadata(); + } + break; + case RESOURCE: + if (!detailed) { + metaData = new ResourceAssetMetadata(); + } else { + metaData = new ResourceAssetDetailedMetadata(); + } + break; + default: + break; + } + return metaData; + } + + private Either generateServiceMetadata(String serverBaseURL, boolean detailed, Component curr) { + AssetMetadata metaData = createMetadaObject(detailed, curr.getComponentType()); + + metaData = convertToServiceAssetMetadata((ServiceAssetMetadata) metaData, (Service) curr, serverBaseURL, detailed); + + if (detailed) { + Either converted = convertToServiceDetailedMetadata((ServiceAssetDetailedMetadata) metaData, (Service) curr, serverBaseURL); + if (converted.isRight()) { + ActionStatus storageResponse = componentsUtils.convertFromStorageResponse(converted.right().value(), ComponentTypeEnum.RESOURCE); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(storageResponse); + return Either.right(responseFormat); + } + } + + return Either.left(metaData); + } + + private U convertToAsset(U asset, T component, String serverBaseURL, boolean detailed) { + asset.setUuid(component.getUUID()); + asset.setInvariantUUID(component.getInvariantUUID()); + asset.setName(component.getName()); + asset.setVersion(component.getVersion()); + if (!detailed) { + asset.setToscaModelURL(serverBaseURL + "/" + component.getUUID() + "/toscaModel"); + } else { + String toscaModelUrl = (new String(serverBaseURL)).replace("metadata", "toscaModel"); + asset.setToscaModelURL(toscaModelUrl); + } + + return asset; + } + + private T convertToResourceMetadata(T assetToPopulate, Resource resource, String serverBaseURL, boolean detailed) { + assetToPopulate = convertToAsset(assetToPopulate, resource, serverBaseURL, detailed); + CategoryDefinition categoryDefinition = resource.getCategories().iterator().next(); + assetToPopulate.setCategory(categoryDefinition.getName()); + + SubCategoryDefinition subCategoryDefinition = categoryDefinition.getSubcategories().iterator().next(); + + assetToPopulate.setSubCategory(subCategoryDefinition.getName()); + assetToPopulate.setResourceType(resource.getResourceType().name()); + assetToPopulate.setLifecycleState(resource.getLifecycleState().name()); + assetToPopulate.setLastUpdaterUserId(resource.getLastUpdaterUserId()); + + return (T) assetToPopulate; + } + + private T convertToServiceAssetMetadata(T assetToPopulate, Service service, String serverBaseURL, boolean detailed) { + assetToPopulate = convertToAsset(assetToPopulate, service, serverBaseURL, detailed); + + CategoryDefinition categoryDefinition = service.getCategories().iterator().next(); + + assetToPopulate.setCategory(categoryDefinition.getName()); + assetToPopulate.setLifecycleState(service.getLifecycleState().name()); + assetToPopulate.setLastUpdaterUserId(service.getLastUpdaterUserId()); + assetToPopulate.setDistributionStatus(service.getDistributionStatus().name()); + + return (T) assetToPopulate; + } + + private Either convertToResourceDetailedMetadata(T assetToPopulate, Resource resource, String serverBaseURL) { + + List componentInstances = resource.getComponentInstances(); + + if (componentInstances != null) { + Either, StorageOperationStatus> resourceInstanceMetadata = convertToResourceInstanceMetadata(componentInstances, ComponentTypeEnum.RESOURCE_PARAM_NAME, resource.getUUID()); + if (resourceInstanceMetadata.isRight()) { + return Either.right(resourceInstanceMetadata.right().value()); + } + + assetToPopulate.setResources(resourceInstanceMetadata.left().value()); + } + + Map deploymentArtifacts = resource.getDeploymentArtifacts(); + assetToPopulate = populateResourceWithArtifacts(assetToPopulate, resource, serverBaseURL, deploymentArtifacts); + + assetToPopulate.setLastUpdaterFullName(resource.getLastUpdaterFullName()); + assetToPopulate.setToscaResourceName(resource.getToscaResourceName()); + + return Either.left(assetToPopulate); + } + + private Either convertToServiceDetailedMetadata(T assetToPopulate, Service service, String serverBaseURL) { + + List componentInstances = service.getComponentInstances(); + + if (componentInstances != null) { + Either, StorageOperationStatus> resourceInstanceMetadata = convertToResourceInstanceMetadata(componentInstances, ComponentTypeEnum.SERVICE_PARAM_NAME, service.getUUID()); + if (resourceInstanceMetadata.isRight()) { + return Either.right(resourceInstanceMetadata.right().value()); + } + + assetToPopulate.setResources(resourceInstanceMetadata.left().value()); + } + + Map deploymentArtifacts = service.getDeploymentArtifacts(); + assetToPopulate = populateServiceWithArtifacts(assetToPopulate, service, deploymentArtifacts); + + assetToPopulate.setLastUpdaterFullName(service.getLastUpdaterFullName()); + + return Either.left(assetToPopulate); + } + + private T populateResourceWithArtifacts(T asset, Resource resource, String serverBaseURL, Map artifacts) { + + List artifactMetaList = populateAssetWithArtifacts(resource, artifacts); + + asset.setArtifacts(artifactMetaList); + + return asset; + } + + private T populateServiceWithArtifacts(T asset, Service service, Map artifacts) { + + List artifactMetaList = populateAssetWithArtifacts(service, artifacts); + + asset.setArtifacts(artifactMetaList); + + return asset; + } + + private List populateAssetWithArtifacts(Component component, Map artifacts) { + List artifactMetaList = null; + if (artifacts != null) { + artifactMetaList = new LinkedList<>(); + Collection artefactDefList = artifacts.values(); + + for (ArtifactDefinition artifactDefinition : artefactDefList) { + if (artifactDefinition.getEsId() != null && !artifactDefinition.getEsId().isEmpty()) { + ArtifactMetadata convertedArtifactMetadata = convertToArtifactMetadata(artifactDefinition, ComponentTypeEnum.findParamByType(component.getComponentType()), component.getUUID(), null); + artifactMetaList.add(convertedArtifactMetadata); + } + } + } + return artifactMetaList.isEmpty() ? null : artifactMetaList; + } + + private ArtifactMetadata convertToArtifactMetadata(ArtifactDefinition artifact, String componentType, String componentUUID, String resourceInstanceName) { + // /asdc/v1/catalog/{services/resources}/{componentUUID}/artifacts/{artifactUUID} + final String COMPONENT_ARTIFACT_URL = "/asdc/v1/catalog/%s/%s/artifacts/%s"; + + // /asdc/v1/catalog/{services/resources}/{componentUUID}/resourceInstances/{resourceInstanceName}/artifacts/{artifactUUID} + final String RESOURCE_INSTANCE_ARTIFACT_URL = "/asdc/v1/catalog/%s/%s/resourceInstances/%s/artifacts/%s"; + + ArtifactMetadata metadata = new ArtifactMetadata(); + + metadata.setArtifactName(artifact.getArtifactName()); + metadata.setArtifactType(artifact.getArtifactType()); + + if (resourceInstanceName == null || resourceInstanceName.isEmpty()) { + metadata.setArtifactURL(String.format(COMPONENT_ARTIFACT_URL, componentType, componentUUID, artifact.getArtifactUUID())); + } else { + metadata.setArtifactURL(String.format(RESOURCE_INSTANCE_ARTIFACT_URL, componentType, componentUUID, resourceInstanceName, artifact.getArtifactUUID())); + } + + metadata.setArtifactDescription(artifact.getDescription()); + metadata.setArtifactTimeout(artifact.getTimeout() > 0 ? artifact.getTimeout() : null); + metadata.setArtifactChecksum(artifact.getArtifactChecksum()); + metadata.setArtifactUUID(artifact.getArtifactUUID()); + metadata.setArtifactVersion(artifact.getArtifactVersion()); + metadata.setGeneratedFromUUID(artifact.getGeneratedFromId()); + + return metadata; + } + + private Either, StorageOperationStatus> convertToResourceInstanceMetadata(List componentInstances, String componentType, String componentUUID) { + List retList = new LinkedList<>(); + Map uuidDuplicatesMap = new HashMap<>(); + + for (ComponentInstance componentInstance : componentInstances) { + ResourceInstanceMetadata metadata = new ResourceInstanceMetadata(); + String componentUid = componentInstance.getComponentUid(); + String invariantUUID; + + if (!uuidDuplicatesMap.containsKey(componentUid)) { + Either getInvarUuidresponse = resourceOperation.getInvariantUUID(NodeTypeEnum.Resource, componentInstance.getComponentUid(), false); + if (getInvarUuidresponse.isRight()) { + log.debug("convertToResourceInstanceMetadata: Failed getting Invariant UUID"); + return Either.right(getInvarUuidresponse.right().value()); + } else { + invariantUUID = getInvarUuidresponse.left().value(); + uuidDuplicatesMap.put(componentUid, invariantUUID); + } + } else { + invariantUUID = uuidDuplicatesMap.get(componentUid); + } + + metadata.setResourceInvariantUUID(invariantUUID); + metadata.setResourceInstanceName(componentInstance.getName()); + metadata.setResourceName(componentInstance.getComponentName()); + metadata.setResourceVersion(componentInstance.getComponentVersion()); + metadata.setResoucreType(componentInstance.getOriginType().getValue()); + metadata.setResourceUUID(componentInstance.getComponentUid()); + + Collection values = componentInstance.getDeploymentArtifacts().values(); + LinkedList artifactMetaList = new LinkedList<>(); + + for (ArtifactDefinition artifactDefinition : values) { + ArtifactMetadata converted = convertToArtifactMetadata(artifactDefinition, componentType, componentUUID, componentInstance.getNormalizedName()); + artifactMetaList.add(converted); + } + + metadata.setArtifacts(artifactMetaList); + + retList.add(metadata); + } + + return Either.left(retList); + } + + // For future US to support Product + /* + * private ProductAssetMetadata convertToProductAssetMetadata(Product product, String serverBaseURL) { ProductAssetMetadata retProdAsset = new ProductAssetMetadata(); + * + * retProdAsset = convertToAsset(retProdAsset, product, serverBaseURL); retProdAsset.setLifecycleState(product.getLifecycleState().name()); retProdAsset.setLastUpdaterUserId(product.getLastUpdaterUserId()); + * retProdAsset.setActive(product.getIsActive()); retProdAsset.setContacts(product.getContacts()); + * + * List categories = product.getCategories(); List categoryMetadataList = new LinkedList<>(); + * + * if (categories == null || categories.isEmpty()) { return retProdAsset; } else { for (CategoryDefinition categoryDefinition : categories) { String categoryName = categoryDefinition.getName(); List subcategories = + * categoryDefinition.getSubcategories(); for (SubCategoryDefinition subCategoryDefinition : subcategories) { String subCategoryName = subCategoryDefinition.getName(); List groups = product.getGroups(); for (GroupDefinition + * groupDefinition : groups) { String groupName = groupDefinition.getName(); categoryMetadataList.add(new ProductCategoryGroupMetadata(categoryName, subCategoryName, groupName)); } } } retProdAsset.setProductGroupings(categoryMetadataList); + * return retProdAsset; } } + */ +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java new file mode 100644 index 0000000000..1b8d6fdb75 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/AssetsDataServlet.java @@ -0,0 +1,300 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet; + +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Predicate; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.http.NameValuePair; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.FilterKeyEnum; +import org.openecomp.sdc.be.externalapi.servlet.representation.AssetMetadata; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.BeGenericServlet; +import org.openecomp.sdc.be.servlets.RepresentationUtils; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Singleton +public class AssetsDataServlet extends BeGenericServlet { + + @Context + private HttpServletRequest request; + + private AssetMetadataConverter assetMetadataUtils; + private static Logger log = LoggerFactory.getLogger(AssetsDataServlet.class.getName()); + + @GET + @Path("/{assetType}") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Fetch list of assets", httpMethod = "GET", notes = "Returns list of assets", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Assets Fetched"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 401, message = "Authorization required"), + @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Asset not found") }) + public Response getAssetList(@PathParam("assetType") final String assetType, @QueryParam("category") String category, @QueryParam("subCategory") String subCategory, @QueryParam("distributionStatus") String distributionStatus) { + + Response response = null; + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String query = request.getQueryString(); + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + String serverBaseURL = request.getRequestURL().toString(); + + AuditingActionEnum auditingActionEnum = query == null ? AuditingActionEnum.GET_ASSET_LIST : AuditingActionEnum.GET_FILTERED_ASSET_LIST; + + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, query == null ? requestURI : requestURI + "?" + query); + + // Mandatory + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ServletContext context = request.getSession().getServletContext(); + ElementBusinessLogic elementLogic = getElementBL(context); + + getAssetUtils(context); + Map filters = new HashMap(); + + if (category != null) { + filters.put(FilterKeyEnum.CATEGORY, category); + } + if (subCategory != null) { + filters.put(FilterKeyEnum.SUB_CATEGORY, subCategory); + } + if (distributionStatus != null) { + filters.put(FilterKeyEnum.DISTRIBUTION_STATUS, distributionStatus); + } + + Either, ResponseFormat> assetTypeData = elementLogic.getFilteredCatalogComponents(assetType, filters, query); + + if (assetTypeData.isRight()) { + log.debug("getAssetList: Asset Fetching Failed"); + responseFormat = assetTypeData.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } else { + log.debug("getAssetList: Asset Fetching Success"); + Either, ResponseFormat> resMetadata = assetMetadataUtils.convertToAssetMetadata(assetTypeData.left().value(), serverBaseURL, false); + if (resMetadata.isRight()) { + log.debug("getAssetList: Asset conversion Failed"); + responseFormat = resMetadata.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + Object result = RepresentationUtils.toRepresentation(resMetadata.left().value()); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + + response = buildOkResponse(responseFormat, result); + return response; + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); + log.debug("getAssetList: Fetch list of assets failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{assetType}/{uuid}/metadata") + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Fetch metadata of asset by uuid", httpMethod = "GET", notes = "Returns metadata of asset", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Assets Fetched"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response getAssetListByUuid(@PathParam("assetType") final String assetType, @PathParam("uuid") final String uuid, @Context final HttpServletRequest request) { + + Response response = null; + ResponseFormat responseFormat = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_ASSET_METADATA; + String requestURI = request.getRequestURI(); + String url = request.getMethod() + " " + requestURI; + log.debug("Start handle request of {}", url); + String serverBaseURL = request.getRequestURL().toString(); + + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, componentType.getValue()); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, uuid); + + // Mandatory + if (instanceIdHeader == null || instanceIdHeader.isEmpty()) { + log.debug("getAssetList: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ServletContext context = request.getSession().getServletContext(); + ElementBusinessLogic elementLogic = getElementBL(context); + getAssetUtils(context); + + Either, ResponseFormat> assetTypeData = elementLogic.getCatalogComponentsByUuidAndAssetType(assetType, uuid); + + if (assetTypeData.isRight()) { + log.debug("getAssetList: Asset Fetching Failed"); + responseFormat = assetTypeData.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + + return buildErrorResponse(responseFormat); + } else { + log.debug("getAssetList: Asset Fetching Success"); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, assetTypeData.left().value().iterator().next().getName()); + Either, ResponseFormat> resMetadata = assetMetadataUtils.convertToAssetMetadata(assetTypeData.left().value(), serverBaseURL, true); + if (resMetadata.isRight()) { + log.debug("getAssetList: Asset conversion Failed"); + responseFormat = resMetadata.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + Object result = RepresentationUtils.toRepresentation(resMetadata.left().value().iterator().next()); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + + response = buildOkResponse(responseFormat, result); + return response; + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Fetch filtered list of assets"); + log.debug("getAssetList: Fetch list of assets failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private void getAssetUtils(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + assetMetadataUtils = webApplicationContext.getBean(AssetMetadataConverter.class); + } + + @GET + @Path("/{assetType}/{uuid}/toscaModel") + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Fetch asset csar", httpMethod = "GET", notes = "Returns asset csar", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Asset Model Fetched"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Asset not found") }) + public Response getToscaModel(@PathParam("uuid") final String uuid, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("assetType") final String assetType, + @HeaderParam(value = Constants.AUTHORIZATION_HEADER) String authorization) { + + String url = request.getRequestURI(); + log.debug("Start handle request of {} {}", request.getMethod(), url); + Response response = null; + ResponseFormat responseFormat = null; + ServletContext context = request.getSession().getServletContext(); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(assetType); + AuditingActionEnum auditingActionEnum = AuditingActionEnum.GET_TOSCA_MODEL; + String userId = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, userId); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, url); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, componentType.getValue()); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, uuid); + + if (userId == null || userId.isEmpty()) { + log.debug("getToscaModel: Missing X-ECOMP-InstanceID header"); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_X_ECOMP_INSTANCE_ID); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return buildErrorResponse(responseFormat); + } + + try { + ComponentBusinessLogic componentBL = getComponentBL(componentType, context); + + Either, ResponseFormat> csarArtifact = componentBL.getToscaModelByComponentUuid(componentType, uuid, additionalParam); + if (csarArtifact.isRight()) { + responseFormat = csarArtifact.right().value(); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + response = buildErrorResponse(responseFormat); + } else { + byte[] value = csarArtifact.left().value().getRight(); + InputStream is = new ByteArrayInputStream(value); + String contenetMD5 = GeneralUtility.calculateMD5ByByteArray(value); + Map headers = new HashMap<>(); + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(csarArtifact.left().value().getLeft())); + headers.put(Constants.MD5_HEADER, contenetMD5); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get asset tosca model"); + log.debug("falied to get asset tosca model", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + response = buildErrorResponse(responseFormat); + getComponentsUtils().auditExternalGetAsset(responseFormat, auditingActionEnum, additionalParam); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ArtifactMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ArtifactMetadata.java new file mode 100644 index 0000000000..f4194cf2f5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ArtifactMetadata.java @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public class ArtifactMetadata { + private String artifactName; + private String artifactType; + private String artifactURL; + private String artifactDescription; + private Integer artifactTimeout; + private String artifactChecksum; + private String artifactUUID; + private String artifactVersion; + private String generatedFromUUID; + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public String getArtifactType() { + return artifactType; + } + + public void setArtifactType(String artifactType) { + this.artifactType = artifactType; + } + + public String getArtifactURL() { + return artifactURL; + } + + public void setArtifactURL(String artifactURL) { + this.artifactURL = artifactURL; + } + + public String getArtifactDescription() { + return artifactDescription; + } + + public void setArtifactDescription(String artifactDescription) { + this.artifactDescription = artifactDescription; + } + + public Integer getArtifactTimeout() { + return artifactTimeout; + } + + public void setArtifactTimeout(Integer artifactTimeout) { + this.artifactTimeout = artifactTimeout; + } + + public String getArtifactChecksum() { + return artifactChecksum; + } + + public void setArtifactChecksum(String artifactChecksum) { + this.artifactChecksum = artifactChecksum; + } + + public String getArtifactUUID() { + return artifactUUID; + } + + public void setArtifactUUID(String artifactUUID) { + this.artifactUUID = artifactUUID; + } + + public String getArtifactVersion() { + return artifactVersion; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public String getGeneratedFromUUID() { + return generatedFromUUID; + } + + public void setGeneratedFromUUID(String generatedFromUUID) { + this.generatedFromUUID = generatedFromUUID; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/AssetMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/AssetMetadata.java new file mode 100644 index 0000000000..cb14f76aff --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/AssetMetadata.java @@ -0,0 +1,129 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public abstract class AssetMetadata implements IAssetMetadata { + private String uuid; + private String invariantUUID; + private String name; + private String version; + private String toscaModelURL; + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# getUuid() + */ + @Override + public String getUuid() { + return uuid; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# setUuid(java.lang.String) + */ + @Override + public void setUuid(String uuid) { + this.uuid = uuid; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# getInvariantUUID() + */ + @Override + public String getInvariantUUID() { + return invariantUUID; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# setInvariantUUID(java.lang.String) + */ + @Override + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# getName() + */ + @Override + public String getName() { + return name; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# setName(java.lang.String) + */ + @Override + public void setName(String name) { + this.name = name; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# getVersion() + */ + @Override + public String getVersion() { + return version; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# setVersion(java.lang.String) + */ + @Override + public void setVersion(String version) { + this.version = version; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# toscaModelURL() + */ + @Override + public String getToscaModelURL() { + return toscaModelURL; + } + + /* + * (non-Javadoc) + * + * @see org.openecomp.sdc.be.distribution.servlet.representation.IAssetMetadata# toscaModelURL(java.lang.String) + */ + @Override + public void setToscaModelURL(String toscaModelURL) { + this.toscaModelURL = toscaModelURL; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/IAssetMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/IAssetMetadata.java new file mode 100644 index 0000000000..f95a8e9684 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/IAssetMetadata.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public interface IAssetMetadata { + + String getUuid(); + + void setUuid(String uuid); + + String getInvariantUUID(); + + void setInvariantUUID(String invariantUUID); + + String getName(); + + void setName(String name); + + String getVersion(); + + void setVersion(String version); + + String getToscaModelURL(); + + void setToscaModelURL(String toscaModelURL); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductAssetMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductAssetMetadata.java new file mode 100644 index 0000000000..d2d9c2c902 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductAssetMetadata.java @@ -0,0 +1,72 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +import java.util.List; + +public class ProductAssetMetadata extends AssetMetadata { + private String lifecycleState; + private String lastUpdaterUserId; + private boolean isActive; + private List contacts; + private List productGroupings; + + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public boolean isActive() { + return isActive; + } + + public void setActive(boolean isActive) { + this.isActive = isActive; + } + + public List getContacts() { + return contacts; + } + + public void setContacts(List contacts) { + this.contacts = contacts; + } + + public List getProductGroupings() { + return productGroupings; + } + + public void setProductGroupings(List productGroupings) { + this.productGroupings = productGroupings; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductCategoryGroupMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductCategoryGroupMetadata.java new file mode 100644 index 0000000000..047f9d6a2c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ProductCategoryGroupMetadata.java @@ -0,0 +1,57 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public class ProductCategoryGroupMetadata { + private String category; + private String subCategory; + private String group; + + public ProductCategoryGroupMetadata(String category, String subCategory, String group) { + this.category = category; + this.subCategory = subCategory; + this.group = group; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSubCategory() { + return subCategory; + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + + public String getGroup() { + return group; + } + + public void setGroup(String group) { + this.group = group; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetDetailedMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetDetailedMetadata.java new file mode 100644 index 0000000000..ea282ec2e8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetDetailedMetadata.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +import java.util.List; + +public class ResourceAssetDetailedMetadata extends ResourceAssetMetadata { + + private String lastUpdaterFullName; + private String toscaResourceName; + private List resources; + private List artifacts; + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public String getToscaResourceName() { + return toscaResourceName; + } + + public void setToscaResourceName(String toscaResourceName) { + this.toscaResourceName = toscaResourceName; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifactMetaList) { + this.artifacts = artifactMetaList; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetMetadata.java new file mode 100644 index 0000000000..2b75facc6c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceAssetMetadata.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public class ResourceAssetMetadata extends AssetMetadata { + private String category; + private String subCategory; + private String resourceType; + private String lifecycleState; + private String lastUpdaterUserId; + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSubCategory() { + return subCategory; + } + + public void setSubCategory(String subCategory) { + this.subCategory = subCategory; + } + + public String getResourceType() { + return resourceType; + } + + public void setResourceType(String resourceType) { + this.resourceType = resourceType; + } + + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceInstanceMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceInstanceMetadata.java new file mode 100644 index 0000000000..a53422f311 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ResourceInstanceMetadata.java @@ -0,0 +1,89 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +import java.util.List; + +public class ResourceInstanceMetadata { + private String resourceInstanceName; + private String resourceName; + private String resourceInvariantUUID; + private String resourceVersion; + private String resoucreType; + private String resourceUUID; + private List artifacts; + + public String getResourceInstanceName() { + return resourceInstanceName; + } + + public void setResourceInstanceName(String resourceInstanceName) { + this.resourceInstanceName = resourceInstanceName; + } + + public String getResourceName() { + return resourceName; + } + + public void setResourceName(String resourceName) { + this.resourceName = resourceName; + } + + public String getResourceInvariantUUID() { + return resourceInvariantUUID; + } + + public void setResourceInvariantUUID(String resourceInvariantUUID) { + this.resourceInvariantUUID = resourceInvariantUUID; + } + + public String getResourceVersion() { + return resourceVersion; + } + + public void setResourceVersion(String resourceVersion) { + this.resourceVersion = resourceVersion; + } + + public String getResoucreType() { + return resoucreType; + } + + public void setResoucreType(String resoucreType) { + this.resoucreType = resoucreType; + } + + public String getResourceUUID() { + return resourceUUID; + } + + public void setResourceUUID(String resourceUUID) { + this.resourceUUID = resourceUUID; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetDetailedMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetDetailedMetadata.java new file mode 100644 index 0000000000..edd88b495d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetDetailedMetadata.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +import java.util.List; + +public class ServiceAssetDetailedMetadata extends ServiceAssetMetadata { + private String lastUpdaterFullName; + private List resources; + private List artifacts; + + public String getLastUpdaterFullName() { + return lastUpdaterFullName; + } + + public void setLastUpdaterFullName(String lastUpdaterFullName) { + this.lastUpdaterFullName = lastUpdaterFullName; + } + + public List getResources() { + return resources; + } + + public void setResources(List resources) { + this.resources = resources; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetMetadata.java new file mode 100644 index 0000000000..094f973553 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/externalapi/servlet/representation/ServiceAssetMetadata.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.externalapi.servlet.representation; + +public class ServiceAssetMetadata extends AssetMetadata { + private String category; + private String lifecycleState; + private String lastUpdaterUserId; + private String distributionStatus; + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getLifecycleState() { + return lifecycleState; + } + + public void setLifecycleState(String lifecycleState) { + this.lifecycleState = lifecycleState; + } + + public String getLastUpdaterUserId() { + return lastUpdaterUserId; + } + + public void setLastUpdaterUserId(String lastUpdaterUserId) { + this.lastUpdaterUserId = lastUpdaterUserId; + } + + public String getDistributionStatus() { + return distributionStatus; + } + + public void setDistributionStatus(String distributionStatus) { + this.distributionStatus = distributionStatus; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BasicAuthenticationFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BasicAuthenticationFilter.java new file mode 100644 index 0000000000..f7e1d758ac --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BasicAuthenticationFilter.java @@ -0,0 +1,225 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.filters; + +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.util.StringTokenizer; + +import javax.annotation.Priority; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + +import org.apache.commons.codec.binary.Base64; +import org.openecomp.sdc.be.components.impl.ConsumerBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ConsumerDefinition; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.openecomp.sdc.security.Passwords; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +@Priority(10) +public class BasicAuthenticationFilter implements ContainerRequestFilter { + + @Context + private HttpServletRequest sr; + + protected Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + private String realm = "ASDC"; + + private static Logger log = LoggerFactory.getLogger(BasicAuthenticationFilter.class.getName()); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String authHeader = requestContext.getHeaderString(Constants.AUTHORIZATION_HEADER); + if (authHeader != null) { + StringTokenizer st = new StringTokenizer(authHeader); + if (st.hasMoreTokens()) { + String basic = st.nextToken(); + + if (basic.equalsIgnoreCase("Basic")) { + try { + String credentials = new String(Base64.decodeBase64(st.nextToken()), "UTF-8"); + log.debug("Credentials: {}", credentials); + checkUserCredentiles(requestContext, credentials); + } catch (UnsupportedEncodingException e) { + log.error("Authentication Filter Failed Couldn't retrieve authentication", e); + authInvalidHeaderError(requestContext); + } + } else { + log.error("Authentication Filter Failed Couldn't retrieve authentication, no basic autantication."); + authInvalidHeaderError(requestContext); + } + } else { + log.error("Authentication Filter Failed Couldn't retrieve authentication, no basic autantication."); + authInvalidHeaderError(requestContext); + } + + } else { + log.error("Authentication Filter Failed no autharization header"); + authRequiredError(requestContext); + } + } + + private void checkUserCredentiles(ContainerRequestContext requestContext, String credentials) { + int p = credentials.indexOf(":"); + if (p != -1) { + String _username = credentials.substring(0, p).trim(); + String _password = credentials.substring(p + 1).trim(); + + ConsumerBusinessLogic consumerBL = getConsumerBusinessLogic(); + if (consumerBL == null) { + log.error("Authentication Filter Failed to get consumerBL."); + requestContext.abortWith(Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build()); + } else { + Either result = consumerBL.getConsumer(_username); + validatePassword(requestContext, _username, _password, result); + } + } else { + log.error("Authentication Filter Failed Couldn't retrieve authentication, no basic autantication."); + authInvalidHeaderError(requestContext); + + } + } + + private void validatePassword(ContainerRequestContext requestContext, String _username, String _password, Either result) { + if (result.isRight()) { + Integer status = result.right().value().getStatus(); + if (status == Status.NOT_FOUND.getStatusCode()) { + log.error("Authentication Filter Failed Couldn't find user"); + authUserNotFoundError(requestContext, _username); + } else { + log.error("Authentication Filter Failed to get consumerBL."); + requestContext.abortWith(Response.serverError().status(Status.INTERNAL_SERVER_ERROR).build()); + } + } else { + ConsumerDefinition consumerCredentials = result.left().value(); + if (!Passwords.isExpectedPassword(_password, consumerCredentials.getConsumerSalt(), consumerCredentials.getConsumerPassword())) { + log.error("Authentication Filter Failed invalide password"); + authInvalidePasswordError(requestContext, _username); + } else { + authSuccesessful(requestContext, _username); + } + } + } + + private void authSuccesessful(ContainerRequestContext requestContext, String _username) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Authentication Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + componentUtils.auditAuthEvent(AuditingActionEnum.AUTH_REQUEST, requestContext.getUriInfo().getPath(), _username, AuthStatus.AUTH_SUCCESS.toString(), realm); + } + + private void authInvalidePasswordError(ContainerRequestContext requestContext, String _username) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Authentication Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + componentUtils.auditAuthEvent(AuditingActionEnum.AUTH_REQUEST, requestContext.getUriInfo().getPath(), _username, AuthStatus.AUTH_FAILED_INVALID_PASSWORD.toString(), realm); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED); + requestContext.abortWith(buildErrorResponse(responseFormat, false)); + } + + private void authUserNotFoundError(ContainerRequestContext requestContext, String _username) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Authentication Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + getComponentsUtils().auditAuthEvent(AuditingActionEnum.AUTH_REQUEST, requestContext.getUriInfo().getPath(), _username, AuthStatus.AUTH_FAILED_USER_NOT_FOUND.toString(), realm); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED); + requestContext.abortWith(buildErrorResponse(responseFormat, false)); + } + + private void authInvalidHeaderError(ContainerRequestContext requestContext) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Authentication Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + getComponentsUtils().auditAuthEvent(AuditingActionEnum.AUTH_REQUEST, requestContext.getUriInfo().getPath(), "", AuthStatus.AUTH_FAILED_INVALID_AUTHENTICATION_HEADER.toString(), realm); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_FAILED_INVALIDE_HEADER); + requestContext.abortWith(buildErrorResponse(responseFormat, false)); + } + + private void authRequiredError(ContainerRequestContext requestContext) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Authentication Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + getComponentsUtils().auditAuthEvent(AuditingActionEnum.AUTH_REQUEST, requestContext.getUriInfo().getPath(), "", AuthStatus.AUTH_REQUIRED.toString(), realm); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.AUTH_REQUIRED); + requestContext.abortWith(buildErrorResponse(responseFormat, true)); + } + + private ComponentsUtils getComponentsUtils() { + ServletContext context = sr.getSession().getServletContext(); + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ComponentsUtils componentsUtils = webApplicationContext.getBean(ComponentsUtils.class); + return componentsUtils; + } + + private ConsumerBusinessLogic getConsumerBusinessLogic() { + ServletContext context = sr.getSession().getServletContext(); + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ConsumerBusinessLogic consumerBusinessLogic = webApplicationContext.getBean(ConsumerBusinessLogic.class); + return consumerBusinessLogic; + } + + public enum AuthStatus { + AUTH_REQUIRED, AUTH_FAILED_USER_NOT_FOUND, AUTH_FAILED_INVALID_PASSWORD, AUTH_FAILED_INVALID_AUTHENTICATION_HEADER, AUTH_SUCCESS + } + + protected Response buildErrorResponse(ResponseFormat requestErrorWrapper, boolean addWwwAuthenticationHeader) { + ResponseBuilder responseBuilder = Response.status(requestErrorWrapper.getStatus()); + if (addWwwAuthenticationHeader) { + responseBuilder = responseBuilder.header("WWW-Authenticate", "Basic realm=\"" + realm + "\""); + } + Response response = responseBuilder.entity(gson.toJson(requestErrorWrapper.getRequestError())).build(); + return response; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeServletFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeServletFilter.java new file mode 100644 index 0000000000..f6c11d062e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/BeServletFilter.java @@ -0,0 +1,202 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.filters; + +import java.io.IOException; +import java.util.UUID; + +import javax.annotation.Priority; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.container.ContainerResponseContext; +import javax.ws.rs.container.ContainerResponseFilter; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.ext.Provider; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.slf4j.MDC; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.GsonBuilder; + +@Provider +@Priority(1) +public class BeServletFilter implements ContainerRequestFilter, ContainerResponseFilter { + + @Context + private HttpServletRequest sr; + + private static Logger log = LoggerFactory.getLogger(BeServletFilter.class.getName()); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + try { + + MDC.clear(); + + // In case of 405 response code, this function is not entered, then + // we'll process + // the MDC fields and UUID during the response + ThreadLocalsHolder.setMdcProcessed(true); + + // Timing HTTP request + ThreadLocalsHolder.setRequestStartTime(System.currentTimeMillis()); + + String uuid = processMdcFields(requestContext); + + ThreadLocalsHolder.setUuid(uuid); + + inHttpRequest(); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Error during request filter"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter"); + log.debug("Error during request filter: {} ", e); + } + } + + @Override + public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { + try { + // Formatting the response in case of 405 + if (responseContext.getStatus() == Response.Status.METHOD_NOT_ALLOWED.getStatusCode()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_ALLOWED); + responseContext.setEntity(new GsonBuilder().setPrettyPrinting().create().toJson(responseFormat.getRequestError())); + } + + if (ThreadLocalsHolder.isMdcProcessed()) { + // filter() was executed during request - this is the regular + // flow + responseContext.getHeaders().add(Constants.X_ECOMP_REQUEST_ID_HEADER, ThreadLocalsHolder.getUuid()); + Long startTime = ThreadLocalsHolder.getRequestStartTime(); + if (startTime != null) { + long endTime = System.currentTimeMillis(); + MDC.put("timer", Long.toString(endTime - startTime)); + } + } else { + // this is the 405 response code case + // we have no MDC fields since filter() wasn't executed during + // request + String uuid = processMdcFields(requestContext); + responseContext.getHeaders().add(Constants.X_ECOMP_REQUEST_ID_HEADER, uuid); + } + + outHttpResponse(responseContext); + + // Cleaning up + MDC.clear(); + ThreadLocalsHolder.cleanup(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Error during request filter"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Error during request filter"); + log.debug("Error during response filter: {} ", e); + } + } + + private String processMdcFields(ContainerRequestContext requestContext) { + // userId for logging + String userId = requestContext.getHeaderString(Constants.USER_ID_HEADER); + MDC.put("userId", userId); + + String serviceInstanceID = requestContext.getHeaderString(Constants.X_ECOMP_SERVICE_ID_HEADER); + MDC.put("serviceInstanceID", serviceInstanceID); + + MDC.put("remoteAddr", sr.getRemoteAddr()); + MDC.put("localAddr", sr.getLocalAddr()); + + // UUID + String uuid = requestContext.getHeaderString(Constants.X_ECOMP_REQUEST_ID_HEADER); + if (uuid == null) { + // Generate the UUID + uuid = UUID.randomUUID().toString(); + + // Add to MDC for logging + MDC.put("uuid", uuid); + + // This log message should already be with the UUID + uuidGeneration(uuid); + + } else { + // According to Ella, in case this header exists, we don't have to + // perform any validations + // since it's not our responsibilty, so we log the UUID just as it + // was received. + MDC.put("uuid", uuid); + } + return uuid; + } + + private ComponentsUtils getComponentsUtils() { + ServletContext context = this.sr.getSession().getServletContext(); + + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + return webApplicationContext.getBean(ComponentsUtils.class); + } + + // Extracted for purpose of clear method name, for logback %M parameter + private void inHttpRequest() { + if (isInfoLog()) { + log.info("{} {} {}", sr.getMethod(), sr.getRequestURI(), sr.getProtocol()); + } else { + log.debug("{} {} {}", sr.getMethod(), sr.getRequestURI(), sr.getProtocol()); + } + } + + // Extracted for purpose of clear method name, for logback %M parameter + private void outHttpResponse(ContainerResponseContext responseContext) { + if (isInfoLog()) { + log.info("{} {} {} SC=\"{}\"", sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), responseContext.getStatus()); + } else { + log.debug("{} {} {} SC=\"{}\"", sr.getMethod(), sr.getRequestURI(), sr.getProtocol(), responseContext.getStatus()); + } + } + + private boolean isInfoLog() { + boolean logRequest = true; + Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); + String requestURI = sr.getRequestURI(); + if (requestURI != null && configuration.getUnLoggedUrls() != null) { + logRequest = !configuration.getUnLoggedUrls().contains(requestURI); + } + + return logRequest; + } + + // Extracted for purpose of clear method name, for logback %M parameter + private void uuidGeneration(String uuid) { + log.info("No requestID provided -> Generated UUID {}", uuid); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/filters/ComponentsAvailabilityFilter.java b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/ComponentsAvailabilityFilter.java new file mode 100644 index 0000000000..c572e2e552 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/filters/ComponentsAvailabilityFilter.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.filters; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Priority; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.container.ContainerRequestContext; +import javax.ws.rs.container.ContainerRequestFilter; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; +import javax.ws.rs.core.Response.Status; + +import org.openecomp.sdc.be.components.impl.HealthCheckBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +@Priority(11) +public class ComponentsAvailabilityFilter implements ContainerRequestFilter { + + @Context + protected HttpServletRequest sr; + protected Gson gson = new GsonBuilder().setPrettyPrinting().create(); + private static Logger log = LoggerFactory.getLogger(ComponentsAvailabilityFilter.class.getName()); + + @Override + public void filter(ContainerRequestContext requestContext) throws IOException { + + String requestUrl = requestContext.getUriInfo().getPath(); + if (!requestUrl.equals("healthCheck")) { + List beHealthCheckInfos = getBeHealthCheckInfos(this.sr.getSession().getServletContext()); + ActionStatus status = getAggregateBeStatus(beHealthCheckInfos); + + if (!status.equals(ActionStatus.OK)) { + log.error("Components Availability Filter Failed - ES/Cassandra is DOWN"); + availabilityError(requestContext); + } + } + + } + + protected ActionStatus getAggregateBeStatus(List beHealthCheckInfos) { + ActionStatus status = ActionStatus.OK; + for (HealthCheckInfo healthCheckInfo : beHealthCheckInfos) { + if (healthCheckInfo.getHealthCheckStatus().equals(HealthCheckStatus.DOWN)) { + status = ActionStatus.GENERAL_ERROR; + break; + } + } + return status; + } + + protected List getBeHealthCheckInfos(ServletContext servletContext) { + + List healthCheckInfos = new ArrayList(); + HealthCheckBusinessLogic healthCheckBusinessLogic = getHealthCheckBL(servletContext); + healthCheckBusinessLogic.getTitanHealthCheck(healthCheckInfos); // Titan + return healthCheckInfos; + } + + protected ComponentsUtils getComponentsUtils() { + ServletContext context = sr.getSession().getServletContext(); + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ComponentsUtils componentsUtils = webApplicationContext.getBean(ComponentsUtils.class); + return componentsUtils; + } + + protected void availabilityError(ContainerRequestContext requestContext) { + ComponentsUtils componentUtils = getComponentsUtils(); + if (componentUtils == null) { + log.error("Components Availability Filter Failed to get component utils."); + requestContext.abortWith(Response.status(Status.INTERNAL_SERVER_ERROR).build()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + ResponseBuilder responseBuilder = Response.status(responseFormat.getStatus()); + Response response = responseBuilder.entity(gson.toJson(responseFormat.getRequestError())).build(); + requestContext.abortWith(response); + } + + private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class); + return healthCheckBl; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java new file mode 100644 index 0000000000..9e2abebdc5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ComponentsUtils.java @@ -0,0 +1,1461 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.impl; + +import java.lang.reflect.Type; +import java.util.ArrayList; +import java.util.Collection; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; +import java.util.regex.Pattern; + +import javax.annotation.PostConstruct; +import javax.servlet.http.HttpServletRequest; + +import org.codehaus.jackson.Version; +import org.codehaus.jackson.map.DeserializationConfig; +import org.codehaus.jackson.map.JsonDeserializer; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.module.SimpleModule; +import org.openecomp.sdc.be.auditing.api.IAuditingManager; +import org.openecomp.sdc.be.components.impl.ResponseFormatManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.graph.datatype.AdditionalInformationEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.CapabilityTypeDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ConsumerDefinition; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintJacksonDeserialiser; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.tosca.ToscaError; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.util.ThreadLocalsHolder; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; + +import fj.data.Either; + +@org.springframework.stereotype.Component("componentUtils") +public class ComponentsUtils { + + @javax.annotation.Resource + private IAuditingManager auditingManager; + + private ResponseFormatManager responseFormatManager; + + private static Logger log = LoggerFactory.getLogger(ComponentsUtils.class.getName()); + + @PostConstruct + public void Init() { + this.responseFormatManager = ResponseFormatManager.getInstance(); + } + + public IAuditingManager getAuditingManager() { + return auditingManager; + } + + public void setAuditingManager(IAuditingManager auditingManager) { + this.auditingManager = auditingManager; + } + + public Either convertJsonToObject(String data, User user, Class clazz, AuditingActionEnum actionEnum) { + if (data == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + ResponseFormat responseFormat = getInvalidContentErrorAndAudit(user, actionEnum); + return Either.right(responseFormat); + } + try { + T obj = parseJsonToObject(data, clazz); + return Either.left(obj); + } catch (Exception e) { + // INVALID JSON + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", data, e); + ResponseFormat responseFormat = getInvalidContentErrorAndAudit(user, actionEnum); + return Either.right(responseFormat); + } + } + + public static T parseJsonToObject(String data, Class clazz) { + Type constraintType = new TypeToken() { + }.getType(); + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + log.trace("convert json to object. json=\n{}", data); + T resource = gson.fromJson(data, clazz); + return resource; + } + + public Either convertJsonToObjectUsingObjectMapper(String data, User user, Class clazz, AuditingActionEnum actionEnum, ComponentTypeEnum typeEnum) { + T component = null; + ObjectMapper mapper = new ObjectMapper().configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + + try { + log.trace("convert json to object. json=\n{}", data); + + final SimpleModule module = new SimpleModule("customerSerializationModule", new Version(1, 0, 0, "static version")); + JsonDeserializer desrializer = new PropertyConstraintJacksonDeserialiser(); + addDeserializer(module, PropertyConstraint.class, desrializer); + // + mapper.registerModule(module); + + component = mapper.readValue(data, clazz); + if (component == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + ResponseFormat responseFormat = getInvalidContentErrorAndAuditComponent(user, actionEnum, typeEnum); + return Either.right(responseFormat); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", data, e); + ResponseFormat responseFormat = getInvalidContentErrorAndAuditComponent(user, actionEnum, typeEnum); + return Either.right(responseFormat); + } + return Either.left(component); + } + + public void addDeserializer(SimpleModule module, Class clazz, final JsonDeserializer deserializer) { + module.addDeserializer(clazz, deserializer); + } + + // Error response + + public ResponseFormat getResponseFormat(ActionStatus actionStatus, String... params) { + return responseFormatManager.getResponseFormat(actionStatus, params); + } + + /** + * Returns the response format of resource error with respective variables according to actionStatus. This is needed for cases where actionStatus is anonymously converted from storage operation, and the caller doesn't know what actionStatus he + * received. It's caller's Responsibility to fill the resource object passed to this function with needed fields. + * + * Note that RESOURCE_IN_USE case passes hardcoded "resource" string to the error parameter. This means that if Resource object will also be used for Service, this code needs to be refactored and we should tell Resource from Service. + * + * @param actionStatus + * @param resource + * @return + */ + public ResponseFormat getResponseFormatByResource(ActionStatus actionStatus, Resource resource) { + if (resource == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case COMPONENT_VERSION_ALREADY_EXIST: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_VERSION_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(), resource.getVersion()); + break; + case RESOURCE_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resource.getName()); + break; + case COMPONENT_NAME_ALREADY_EXIST: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, ComponentTypeEnum.RESOURCE.getValue(), resource.getName()); + break; + case COMPONENT_IN_USE: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_IN_USE, ComponentTypeEnum.RESOURCE.name().toLowerCase(), resource.getUniqueId()); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public ResponseFormat getResponseFormatByResource(ActionStatus actionStatus, String resourceName) { + if (resourceName == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case RESOURCE_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, resourceName); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public ResponseFormat getResponseFormatByCapabilityType(ActionStatus actionStatus, CapabilityTypeDefinition capabilityType) { + if (capabilityType == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case CAPABILITY_TYPE_ALREADY_EXIST: + responseFormat = getResponseFormat(ActionStatus.CAPABILITY_TYPE_ALREADY_EXIST, capabilityType.getType()); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + /** + * Returns the response format of resource error with respective variables according to actionStatus. This is needed for cases where actionStatus is anynomously converted from storage operation, and the caller doesn't know what actionStatus he + * received. It's caller's responisibility to fill the passed resource object with needed fields. + * + * @param actionStatus + * @param user + * @return + */ + public ResponseFormat getResponseFormatByUser(ActionStatus actionStatus, User user) { + if (user == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat requestErrorWrapper; + switch (actionStatus) { + case INVALID_USER_ID: + requestErrorWrapper = getResponseFormat(actionStatus, user.getUserId()); + break; + case INVALID_EMAIL_ADDRESS: + requestErrorWrapper = getResponseFormat(actionStatus, user.getEmail()); + break; + case INVALID_ROLE: + requestErrorWrapper = getResponseFormat(actionStatus, user.getRole()); + break; + case USER_NOT_FOUND: + case USER_ALREADY_EXIST: + case USER_INACTIVE: + case USER_HAS_ACTIVE_ELEMENTS: + requestErrorWrapper = getResponseFormat(actionStatus, user.getUserId()); + break; + default: + requestErrorWrapper = getResponseFormat(actionStatus); + break; + } + return requestErrorWrapper; + } + + public ResponseFormat getResponseFormatByUserId(ActionStatus actionStatus, String userId) { + User user = new User(); + user.setUserId(userId); + return getResponseFormatByUser(actionStatus, user); + } + + public ResponseFormat getResponseFormatByDE(ActionStatus actionStatus, String serviceId, String envName) { + ResponseFormat responseFormat; + + switch (actionStatus) { + case DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE: + responseFormat = getResponseFormat(ActionStatus.DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE, envName); + break; + case DISTRIBUTION_ENVIRONMENT_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.DISTRIBUTION_ENVIRONMENT_NOT_FOUND, envName); + break; + case DISTRIBUTION_ARTIFACT_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.DISTRIBUTION_ARTIFACT_NOT_FOUND, serviceId); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public ResponseFormat getResponseFormatByArtifactId(ActionStatus actionStatus, String artifactId) { + ResponseFormat responseFormat; + + switch (actionStatus) { + case RESOURCE_NOT_FOUND: + case ARTIFACT_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactId); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public ResponseFormat getInvalidContentErrorAndAudit(User user, AuditingActionEnum actionEnum) { + ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_CONTENT); + log.debug("audit before sending response"); + auditResource(responseFormat, user, null, "", "", actionEnum, null); + return responseFormat; + } + + public ResponseFormat getInvalidContentErrorAndAuditComponent(User user, AuditingActionEnum actionEnum, ComponentTypeEnum typeEnum) { + ResponseFormat responseFormat = responseFormatManager.getResponseFormat(ActionStatus.INVALID_CONTENT); + log.debug("audit before sending response"); + auditComponentAdmin(responseFormat, user, null, "", "", actionEnum, typeEnum); + return responseFormat; + } + + public void auditResource(ResponseFormat responseFormat, User modifier, Resource resource, String prevState, String prevVersion, AuditingActionEnum actionEnum, EnumMap additionalParams) { + if (actionEnum != null) { + log.trace("Inside auditing for audit action {}", actionEnum.name()); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + + updateUserFields(modifier, auditingFields); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, ComponentTypeEnum.RESOURCE.getValue()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, prevVersion); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, prevState); + if (resource != null) { + // fields that are filled during creation and might still be + // empty + String resourceCurrVersion = (resource.getVersion() != null) ? resource.getVersion() : ""; + String resourceCurrState = (resource.getLifecycleState() != null) ? resource.getLifecycleState().name() : ""; + String uuid = (resource.getUUID() != null) ? resource.getUUID() : ""; + String invariantUUID = (resource.getInvariantUUID() != null) ? resource.getInvariantUUID() : ""; + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, resourceCurrVersion); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, resourceCurrState); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, uuid); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, invariantUUID); + + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + // In those specific cases we want some specific fields from + // resource object + switch (actionEnum) { + case IMPORT_RESOURCE: + if (resource != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TOSCA_NODE_TYPE, resource.getToscaResourceName()); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TOSCA_NODE_TYPE, ""); + } + break; + default: + break; + } + + // This is to add/overwrite anything set in this function if some + // params were passed from above, + // for example resourceName of resource import + if (additionalParams != null) { + auditingFields.putAll(additionalParams); + } + + getAuditingManager().auditEvent(auditingFields); + } + } + + private void updateUserFields(User modifier, EnumMap auditingFields) { + if (modifier != null) { + String firstName = modifier.getFirstName(); + String lastName = modifier.getLastName(); + if (firstName != null || lastName != null) {// to prevent "null + // null" names + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, firstName + " " + lastName); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } + } + + public void auditDistributionDownload(ResponseFormat responseFormat, AuditingActionEnum actionEnum, EnumMap additionalParams) { + log.trace("Inside auditing for audit action {}", actionEnum.name()); + int status = responseFormat.getStatus(); + String message = ""; + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + // This is to add/overwrite anything set in this function if some params + // were passed from above, + // for example resourceName of resource import + if (additionalParams != null) { + auditingFields.putAll(additionalParams); + } + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditExternalGetAsset(ResponseFormat responseFormat, AuditingActionEnum actionEnum, EnumMap additionalParams) { + log.trace("Inside auditing for audit action {}", actionEnum.name()); + int status = responseFormat.getStatus(); + String message = ""; + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + if (additionalParams != null) { + auditingFields.putAll(additionalParams); + } + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditExternalCrudApiArtifact(ResponseFormat responseFormat, String componentType, String actionEnum, HttpServletRequest request, EnumMap additionalParams) { + log.trace("Inside auditing for audit action {}", actionEnum); + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + int status = responseFormat.getStatus(); + String message = ""; + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, instanceIdHeader); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, requestURI); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, componentType); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + if (additionalParams != null) { + auditingFields.putAll(additionalParams); + } + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditExternalDownloadArtifact(ResponseFormat responseFormat, String componentType, HttpServletRequest request, EnumMap additionalParams) { + auditExternalCrudApiArtifact(responseFormat, componentType, AuditingActionEnum.DOWNLOAD_ARTIFACT.getName(), request, additionalParams); + } + + public void auditExternalUploadArtifact(ResponseFormat responseFormat, String componentType, HttpServletRequest request, EnumMap additionalParams) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, request.getHeader(Constants.USER_ID_HEADER)); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, ""); + auditExternalCrudApiArtifact(responseFormat, componentType, AuditingActionEnum.ARTIFACT_UPLOAD_BY_API.getName(), request, additionalParams); + } + + public void auditExternalUpdateArtifact(ResponseFormat responseFormat, String componentType, HttpServletRequest request, EnumMap additionalParams) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, request.getHeader(Constants.USER_ID_HEADER)); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, ""); + auditExternalCrudApiArtifact(responseFormat, componentType, AuditingActionEnum.ARTIFACT_UPDATE_BY_API.getName(), request, additionalParams); + } + + public void auditExternalDeleteArtifact(ResponseFormat responseFormat, String componentType, HttpServletRequest request, EnumMap additionalParams) { + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, request.getHeader(Constants.USER_ID_HEADER)); + additionalParams.put(AuditingFieldsKeysEnum.AUDIT_PREV_ARTIFACT_UUID, ""); + auditExternalCrudApiArtifact(responseFormat, componentType, AuditingActionEnum.ARTIFACT_DELETE_BY_API.getName(), request, additionalParams); + } + + public void auditCategory(ResponseFormat responseFormat, User modifier, String categoryName, String subCategoryName, String groupingName, AuditingActionEnum actionEnum, String componentType) { + log.trace("Inside auditing for audit action {}", actionEnum.name()); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + updateUserFields(modifier, auditingFields); + // String componentTypeStr = (componentTypeEnum != null ? + // componentTypeEnum.getValue() : null); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, componentType); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_CATEGORY_NAME, categoryName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SUB_CATEGORY_NAME, subCategoryName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_GROUPING_NAME, groupingName); + getAuditingManager().auditEvent(auditingFields); + } + + public ActionStatus convertFromStorageResponse(StorageOperationStatus storageResponse) { + + return convertFromStorageResponse(storageResponse, ComponentTypeEnum.RESOURCE); + } + + public ActionStatus convertFromStorageResponse(StorageOperationStatus storageResponse, ComponentTypeEnum type) { + + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + if (storageResponse == null) { + return responseEnum; + } + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.COMPONENT_NAME_ALREADY_EXIST; + break; + case PARENT_RESOURCE_NOT_FOUND: + responseEnum = ActionStatus.PARENT_RESOURCE_NOT_FOUND; + break; + case MULTIPLE_PARENT_RESOURCE_FOUND: + responseEnum = ActionStatus.MULTIPLE_PARENT_RESOURCE_FOUND; + break; + case NOT_FOUND: + if (ComponentTypeEnum.RESOURCE == type) { + responseEnum = ActionStatus.RESOURCE_NOT_FOUND; + } else if (ComponentTypeEnum.PRODUCT == type) { + responseEnum = ActionStatus.PRODUCT_NOT_FOUND; + } else { + responseEnum = ActionStatus.SERVICE_NOT_FOUND; + } + break; + case FAILED_TO_LOCK_ELEMENT: + responseEnum = ActionStatus.COMPONENT_IN_USE; + break; + case ARTIFACT_NOT_FOUND: + responseEnum = ActionStatus.ARTIFACT_NOT_FOUND; + break; + case DISTR_ENVIRONMENT_NOT_AVAILABLE: + responseEnum = ActionStatus.DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE; + break; + case DISTR_ENVIRONMENT_NOT_FOUND: + responseEnum = ActionStatus.DISTRIBUTION_ENVIRONMENT_NOT_FOUND; + break; + case DISTR_ENVIRONMENT_SENT_IS_INVALID: + responseEnum = ActionStatus.DISTRIBUTION_ENVIRONMENT_INVALID; + break; + case DISTR_ARTIFACT_NOT_FOUND: + responseEnum = ActionStatus.DISTRIBUTION_ARTIFACT_NOT_FOUND; + break; + case INVALID_TYPE: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case INVALID_VALUE: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case CSAR_NOT_FOUND: + responseEnum = ActionStatus.CSAR_NOT_FOUND; + break; + case PROPERTY_NAME_ALREADY_EXISTS: + responseEnum = ActionStatus.PROPERTY_NAME_ALREADY_EXISTS; + break; + case MATCH_NOT_FOUND: + responseEnum = ActionStatus.COMPONENT_SUB_CATEGORY_NOT_FOUND_FOR_CATEGORY; + break; + case CATEGORY_NOT_FOUND: + responseEnum = ActionStatus.COMPONENT_CATEGORY_NOT_FOUND; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ActionStatus convertFromToscaError(ToscaError toscaError) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + if (toscaError == null) { + return responseEnum; + } + switch (toscaError) {// TODO match errors + case NODE_TYPE_CAPABILITY_ERROR: + case NOT_SUPPORTED_TOSCA_TYPE: + case NODE_TYPE_REQUIREMENT_ERROR: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + return responseEnum; + } + + public ActionStatus convertFromStorageResponseForCapabilityType(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.CAPABILITY_TYPE_ALREADY_EXIST; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.CAPABILITY_TYPE_ALREADY_EXIST; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ActionStatus convertFromStorageResponseForLifecycleType(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.LIFECYCLE_TYPE_ALREADY_EXIST; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.LIFECYCLE_TYPE_ALREADY_EXIST; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ActionStatus convertFromStorageResponseForResourceInstance(StorageOperationStatus storageResponse, boolean isRelation) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case INVALID_ID: + responseEnum = ActionStatus.RESOURCE_INSTANCE_BAD_REQUEST; + break; + case INVALID_PROPERTY: + responseEnum = ActionStatus.INVALID_PROPERTY; + break; + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case MATCH_NOT_FOUND: + responseEnum = ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.RESOURCE_INSTANCE_ALREADY_EXIST; + break; + case NOT_FOUND: + if (isRelation) { + responseEnum = ActionStatus.RESOURCE_INSTANCE_RELATION_NOT_FOUND; + } else { + responseEnum = ActionStatus.RESOURCE_INSTANCE_NOT_FOUND; + } + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ResponseFormat getResponseFormatForResourceInstance(ActionStatus actionStatus, String serviceName, String resourceInstanceName) { + ResponseFormat responseFormat; + + switch (actionStatus) { + case RESOURCE_INSTANCE_NOT_FOUND: + responseFormat = getResponseFormat(actionStatus, resourceInstanceName); + break; + default: + responseFormat = getResponseFormat(actionStatus, serviceName); + break; + } + return responseFormat; + } + + public ResponseFormat getResponseFormatForResourceInstanceProperty(ActionStatus actionStatus, String resourceInstanceName) { + ResponseFormat responseFormat; + + switch (actionStatus) { + case RESOURCE_INSTANCE_NOT_FOUND: + responseFormat = getResponseFormat(actionStatus, resourceInstanceName); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public ActionStatus convertFromStorageResponseForResourceInstanceProperty(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case INVALID_ID: + responseEnum = ActionStatus.RESOURCE_INSTANCE_BAD_REQUEST; + break; + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case MATCH_NOT_FOUND: + responseEnum = ActionStatus.RESOURCE_INSTANCE_MATCH_NOT_FOUND; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.RESOURCE_INSTANCE_ALREADY_EXIST; + break; + case NOT_FOUND: + responseEnum = ActionStatus.RESOURCE_INSTANCE_NOT_FOUND; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public void auditComponentAdmin(ResponseFormat responseFormat, User modifier, Component component, String prevState, String prevVersion, AuditingActionEnum actionEnum, ComponentTypeEnum type) { + auditComponent(responseFormat, modifier, component, prevState, prevVersion, actionEnum, type, null); + } + + public void auditComponent(ResponseFormat responseFormat, User modifier, Component component, String prevState, String prevVersion, AuditingActionEnum actionEnum, ComponentTypeEnum type, EnumMap additionalParams) { + if (actionEnum != null) { + log.trace("Inside auditing for audit action {}", actionEnum.name()); + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + + updateUserFields(modifier, auditingFields); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, type.getValue().replace(" ", "")); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_VERSION, prevVersion); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_PREV_STATE, prevState); + if (component != null) { + // fields that are filled during creation and might still be + // empty + String resourceCurrVersion = component.getVersion(); + String resourceCurrState = (component.getLifecycleState() != null) ? component.getLifecycleState().name() : ""; + String resourceUuid = (component.getUUID() != null) ? component.getUUID() : ""; + String invariantUUID = (component.getInvariantUUID() != null) ? component.getInvariantUUID() : ""; + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, resourceCurrVersion); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, resourceCurrState); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, resourceUuid); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, invariantUUID); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, ""); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_INVARIANT_UUID, ""); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + // This is meant to overwrite anything set in this function if some + // params were passed from above, + // for example resourceName of resource import + if (additionalParams != null) { + auditingFields.putAll(additionalParams); + } + + getAuditingManager().auditEvent(auditingFields); + } + } + + public void auditDistributionEngine(AuditingActionEnum actionEnum, String environmentName, String topicName, String role, String apiKey, String status) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, environmentName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, topicName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ROLE, role); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, apiKey); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditDistributionNotification(AuditingActionEnum actionEnum, String serviceUUID, String resourceName, String resourceType, String currVersion, String modifierUid, String modifierName, String environmentName, String currState, + String topicName, String distributionId, String description, String status) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, serviceUUID); + + // auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, + // environmentName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, topicName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, distributionId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, currVersion); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_STATE, currState); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, resourceType); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, description); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifierUid); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifierName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceName); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditAuthEvent(AuditingActionEnum actionEnum, String url, String user, String authStatus, String realm) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_URL, url); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_USER, user); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_STATUS, authStatus); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_AUTH_REALM, realm); + getAuditingManager().auditEvent(auditingFields); + } + + public void auditDistributionStatusNotification(AuditingActionEnum actionEnum, String distributionId, String consumerId, String topicName, String resourceUrl, String statusTime, String status, String errorReason) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_REQUEST_ID, distributionId); + ThreadLocalsHolder.setUuid(distributionId); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, distributionId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, consumerId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, topicName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL, resourceUrl); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME, statusTime); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, errorReason); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditGetUebCluster(AuditingActionEnum actionEnum, String consumerId, String statusTime, String status, String description) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, consumerId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME, statusTime); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_DESC, description); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditMissingInstanceId(AuditingActionEnum actionEnum, String status, String description) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, null); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_TIMESTAMP, null); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, description); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditTopicACLKeys(AuditingActionEnum actionEnum, String envName, String topicName, String role, String apiPublicKey, String status) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, envName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_TOPIC_NAME, topicName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ROLE, role); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, apiPublicKey); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditRegisterOrUnRegisterEvent(AuditingActionEnum actionEnum, String consumerId, String apiPublicKey, String envName, String status, String statusDesc, String notifTopicName, String statusTopicName) { + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID, consumerId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_API_KEY, apiPublicKey); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ENVRIONMENT_NAME, envName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_DESC, statusDesc); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_NOTIFICATION_TOPIC_NAME, notifTopicName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TOPIC_NAME, statusTopicName); + getAuditingManager().auditEvent(auditingFields); + } + + public void auditServiceDistributionDeployed(AuditingActionEnum actionEnum, String serviceName, String serviceVersion, String serviceUUID, String distributionId, String status, String desc, User modifier) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_SERVICE_INSTANCE_ID, serviceUUID); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFirstName() + " " + modifier.getLastName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_TYPE, "Service"); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, serviceName); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_CURR_VERSION, serviceVersion); + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_ID, distributionId); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, desc); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditConsumerCredentialsEvent(AuditingActionEnum actionEnum, ConsumerDefinition consumer, ResponseFormat responseFormat, User modifier) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + if (modifier != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFirstName() + " " + modifier.getLastName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } + StringBuilder ecompUser = new StringBuilder(); + if (consumer != null) { + if (consumer.getConsumerName() != null && !consumer.getConsumerName().trim().isEmpty()) { + ecompUser.append(consumer.getConsumerName()); + } + if (consumer.getConsumerSalt() != null && !consumer.getConsumerSalt().trim().isEmpty()) { + if (ecompUser.length() > 0) { + ecompUser.append(","); + } + ecompUser.append(consumer.getConsumerSalt()); + } + if (consumer.getConsumerPassword() != null && !consumer.getConsumerPassword().trim().isEmpty()) { + if (ecompUser.length() > 0) { + ecompUser.append(","); + } + ecompUser.append(consumer.getConsumerPassword()); + } + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ECOMP_USER, ecompUser.toString()); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + + getAuditingManager().auditEvent(auditingFields); + } + + public void auditGetUsersList(AuditingActionEnum actionEnum, User modifier, String details, ResponseFormat responseFormat) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + if (modifier != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFirstName() + " " + modifier.getLastName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_DETAILS, details); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + getAuditingManager().auditEvent(auditingFields); + } + + public void auditAdminUserAction(AuditingActionEnum actionEnum, User modifier, User userBefore, User userAfter, ResponseFormat responseFormat) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + if (modifier != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFirstName() + " " + modifier.getLastName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, ""); + } + if (userBefore != null) { + String userBeforeUserId = (userBefore.getUserId() != null) ? userBefore.getUserId() : ""; + String userBeforFirstName = (userBefore.getFirstName() != null) ? ", " + userBefore.getFirstName() + " " : ""; + String userBeforLastName = (userBefore.getLastName() != null) ? userBefore.getLastName() : ""; + String userBeforEmail = (userBefore.getEmail() != null) ? ", " + userBefore.getEmail() : ""; + String userBeforRloe = (userBefore.getRole() != null) ? ", " + userBefore.getRole() : ""; + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_BEFORE, userBeforeUserId + userBeforFirstName + userBeforLastName + userBeforEmail + userBeforRloe); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_BEFORE, ""); + } + if (userAfter != null) { + String userAfterUserId = (userAfter.getUserId() != null) ? userAfter.getUserId() : ""; + String userAfterFirstName = (userAfter.getFirstName() != null) ? ", " + userAfter.getFirstName() + " " : ""; + String userAfterLastName = (userAfter.getLastName() != null) ? userAfter.getLastName() : ""; + String userAfterEmail = (userAfter.getEmail() != null) ? ", " + userAfter.getEmail() : ""; + String userAfterRloe = (userAfter.getRole() != null) ? ", " + userAfter.getRole() : ""; + + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_AFTER, userAfterUserId + userAfterFirstName + userAfterLastName + userAfterEmail + userAfterRloe); + } else { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_AFTER, ""); + } + + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + getAuditingManager().auditEvent(auditingFields); + } + + public void auditUserAccess(AuditingActionEnum actionEnum, User user, ResponseFormat responseFormat) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_USER_UID, user.getFirstName() + " " + user.getLastName() + '(' + user.getUserId() + ')'); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + getAuditingManager().auditEvent(auditingFields); + } + + public void auditGetCategoryHierarchy(AuditingActionEnum actionEnum, User modifier, String details, ResponseFormat responseFormat) { + + EnumMap auditingFields = new EnumMap(AuditingFieldsKeysEnum.class); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_ACTION, actionEnum.getName()); + if (modifier != null) { + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_NAME, modifier.getFirstName() + " " + modifier.getLastName()); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_MODIFIER_UID, modifier.getUserId()); + } + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DETAILS, details); + int status = responseFormat.getStatus(); + String message = ""; + + if (responseFormat.getMessageId() != null) { + message = responseFormat.getMessageId() + ": "; + } + message += responseFormat.getFormattedMessage(); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_STATUS, status); + auditingFields.put(AuditingFieldsKeysEnum.AUDIT_DESC, message); + getAuditingManager().auditEvent(auditingFields); + } + + public ResponseFormat getResponseFormatByComponent(ActionStatus actionStatus, Component component, ComponentTypeEnum type) { + if (component == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case COMPONENT_VERSION_ALREADY_EXIST: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_VERSION_ALREADY_EXIST, type.getValue(), component.getVersion()); + break; + case RESOURCE_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.RESOURCE_NOT_FOUND, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + break; + case COMPONENT_NAME_ALREADY_EXIST: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_NAME_ALREADY_EXIST, type.getValue(), component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + break; + case COMPONENT_IN_USE: + responseFormat = getResponseFormat(ActionStatus.COMPONENT_IN_USE, type.name().toLowerCase(), component.getUniqueId()); + break; + case SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND: + responseFormat = getResponseFormat(ActionStatus.SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND, component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } + + public Either validateStringNotEmpty(User user, Component component, String value, ActionStatus badResult, AuditingActionEnum actionEnum) { + if ((value == null) || (value.trim().isEmpty())) { + log.info(badResult.name()); + ResponseFormat errorResponse = getResponseFormat(badResult); + if (actionEnum != null) { + log.debug("audit before sending response"); + auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, getComponentType(component)); + } + return Either.right(errorResponse); + } + return Either.left(true); + } + + public Boolean validateStringNotEmpty(String value) { + if ((value == null) || (value.trim().isEmpty())) { + return false; + } + return true; + } + + private ComponentTypeEnum getComponentType(Component component) { + if (component instanceof Service) { + return ComponentTypeEnum.SERVICE; + } // else if(component instanceof Resource){ + return null; + } + + public Either validateStringMatchesPattern(User user, Component component, String value, Pattern pattern, ActionStatus badResult, AuditingActionEnum actionEnum) { + if (!pattern.matcher(value).matches()) { + log.error(badResult.name()); + ResponseFormat errorResponse = getResponseFormat(badResult); + if (actionEnum != null) { + log.debug("audit before sending response"); + auditComponentAdmin(errorResponse, user, component, "", "", actionEnum, getComponentType(component)); + } + return Either.right(errorResponse); + } + return Either.left(true); + } + + /** + * + * " Error: Missing Mandatory Informational %s1 %s2 : %s3 " where %s1 - "resource"/"service" %s2 - "artifact"/ "artifacts" %s3 - Comma separated list of missing informational artifact types + * + * @param resource + * @param componentMissingMandatoryArtifacts + * @param value + * @return + */ + public ResponseFormat getResponseFormatByMissingArtifacts(ComponentTypeEnum componentType, Map artifacts) { + + String artifactTitle = "artifact"; + if (artifacts.size() > 1) { + artifactTitle = "artifacts"; + } + Collection artifactsLabels = artifacts.values(); + StringBuilder artifactsLabelBuilder = new StringBuilder(); + + List artifactsLabelsList = new ArrayList(); + artifactsLabelsList.addAll(artifactsLabels); + for (int i = 0; i < artifactsLabelsList.size(); i++) { + ArtifactDefinition artifactDef = artifactsLabelsList.get(i); + artifactsLabelBuilder.append(artifactDef.getArtifactDisplayName()); + if (i < artifactsLabelsList.size() - 1) { + artifactsLabelBuilder.append(";"); + } + } + ResponseFormat responseFormat = getResponseFormat(ActionStatus.COMPONENT_MISSING_MANDATORY_ARTIFACTS, componentType.name().toLowerCase(), artifactTitle, artifactsLabelBuilder.toString()); + + return responseFormat; + } + + public ActionStatus convertFromStorageResponseForAdditionalInformation(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.COMPONENT_NAME_ALREADY_EXIST; + break; + case INVALID_ID: + responseEnum = ActionStatus.ADDITIONAL_INFORMATION_NOT_FOUND; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ResponseFormat getResponseFormatAdditionalProperty(ActionStatus actionStatus, AdditionalInfoParameterInfo additionalInfoParameterInfo, NodeTypeEnum nodeType, AdditionalInformationEnum labelOrValue) { + + if (additionalInfoParameterInfo == null) { + additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + } + if (labelOrValue == null) { + labelOrValue = AdditionalInformationEnum.None; + } + + ResponseFormat responseFormat = null; + switch (actionStatus) { + case COMPONENT_NAME_ALREADY_EXIST: + responseFormat = getResponseFormat(actionStatus, "Additional parameter", additionalInfoParameterInfo.getKey()); + break; + case ADDITIONAL_INFORMATION_EXCEEDS_LIMIT: + responseFormat = getResponseFormat(actionStatus, labelOrValue.name().toLowerCase(), ValidationUtils.ADDITIONAL_INFORMATION_KEY_MAX_LENGTH.toString()); + break; + case ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED: + responseFormat = getResponseFormat(actionStatus, nodeType.name().toLowerCase()); + break; + case ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED: + responseFormat = getResponseFormat(actionStatus); + break; + case ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS: + responseFormat = getResponseFormat(actionStatus); + break; + case ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS: + responseFormat = getResponseFormat(actionStatus); + break; + case ADDITIONAL_INFORMATION_NOT_FOUND: + responseFormat = getResponseFormat(actionStatus); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + + return responseFormat; + } + + public ResponseFormat getResponseFormatAdditionalProperty(ActionStatus actionStatus) { + return getResponseFormatAdditionalProperty(actionStatus, null, null, null); + } + + public ActionStatus convertFromStorageResponseForConsumer(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.CONSUMER_ALREADY_EXISTS; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.CONSUMER_ALREADY_EXISTS; + break; + case NOT_FOUND: + responseEnum = ActionStatus.ECOMP_USER_NOT_FOUND; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ActionStatus convertFromStorageResponseForGroupType(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.GROUP_TYPE_ALREADY_EXIST; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.GROUP_TYPE_ALREADY_EXIST; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ActionStatus convertFromStorageResponseForDataType(StorageOperationStatus storageResponse) { + ActionStatus responseEnum = ActionStatus.GENERAL_ERROR; + + switch (storageResponse) { + case OK: + responseEnum = ActionStatus.OK; + break; + case CONNECTION_FAILURE: + case GRAPH_IS_LOCK: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + case BAD_REQUEST: + responseEnum = ActionStatus.INVALID_CONTENT; + break; + case ENTITY_ALREADY_EXISTS: + responseEnum = ActionStatus.DATA_TYPE_ALREADY_EXIST; + break; + case SCHEMA_VIOLATION: + responseEnum = ActionStatus.DATA_TYPE_ALREADY_EXIST; + break; + case CANNOT_UPDATE_EXISTING_ENTITY: + responseEnum = ActionStatus.DATA_TYPE_CANNOT_BE_UPDATED_BAD_REQUEST; + break; + default: + responseEnum = ActionStatus.GENERAL_ERROR; + break; + } + log.debug("convert storage response {} to action response {}", storageResponse.name(), responseEnum.name()); + return responseEnum; + } + + public ResponseFormat getResponseFormatByGroupType(ActionStatus actionStatus, GroupTypeDefinition groupType) { + if (groupType == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case GROUP_MEMBER_EMPTY: + case GROUP_TYPE_ALREADY_EXIST: + responseFormat = getResponseFormat(actionStatus, groupType.getType()); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + + } + + public ResponseFormat getResponseFormatByPolicyType(ActionStatus actionStatus, PolicyTypeDefinition policyType) { + if (policyType == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case POLICY_TYPE_ALREADY_EXIST: + responseFormat = getResponseFormat(actionStatus, policyType.getType()); + break; + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + + } + + public ResponseFormat getResponseFormatByDataType(ActionStatus actionStatus, DataTypeDefinition dataType, List properties) { + if (dataType == null) { + return getResponseFormat(actionStatus); + } + ResponseFormat responseFormat; + + switch (actionStatus) { + case DATA_TYPE_ALREADY_EXIST: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + case DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + case DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + case DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR: + responseFormat = getResponseFormat(actionStatus, dataType.getName(), properties == null ? "" : String.valueOf(properties)); + break; + case DATA_TYPE_DERIVED_IS_MISSING: + responseFormat = getResponseFormat(actionStatus, dataType.getDerivedFromName()); + break; + case DATA_TYPE_DUPLICATE_PROPERTY: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + case DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE: + responseFormat = getResponseFormat(actionStatus, dataType.getName(), properties == null ? "" : String.valueOf(properties)); + break; + case DATA_TYPE_CANNOT_HAVE_PROPERTIES: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + case DATA_TYPE_CANNOT_BE_UPDATED_BAD_REQUEST: + responseFormat = getResponseFormat(actionStatus, dataType.getName()); + break; + + default: + responseFormat = getResponseFormat(actionStatus); + break; + } + return responseFormat; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/DownloadArtifactLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/DownloadArtifactLogic.java new file mode 100644 index 0000000000..fff6fd15a4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/DownloadArtifactLogic.java @@ -0,0 +1,166 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.impl; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; + +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.StreamingOutput; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpStatus; +import org.eclipse.jgit.util.Base64; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ResourceUploadStatus; +import org.openecomp.sdc.be.info.ArtifactAccessInfo; +import org.openecomp.sdc.be.info.ArtifactAccessList; +import org.openecomp.sdc.be.info.ServletJsonResponse; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; + +import fj.data.Either; + +public class DownloadArtifactLogic { + + private static Logger log = LoggerFactory.getLogger(DownloadArtifactLogic.class.getName()); + + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + public Response downloadArtifact(final String resourceName, final String resourceVersion, final String artifactName, Either getArtifactStatus, String artifactId) { + Response response = null; + + if (getArtifactStatus.isRight()) { + log.debug("Could not find artifact for with id: {}", artifactId); + ResourceUploadStatus status = getArtifactStatus.right().value(); + if (status == status.COMPONENT_NOT_EXIST) + response = Response.status(HttpStatus.SC_NO_CONTENT).build(); + else + response = Response.status(HttpStatus.SC_NOT_FOUND).build(); + + return response; + } + // convert artifact to inputstream + else { + ESArtifactData artifactData = getArtifactStatus.left().value(); + byte[] artifactPayload = artifactData.getDataAsArray(); + + String payloadStr = new String(artifactPayload); + byte[] decodedPayload = artifactPayload; + boolean isEncoded = GeneralUtility.isBase64Encoded(payloadStr); + if (isEncoded) { + log.debug("payload is encoded. perform decode"); + decodedPayload = Base64.decode(new String(artifactPayload)); + } + final InputStream artifactStream = new ByteArrayInputStream(decodedPayload); + log.debug("found artifact for with id: {}", artifactId); + try { + + // outputstream for response + StreamingOutput stream = new StreamingOutput() { + public void write(OutputStream output) throws IOException, WebApplicationException { + try { + IOUtils.copy(artifactStream, output); + } catch (Exception e) { + throw new WebApplicationException(e); + } + } + }; + artifactStream.close(); + return Response.ok(stream).type(MediaType.APPLICATION_OCTET_STREAM_TYPE).header("content-disposition", "attachment; filename = " + artifactName) + // .header(Constants.MD5_HEADER, new + // String(artifactData.getArtifactChecksum())) + .build(); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Failed to stream artifact data on the response"); + BeEcompErrorManager.getInstance().logBeSystemError("Failed to stream artifact data on the response"); + log.debug("Failed to stream artifact data on the response: {}", e.getMessage()); + response = buildResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Failed to stream artifact data on the response"); + return response; + } + } + } + + public List convertArtifactList(List artifactsList, String servletPath) { + + List artifactAccessList = new ArrayList(); + for (ESArtifactData artifact : artifactsList) { + ArtifactAccessInfo accessInfo = new ArtifactAccessInfo(artifact, servletPath); + artifactAccessList.add(accessInfo); + } + return artifactAccessList; + } + + public Response createArtifactListResponse(final String serviceName, Either, ResourceUploadStatus> getArtifactsStatus/* + * List < ? extends IResourceData> artifactsList + */, String servletPath) { + Response response; + List artifactAccessInfos; + if (getArtifactsStatus.isRight()) { + // if there are no artifacts - return No-Content + ResourceUploadStatus status = getArtifactsStatus.right().value(); + if (status == ResourceUploadStatus.COMPONENT_NOT_EXIST || status == ResourceUploadStatus.SERVICE_NOT_EXIST) { + log.debug("resource {} does not exist", serviceName); + response = Response.status(HttpStatus.SC_NOT_FOUND).entity("[]").build(); + + } else { + log.debug("No content was found for {}", serviceName); + response = Response.status(HttpStatus.SC_NO_CONTENT).entity("[]").build(); + } + return response; + } else { + List artifactsList = getArtifactsStatus.left().value(); + log.debug("{} artifacts were found for {}", artifactsList.size(), serviceName); + artifactAccessInfos = convertArtifactList(artifactsList, servletPath); + + String artifactDataJson = gson.toJson(new ArtifactAccessList(artifactAccessInfos)); + response = Response.status(HttpStatus.SC_OK).entity(artifactDataJson).type(MediaType.APPLICATION_JSON_TYPE).build(); + + return response; + } + } + + public Response buildResponse(int status, String errorMessage) { + + ServletJsonResponse jsonResponse = new ServletJsonResponse(); + jsonResponse.setDescription(errorMessage); + jsonResponse.setSource(Constants.CATALOG_BE); + + Response response = Response.status(status).entity(jsonResponse).build(); + + return response; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServletUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServletUtils.java new file mode 100644 index 0000000000..3a5d9bf85f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/ServletUtils.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.impl; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.springframework.stereotype.Component; + +import com.google.gson.Gson; + +@Component("servletUtils") +public class ServletUtils { + @Resource + private ComponentsUtils componentsUtils; + private Gson gson = new Gson(); + @Resource + private IUserBusinessLogic adminManager; + + public ComponentsUtils getComponentsUtils() { + return componentsUtils; + } + + public Gson getGson() { + return gson; + } + + public IUserBusinessLogic getUserAdmin() { + return adminManager; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/impl/WebAppContextWrapper.java b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/WebAppContextWrapper.java new file mode 100644 index 0000000000..cb21984a7f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/impl/WebAppContextWrapper.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.impl; + +import javax.servlet.ServletContext; + +import org.springframework.web.context.WebApplicationContext; +import org.springframework.web.context.support.WebApplicationContextUtils; + +public class WebAppContextWrapper { + + public WebApplicationContext getWebAppContext(ServletContext context) { + + return WebApplicationContextUtils.getWebApplicationContext(context); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessInfo.java new file mode 100644 index 0000000000..deb446e32f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessInfo.java @@ -0,0 +1,159 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import org.openecomp.sdc.be.resources.data.ESArtifactData; + +public class ArtifactAccessInfo { + + public ArtifactAccessInfo() { + } + + public ArtifactAccessInfo(ESArtifactData artifactData) { + // this.name = artifactData.getArtifactName(); + this.id = artifactData.getId(); + // this.type = artifactData.getArtifactType(); + // this.description = artifactData.getArtifactDescription(); + // this.creator = artifactData.getArtifactCreator(); + // DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL); + // Date creationTimestamp = artifactData.getArtifactCreationTimestamp(); + // this.creationTime = (creationTimestamp != + // null)?dateFormat.format(creationTimestamp): null; + // Date updateTimestamp = artifactData.getArtifactLastUpdateTimestamp(); + // this.lastUpdateTime = (updateTimestamp != + // null)?dateFormat.format(updateTimestamp):null; + // this.lastUpdater = artifactData.getArtifactLastUpdater(); + // if (artifactData.getArtifactChecksum() != null){ + // this.checksum = new String(artifactData.getArtifactChecksum()); + // } else { + // this.checksum = null; + // } + } + + public ArtifactAccessInfo(ESArtifactData artifactData, String servletContext) { + // this.name = artifactData.getArtifactName(); + StringBuilder urlBuilder = new StringBuilder(); + urlBuilder = urlBuilder.append(servletContext).append("/"); + // if (ArtifactDataEnum.COMPONENT_ARTIFACT.equals(resource)){ + urlBuilder.append("resources/") + // .append(artifactData.getResourceId()).append("/") + + .append("/artifacts/"); + /* + * }else { ServiceArtifactData serviceArtifact = (ServiceArtifactData)artifactData; urlBuilder.append("services/") .append(serviceArtifact.getServiceName()).append("/") .append(serviceArtifact.getServiceVersion()) .append("/artifacts/") + * .append(serviceArtifact.getNodeTemplateName()) .append("/"); } + */ + // urlBuilder.append(artifactData.getArtifactName()); + this.url = urlBuilder.toString(); + + } + + private String name; + private String url; + private String id; + private String type; + private String description; + private String creator; + private String creationTime; + private String lastUpdater; + private String lastUpdateTime; + private String checksum; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getCreator() { + return creator; + } + + public void setCreator(String creator) { + this.creator = creator; + } + + public String getCreationTime() { + return creationTime; + } + + public void setCreationTime(String creationTime) { + this.creationTime = creationTime; + } + + public String getLastUpdater() { + return lastUpdater; + } + + public void setLastUpdater(String lastUpdater) { + this.lastUpdater = lastUpdater; + } + + public String getLastUpdateTime() { + return lastUpdateTime; + } + + public void setLastUpdateTime(String lastUpdateTime) { + this.lastUpdateTime = lastUpdateTime; + } + + public String getChecksum() { + return checksum; + } + + public void setChecksum(String checksum) { + this.checksum = checksum; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessList.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessList.java new file mode 100644 index 0000000000..ddeb0505d9 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactAccessList.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class ArtifactAccessList { + + public ArtifactAccessList(List artifacts) { + this.artifacts = artifacts; + } + + private List artifacts; + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactDefinitionInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactDefinitionInfo.java new file mode 100644 index 0000000000..163d220871 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactDefinitionInfo.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; + +public class ArtifactDefinitionInfo { + + private String uniqueId; + /** Specifies the display name of the artifact. */ + private String artifactName; + private String artifactDisplayName; + private String artifactVersion; + private String artifactUUID; + + public ArtifactDefinitionInfo(ArtifactDefinition artifactDefinition) { + uniqueId = artifactDefinition.getUniqueId(); + artifactName = artifactDefinition.getArtifactName(); + artifactDisplayName = artifactDefinition.getArtifactDisplayName(); + artifactVersion = artifactDefinition.getArtifactVersion(); + artifactUUID = artifactDefinition.getArtifactUUID(); + + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getArtifactName() { + return artifactName; + } + + public void setArtifactName(String artifactName) { + this.artifactName = artifactName; + } + + public String getArtifactDisplayName() { + return artifactDisplayName; + } + + public void setArtifactDisplayName(String artifactDisplayName) { + this.artifactDisplayName = artifactDisplayName; + } + + public String getArtifactVersion() { + return artifactVersion; + } + + public void setArtifactVersion(String artifactVersion) { + this.artifactVersion = artifactVersion; + } + + public String getArtifactUUID() { + return artifactUUID; + } + + public void setArtifactUUID(String artifactUUID) { + this.artifactUUID = artifactUUID; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTemplateInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTemplateInfo.java new file mode 100644 index 0000000000..fca7bf38d8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTemplateInfo.java @@ -0,0 +1,352 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.DeploymentArtifactTypeConfig; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonObject; + +import fj.data.Either; + +public class ArtifactTemplateInfo { + public static final String TYPE = "type"; + public static final String FILE_NAME = "fileName"; + public static final String ENV = "env"; + public static final String IS_BASE = "isBase"; + + private static final String CSAR_HEAT = "HEAT"; + private static final String CSAR_ARTIFACT = "artifacts"; + private static final String CSAR_NETWORK = "network"; + private static final String CSAR_VOLUME = "volume"; + private static final String CSAR_NESTED = "nested"; + private static final Object DESC = "description"; + private static Logger log = LoggerFactory.getLogger(ArtifactTemplateInfo.class.getName()); + String type; + String fileName; + String env; + boolean isBase; + String groupName; + String description; + + List relatedArtifactsInfo; + private static Gson gson = new Gson(); + + public ArtifactTemplateInfo() { + super(); + } + + public ArtifactTemplateInfo(String type, String fileName, String env, List relatedArtifactsInfo) { + super(); + this.type = type; + this.fileName = fileName; + this.env = env; + this.relatedArtifactsInfo = relatedArtifactsInfo; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getFileName() { + return fileName; + } + + public void setFileName(String fileName) { + this.fileName = fileName; + } + + public String getEnv() { + return env; + } + + public void setEnv(String env) { + this.env = env; + } + + public List getRelatedArtifactsInfo() { + return relatedArtifactsInfo; + } + + public void setRelatedArtifactsInfo(List relatedArtifactsInfo) { + this.relatedArtifactsInfo = relatedArtifactsInfo; + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public boolean isBase() { + return isBase; + } + + public void setBase(boolean isBase) { + this.isBase = isBase; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @Override + public String toString() { + return "ArtifactTemplateInfo [type=" + type + ", fileName=" + fileName + ", env=" + env + ", isBase=" + isBase + ", groupName=" + groupName + ", description=" + description + ", relatedArtifactsInfo=" + relatedArtifactsInfo + "]"; + } + + public static Either createArtifactTemplateInfoFromJson(ComponentsUtils componentsUtils, String type, Map o, List createdArtifactTemplateInfoList, + ArtifactTemplateInfo parentArtifact) { + String content = gson.toJson(o); + JsonObject jsonElement = new JsonObject(); + ArtifactTemplateInfo resourceInfo = new ArtifactTemplateInfo(); + + jsonElement = gson.fromJson(content, jsonElement.getClass()); + + Map artifactTemplateMap = componentsUtils.parseJsonToObject(jsonElement.toString(), HashMap.class); + if (artifactTemplateMap.containsKey(TYPE)) + resourceInfo.setType((String) artifactTemplateMap.get(TYPE)); + if (artifactTemplateMap.containsKey(FILE_NAME)) + resourceInfo.setFileName((String) artifactTemplateMap.get(FILE_NAME)); + if (artifactTemplateMap.containsKey(IS_BASE)) + resourceInfo.setBase((Boolean) artifactTemplateMap.get(IS_BASE)); + if (artifactTemplateMap.containsKey(ENV)) { + Object envObj = artifactTemplateMap.get(ENV); + String envStr = ""; + if (envObj instanceof String) { + envStr = (String) envObj; + } else if (envObj instanceof Map) { + Map envMap = (Map) envObj; + if (envMap.containsKey(FILE_NAME)) { + envStr = (String) envMap.get(FILE_NAME); + } + } + resourceInfo.setEnv(envStr); + } + if (artifactTemplateMap.containsKey(DESC)) { + resourceInfo.setDescription((String) artifactTemplateMap.get(DESC)); + } else { + resourceInfo.setDescription((String) artifactTemplateMap.get(FILE_NAME)); + } + + boolean artifactTypeExist = false; + String correctType = type; + if (type.equalsIgnoreCase(CSAR_NESTED)) + correctType = ArtifactTypeEnum.HEAT_NESTED.getType(); + else if ((type.equalsIgnoreCase(CSAR_VOLUME))) + correctType = ArtifactTypeEnum.HEAT_VOL.getType(); + else if ((type.equalsIgnoreCase(CSAR_NETWORK))) + correctType = ArtifactTypeEnum.HEAT_NET.getType(); + else if ((type.equalsIgnoreCase(CSAR_ARTIFACT))) + correctType = ArtifactTypeEnum.HEAT_ARTIFACT.getType(); + else if ((type.equalsIgnoreCase(CSAR_HEAT))) + correctType = ArtifactTypeEnum.HEAT.getType(); + else + correctType = ArtifactTypeEnum.OTHER.getType(); + Either, ActionStatus> allArtifactTypes = getDeploymentArtifactTypes(NodeTypeEnum.Resource); + + if (allArtifactTypes.isRight()) { + BeEcompErrorManager.getInstance().logBeInvalidConfigurationError("Artifact Upload / Update", "artifactTypes", allArtifactTypes.right().value().name()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.FAILED_RETRIVE_ARTIFACTS_TYPES)); + } + + for (ArtifactType artType : allArtifactTypes.left().value()) { + + if (artType.getName().contains(correctType)) { + resourceInfo.type = artType.getName(); + artifactTypeExist = true; + break; + } + } + + if (!artifactTypeExist) { + BeEcompErrorManager.getInstance().logBeInvalidTypeError("Artifact", "-Not supported artifact type ", correctType); + log.debug("Not supported artifact type = {}", correctType); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_TYPE_NOT_SUPPORTED, correctType)); + } + + Either eitherNeedToCreate = validateEnv(componentsUtils, createdArtifactTemplateInfoList, resourceInfo); + if (eitherNeedToCreate.isRight()) + return Either.right(eitherNeedToCreate.right().value()); + eitherNeedToCreate = validateParentType(componentsUtils, resourceInfo, parentArtifact); + if (eitherNeedToCreate.isRight()) + return Either.right(eitherNeedToCreate.right().value()); + eitherNeedToCreate = validateIsAlreadyExist(componentsUtils, resourceInfo, createdArtifactTemplateInfoList, parentArtifact); + if (eitherNeedToCreate.isRight()) + return Either.right(eitherNeedToCreate.right().value()); + Set keys = o.keySet(); + for (String key : keys) { + if (o.get(key) instanceof List) { + List> artifList = (List>) o.get(key); + for (Map relatedArtifactsMap : artifList) { + Either relatedArtifact = ArtifactTemplateInfo.createArtifactTemplateInfoFromJson(componentsUtils, key, relatedArtifactsMap, createdArtifactTemplateInfoList, resourceInfo); + if (relatedArtifact.isRight()) + return relatedArtifact; + if (resourceInfo.relatedArtifactsInfo == null) + resourceInfo.relatedArtifactsInfo = new ArrayList(); + resourceInfo.relatedArtifactsInfo.add(relatedArtifact.left().value()); + } + } + } + return Either.left(resourceInfo); + } + + private static Either validateIsAlreadyExist(ComponentsUtils componentsUtils, ArtifactTemplateInfo resourceInfo, List createdArtifactTemplateInfoList, ArtifactTemplateInfo parentArtifact) { + + if (parentArtifact == null) { + if (createdArtifactTemplateInfoList == null || createdArtifactTemplateInfoList.isEmpty()) + return Either.left(true); + for (ArtifactTemplateInfo createdArtifact : createdArtifactTemplateInfoList) { + if (createdArtifact.getType().equalsIgnoreCase(resourceInfo.getType()) && createdArtifact.getFileName().equalsIgnoreCase(resourceInfo.getFileName())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_MASTER_IN_CSAR, resourceInfo.getFileName(), createdArtifact.type)); + } + } + return Either.left(true); + } else { + List relatedArtifacts = parentArtifact.getRelatedArtifactsInfo(); + if (relatedArtifacts == null || relatedArtifacts.isEmpty()) + return Either.left(true); + for (ArtifactTemplateInfo relatedArtifact : relatedArtifacts) { + if (relatedArtifact.getType().equalsIgnoreCase(resourceInfo.getType())) { + if (relatedArtifact.getFileName().equalsIgnoreCase(resourceInfo.getFileName())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_ALRADY_EXIST_IN_MASTER_IN_CSAR, resourceInfo.getFileName(), parentArtifact.getFileName())); + } + } + } + return Either.left(true); + } + } + + private static Either validateParentType(ComponentsUtils componentsUtils, ArtifactTemplateInfo resourceInfo, ArtifactTemplateInfo parentArtifact) { + + if (parentArtifact == null) + return Either.left(true); + if (resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ARTIFACT.getType())) + return Either.left(true); + if (resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) && parentArtifact != null) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_IN_MASTER, resourceInfo.getFileName(), resourceInfo.getType(), parentArtifact.getFileName(), parentArtifact.getType())); + } + if ((resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_NET.getType()) || resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) + && !parentArtifact.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_IN_MASTER, resourceInfo.getFileName(), resourceInfo.getType(), parentArtifact.getFileName(), parentArtifact.getType())); + } + if (parentArtifact.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_NESTED.getType())) { + if (resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ARTIFACT.getType())) { + Either.left(true); + } + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_IN_MASTER, resourceInfo.getFileName(), resourceInfo.getType(), parentArtifact.getFileName(), parentArtifact.getType())); + } + if (parentArtifact.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType()) && resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_IN_MASTER, resourceInfo.getFileName(), resourceInfo.getType(), parentArtifact.getFileName(), parentArtifact.getType())); + } + + if (parentArtifact.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT.getType())) { + Either.left(true); + } + return Either.left(true); + } + + private static Either validateEnv(ComponentsUtils componentsUtils, List createdArtifactTemplateInfoList, ArtifactTemplateInfo resourceInfo) { + + if (createdArtifactTemplateInfoList == null || createdArtifactTemplateInfoList.isEmpty()) + return Either.left(true); + if (resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_NESTED.getType()) || resourceInfo.getType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_ARTIFACT.getType())) + return Either.left(true); + for (ArtifactTemplateInfo createdArtifactTemplateInfo : createdArtifactTemplateInfoList) { + // check if artifact with this name already parsed. If parsed check + // env name. it must be the same. + if (resourceInfo.getFileName().equalsIgnoreCase(createdArtifactTemplateInfo.getFileName())) { + if ((resourceInfo.getEnv() == null || resourceInfo.getEnv().isEmpty()) && (createdArtifactTemplateInfo.getEnv() != null && !createdArtifactTemplateInfo.getEnv().isEmpty())) { + log.debug("Artifact file with name {} type{} already parsed but with env {}", resourceInfo.getFileName(), resourceInfo.getType(), createdArtifactTemplateInfo.getEnv()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_ENV, resourceInfo.getFileName(), resourceInfo.getType(), resourceInfo.getEnv(), createdArtifactTemplateInfo.getEnv())); + } + if (resourceInfo.getEnv() != null && !resourceInfo.getEnv().isEmpty() && createdArtifactTemplateInfo.getEnv() != null && !createdArtifactTemplateInfo.getEnv().isEmpty() + && !createdArtifactTemplateInfo.getEnv().equalsIgnoreCase(resourceInfo.getEnv())) { + log.debug("Artifact file with name {} type{} env {} already parsed but with env {}", resourceInfo.getFileName(), resourceInfo.getType(), resourceInfo.getEnv(), createdArtifactTemplateInfo.getEnv()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_ENV, resourceInfo.getFileName(), resourceInfo.getType(), resourceInfo.getEnv(), createdArtifactTemplateInfo.getEnv())); + } + if ((resourceInfo.getEnv() != null && !resourceInfo.getEnv().isEmpty()) && (createdArtifactTemplateInfo.getEnv() == null || createdArtifactTemplateInfo.getEnv().isEmpty())) { + log.debug("Artifact file with name {} type{} env {} already parsed but with env {}", resourceInfo.getFileName(), resourceInfo.getType(), resourceInfo.getEnv(), createdArtifactTemplateInfo.getEnv()); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.ARTIFACT_NOT_VALID_ENV, resourceInfo.getFileName(), resourceInfo.getType(), resourceInfo.getEnv(), createdArtifactTemplateInfo.getEnv())); + } + } + List relatedArtifacts = createdArtifactTemplateInfo.getRelatedArtifactsInfo(); + Either status = validateEnv(componentsUtils, relatedArtifacts, resourceInfo); + if (status.isRight()) + return status; + } + return Either.left(true); + } + + private static Either, ActionStatus> getDeploymentArtifactTypes(NodeTypeEnum parentType) { + + Map deploymentArtifacts = null; + List artifactTypes = new ArrayList(); + + if (parentType.equals(NodeTypeEnum.Service)) { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getServiceDeploymentArtifacts(); + } else { + deploymentArtifacts = ConfigurationManager.getConfigurationManager().getConfiguration().getResourceDeploymentArtifacts(); + } + if (deploymentArtifacts != null) { + for (String artifactType : deploymentArtifacts.keySet()) { + ArtifactType artifactT = new ArtifactType(); + artifactT.setName(artifactType); + artifactTypes.add(artifactT); + } + return Either.left(artifactTypes); + } else { + return Either.right(ActionStatus.GENERAL_ERROR); + } + + } + + public static int compareByGroupName(ArtifactTemplateInfo art1, ArtifactTemplateInfo art2) { + return art1.isBase ? (art2.isBase ? 0 : -1) : (art2.isBase ? 1 : 0); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTypesInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTypesInfo.java new file mode 100644 index 0000000000..249b420908 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ArtifactTypesInfo.java @@ -0,0 +1,48 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +import org.openecomp.sdc.be.model.ArtifactType; + +public class ArtifactTypesInfo { + + Integer heatDefaultTimeout = 60; + List artifactTypes; + + public List getArtifactTypes() { + return artifactTypes; + } + + public void setArtifactTypes(List artifactTypes) { + this.artifactTypes = artifactTypes; + } + + public Integer getHeatDefaultTimeout() { + return heatDefaultTimeout; + } + + public void setHeatDefaultTimeout(Integer heatDefaultTimeout) { + this.heatDefaultTimeout = heatDefaultTimeout; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/CreateAndAssotiateInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/CreateAndAssotiateInfo.java new file mode 100644 index 0000000000..b2fa493443 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/CreateAndAssotiateInfo.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; + +public class CreateAndAssotiateInfo { + private ComponentInstance node; + private RequirementCapabilityRelDef associate; + + public CreateAndAssotiateInfo(ComponentInstance node, RequirementCapabilityRelDef associate) { + super(); + this.node = node; + this.associate = associate; + } + + public ComponentInstance getNode() { + return node; + } + + public void setNode(ComponentInstance node) { + this.node = node; + } + + public RequirementCapabilityRelDef getAssociate() { + return associate; + } + + public void setAssociate(RequirementCapabilityRelDef associate) { + this.associate = associate; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatus.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatus.java new file mode 100644 index 0000000000..d0f3ff868e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatus.java @@ -0,0 +1,62 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public enum DistributionStatus { + DEPLOYED("Deployed", "DEPLOYED"); + + private String name; + private String auditingStatus; + + private static Logger log = LoggerFactory.getLogger(DistributionStatus.class.getName()); + + DistributionStatus(String name, String auditingStatus) { + this.name = name; + this.auditingStatus = auditingStatus; + } + + public String getName() { + return name; + } + + public String getAuditingStatus() { + return auditingStatus; + } + + public static DistributionStatus getStatusByAuditingStatusName(String auditingStatus) { + DistributionStatus res = null; + DistributionStatus[] values = values(); + for (DistributionStatus value : values) { + if (value.getAuditingStatus().equals(auditingStatus)) { + res = value; + break; + } + } + if (res == null) { + log.debug("No DistributionStatus is mapped to name {}", auditingStatus); + } + return res; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusInfo.java new file mode 100644 index 0000000000..6f7596cd5f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusInfo.java @@ -0,0 +1,91 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.ESTimeBasedEvent; + +public class DistributionStatusInfo { + String omfComponentID; + String timestamp; + String url; + String status; + String errorReason; + + public DistributionStatusInfo(ESTimeBasedEvent distributionStatusEvent) { + super(); + omfComponentID = (String) distributionStatusEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_CONSUMER_ID.getDisplayName()); + timestamp = (String) distributionStatusEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_STATUS_TIME.getDisplayName());// distributionStatusEvent.getStatusTime(); + url = (String) distributionStatusEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_DISTRIBUTION_RESOURCE_URL.getDisplayName());// distributionStatusEvent.getResoureURL(); + status = (String) distributionStatusEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_STATUS.getDisplayName());// distributionStatusEvent.getStatus(); + errorReason = (String) distributionStatusEvent.getFields().get(AuditingFieldsKeysEnum.AUDIT_DESC.getDisplayName()); + + } + + public DistributionStatusInfo(String omfComponentID, String timestamp, String url, String status) { + super(); + this.omfComponentID = omfComponentID; + this.timestamp = timestamp; + this.url = url; + this.status = status; + } + + public String getOmfComponentID() { + return omfComponentID; + } + + public void setOmfComponentID(String omfComponentID) { + this.omfComponentID = omfComponentID; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + + public String getErrorReason() { + return errorReason; + } + + public void setErrorReason(String errorReason) { + this.errorReason = errorReason; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java new file mode 100644 index 0000000000..ab122efc74 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusListResponse.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class DistributionStatusListResponse { + + private List distribStatusInfoList; + + public List getDistributionStatusList() { + return distribStatusInfoList; + } + + public void setDistributionStatusList(List distribStatusInfoList) { + this.distribStatusInfoList = distribStatusInfoList; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceInfo.java new file mode 100644 index 0000000000..dfa481d34d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceInfo.java @@ -0,0 +1,74 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +public class DistributionStatusOfServiceInfo { + String distributionID; + String timestamp; + String userId; + String deployementStatus; + + public DistributionStatusOfServiceInfo() { + super(); + + } + + public DistributionStatusOfServiceInfo(String distributionID, String timestamp, String userId, String deployementStatus) { + super(); + this.distributionID = distributionID; + this.timestamp = timestamp; + this.userId = userId; + this.deployementStatus = deployementStatus; + } + + public String getDistributionID() { + return distributionID; + } + + public void setDistributionID(String distributionID) { + this.distributionID = distributionID; + } + + public String getTimestamp() { + return timestamp; + } + + public void setTimestamp(String timestamp) { + this.timestamp = timestamp; + } + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getDeployementStatus() { + return deployementStatus; + } + + public void setDeployementStatus(String deployementStatus) { + this.deployementStatus = deployementStatus; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java new file mode 100644 index 0000000000..8415736be1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/DistributionStatusOfServiceListResponce.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class DistributionStatusOfServiceListResponce { + + private List distribStatusOfServiceInfoList; + + public List getDistributionStatusOfServiceList() { + return distribStatusOfServiceInfoList; + } + + public void setDistributionStatusOfServiceList(List distribStatusOfServiceInfoList) { + this.distribStatusOfServiceInfoList = distribStatusOfServiceInfoList; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupDefinitionInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupDefinitionInfo.java new file mode 100644 index 0000000000..24d9c5644d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupDefinitionInfo.java @@ -0,0 +1,130 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +import org.openecomp.sdc.be.datatypes.elements.GroupDataDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; + +public class GroupDefinitionInfo { + private String name; + + // the id is unique per group instance on graph. + private String uniqueId; + + // the group UUID should be changed when one of the artifacts/component + // instances has been changed. + private String groupUUID; + + // version should be changed when there is a change to the group's metadata + // or to the groups members + // (not necessarily when the VF version is changed). This field cannot be + // updated by user + private String version; + + private String invariantUUID; + + Boolean isBase = null; + + // artifacts - list of artifact uid. All artifacts in the group must already + // be uploaded to the VF + private List artifacts; + + public GroupDefinitionInfo() { + super(); + } + + public GroupDefinitionInfo(GroupDefinition other) { + this.setName(other.getName()); + this.setUniqueId(other.getUniqueId()); + this.setVersion(other.getVersion()); + this.setGroupUUID(other.getGroupUUID()); + this.setInvariantUUID(other.getInvariantUUID()); + + } + + public String getInvariantUUID() { + return invariantUUID; + } + + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getUniqueId() { + return uniqueId; + } + + public void setUniqueId(String uniqueId) { + this.uniqueId = uniqueId; + } + + public String getGroupUUID() { + return groupUUID; + } + + public void setGroupUUID(String groupUUID) { + this.groupUUID = groupUUID; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public Boolean getIsBase() { + return isBase; + } + + public void setIsBase(Boolean isBase) { + this.isBase = isBase; + } + + public List getArtifacts() { + return artifacts; + } + + public void setArtifacts(List artifacts) { + this.artifacts = artifacts; + } + + @Override + public String toString() { + return "GroupDefinitionInfo [" + super.toString() + ", isBase=" + isBase + ", artifacts=" + artifacts + "]"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupTemplateInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupTemplateInfo.java new file mode 100644 index 0000000000..8471a801ac --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/GroupTemplateInfo.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; +import java.util.Map; + +public class GroupTemplateInfo { + String groupName; + boolean isBase; + ArtifactTemplateInfo artifactTemplateInfo; + + public GroupTemplateInfo() { + super(); + // TODO Auto-generated constructor stub + } + + public String getGroupName() { + return groupName; + } + + public void setGroupName(String groupName) { + this.groupName = groupName; + } + + public boolean isBase() { + return isBase; + } + + public void setBase(boolean isBase) { + this.isBase = isBase; + } + + public ArtifactTemplateInfo getArtifactTemplateInfo() { + return artifactTemplateInfo; + } + + public void setArtifactTemplateInfo(ArtifactTemplateInfo artifactTemplateInfo) { + this.artifactTemplateInfo = artifactTemplateInfo; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/MergedArtifactInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/MergedArtifactInfo.java new file mode 100644 index 0000000000..95038b1830 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/MergedArtifactInfo.java @@ -0,0 +1,151 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.model.ArtifactDefinition; + +public class MergedArtifactInfo { + + private List createdArtifact; + private ArtifactTemplateInfo jsonArtifactTemplate; + private Set parsetArtifactsNames; + + public List getCreatedArtifact() { + return createdArtifact; + } + + public void setCreatedArtifact(List createdArtifact) { + this.createdArtifact = createdArtifact; + parsetArtifactsNames = new HashSet(); + parsetArtifactsNames.add(jsonArtifactTemplate.getFileName()); + List relatedGroupTemplateList = jsonArtifactTemplate.getRelatedArtifactsInfo(); + if (relatedGroupTemplateList != null && !relatedGroupTemplateList.isEmpty()) { + this.createArtifactsGroupSet(relatedGroupTemplateList, parsetArtifactsNames); + } + + } + + public ArtifactTemplateInfo getJsonArtifactTemplate() { + return jsonArtifactTemplate; + } + + public void setJsonArtifactTemplate(ArtifactTemplateInfo jsonArtifactTemplate) { + this.jsonArtifactTemplate = jsonArtifactTemplate; + } + + public List getListToAssociateArtifactToGroup() { + List resList = new ArrayList(); + List relatedArtifacts = jsonArtifactTemplate.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + getNewArtifactsInGroup(resList, relatedArtifacts); + } + return resList; + } + + public List getListToDissotiateArtifactFromGroup(List deletedArtifacts) { + List resList = new ArrayList(); + for (ArtifactDefinition artifactDefinition : createdArtifact) { + if (!parsetArtifactsNames.contains(artifactDefinition.getArtifactName())) { + boolean isDeleted = false; + for (ArtifactDefinition deletedArtifact : deletedArtifacts) { + if (artifactDefinition.getUniqueId().equalsIgnoreCase(deletedArtifact.getUniqueId())) { + isDeleted = true; + break; + } + + } + if (!isDeleted) + resList.add(artifactDefinition); + } + + } + + return resList; + } + + public List> getListToUpdateArtifactInGroup() { + List> resList = new ArrayList>(); + for (ArtifactDefinition artifactDefinition : createdArtifact) { + if (artifactDefinition.getArtifactName().equalsIgnoreCase(jsonArtifactTemplate.getFileName())) { + resList.add(new ImmutablePair(artifactDefinition, jsonArtifactTemplate)); + } + } + List relatedArtifacts = jsonArtifactTemplate.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + getUpdateArtifactsInGroup(resList, relatedArtifacts); + } + return resList; + } + + private void getUpdateArtifactsInGroup(List> resList, List jsonArtifacts) { + + for (ArtifactTemplateInfo artifactTemplateInfo : jsonArtifacts) { + + for (ArtifactDefinition artifactDefinition : createdArtifact) { + if (artifactDefinition.getArtifactName().equalsIgnoreCase(artifactTemplateInfo.getFileName())) { + resList.add(new ImmutablePair(artifactDefinition, artifactTemplateInfo)); + } + } + + List relatedArtifacts = artifactTemplateInfo.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + getUpdateArtifactsInGroup(resList, relatedArtifacts); + } + } + } + + private void getNewArtifactsInGroup(List resList, List jsonArtifacts) { + + for (ArtifactTemplateInfo artifactTemplateInfo : jsonArtifacts) { + boolean isNewArtifact = true; + for (ArtifactDefinition artifactDefinition : createdArtifact) { + if (artifactDefinition.getArtifactName().equalsIgnoreCase(artifactTemplateInfo.getFileName())) { + isNewArtifact = false; + } + } + if (isNewArtifact) + resList.add(artifactTemplateInfo); + List relatedArtifacts = artifactTemplateInfo.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + getNewArtifactsInGroup(resList, relatedArtifacts); + } + } + } + + private void createArtifactsGroupSet(List parsedGroupTemplateList, Set parsedArtifactsName) { + + for (ArtifactTemplateInfo parsedGroupTemplate : parsedGroupTemplateList) { + parsedArtifactsName.add(parsedGroupTemplate.getFileName()); + List relatedArtifacts = parsedGroupTemplate.getRelatedArtifactsInfo(); + if (relatedArtifacts != null && !relatedArtifacts.isEmpty()) { + createArtifactsGroupSet(relatedArtifacts, parsedArtifactsName); + } + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceInfo.java new file mode 100644 index 0000000000..457c49ee8e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceInfo.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class ServiceInfo { + + private String name; + private List versions; + + public ServiceInfo(String serviceName, List list) { + this.name = serviceName; + this.versions = list; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List getVersions() { + return versions; + } + + public void setVersions(List versions) { + this.versions = versions; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceVersionInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceVersionInfo.java new file mode 100644 index 0000000000..13f8a1307f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServiceVersionInfo.java @@ -0,0 +1,53 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +public class ServiceVersionInfo { + + // private String serviceName; + private String version; + private String url; + + public ServiceVersionInfo(String serviceName, String serviceVersion, String context) { + super(); + // this.serviceName = serviceName; + this.version = serviceVersion; + StringBuilder sb = new StringBuilder(context); + sb.append("services/").append(serviceName).append("/").append(serviceVersion); + url = sb.toString(); + } + + public String getVersion() { + return version; + } + + public void setVersion(String serviceVersion) { + this.version = serviceVersion; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServicesWrapper.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServicesWrapper.java new file mode 100644 index 0000000000..9c26cf5959 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServicesWrapper.java @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class ServicesWrapper { + private List services; + + public List getServices() { + return services; + } + + public void setServices(List services) { + this.services = services; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServletJsonResponse.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServletJsonResponse.java new file mode 100644 index 0000000000..5559311e9e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ServletJsonResponse.java @@ -0,0 +1,44 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +public class ServletJsonResponse { + + String source; + String description; + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getSource() { + return source; + } + + public void setSource(String source) { + this.source = source; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInfo.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInfo.java new file mode 100644 index 0000000000..11b27af7a1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInfo.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class ToscaNodeTypeInfo { + + private String nodeName; + private String templateVersion; + private List interfaces; + private String iconPath; + + public String getNodeName() { + return nodeName; + } + + public void setNodeName(String nodeName) { + this.nodeName = nodeName; + } + + public String getTemplateVersion() { + return templateVersion; + } + + public void setTemplateVersion(String templateVersion) { + this.templateVersion = templateVersion; + } + + public List getInterfaces() { + return interfaces; + } + + public void setInterfaces(List interfaces) { + this.interfaces = interfaces; + } + + public String getIconPath() { + return iconPath; + } + + public void setIconPath(String iconPath) { + this.iconPath = iconPath; + } + + @Override + public String toString() { + return "ToscaNodeTypeInfo [nodeName=" + nodeName + ", templateVersion=" + templateVersion + ", interfaces=" + interfaces + ", iconPath=" + iconPath + "]"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInterface.java b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInterface.java new file mode 100644 index 0000000000..25bab766bf --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/info/ToscaNodeTypeInterface.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.info; + +import java.util.List; + +public class ToscaNodeTypeInterface { + + List scripts; + + public List getScripts() { + return scripts; + } + + public void setScripts(List scripts) { + this.scripts = scripts; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/listen/BEAppContextListener.java b/catalog-be/src/main/java/org/openecomp/sdc/be/listen/BEAppContextListener.java new file mode 100644 index 0000000000..d40a3d4433 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/listen/BEAppContextListener.java @@ -0,0 +1,132 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.listen; + +import java.io.IOException; +import java.io.InputStream; +import java.util.jar.Attributes; +import java.util.jar.Manifest; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.impl.DownloadArtifactLogic; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.monitoring.BeMonitoringService; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.impl.ExternalConfiguration; +import org.openecomp.sdc.common.listener.AppContextListener; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import org.openecomp.portalsdk.core.onboarding.ueb.UebException; +import org.openecomp.portalsdk.core.onboarding.ueb.UebManager; + +public class BEAppContextListener extends AppContextListener implements ServletContextListener { + + private static final String MANIFEST_FILE_NAME = "/META-INF/MANIFEST.MF"; + private static Logger log = LoggerFactory.getLogger(BEAppContextListener.class.getName()); + + private static UebManager uebManager = null; + + public void contextInitialized(ServletContextEvent context) { + + super.contextInitialized(context); + + ConfigurationManager configurationManager = new ConfigurationManager(ExternalConfiguration.getConfigurationSource()); + log.debug("loading configuration from configDir: {} appName: {}", ExternalConfiguration.getConfigDir(), ExternalConfiguration.getAppName()); + + context.getServletContext().setAttribute(Constants.CONFIGURATION_MANAGER_ATTR, configurationManager); + + WebAppContextWrapper webAppContextWrapper = new WebAppContextWrapper(); + context.getServletContext().setAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR, webAppContextWrapper); + + DownloadArtifactLogic downloadArtifactLogic = new DownloadArtifactLogic(); + context.getServletContext().setAttribute(Constants.DOWNLOAD_ARTIFACT_LOGIC_ATTR, downloadArtifactLogic); + + context.getServletContext().setAttribute(Constants.SDC_RELEASE_VERSION_ATTR, getVersionFromManifest(context)); + + // Monitoring service + BeMonitoringService bms = new BeMonitoringService(context.getServletContext()); + bms.start(configurationManager.getConfiguration().getSystemMonitoring().getProbeIntervalInSeconds(15)); + + initUebManager(); + + log.debug("After executing {}", this.getClass()); + + } + + private void initUebManager() { + try { + if (uebManager == null) { + uebManager = UebManager.getInstance(); + uebManager.initListener(null); + } + } catch (UebException ex) { + log.debug("Failed to initialize UebManager", ex); + BeEcompErrorManager.getInstance().logInternalConnectionError("InitUebManager", "Failed to initialize listener of UebManager", ErrorSeverity.ERROR); + } + log.debug("After init listener of UebManager"); + } + + public void contextDestroyed(ServletContextEvent context) { + if (uebManager != null) { + uebManager.shutdown(); + uebManager = null; + } + super.contextDestroyed(context); + + } + + private IResourceOperation getResourceOperationManager(Class clazz, WebApplicationContext webContext) { + + return webContext.getBean(clazz); + } + + private String getVersionFromManifest(ServletContextEvent context) { + ServletContext servletContext = context.getServletContext(); + InputStream inputStream = servletContext.getResourceAsStream(MANIFEST_FILE_NAME); + + String version = null; + try { + Manifest mf = new Manifest(inputStream); + Attributes atts = mf.getMainAttributes(); + version = atts.getValue(Constants.SDC_RELEASE_VERSION_ATTR); + if (version == null || version.isEmpty()) { + log.warn("failed to read ASDC version from MANIFEST."); + } else { + log.info("ASDC version from MANIFEST is {}", version); + } + + } catch (IOException e) { + log.warn("failed to read ASDC version from MANIFEST", e.getMessage()); + } + + return version; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/monitoring/EsGateway.java b/catalog-be/src/main/java/org/openecomp/sdc/be/monitoring/EsGateway.java new file mode 100644 index 0000000000..34a56cdd13 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/monitoring/EsGateway.java @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.monitoring; + +import java.net.URI; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.client.api.Response; +import org.eclipse.jetty.proxy.ProxyServlet; +import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.common.api.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +public class EsGateway extends ProxyServlet { + + private static final long serialVersionUID = 1L; + private static Logger log = LoggerFactory.getLogger(EsGateway.class.getName()); + + @Override + public URI rewriteURI(HttpServletRequest request) { + + String originalUrl = request.getRequestURI(); + + String redirectedUrl = getModifiedUrl(request); + + log.debug("EsGateway Redirecting request from: {} , to: {}", originalUrl, redirectedUrl); + return URI.create(redirectedUrl); + } + + @Override + public void customizeProxyRequest(Request proxyRequest, HttpServletRequest request) { + super.customizeProxyRequest(proxyRequest, request); + + } + + @Override + protected void onResponseSuccess(HttpServletRequest request, HttpServletResponse response, Response proxyResponse) { + super.onResponseSuccess(request, response, proxyResponse); + } + + public String getModifiedUrl(HttpServletRequest request) { + String esHost = null; + String esPort = null; + MonitoringBusinessLogic monitoringBL = getMonitoringBL(request.getSession().getServletContext()); + if (monitoringBL == null) { + log.error("failed to retrive monitoringBL."); + } else { + esHost = monitoringBL.getEsHost(); + esPort = monitoringBL.getEsPort(); + } + + String scheme = request.getScheme(); + String contextPath = request.getContextPath(); // /mywebapp + String servletPath = request.getServletPath(); // /servlet/MyServlet + String pathInfo = request.getPathInfo(); // /a/b;c=123 + String queryString = request.getQueryString(); // d=789 + + StringBuilder url = new StringBuilder(); + url.append(scheme).append("://").append(esHost); + url.append(":").append(esPort); + url.append(contextPath).append(servletPath); + + if (pathInfo != null) { + url.append(pathInfo); + } + if (queryString != null) { + url.append("?").append(queryString); + } + + String redirectedUrl = url.toString().replace("/sdc2/esGateway/", "/"); + return redirectedUrl; + + } + + protected MonitoringBusinessLogic getMonitoringBL(ServletContext context) { + + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + MonitoringBusinessLogic monitoringBusinessLogic = webApplicationContext.getBean(MonitoringBusinessLogic.class); + + return monitoringBusinessLogic; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java new file mode 100644 index 0000000000..0e8addf692 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AbstractValidationsServlet.java @@ -0,0 +1,843 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.EnumMap; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.Supplier; +import java.util.zip.ZipInputStream; + +import javax.annotation.Resource; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Response; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.CsarValidationUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils.ResultStatusEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaElementTypeEnum; +import org.openecomp.sdc.be.components.impl.ImportUtils.ToscaTagNamesEnum; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.ServletUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; +import org.openecomp.sdc.be.user.IUserBusinessLogic; +import org.openecomp.sdc.be.user.Role; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.UploadArtifactInfo; +import org.openecomp.sdc.common.datastructure.AuditingFieldsKeysEnum; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.YamlToObjectConverter; +import org.openecomp.sdc.common.util.ZipUtil; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.context.WebApplicationContext; +import org.yaml.snakeyaml.Yaml; + +import com.google.gson.Gson; +import com.google.gson.JsonSyntaxException; + +import fj.data.Either; + +public abstract class AbstractValidationsServlet extends BeGenericServlet { + + @Resource + private ServletUtils servletUtils; + + @Resource + private ResourceImportManager resourceImportManager; + + @Autowired + protected ComponentsUtils componentsUtils; + + private static final Object LOCK = new Object(); + private Logger log = null; + + protected void init(Logger log) { + initLog(log); + initSpringFromContext(); + + } + + private void initLog(Logger log) { + if (this.log == null) { + synchronized (LOCK) { + if (this.log == null) { + this.log = log; + } + + } + } + } + + private void initSpringFromContext() { + if (servletUtils == null) { + synchronized (LOCK) { + if (servletUtils == null) { + ServletContext context = servletRequest.getSession().getServletContext(); + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + servletUtils = webApplicationContext.getBean(ServletUtils.class); + resourceImportManager = webApplicationContext.getBean(ResourceImportManager.class); + } + } + } + } + + protected void validateResourceDoesNotExist(Wrapper responseWrapper, User user, String resourceName) { + if (resourceImportManager.isResourceExist(resourceName)) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESOURCE_ALREADY_EXISTS); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceName); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + } + + protected void validateUserExist(Wrapper responseWrapper, Wrapper userWrapper, String userId) { + log.debug("get user {} from DB", userId); + // get user details + if (userId == null) { + log.info("user userId is null"); + Response response = returnMissingInformation(new User()); + responseWrapper.setInnerElement(response); + } + + else { + IUserBusinessLogic userAdmin = getServletUtils().getUserAdmin(); + Either eitherCreator = userAdmin.getUser(userId, false); + if (eitherCreator.isRight()) { + log.info("user is not listed. userId={}", userId); + User user = new User(); + user.setUserId(userId); + Response response = returnMissingInformation(user); + responseWrapper.setInnerElement(response); + } else { + userWrapper.setInnerElement(eitherCreator.left().value()); + } + } + } + + protected Response returnMissingInformation(User user) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + return buildErrorResponse(responseFormat); + } + + protected void validateDataNotNull(Wrapper responseWrapper, Object... dataParams) { + for (Object dataElement : dataParams) { + if (dataElement == null) { + log.info("Invalid body was received."); + Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(response); + break; + } + } + + } + + protected void validateUserRole(Wrapper errorResponseWrapper, User user) { + log.debug("validate user role"); + if (!user.getRole().equals(Role.ADMIN.name()) && !user.getRole().equals(Role.DESIGNER.name())) { + log.info("user is not in appropriate role to perform action"); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("audit before sending response"); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + + Response response = buildErrorResponse(responseFormat); + errorResponseWrapper.setInnerElement(response); + } + + } + + protected void validateZip(Wrapper responseWrapper, File file, String payloadName) throws FileNotFoundException { + InputStream fileInputStream = new FileInputStream(file); + Map unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream)); + if (payloadName == null || payloadName.isEmpty() || !unzippedFolder.containsKey(payloadName)) { + log.info("Invalid json was received. payloadName should be yml file name"); + Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void fillZipContents(Wrapper yamlStringWrapper, File file) throws FileNotFoundException { + InputStream fileInputStream = new FileInputStream(file); + Map unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream)); + String ymlName = unzippedFolder.keySet().iterator().next(); + fillToscaTemplateFromZip(yamlStringWrapper, ymlName, file); + } + + protected void fillToscaTemplateFromZip(Wrapper yamlStringWrapper, String payloadName, File file) throws FileNotFoundException { + InputStream fileInputStream = new FileInputStream(file); + Map unzippedFolder = ZipUtil.readZip(new ZipInputStream(fileInputStream)); + byte[] yamlFileInBytes = unzippedFolder.get(payloadName); + String yamlAsString = new String(yamlFileInBytes, StandardCharsets.UTF_8); + log.debug("received yaml: {}", yamlAsString); + yamlStringWrapper.setInnerElement(yamlAsString); + } + + protected void validateUserRole(Wrapper errorResponseWrapper, User user, ResourceAuthorityTypeEnum resourceAuthority) { + log.debug("validate user role"); + if (resourceAuthority == ResourceAuthorityTypeEnum.NORMATIVE_TYPE_BE) { + if (!user.getRole().equals(Role.ADMIN.name())) { + log.info("user is not in appropriate role to perform action"); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + log.debug("audit before sending response"); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + + Response response = buildErrorResponse(responseFormat); + errorResponseWrapper.setInnerElement(response); + } + } else { + validateUserRole(errorResponseWrapper, user); + } + + } + + protected void validateAndFillResourceJson(Wrapper responseWrapper, Wrapper uploadResourceInfoWrapper, User user, ResourceAuthorityTypeEnum resourceAuthorityEnum, String resourceInfo) { + boolean isValid; + try { + log.debug("The received json is {}", resourceInfo); + UploadResourceInfo resourceInfoObject = gson.fromJson(resourceInfo, UploadResourceInfo.class); + if (resourceInfoObject == null) { + isValid = false; + } else { + if (!resourceAuthorityEnum.isBackEndImport()) { + isValid = resourceInfoObject.getPayloadName() != null && !resourceInfoObject.getPayloadName().isEmpty(); + // TODO Tal only resource name is checked + } else { + isValid = true; + } + uploadResourceInfoWrapper.setInnerElement(resourceInfoObject); + } + + } catch (JsonSyntaxException e) { + isValid = false; + + } + if (!isValid) { + log.info("Invalid json was received."); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, null); + Response errorResp = buildErrorResponse(responseFormat); + responseWrapper.setInnerElement(errorResp); + } + } + + protected void validateAuthorityType(Wrapper responseWrapper, String authorityType) { + log.debug("The received authority type is {}", authorityType); + ResourceAuthorityTypeEnum authorityTypeEnum = ResourceAuthorityTypeEnum.findByUrlPath(authorityType); + if (authorityTypeEnum == null) { + log.info("Invalid authority type was received."); + Response errorResp = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + responseWrapper.setInnerElement(errorResp); + } + } + + public ServletUtils getServletUtils() { + initSpringFromContext(); + return servletUtils; + } + + public Gson getGson() { + return getServletUtils().getGson(); + } + + public ComponentsUtils getComponentsUtils() { + return getServletUtils().getComponentsUtils(); + } + + protected void validatePayloadIsTosca(Wrapper responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) { + log.debug("checking payload is valid tosca"); + boolean isValid; + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION); + + if (findFirstToscaStringElement.isRight()) { + isValid = false; + } else { + String defenitionVersionFound = findFirstToscaStringElement.left().value(); + if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) { + isValid = false; + } else { + isValid = ImportUtils.Constants.TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound); + } + } + + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void validatePayloadIsYml(Wrapper responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaTamplatePayload) { + log.debug("checking tosca template is valid yml"); + YamlToObjectConverter yamlConvertor = new YamlToObjectConverter(); + boolean isYamlValid = yamlConvertor.isValidYaml(toscaTamplatePayload.getBytes()); + if (!isYamlValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + } + + protected void validatePayloadNameSpace(Wrapper responseWrapper, UploadResourceInfo resourceInfo, User user, String toscaPayload) { + boolean isValid; + String nameSpace = ""; + + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES); + if (toscaElement.isRight() || toscaElement.left().value().size() != 1) { + isValid = false; + } else { + nameSpace = toscaElement.left().value().keySet().iterator().next(); + isValid = nameSpace.startsWith(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX); + } + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_NAMESPACE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } else { + String str1 = nameSpace.substring(Constants.USER_DEFINED_RESOURCE_NAMESPACE_PREFIX.length()); + String[] findTypes = str1.split("\\."); + if (ResourceTypeEnum.contains(findTypes[0].toUpperCase())) { + String type = findTypes[0].toUpperCase(); + resourceInfo.setResourceType(type); + } else { + resourceInfo.setResourceType(ResourceTypeEnum.VFC.name()); + } + } + + } + + protected void validatePayloadIsSingleResource(Wrapper responseWrapper, UploadResourceInfo uploadResourceInfo, User user, String toscaPayload) { + log.debug("checking payload contains single resource"); + boolean isValid; + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either, ResultStatusEnum> toscaElement = ImportUtils.findFirstToscaMapElement(mappedToscaTemplate, ToscaTagNamesEnum.NODE_TYPES); + if (toscaElement.isRight()) { + isValid = false; + } else { + isValid = toscaElement.left().value().size() == 1; + } + + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_SINGLE_RESOURCE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void validatePayloadIsNotService(Wrapper responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) { + log.debug("checking payload is not a tosca service"); + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL); + + if (toscaElement.isLeft()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_RESOURCE_TOSCA_TEMPLATE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void validatePayloadIsTopologyTemplate(Wrapper responseWrapper, User user, UploadResourceInfo uploadResourceInfo, String toscaPayload) { + log.debug("checking payload is a tosca topology template"); + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either toscaElement = ImportUtils.findToscaElement(mappedToscaTemplate, ToscaTagNamesEnum.TOPOLOGY_TEMPLATE, ToscaElementTypeEnum.ALL); + + if (toscaElement.isRight()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NOT_TOPOLOGY_TOSCA_TEMPLATE); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void validateToscaTemplatePayloadName(Wrapper responseWrapper, UploadResourceInfo uploadResourceInfo, User user) { + String toscaTemplatePayloadName = uploadResourceInfo.getPayloadName(); + boolean isValidSuffix = false; + if (toscaTemplatePayloadName != null && !toscaTemplatePayloadName.isEmpty()) { + for (String validSuffix : ImportUtils.Constants.TOSCA_YML_CSAR_VALID_SUFFIX) { + isValidSuffix = isValidSuffix || toscaTemplatePayloadName.toLowerCase().endsWith(validSuffix); + } + } + if (!isValidSuffix) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_FILE_EXTENSION); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + + } + + protected void validateMD5(Wrapper responseWrapper, User user, UploadResourceInfo resourceInfo, HttpServletRequest request, String resourceInfoJsonString) { + boolean isValid; + String recievedMD5 = request.getHeader(Constants.MD5_HEADER); + if (recievedMD5 == null) { + isValid = false; + } else { + String calculateMD5 = GeneralUtility.calculateMD5ByString(resourceInfoJsonString); + isValid = calculateMD5.equals(recievedMD5); + } + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_CHECKSUM); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + } + + protected void validateComponentType(Wrapper responseWrapper, Wrapper componentWrapper, String componentType) { + boolean isValid; + if (componentType == null) { + isValid = false; + } else { + if (ComponentTypeEnum.RESOURCE_PARAM_NAME.equalsIgnoreCase(componentType)) { + isValid = true; + componentWrapper.setInnerElement(ComponentTypeEnum.RESOURCE); + } else if (ComponentTypeEnum.SERVICE_PARAM_NAME.equalsIgnoreCase(componentType)) { + isValid = true; + componentWrapper.setInnerElement(ComponentTypeEnum.SERVICE); + } else { + isValid = false; + } + } + if (!isValid) { + log.debug("Invalid componentType:{}", componentType); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + Response errorResp = buildErrorResponse(responseFormat); + responseWrapper.setInnerElement(errorResp); + } + } + + protected void fillToscaTemplateFromJson(Wrapper responseWrapper, Wrapper yamlStringWrapper, User user, UploadResourceInfo resourceInfo) { + if (resourceInfo.getPayloadData() == null || resourceInfo.getPayloadData().isEmpty()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_RESOURCE_PAYLOAD); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } else { + String toscaPayload = resourceInfo.getPayloadData(); + String decodedPayload = (GeneralUtility.isBase64Encoded(toscaPayload)) ? new String(Base64.decodeBase64(toscaPayload)) : toscaPayload; + yamlStringWrapper.setInnerElement(decodedPayload); + } + + } + + protected void fillPayload(Wrapper responseWrapper, Wrapper uploadResourceInfoWrapper, Wrapper yamlStringWrapper, User user, String resourceInfoJsonString, ResourceAuthorityTypeEnum resourceAuthorityEnum, + File file) throws FileNotFoundException { + + if (responseWrapper.isEmpty()) { + if (resourceAuthorityEnum.isBackEndImport()) { + // PrePayload Validations + if (responseWrapper.isEmpty()) { + validateDataNotNull(responseWrapper, file, resourceInfoJsonString); + } + if (responseWrapper.isEmpty()) { + validateZip(responseWrapper, file, uploadResourceInfoWrapper.getInnerElement().getPayloadName()); + } + + // Fill PayLoad From File + if (responseWrapper.isEmpty()) { + fillToscaTemplateFromZip(yamlStringWrapper, uploadResourceInfoWrapper.getInnerElement().getPayloadName(), file); + } + + } else { + // Fill PayLoad From JSON + if (responseWrapper.isEmpty()) { + fillToscaTemplateFromJson(responseWrapper, yamlStringWrapper, user, uploadResourceInfoWrapper.getInnerElement()); + } + } + + } + + } + + protected void specificResourceAuthorityValidations(Wrapper responseWrapper, Wrapper uploadResourceInfoWrapper, Wrapper yamlStringWrapper, User user, HttpServletRequest request, String resourceInfoJsonString, + ResourceAuthorityTypeEnum resourceAuthorityEnum) throws FileNotFoundException { + + if (responseWrapper.isEmpty()) { + // UI Only Validation + if (!resourceAuthorityEnum.isBackEndImport()) { + importUIValidations(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, request, resourceInfoJsonString); + } + + // User Defined Type Resources + if (resourceAuthorityEnum.isUserTypeResource() && !CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { + if (responseWrapper.isEmpty()) { + validatePayloadNameSpace(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), user, yamlStringWrapper.getInnerElement()); + } + + } + } + } + + protected void commonGeneralValidations(Wrapper responseWrapper, Wrapper userWrapper, Wrapper uploadResourceInfoWrapper, ResourceAuthorityTypeEnum resourceAuthorityEnum, String userId, + String resourceInfoJsonString) { + + if (responseWrapper.isEmpty()) { + validateUserExist(responseWrapper, userWrapper, userId); + } + + if (responseWrapper.isEmpty()) { + validateUserRole(responseWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum); + } + + if (responseWrapper.isEmpty()) { + validateAndFillResourceJson(responseWrapper, uploadResourceInfoWrapper, userWrapper.getInnerElement(), resourceAuthorityEnum, resourceInfoJsonString); + } + + if (responseWrapper.isEmpty()) { + validateToscaTemplatePayloadName(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validateResourceType(responseWrapper, uploadResourceInfoWrapper.getInnerElement(), userWrapper.getInnerElement()); + } + + } + + private void validateResourceType(Wrapper responseWrapper, UploadResourceInfo uploadResourceInfo, User user) { + String resourceType = uploadResourceInfo.getResourceType(); + if (resourceType == null || !ResourceTypeEnum.contains(resourceType)) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + Response errorResponse = buildErrorResponse(responseFormat); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, uploadResourceInfo.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + responseWrapper.setInnerElement(errorResponse); + } + } + + protected void importUIValidations(Wrapper responseWrapper, UploadResourceInfo resourceInfo, User user, HttpServletRequest request, String resourceInfoJsonString) { + if (responseWrapper.isEmpty()) { + validateMD5(responseWrapper, user, resourceInfo, request, resourceInfoJsonString); + } + if (responseWrapper.isEmpty() && request != null && request.getMethod() != null && request.getMethod().equals("POST")) { + validateResourceDoesNotExist(responseWrapper, user, resourceInfo.getName()); + } + } + + protected void commonPayloadValidations(Wrapper responseWrapper, Wrapper yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) { + + if (responseWrapper.isEmpty()) { + validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validatePayloadIsNotService(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validatePayloadIsSingleResource(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement()); + } + } + + protected void topologyTemplatePayloadValidations(Wrapper responseWrapper, Wrapper yamlStringWrapper, User user, UploadResourceInfo uploadResourceInfo) { + + if (responseWrapper.isEmpty()) { + validatePayloadIsYml(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validatePayloadIsTosca(responseWrapper, uploadResourceInfo, user, yamlStringWrapper.getInnerElement()); + } + if (responseWrapper.isEmpty()) { + validatePayloadIsTopologyTemplate(responseWrapper, user, uploadResourceInfo, yamlStringWrapper.getInnerElement()); + } + + } + + protected void handleImport(Wrapper responseWrapper, User user, UploadResourceInfo resourceInfoObject, String yamlAsString, ResourceAuthorityTypeEnum authority, boolean createNewVersion, String resourceUniqueId) { + Either, ResponseFormat> createOrUpdateResponse = null; + Response response = null; + Object representation = null; + + if (CsarValidationUtils.isCsarPayloadName(resourceInfoObject.getPayloadName())) { + log.debug("import resource from csar"); + createOrUpdateResponse = importResourceFromUICsar(resourceInfoObject, user, resourceUniqueId); + } else if (!authority.isUserTypeResource()) { + log.debug("import normative type resource"); + createOrUpdateResponse = resourceImportManager.importNormativeResource(yamlAsString, resourceInfoObject, user, createNewVersion, true); + } else { + log.debug("import user resource (not normative type)"); + createOrUpdateResponse = resourceImportManager.importUserDefinedResource(yamlAsString, resourceInfoObject, user, false, false); + } + if (createOrUpdateResponse.isRight()) { + response = buildErrorResponse(createOrUpdateResponse.right().value()); + } else { + try { + representation = RepresentationUtils.toRepresentation(createOrUpdateResponse.left().value().getLeft()); + } catch (IOException e) { + e.printStackTrace(); + } + ActionStatus successStatus = createOrUpdateResponse.left().value().right; + response = buildOkResponse(getComponentsUtils().getResponseFormat(successStatus), representation); + } + responseWrapper.setInnerElement(response); + } + + private Either, ResponseFormat> importResourceFromUICsar(UploadResourceInfo resourceInfoObject, User user, String resourceUniqueId) { + + Either createOrUpdateResourceRes = null; + ImmutablePair result = null; + ActionStatus actionStatus = null; + org.openecomp.sdc.be.model.Resource resource = new org.openecomp.sdc.be.model.Resource(); + String payloadName = resourceInfoObject.getPayloadName(); + fillResourceFromResourceInfoObject(resource, resourceInfoObject); + + Either, ResponseFormat> csarUIPayloadRes = getScarFromPayload(resourceInfoObject); + if (csarUIPayloadRes.isRight()) { + return Either.right(csarUIPayloadRes.right().value()); + } + Map csarUIPayload = csarUIPayloadRes.left().value(); + + createOrUpdateResourceRes = getAndValidateCsarYaml(csarUIPayload, resource, user, payloadName); + if (createOrUpdateResourceRes.isRight()) { + return Either.right(createOrUpdateResourceRes.right().value()); + } + if (resourceUniqueId == null || resourceUniqueId.isEmpty()) { + createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().createResource(resource, user, csarUIPayload, payloadName); + if (createOrUpdateResourceRes.isRight()) { + return Either.right(createOrUpdateResourceRes.right().value()); + } + actionStatus = ActionStatus.CREATED; + } else { + createOrUpdateResourceRes = resourceImportManager.getResourceBusinessLogic().validateAndUpdateResourceFromCsar(resource, user, csarUIPayload, payloadName, resourceUniqueId); + if (createOrUpdateResourceRes.isRight()) { + return Either.right(createOrUpdateResourceRes.right().value()); + } + actionStatus = ActionStatus.OK; + } + result = new ImmutablePair(createOrUpdateResourceRes.left().value(), actionStatus); + return Either.left(result); + } + + private Either getAndValidateCsarYaml(Map csarUIPayload, org.openecomp.sdc.be.model.Resource resource, User user, String csarUUID) { + + Either, ResponseFormat> getToscaYamlRes = CsarValidationUtils.getToscaYaml(csarUIPayload, csarUUID, getComponentsUtils()); + + if (getToscaYamlRes.isRight()) { + ResponseFormat responseFormat = getToscaYamlRes.right().value(); + log.debug("Error when try to get csar toscayamlFile with csar ID {}, error: {}", csarUUID, responseFormat); + BeEcompErrorManager.getInstance().logBeDaoSystemError("Creating resource from CSAR: fetching CSAR with id " + csarUUID + " failed"); + getComponentsUtils().auditResource(responseFormat, user, resource, "", "", AuditingActionEnum.CREATE_RESOURCE, null); + return Either.right(responseFormat); + } + String toscaYaml = getToscaYamlRes.left().value().getValue(); + + log.debug("checking tosca template is valid yml"); + YamlToObjectConverter yamlConvertor = new YamlToObjectConverter(); + boolean isValid = yamlConvertor.isValidYaml(toscaYaml.getBytes()); + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_YAML_FILE); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + return Either.right(responseFormat); + } + + log.debug("checking payload is valid tosca"); + String heatDecodedPayload = (GeneralUtility.isBase64Encoded(toscaYaml)) ? new String(Base64.decodeBase64(toscaYaml)) : toscaYaml; + Map mappedToscaTemplate = (Map) new Yaml().load(heatDecodedPayload); + Either findFirstToscaStringElement = ImportUtils.findFirstToscaStringElement(mappedToscaTemplate, ToscaTagNamesEnum.TOSCA_VERSION); + + if (findFirstToscaStringElement.isRight()) { + isValid = false; + } else { + String defenitionVersionFound = findFirstToscaStringElement.left().value(); + if (defenitionVersionFound == null || defenitionVersionFound.isEmpty()) { + isValid = false; + } else { + isValid = ImportUtils.Constants.TOSCA_DEFINITION_VERSIONS.contains(defenitionVersionFound); + } + } + + if (!isValid) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_TOSCA_TEMPLATE); + EnumMap additionalParam = new EnumMap(AuditingFieldsKeysEnum.class); + additionalParam.put(AuditingFieldsKeysEnum.AUDIT_RESOURCE_NAME, resource.getName()); + getComponentsUtils().auditResource(responseFormat, user, null, "", "", AuditingActionEnum.IMPORT_RESOURCE, additionalParam); + return Either.right(responseFormat); + } + return Either.left(resource); + } + + private void fillResourceFromResourceInfoObject(org.openecomp.sdc.be.model.Resource resource, UploadResourceInfo resourceInfoObject) { + if (resource != null && resourceInfoObject != null) { + resource.setDescription(resourceInfoObject.getDescription()); + resource.setTags(resourceInfoObject.getTags()); + resource.setCategories(resourceInfoObject.getCategories()); + resource.setContactId(resourceInfoObject.getContactId()); + resource.setName(resourceInfoObject.getName()); + resource.setIcon(resourceInfoObject.getResourceIconPath()); + resource.setVendorName(resourceInfoObject.getVendorName()); + resource.setVendorRelease(resourceInfoObject.getVendorRelease()); + resource.setResourceType(ResourceTypeEnum.valueOf(resourceInfoObject.getResourceType())); + List artifactList = resourceInfoObject.getArtifactList(); + if (artifactList != null) { + Map artifactsHM = new HashMap(); + for (UploadArtifactInfo artifact : artifactList) { + ArtifactDefinition artifactDef = new ArtifactDefinition(); + artifactDef.setArtifactName(artifact.getArtifactName()); + artifactDef.setArtifactType(artifact.getArtifactType().getType()); + artifactDef.setDescription(artifact.getArtifactDescription()); + artifactDef.setPayloadData(artifact.getArtifactData()); + artifactDef.setArtifactRef(artifact.getArtifactPath()); + artifactsHM.put(artifactDef.getArtifactName(), artifactDef); + } + resource.setArtifacts(artifactsHM); + } + } + + } + + private Either, ResponseFormat> getScarFromPayload(UploadResourceInfo innerElement) { + String csarUUID = innerElement.getPayloadName(); + String payloadData = innerElement.getPayloadData(); + if (payloadData == null) { + log.info("Failed to decode received csar", csarUUID); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID)); + } + + byte[] decodedPayload = (GeneralUtility.isBase64Encoded(payloadData)) ? Base64.decodeBase64(payloadData.getBytes(StandardCharsets.UTF_8)) : payloadData.getBytes(StandardCharsets.UTF_8); + if (decodedPayload == null) { + log.info("Failed to decode received csar", csarUUID); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_NOT_FOUND, csarUUID)); + } + + Map csar = ZipUtil.readZip(decodedPayload); + if (csar == null) { + log.info("Failed to unzip received csar", csarUUID); + return Either.right(componentsUtils.getResponseFormat(ActionStatus.CSAR_INVALID, csarUUID)); + } + return Either.left(csar); + } + + protected void validateInputStream(final HttpServletRequest request, Wrapper dataWrapper, Wrapper errorWrapper) throws IOException { + InputStream inputStream = request.getInputStream(); + byte[] bytes = IOUtils.toByteArray(inputStream); + if (bytes == null || bytes.length == 0) { + log.info("Empty body was sent."); + errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } else { + dataWrapper.setInnerElement(new String(bytes, StandardCharsets.UTF_8)); + } + + } + + protected void validateClassParse(String data, Wrapper parsedClassWrapper, Supplier> classGen, Wrapper errorWrapper) { + try { + T parsedClass = gson.fromJson(data, classGen.get()); + if (parsedClass == null) { + errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } else { + parsedClassWrapper.setInnerElement(parsedClass); + } + } catch (JsonSyntaxException e) { + log.debug("Failed to decode received {} {} to object.", classGen.get().getName(), data, e); + errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + } + + protected void validateComponentInstanceBusinessLogic(HttpServletRequest request, String containerComponentType, Wrapper blWrapper, Wrapper errorWrapper) { + ServletContext context = request.getSession().getServletContext(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + errorWrapper.setInnerElement(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } else { + blWrapper.setInnerElement(componentInstanceLogic); + } + } + + protected Response buildResponseFromElement(Wrapper errorWrapper, Wrapper attributeWrapper) throws IOException { + Response response; + if (errorWrapper.isEmpty()) { + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(attributeWrapper.getInnerElement()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } else { + response = buildErrorResponse(errorWrapper.getInnerElement()); + } + return response; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java new file mode 100644 index 0000000000..aaf8f96dca --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AdditionalInformationServlet.java @@ -0,0 +1,472 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.AdditionalInformationBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.AdditionalInfoParameterInfo; +import org.openecomp.sdc.be.model.AdditionalInformationDefinition; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Additional Information Servlet", description = "Additional Information Servlet") +@Singleton +public class AdditionalInformationServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(AdditionalInformationServlet.class.getName()); + + @POST + @Path("/resources/{resourceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "POST", notes = "Returns created Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Additional information created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response createResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return createAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userId, data); + + } + + @POST + @Path("/services/{serviceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "POST", notes = "Returns created Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Additional information created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response createServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, + @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return createAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userId, data); + + } + + @PUT + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Additional Information Label and Value", httpMethod = "PUT", notes = "Returns updated Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response updateResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId, data); + + } + + @PUT + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Additional Information Label and Value", httpMethod = "PUT", notes = "Returns updated Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response updateServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @ApiParam(value = "Additional information key value to be created", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return updateAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId, data); + + } + + @DELETE + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "DELETE", notes = "Returns deleted Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response updateResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId); + + } + + @DELETE + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Additional Information Label and Value", httpMethod = "DELETE", notes = "Returns deleted Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Additional information deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response deleteServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return deleteAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); + + } + + @GET + @Path("/resources/{resourceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Additional Information by id", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "fetched additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response getResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, labelId, request, userId); + + } + + @GET + @Path("/services/{serviceId}/additionalinfo/{labelId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Additional Information by id", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "fetched additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response getServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, + @ApiParam(value = "label id", required = true) @PathParam("labelId") final String labelId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, labelId, request, userId); + + } + + @GET + @Path("/resources/{resourceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get all Additional Information under resource", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "list of additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response getAllResourceAdditionalInformationLabel(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Resource, resourceId, request, userId); + + } + + @GET + @Path("/services/{serviceId}/additionalinfo") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get all Additional Information under service", httpMethod = "GET", notes = "Returns Additional Inforamtion property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "list of additional information"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Additional information key already exist") }) + public Response getAllServiceAdditionalInformationLabel(@ApiParam(value = "service id to update with new property", required = true) @PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + return getAllAdditionalInformationLabelForComponent(NodeTypeEnum.Service, serviceId, request, userId); + + } + + /** + * + * Create additional information property under given resource/service + * + * @param nodeType + * @param uniqueId + * @param request + * @param userId + * @param data + * @return + */ + protected Response createAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId, String data) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + // convert json to AdditionalInfoParameterInfo + AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); + + // create the new property + AdditionalInformationBusinessLogic businessLogic = getBL(context); + + Either either = businessLogic.createAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, null, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to create additional information {}. REason - {}", additionalInfoParameterInfo, responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} created successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Additional Information"); + log.debug("Create additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Update additional information property by id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @param data + * @return + */ + protected Response updateAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId, String data) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + // convert json to AdditionalInfoParameterInfo + AdditionalInfoParameterInfo additionalInfoParameterInfo = gson.fromJson(data, AdditionalInfoParameterInfo.class); + + // create the new property + AdditionalInformationBusinessLogic businessLogic = getBL(context); + + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.updateAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, null, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} updated successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Additional Information"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Additional Information"); + log.debug("Update additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * + * Delete an additional information property by id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @return + */ + protected Response deleteAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + AdditionalInformationBusinessLogic businessLogic = getBL(context); + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.deleteAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, null, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} deleted successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Additional Information"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Additional Information"); + log.debug("Delete additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Get a specific additional information property by a given id under given resource/service + * + * @param nodeType + * @param uniqueId + * @param labelId + * @param request + * @param userId + * @return + */ + protected Response getAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, String labelId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + // create the new property + AdditionalInformationBusinessLogic businessLogic = getBL(context); + + AdditionalInfoParameterInfo additionalInfoParameterInfo = new AdditionalInfoParameterInfo(); + additionalInfoParameterInfo.setUniqueId(labelId); + + Either either = businessLogic.getAdditionalInformation(nodeType, uniqueId, additionalInfoParameterInfo, null, userId); + + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInfoParameterInfo createdAI = either.left().value(); + + log.debug("Additional information {}={} fetched successfully with id {}", createdAI.getKey(), createdAI.getValue(), createdAI.getUniqueId()); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, createdAI); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Additional Information"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Additional Information"); + + log.debug("get additional information failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + /** + * Get all additional information properties under given resource/service + * + * @param nodeType + * @param uniqueId + * @param request + * @param userId + * @return + */ + protected Response getAllAdditionalInformationLabelForComponent(NodeTypeEnum nodeType, String uniqueId, HttpServletRequest request, String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + AdditionalInformationBusinessLogic businessLogic = getBL(context); + + Either either = businessLogic.getAllAdditionalInformation(nodeType, uniqueId, null, userId); + if (either.isRight()) { + ResponseFormat responseFormat = either.right().value(); + log.info("Failed to update additional information property. Reason - {}", responseFormat); + return buildErrorResponse(responseFormat); + } + + AdditionalInformationDefinition additionalInformationDefinition = either.left().value(); + + log.debug("All Additional information retrieved for component {} is {}", uniqueId, additionalInformationDefinition); + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, additionalInformationDefinition); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get All Additional Information"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Additional Information"); + log.debug("Get all addiotanl information properties failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + + } + + private AdditionalInformationBusinessLogic getBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + AdditionalInformationBusinessLogic bl = webApplicationContext.getBean(AdditionalInformationBusinessLogic.class); + return bl; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java new file mode 100644 index 0000000000..b7af00a7d2 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ArtifactServlet.java @@ -0,0 +1,564 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperation; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.ArtifactUiDownloadData; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resource Artifact Servlet", description = "Resource Artifact Servlet") +@Singleton +public class ArtifactServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(ArtifactServlet.class.getName()); + + private Gson gson = new Gson(); + + // *************** Resources + @POST + @Path("/resources/{resourceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Artifact already exist") }) + public Response loadArtifact(@PathParam("resourceId") final String resourceId, @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUploadRequest(data, request, resourceId, ComponentTypeEnum.RESOURCE); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "loadArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifact"); + log.debug("loadArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Artifact", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUpdateRequest(data, request, resourceId, artifactId, ComponentTypeEnum.RESOURCE); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "updateArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifact"); + log.debug("updateArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete Artifact", httpMethod = "DELETE", notes = "Returns delete artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response deleteArtifact(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, null, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "deleteArtifact"); + log.debug("deleteArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Services + @POST + @Path("/services/{serviceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Artifact already exist") }) + public Response loadInformationArtifact(@PathParam("serviceId") final String serviceId, @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUploadRequest(data, request, serviceId, ComponentTypeEnum.SERVICE); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "loadInformationArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadInformationArtifact"); + log.debug("loadInformationArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Artifact", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Service artifact created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateInformationArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "updateInformationArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateInformationArtifact"); + log.debug("updateInformationArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Services api artifacts + @POST + @Path("/services/{serviceId}/artifacts/api/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Api Artifact", httpMethod = "POST", notes = "Returns created ArtifactDefinition", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Api Artifact Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @ApiParam(value = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleUpdateRequest(data, request, serviceId, artifactId, ComponentTypeEnum.SERVICE); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "updateApiArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateApiArtifact"); + log.debug("updateApiArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/services/{serviceId}/artifacts/api/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete Api Artifact", httpMethod = "DELETE", notes = "Returns Deleted ArtifactDefinition", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "Api Artifact deleted"), @ApiResponse(code = 403, message = "Restricted operation") }) + public Response deleteApiArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @HeaderParam(value = Constants.MD5_HEADER) String origMd5) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "deleteApiArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteApiArtifact"); + log.debug("deleteApiArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete Artifact", httpMethod = "DELETE", notes = "Returns delete artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Service artifact deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response deleteInformationalArtifact(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, serviceId, artifactId, ComponentTypeEnum.SERVICE, null, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "deleteInformationalArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteInformationalArtifact"); + log.debug("deleteInformationalArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /* + * DOWNLOAD Artifacts by json body in base 64 (because of userId problem with href) + */ + + @GET + @Path("/services/{serviceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Download service Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service artifact downloaded"), @ApiResponse(code = 404, message = "Service/Artifact not found") }) + public Response downloadServiceArtifactBase64(@PathParam("serviceId") final String serviceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, serviceId, artifactId, null, ComponentTypeEnum.SERVICE, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "downloadServiceArtifactBase64"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadServiceArtifactBase64"); + log.debug("downloadServiceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/resources/{resourceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Download resource Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource artifact downloaded"), @ApiResponse(code = 404, message = "Resource/Artifact not found") }) + public Response downloadResourceArtifactBase64(@PathParam("resourceId") final String resourceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, resourceId, artifactId, null, ComponentTypeEnum.RESOURCE, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "downloadResourceArtifactBase64"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceArtifactBase64"); + log.debug("downloadResourceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{containerComponentType}/{componentId}/resourceInstances/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Download component Artifact in Base64", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "ResourceInstance artifact downloaded"), @ApiResponse(code = 404, message = "ResourceInstance/Artifact not found") }) + public Response downloadResourceInstanceArtifactBase64( + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDownloadRequest(request, componentInstanceId, artifactId, componentId, ComponentTypeEnum.RESOURCE_INSTANCE, containerComponentType); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "downloadResourceInstanceArtifactBase64"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("downloadResourceInstanceArtifactBase64"); + log.debug("downloadResourceInstanceArtifactBase64 unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // *************** Resource lifecycle ( interfces ) + + @POST + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Artifact and Attach to interface", httpMethod = "POST", notes = "Returns created resource", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Artifact already exist") }) + public Response loadArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @ApiParam(value = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, resourceId, interfaceType, operation, null, ComponentTypeEnum.RESOURCE, ArtifactOperation.Create, null, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "loadArtifactToInterface"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("loadArtifactToInterface"); + log.debug("loadArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "delete Artifact from interface", httpMethod = "delete", notes = "delete matching artifact from interface", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "delete artifact under interface deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Artifact already exist") }) + public Response deleteArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, @PathParam("artifactId") final String artifactId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleDeleteRequest(request, resourceId, artifactId, ComponentTypeEnum.RESOURCE, interfaceType, operation); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "deleteArtifactToInterface"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("deleteArtifactToInterface"); + log.debug("deleteArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/resources/{resourceId}/{interfaceType}/{operation}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "update Artifact Attach to interface", httpMethod = "post", notes = "updates artifact by interface", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "delete artifact under interface deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Artifact already exist") }) + public Response updateArtifactToInterface(@PathParam("resourceId") final String resourceId, @PathParam("interfaceType") final String interfaceType, @PathParam("operation") final String operation, @PathParam("artifactId") final String artifactId, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, @Context final HttpServletRequest request, + @ApiParam(value = "json describe the artifact", required = true) String data) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, resourceId, interfaceType, operation, artifactId, ComponentTypeEnum.RESOURCE, ArtifactOperation.Update, null, null); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "updateArtifactToInterface"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateArtifactToInterface"); + log.debug("updateArtifactToInterface unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}/heatParams") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Instance HEAT_ENV parameters", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateRIArtifact( + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, + @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperation.Update, componentId, containerComponentType); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "updateRIArtifact"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("updateRIArtifact"); + log.debug("updateRIArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Instance artifact payload", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, + @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperation.Update, componentId, containerComponentType); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "loadResourceInstanceHeatEnvArtifact"); + log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Load Resource Instance artifact payload", httpMethod = "POST", notes = "Returns updated artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response loadComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "json describe the artifact", required = true) String data, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + return handleArtifactRequest(data, request, componentInstanceId, null, null, null, ComponentTypeEnum.RESOURCE_INSTANCE, ArtifactOperation.Create, componentId, containerComponentType); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "loadResourceInstanceHeatEnvArtifact"); + log.debug("loadResourceInstanceHeatEnvArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/artifacts/{artifactId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete Resource Instance artifact", httpMethod = "POST", notes = "Returns deleted artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response deleteComponentInstanceArtifact(@HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam(value = Constants.MD5_HEADER) String origMd5, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, @PathParam("artifactId") final String artifactId, + @ApiParam(value = "json describe the artifact", required = true) String data, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(containerComponentType); + return handleDeleteRequest(request, componentInstanceId, artifactId, ComponentTypeEnum.RESOURCE_INSTANCE, null, null, componentId); + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "deleteArtifact"); + log.debug("deleteArtifact unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + // ////////// API END /////////////////////////// + + // ************ private ********************* + + private Response handleUploadRequest(String data, HttpServletRequest request, String componentId, ComponentTypeEnum componentType) { + return handleArtifactRequest(data, request, componentId, null, componentType, ArtifactOperation.Create); + } + + private Response handleUpdateRequest(String data, HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType) { + return handleArtifactRequest(data, request, componentId, artifactId, componentType, ArtifactOperation.Update); + } + + private Response handleDownloadRequest(HttpServletRequest request, String componentId, String artifactId, String parentId, ComponentTypeEnum componentType, String containerComponentType) { + String userId = request.getHeader(Constants.USER_ID_HEADER); + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either, ResponseFormat> actionResult = artifactsLogic.handleDownloadRequestById(componentId, artifactId, userId, componentType, parentId, containerComponentType); + + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + byte[] file = actionResult.left().value().getRight(); + String base64Contents = new String(Base64.encodeBase64(file)); + String artifactName = actionResult.left().value().getLeft(); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + ArtifactUiDownloadData artifactUiDownloadData = new ArtifactUiDownloadData(); + artifactUiDownloadData.setArtifactName(artifactName); + artifactUiDownloadData.setBase64Contents(base64Contents); + response = buildOkResponse(responseFormat, artifactUiDownloadData); + } + return response; + } + + private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName) { + return handleDeleteRequest(request, componentId, artifactId, componentType, interfaceType, operationName, null); + } + + private Response handleDeleteRequest(HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, String interfaceType, String operationName, String parentId) { + String userId = request.getHeader(Constants.USER_ID_HEADER); + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either, ResponseFormat> actionResult = artifactsLogic.handleArtifactRequest(componentId, userId, componentType, ArtifactOperation.Delete, artifactId, null, null, null, interfaceType, operationName, + parentId, null); + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + Either result = actionResult.left().value(); + if (result.isLeft()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); + } + } + return response; + + } + + private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String interfaceName, String operationName, String artifactId, ComponentTypeEnum componentType, ArtifactOperation operation, String parentId, + String containerComponentType) { + ArtifactDefinition artifactInfo = RepresentationUtils.convertJsonToArtifactDefinition(data, ArtifactDefinition.class); + String origMd5 = request.getHeader(Constants.MD5_HEADER); + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ServletContext context = request.getSession().getServletContext(); + ArtifactsBusinessLogic artifactsLogic = getArtifactBL(context); + Either, ResponseFormat> actionResult = artifactsLogic.handleArtifactRequest(componentId, userId, componentType, operation, artifactId, artifactInfo, origMd5, data, interfaceName, operationName, parentId, + containerComponentType); + Response response; + if (actionResult.isRight()) { + response = buildErrorResponse(actionResult.right().value()); + } else { + Either result = actionResult.left().value(); + if (result.isLeft()) { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.left().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result.right().value()); + } + } + return response; + + } + + private Response handleArtifactRequest(String data, HttpServletRequest request, String componentId, String artifactId, ComponentTypeEnum componentType, ArtifactOperation operation) { + return handleArtifactRequest(data, servletRequest, componentId, null, null, artifactId, componentType, operation, null, null); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java new file mode 100644 index 0000000000..b5e64ae00e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/AttributeServlet.java @@ -0,0 +1,278 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.AttributeBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.AttributeDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * Web Servlet for actions on Attributes + * + * @author mshitrit + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resource Attribute Servlet", description = "Resource Attribute Servlet") +@Singleton +public class AttributeServlet extends AbstractValidationsServlet { + private static Logger log = LoggerFactory.getLogger(AttributeServlet.class.getName()); + + /** + * Creates new Attribute on a resource with given resource ID + * + * @param resourceId + * @param data + * @param request + * @param userId + * @return + */ + @POST + @Path("resources/{resourceId}/attributes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource Attribute", httpMethod = "POST", notes = "Returns created resource attribute", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Resource attribute already exist") }) + public Response createAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource attribute to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + Wrapper errorWrapper = new Wrapper<>(); + Wrapper attributesWrapper = new Wrapper<>(); + // convert json to AttributeDefinition + + buildAttributeFromString(data, attributesWrapper, errorWrapper); + if (errorWrapper.isEmpty()) { + AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class); + Either createAttribute = businessLogic.createAttribute(resourceId, attributesWrapper.getInnerElement(), userId); + if (createAttribute.isRight()) { + errorWrapper.setInnerElement(createAttribute.right().value()); + } else { + attributesWrapper.setInnerElement(createAttribute.left().value()); + } + } + + Response response; + if (!errorWrapper.isEmpty()) { + log.info("Failed to create Attribute. Reason - ", errorWrapper.getInnerElement()); + response = buildErrorResponse(errorWrapper.getInnerElement()); + } else { + AttributeDefinition createdAttDef = attributesWrapper.getInnerElement(); + log.debug("Attribute {} created successfully with id {}", createdAttDef.getName(), createdAttDef.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(createdAttDef)); + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Attribute"); + log.debug("create property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + /** + * Updates existing Attribute with given attributeID on a resource with given resourceID + * + * @param resourceId + * @param attributeId + * @param data + * @param request + * @param userId + * @return + */ + @PUT + @Path("resources/{resourceId}/attributes/{attributeId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Attribute", httpMethod = "PUT", notes = "Returns updated attribute", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource attribute updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateAttribute(@ApiParam(value = "resource id to update with new attribute", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "attribute id to update", required = true) @PathParam("attributeId") final String attributeId, @ApiParam(value = "Resource attribute to update", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + try { + // convert json to PropertyDefinition + Wrapper errorWrapper = new Wrapper<>(); + Wrapper attributesWrapper = new Wrapper<>(); + // convert json to AttributeDefinition + + buildAttributeFromString(data, attributesWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class); + Either eitherUpdateAttribute = businessLogic.updateAttribute(resourceId, attributeId, attributesWrapper.getInnerElement(), userId); + // update property + if (eitherUpdateAttribute.isRight()) { + errorWrapper.setInnerElement(eitherUpdateAttribute.right().value()); + } else { + attributesWrapper.setInnerElement(eitherUpdateAttribute.left().value()); + } + } + + Response response; + if (!errorWrapper.isEmpty()) { + log.info("Failed to update Attribute. Reason - ", errorWrapper.getInnerElement()); + response = buildErrorResponse(errorWrapper.getInnerElement()); + } else { + AttributeDefinition updatedAttribute = attributesWrapper.getInnerElement(); + log.debug("Attribute id {} updated successfully ", updatedAttribute.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(updatedAttribute)); + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Attribute"); + log.debug("update attribute failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + /** + * Deletes existing Attribute with given attributeID on a resource with given resourceID + * + * @param resourceId + * @param attributeId + * @param request + * @param userId + * @return + */ + @DELETE + @Path("resources/{resourceId}/attributes/{attributeId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource Attribute", httpMethod = "DELETE", notes = "Returns deleted attribute", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted attribute"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 404, message = "Resource property not found") }) + public Response deleteAttribute(@ApiParam(value = "resource id of attribute", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "Attribute id to delete", required = true) @PathParam("attributeId") final String attributeId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + // delete the property + AttributeBusinessLogic businessLogic = getBusinessLogic(context, () -> AttributeBusinessLogic.class); + Either eitherAttribute = businessLogic.deleteAttribute(resourceId, attributeId, userId); + if (eitherAttribute.isRight()) { + log.debug("Failed to delete Attribute. Reason - ", eitherAttribute.right().value()); + return buildErrorResponse(eitherAttribute.right().value()); + } + AttributeDefinition attributeDefinition = eitherAttribute.left().value(); + String name = attributeDefinition.getName(); + + log.debug("Attribute {} deleted successfully with id {}", name, attributeDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, RepresentationUtils.toRepresentation(attributeDefinition)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Attribute"); + log.debug("delete attribute failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + private void buildAttributeFromString(String data, Wrapper attributesWrapper, Wrapper errorWrapper) { + + try { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + final AttributeDefinition attribute = gson.fromJson(data, AttributeDefinition.class); + if (attribute == null) { + log.info("Attribute content is invalid - {}", data); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + errorWrapper.setInnerElement(responseFormat); + } else { + attributesWrapper.setInnerElement(attribute); + } + + } catch (Exception e) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + errorWrapper.setInnerElement(responseFormat); + log.debug("Attribute content is invalid - {}", data, e); + log.info("Attribute content is invalid - {}", data); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java new file mode 100644 index 0000000000..f21b57f6fb --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeGenericServlet.java @@ -0,0 +1,226 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.function.Supplier; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.ResponseBuilder; + +import org.openecomp.sdc.be.components.clean.ComponentsCleanBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; +import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; +import org.openecomp.sdc.be.components.impl.ProductComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.components.impl.VFComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.IElementDAO; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.servlets.BasicServlet; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +public class BeGenericServlet extends BasicServlet { + + @Context + protected HttpServletRequest servletRequest; + + private static Logger log = LoggerFactory.getLogger(BeGenericServlet.class.getName()); + + /******************** New error response mechanism **************/ + + protected Response buildErrorResponse(ResponseFormat requestErrorWrapper) { + Response response = Response.status(requestErrorWrapper.getStatus()).entity(gson.toJson(requestErrorWrapper.getRequestError())).build(); + return response; + } + + protected Response buildOkResponse(ResponseFormat errorResponseWrapper, Object entity) { + return buildOkResponse(errorResponseWrapper, entity, null); + } + + protected Response buildOkResponse(ResponseFormat errorResponseWrapper, Object entity, Map additionalHeaders) { + int status = errorResponseWrapper.getStatus(); + ResponseBuilder responseBuilder = Response.status(status); + if (entity != null) { + if (log.isTraceEnabled()) + log.trace("returned entity is {}", entity.toString()); + responseBuilder = responseBuilder.entity(entity); + } + if (additionalHeaders != null) { + for (Entry additionalHeader : additionalHeaders.entrySet()) { + String headerName = additionalHeader.getKey(); + String headerValue = additionalHeader.getValue(); + if (log.isTraceEnabled()) + log.trace("Adding header {} with value {} to the response", headerName, headerValue); + responseBuilder.header(headerName, headerValue); + } + } + return responseBuilder.build(); + } + + /*******************************************************************************************************/ + + protected UserBusinessLogic getUserAdminManager(ServletContext context) { + return getBusinessLogic(context, () -> UserBusinessLogic.class); + } + + protected ResourceBusinessLogic getResourceBL(ServletContext context) { + return getBusinessLogic(context, () -> ResourceBusinessLogic.class); + } + + protected ComponentsCleanBusinessLogic getComponentCleanerBL(ServletContext context) { + return getBusinessLogic(context, () -> ComponentsCleanBusinessLogic.class); + } + + protected ServiceBusinessLogic getServiceBL(ServletContext context) { + return getBusinessLogic(context, () -> ServiceBusinessLogic.class); + } + + protected ProductBusinessLogic getProductBL(ServletContext context) { + return getBusinessLogic(context, () -> ProductBusinessLogic.class); + } + + protected ArtifactsBusinessLogic getArtifactBL(ServletContext context) { + return getBusinessLogic(context, () -> ArtifactsBusinessLogic.class); + } + + protected ElementBusinessLogic getElementBL(ServletContext context) { + return getBusinessLogic(context, () -> ElementBusinessLogic.class); + } + + protected MonitoringBusinessLogic getMonitoringBL(ServletContext context) { + return getBusinessLogic(context, () -> MonitoringBusinessLogic.class); + } + + protected SomeBusinessLogic getBusinessLogic(ServletContext context, Supplier> businessLogicClassGen) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + SomeBusinessLogic monitoringBusinessLogic = webApplicationContext.getBean(businessLogicClassGen.get()); + return monitoringBusinessLogic; + } + + protected GroupBusinessLogic getGroupBL(ServletContext context) { + + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + GroupBusinessLogic groupBusinessLogic = webApplicationContext.getBean(GroupBusinessLogic.class); + return groupBusinessLogic; + } + + protected ComponentInstanceBusinessLogic getComponentInstanceBL(ServletContext context, ComponentTypeEnum containerComponentType) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + if (containerComponentType == ComponentTypeEnum.RESOURCE) { + return webApplicationContext.getBean(VFComponentInstanceBusinessLogic.class); + } + if (containerComponentType == ComponentTypeEnum.SERVICE) { + return webApplicationContext.getBean(ServiceComponentInstanceBusinessLogic.class); + } + if (containerComponentType == ComponentTypeEnum.PRODUCT) { + return webApplicationContext.getBean(ProductComponentInstanceBusinessLogic.class); + } + return null; + } + + protected IElementDAO getElementDao(Class clazz, ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + + return webApplicationContext.getBean(clazz); + } + + protected ComponentsUtils getComponentsUtils() { + ServletContext context = this.servletRequest.getSession().getServletContext(); + + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ComponentsUtils componentsUtils = webApplicationContext.getBean(ComponentsUtils.class); + return componentsUtils; + } + + /** + * Used to support Unit Test.
+ * Header Params are not supported in Unit Tests + * + * @return + */ + protected String initHeaderParam(String headerValue, HttpServletRequest request, String headerName) { + String retValue; + if (headerValue != null) { + retValue = headerValue; + } else { + retValue = request.getHeader(headerName); + } + return retValue; + } + + protected String getContentDispositionValue(String artifactFileName) { + return new StringBuilder().append("attachment; filename=\"").append(artifactFileName).append("\"").toString(); + } + + protected ComponentBusinessLogic getComponentBL(ComponentTypeEnum componentTypeEnum, ServletContext context) { + ComponentBusinessLogic businessLogic; + switch (componentTypeEnum) { + case RESOURCE: { + businessLogic = getResourceBL(context); + break; + } + case SERVICE: { + businessLogic = getServiceBL(context); + break; + } + case PRODUCT: { + businessLogic = getProductBL(context); + break; + } + case RESOURCE_INSTANCE: { + businessLogic = getResourceBL(context); + break; + } + default: { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "getComponentBL"); + BeEcompErrorManager.getInstance().logBeSystemError("getComponentBL"); + throw new IllegalArgumentException("Illegal component type:" + componentTypeEnum.getValue()); + } + } + return businessLogic; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java new file mode 100644 index 0000000000..ffcd9c68fc --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/BeMonitoringServlet.java @@ -0,0 +1,203 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.List; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.DistributionMonitoringBusinessLogic; +import org.openecomp.sdc.be.components.impl.HealthCheckBusinessLogic; +import org.openecomp.sdc.be.components.impl.MonitoringBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.api.HealthCheckInfo; +import org.openecomp.sdc.common.api.HealthCheckWrapper; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckComponent; +import org.openecomp.sdc.common.api.HealthCheckInfo.HealthCheckStatus; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.monitoring.MonitoringEvent; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.TRACE, trim = false) +@Path("/") +@Api(value = "BE Monitoring", description = "BE Monitoring") +@Singleton +public class BeMonitoringServlet extends BeGenericServlet { + + Gson prettyGson = new GsonBuilder().setPrettyPrinting().create(); + + private static Logger log = LoggerFactory.getLogger(ConfigServlet.class.getName()); + + @GET + @Path("/healthCheck") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "return aggregate BE health check of Titan, ES and BE", notes = "return BE health check", response = String.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Titan, ES and BE are all up"), @ApiResponse(code = 500, message = "One or more BE components (Titan, ES, BE) are down") }) + public Response getHealthCheck(@Context final HttpServletRequest request) { + try { + HealthCheckBusinessLogic healthCheckBusinessLogic = getHealthCheckBL(request.getSession().getServletContext()); + List beHealthCheckInfos = healthCheckBusinessLogic.getBeHealthCheckInfosStatus(); + + // List beHealthCheckInfos = + // HealthCheckBusinessLogic.getInstance().getBeHealthCheckInfos(request.getSession().getServletContext()); + ActionStatus status = getAggregateBeStatus(beHealthCheckInfos); + String sdcVersion = getVersionFromContext(request); + if (sdcVersion == null || sdcVersion.isEmpty()) { + sdcVersion = "UNKNOWN"; + } + String siteMode = healthCheckBusinessLogic.getSiteMode(); + HealthCheckWrapper healthCheck = new HealthCheckWrapper(beHealthCheckInfos, sdcVersion, siteMode); + // The response can be either with 200 or 500 aggregate status - the + // body of individual statuses is returned either way + + String healthCheckStr = prettyGson.toJson(healthCheck); + return buildOkResponse(getComponentsUtils().getResponseFormat(status), healthCheckStr); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeHealthCheckError, "BeHealthCheck"); + BeEcompErrorManager.getInstance().logBeHealthCheckError("BeHealthCheck"); + log.debug("BE health check unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/monitoring") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response processMonitoringMetrics(@Context final HttpServletRequest request, String json) { + try { + MonitoringEvent monitoringEvent = convertContentToJson(json, MonitoringEvent.class); + if (monitoringEvent == null) { + return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); + } + log.trace("Received monitoring metrics: {}", monitoringEvent.toString()); + ServletContext context = request.getSession().getServletContext(); + MonitoringBusinessLogic bl = getMonitoringBL(context); + Either result = bl.logMonitoringEvent(monitoringEvent); + if (result.isRight()) { + return buildErrorResponse(result.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + + } catch (Exception e) { + log.debug("BE system metrics unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormatAdditionalProperty(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/version") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "return the ASDC application version", notes = "return the SDC application version", response = String.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "return SDC version"), @ApiResponse(code = 500, message = "Internal Error") }) + public Response getSdcVersion(@Context final HttpServletRequest request) { + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + String version = getVersionFromContext(request); + log.debug("sdc version from manifest is: {}", version); + if (version == null || version.isEmpty()) { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.SDC_VERSION_NOT_FOUND)); + } + + HealthCheckInfo versionInfo = new HealthCheckInfo(); + versionInfo.setVersion(version); + + // The response can be either with 200 or 500 aggregate status - the + // body of individual statuses is returned either way + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), versionInfo); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "getSDCVersion"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getSDCVersion"); + log.debug("BE get SDC version unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private String getVersionFromContext(HttpServletRequest request) { + ServletContext servletContext = request.getSession().getServletContext(); + String version = (String) servletContext.getAttribute(Constants.SDC_RELEASE_VERSION_ATTR); + return version; + } + + private ActionStatus getAggregateBeStatus(List beHealthCheckInfos) { + ActionStatus status = ActionStatus.OK; + for (HealthCheckInfo healthCheckInfo : beHealthCheckInfos) { + if (healthCheckInfo.getHealthCheckStatus().equals(HealthCheckStatus.DOWN) && healthCheckInfo.getHealthCheckComponent() != HealthCheckComponent.DE) { + status = ActionStatus.GENERAL_ERROR; + break; + } + } + return status; + } + + protected MonitoringEvent convertContentToJson(String content, Class clazz) { + + MonitoringEvent object = null; + try { + object = gson.fromJson(content, clazz); + object.setFields(null); + } catch (Exception e) { + log.debug("Failed to convert the content {} to object. {}", content.substring(0, Math.min(50, content.length())), e); + } + + return object; + } + + private HealthCheckBusinessLogic getHealthCheckBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + HealthCheckBusinessLogic healthCheckBl = webApplicationContext.getBean(HealthCheckBusinessLogic.class); + return healthCheckBl; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java new file mode 100644 index 0000000000..4e6d0bcd7f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentInstanceServlet.java @@ -0,0 +1,744 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.InputStream; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.io.IOUtils; +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.components.impl.ComponentInstanceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.info.CreateAndAssotiateInfo; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceAttribute; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resource Instance Servlet", description = "Resource Instance Servlet") +@Singleton +public class ComponentInstanceServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(ComponentInstanceServlet.class.getName()); + + Type constraintType = new TypeToken() { + }.getType(); + + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create ComponentInstance", httpMethod = "POST", notes = "Returns created ComponentInstance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Component created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Component instance already exist") }) + public Response createComponentInstance(@ApiParam(value = "RI object to be created", required = true) String data, @PathParam("componentId") final String containerComponentId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of modifier user", required = true) String userId, @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + try { + + ComponentInstance componentInstance = RepresentationUtils.fromRepresentation(data, ComponentInstance.class); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either actionResponse = componentInstanceLogic.createComponentInstance(containerComponentType, containerComponentId, userId, componentInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Component Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Component Instance"); + log.debug("create component instance failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateComponentInstance(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, + @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + + log.debug("Start handle request of {}", url); + + InputStream inputStream = request.getInputStream(); + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info("Empty body was sent."); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + Either convertResponse = convertToResourceInstance(data); + + if (convertResponse.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Resource Instance - updateResourceInstance"); + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance"); + log.debug("Failed to convert received data to BE format."); + return buildErrorResponse(convertResponse.right().value()); + } + + ComponentInstance resourceInstance = convertResponse.left().value(); + Either actionResponse = componentInstanceLogic.updateComponentInstance(containerComponentType, componentId, componentInstanceId, userId, resourceInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Instance"); + log.debug("update resource instance with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + // TODO Tal New Multiple Instance API + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/multipleComponentInstance") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance multiple component", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource instance updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateMultipleComponentInstance(@PathParam("componentId") final String componentId, + @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request, @ApiParam(value = "Component Instance JSON Array", required = true) final String componentInstanceJsonArray) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + try { + log.debug("Start handle request of {}", url); + + if (componentInstanceJsonArray == null || componentInstanceJsonArray.length() == 0) { + log.info("Empty JSON list was sent."); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either, ResponseFormat> convertResponse = convertToMultipleResourceInstance(componentInstanceJsonArray); + + if (convertResponse.isRight()) { + // Using both ECOMP error methods, show to Sofer + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance"); + /* + * BeEcompErrorManager.getInstance().processEcompError( EcompErrorName.BeSystemError, "Resource Instance - updateResourceInstance"); + */ + log.debug("Failed to convert received data to BE format."); + return buildErrorResponse(convertResponse.right().value()); + } + + List componentInstanceList = convertResponse.left().value(); + + Either, ResponseFormat> actionResponse = componentInstanceLogic.updateComponentInstance(containerComponentType, componentId, userId, componentInstanceList, true, true); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + /* + * BeEcompErrorManager.getInstance().processEcompError( EcompErrorName.BeRestApiGeneralError, "Update Resource Instance" ); + */ + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Instance"); + log.debug("update resource instance with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{resourceInstanceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete ResourceInstance", httpMethod = "DELETE", notes = "Returns delete resourceInstance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "ResourceInstance deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response deleteResourceInstance(@PathParam("componentId") final String componentId, @PathParam("resourceInstanceId") final String resourceInstanceId, + @ApiParam(value = "valid values: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + Response response = null; + try { + log.debug("Start handle request of {}", url); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + String userId = request.getHeader(Constants.USER_ID_HEADER); + Either actionResponse = componentInstanceLogic.deleteComponentInstance(containerComponentType, componentId, resourceInstanceId, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + } + return response; + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource Instance"); + log.debug("delete resource instance with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/associate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Associate RI to RI", httpMethod = "POST", notes = "Returns created RelationshipInfo", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship created"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Relationship already exist") }) + public Response associateRIToRI(@ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId, + @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "RelationshipInfo", required = true) String data, @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + + try { + + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either regInfoW = convertToRequirementCapabilityRelDef(data); + + Either resultOp; + if (regInfoW.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Resource Instance - associateRIToRI"); + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - associateRIToRI"); + log.debug("Failed to convert received data to BE format."); + resultOp = Either.right(regInfoW.right().value()); + } else { + RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); + resultOp = componentInstanceLogic.associateRIToRI(componentId, userId, requirementDef, componentTypeEnum); + } + + Either actionResponse = resultOp; + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Associate Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Associate Resource Instance"); + log.debug("associate resource instance to another RI with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @PUT + @Path("/{containerComponentType}/{componentId}/resourceInstance/dissociate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Dissociate RI from RI", httpMethod = "PUT", notes = "Returns deleted RelationshipInfo", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Relationship deleted"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response dissociateRIFromRI( + @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam("containerComponentType") final String containerComponentType, + @ApiParam(value = "unique id of the container component") @PathParam("componentId") final String componentId, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "RelationshipInfo", required = true) String data, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + try { + + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either regInfoW = convertToRequirementCapabilityRelDef(data); + if (regInfoW.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Resource Instance - dissociateRIFromRI"); + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - dissociateRIFromRI"); + log.debug("Failed to convert received data to BE format."); + return buildErrorResponse(regInfoW.right().value()); + } + + RequirementCapabilityRelDef requirementDef = regInfoW.left().value(); + Either actionResponse = componentInstanceLogic.dissociateRIFromRI(componentId, userId, requirementDef, componentTypeEnum); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Dissociate Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Dissociate Resource Instance"); + log.debug("dissociate resource instance from service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/createAndAssociate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create RI and associate RI to RI", httpMethod = "POST", notes = "Returns created RI and RelationshipInfo", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "RI created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Relationship already exist") }) + public Response createAndAssociateRIToRI(@PathParam("componentId") final String componentId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + + log.debug("Start handle request of {}", url); + + InputStream inputStream = request.getInputStream(); + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info("Empty body was sent."); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either convertStatus = convertJsonToObject(data, CreateAndAssotiateInfo.class); + if (convertStatus.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Resource Instance - createAndAssociateRIToRI"); + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - createAndAssociateRIToRI"); + log.debug("Failed to convert received data to BE format."); + Either formattedResponse = Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); + return buildErrorResponse(formattedResponse.right().value()); + } + + CreateAndAssotiateInfo createAndAssotiateInfo = convertStatus.left().value(); + Either actionResponse = componentInstanceLogic.createAndAssociateRIToRI(containerComponentType, componentId, userId, createAndAssotiateInfo); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create and Associate Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create and Associate Resource Instance"); + log.debug("create and associate RI failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance property", httpMethod = "POST", notes = "Returns updated resource instance property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateResourceInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + try { + Wrapper dataWrapper = new Wrapper<>(); + Wrapper errorWrapper = new Wrapper<>(); + Wrapper propertyWrapper = new Wrapper<>(); + + validateInputStream(request, dataWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + validateClassParse(dataWrapper.getInnerElement(), propertyWrapper, () -> ComponentInstanceProperty.class, errorWrapper); + } + + if (!errorWrapper.isEmpty()) { + return buildErrorResponse(errorWrapper.getInnerElement()); + } + + ComponentInstanceProperty property = propertyWrapper.getInnerElement(); + + log.debug("Start handle request of updateResourceInstanceProperty. Received property is {}", property); + + ServletContext context = request.getSession().getServletContext(); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either actionResponse = componentInstanceLogic.createOrUpdatePropertyValue(componentTypeEnum, componentId, componentInstanceId, property, userId); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + + ComponentInstanceProperty resourceInstanceProperty = actionResponse.left().value(); + ObjectMapper mapper = new ObjectMapper(); + String result = mapper.writeValueAsString(resourceInstanceProperty); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: ", e.getMessage()); + log.debug("create and associate RI failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + /** + * Updates ResourceInstance Attribute + * + * @param componentId + * @param containerComponentType + * @param componentInstanceId + * @param userId + * @param request + * @return + */ + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/attribute") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance attribute", httpMethod = "POST", notes = "Returns updated resource instance attribute", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateResourceInstanceAttribute(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + try { + + Wrapper errorWrapper = new Wrapper<>(); + Wrapper dataWrapper = new Wrapper<>(); + Wrapper attributeWrapper = new Wrapper<>(); + Wrapper blWrapper = new Wrapper<>(); + + validateInputStream(request, dataWrapper, errorWrapper); + + if (errorWrapper.isEmpty()) { + validateClassParse(dataWrapper.getInnerElement(), attributeWrapper, () -> ComponentInstanceAttribute.class, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + validateComponentInstanceBusinessLogic(request, containerComponentType, blWrapper, errorWrapper); + } + + if (errorWrapper.isEmpty()) { + ComponentInstanceBusinessLogic componentInstanceLogic = blWrapper.getInnerElement(); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + log.debug("Start handle request of ComponentInstanceAttribute. Received attribute is {}", attributeWrapper.getInnerElement()); + Either eitherAttribute = componentInstanceLogic.createOrUpdateAttributeValue(componentTypeEnum, componentId, componentInstanceId, attributeWrapper.getInnerElement(), userId); + if (eitherAttribute.isRight()) { + errorWrapper.setInnerElement(eitherAttribute.right().value()); + } else { + attributeWrapper.setInnerElement(eitherAttribute.left().value()); + } + } + + return buildResponseFromElement(errorWrapper, attributeWrapper); + + } catch (Exception e) { + log.error("create and associate RI failed with exception: ", e.getMessage()); + log.debug("create and associate RI failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @DELETE + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/property/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance", httpMethod = "DELETE", notes = "Returns deleted resource instance property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response deleteResourceInstanceProperty(@ApiParam(value = "service id") @PathParam("componentId") final String componentId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @ApiParam(value = "resource instance id") @PathParam("componentInstanceId") final String componentInstanceId, @ApiParam(value = "property id") @PathParam("propertyId") final String propertyId, + @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either actionResponse = componentInstanceLogic.deletePropertyValue(componentTypeEnum, componentId, componentInstanceId, propertyId, userId); + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + } catch (Exception e) { + log.error("create and associate RI failed with exception: ", e.getMessage()); + log.debug("create and associate RI failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @POST + @Path("/{containerComponentType}/{componentId}/resourceInstance/{componentInstanceId}/changeVersion") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update resource instance", httpMethod = "POST", notes = "Returns updated resource instance", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource instance created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response changeResourceInstanceVersion(@PathParam("componentId") final String componentId, @PathParam("componentInstanceId") final String componentInstanceId, + @ApiParam(value = "valid values: resources / services", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME) @PathParam("containerComponentType") final String containerComponentType, + @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + try { + + log.debug("Start handle request of {}", url); + + InputStream inputStream = request.getInputStream(); + + byte[] bytes = IOUtils.toByteArray(inputStream); + + if (bytes == null || bytes.length == 0) { + log.info("Empty body was sent."); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + String userId = request.getHeader(Constants.USER_ID_HEADER); + + String data = new String(bytes); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + ComponentInstanceBusinessLogic componentInstanceLogic = getComponentInstanceBL(context, componentTypeEnum); + if (componentInstanceLogic == null) { + log.debug("Unsupported component type {}", containerComponentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.UNSUPPORTED_ERROR, containerComponentType)); + } + + Either convertResponse = convertToResourceInstance(data); + + if (convertResponse.isRight()) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "Resource Instance - updateResourceInstance"); + BeEcompErrorManager.getInstance().logBeSystemError("Resource Instance - updateResourceInstance"); + log.debug("Failed to convert received data to BE format."); + return buildErrorResponse(convertResponse.right().value()); + } + + ComponentInstance newResourceInstance = convertResponse.left().value(); + Either actionResponse = componentInstanceLogic.changeComponentInstanceVersion(containerComponentType, componentId, componentInstanceId, userId, newResourceInstance); + + if (actionResponse.isRight()) { + return buildErrorResponse(actionResponse.right().value()); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Resource Instance"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Instance"); + log.debug("update resource instance with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + private Either convertToResourceInstance(String data) { + + // Either convertStatus = + // convertJsonToObject(data, ComponentInstance.class); + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, new User(), ComponentInstance.class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + ComponentInstance resourceInstanceInfo = convertStatus.left().value(); + + return Either.left(resourceInstanceInfo); + } + + // TODO Tal New API for Multiple Items move on canvas + private Either, ResponseFormat> convertToMultipleResourceInstance(String dataList) { + + Either convertStatus = getComponentsUtils().convertJsonToObjectUsingObjectMapper(dataList, new User(), ComponentInstance[].class, null, ComponentTypeEnum.RESOURCE_INSTANCE); + if (convertStatus.isRight()) { + return Either.right(convertStatus.right().value()); + } + + return Either.left(Arrays.asList(convertStatus.left().value())); + } + + private Either convertToRequirementCapabilityRelDef(String data) { + + Either convertStatus = convertJsonToObject(data, RequirementCapabilityRelDef.class); + if (convertStatus.isRight()) { + return Either.right(getComponentsUtils().getResponseFormat(convertStatus.right().value())); + } + RequirementCapabilityRelDef requirementCapabilityRelDef = convertStatus.left().value(); + return Either.left(requirementCapabilityRelDef); + } + + private Either convertJsonToObject(String data, Class clazz) { + try { + log.trace("convert json to object. json=\n{}", data); + T t = null; + t = gson.fromJson(data, clazz); + if (t == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + return Either.right(ActionStatus.INVALID_CONTENT); + } + return Either.left(t); + } catch (Exception e) { + // INVALID JSON + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json", e); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java new file mode 100644 index 0000000000..c5bebb41bf --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ComponentServlet.java @@ -0,0 +1,270 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.List; +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.ComponentBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.CapReqDef; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Component Servlet", description = "Component Servlet") +@Singleton +public class ComponentServlet extends BeGenericServlet { + private static Logger log = LoggerFactory.getLogger(ComponentServlet.class.getName()); + + @GET + @Path("/{componentType}/{componentId}/requirmentsCapabilities") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirments And Capabilities according to componentId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getRequirementAndCapabilities(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + Response response; + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + if (componentTypeEnum != null) { + ComponentBusinessLogic compBL = getComponentBL(componentTypeEnum, context); + Either eitherRequirementsAndCapabilities = compBL.getRequirementsAndCapabilities(componentId, componentTypeEnum, userId); + if (eitherRequirementsAndCapabilities.isRight()) { + response = buildErrorResponse(eitherRequirementsAndCapabilities.right().value()); + } else { + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), gson.toJson(eitherRequirementsAndCapabilities.left().value())); + } + } else { + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + return response; + } + + @GET + @Path("/{componentType}/latestversion/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirments And Capabilities according to componentId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getLatestVersionNotAbstractCheckoutComponents(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, + @QueryParam("componentUids") List componentUids, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = getComponentBL(componentTypeEnum, context); + + log.debug("Received componentUids size is {}", (componentUids == null ? 0 : componentUids.size())); + + Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, HighestFilterEnum.HIGHEST_ONLY, componentTypeEnum, internalComponentType, componentUids, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract {}", componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Certified Non Abstract" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract" + componentType); + log.debug("getCertifiedNotAbstractComponents failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @POST + @Path("/{componentType}/latestversion/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Component Requirments And Capabilities", httpMethod = "GET", notes = "Returns Requirments And Capabilities according to componentId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getLatestVersionNotAbstractCheckoutComponentsByBody(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "Consumer Object to be created", required = true) List data) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + if (log.isDebugEnabled()) + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = getComponentBL(componentTypeEnum, context); + List componentUids = data; + if (log.isDebugEnabled()) + log.debug("Received componentUids size is {}", (componentUids == null ? 0 : componentUids.size())); + + // long start = System.currentTimeMillis(); + + Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponents(false, HighestFilterEnum.HIGHEST_ONLY, componentTypeEnum, internalComponentType, componentUids, userId); + + // long endBl = System.currentTimeMillis(); + + if (actionResponse.isRight()) { + if (log.isDebugEnabled()) + log.debug("failed to get all non abstract {}", componentType); + return buildErrorResponse(actionResponse.right().value()); + + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + Response responseToReturn = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + long endResp = System.currentTimeMillis(); + + // log.info("********** Time calculation in ms: BL {} , Response {}, + // Total {}", (endBl - start ), (endResp - endBl), (endResp - + // start)); + return responseToReturn; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Certified Non Abstract" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract" + componentType); + log.debug("getCertifiedNotAbstractComponents failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @GET + @Path("/{componentType}/latestversion/notabstract/uidonly") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Component uid only", httpMethod = "GET", notes = "Returns componentId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getLatestVersionNotAbstractCheckoutComponentsIdesOnly(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request, @QueryParam("internalComponentType") String internalComponentType, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "uid list", required = true) String data) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = getComponentBL(componentTypeEnum, context); + + Either>, ResponseFormat> actionResponse = businessLogic.getLatestVersionNotAbstractComponentsUidOnly(false, HighestFilterEnum.HIGHEST_ONLY, componentTypeEnum, internalComponentType, userId); + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract {}", componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Certified Non Abstract" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract" + componentType); + log.debug("getCertifiedNotAbstractComponents failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @GET + @Path("/{componentType}/{componentId}/componentInstances") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Component instances", httpMethod = "GET", notes = "Returns component instances", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getComponentInstancesFilteredByPropertiesAndInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @QueryParam("searchText") String searchText, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "uid" + "" + "list", required = true) String data) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + try { + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentBusinessLogic businessLogic = getComponentBL(componentTypeEnum, context); + + Either, ResponseFormat> actionResponse = businessLogic.getComponentInstancesFilteredByPropertiesAndInputs(componentId, componentTypeEnum, userId, searchText); + if (actionResponse.isRight()) { + log.debug("failed to get all component instances filtered by properties and inputs {}", componentType); + return buildErrorResponse(actionResponse.right().value()); + } + Object components = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), components); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Component Instances filtered by properties & inputs" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Instances filtered by properties & inputs" + componentType); + log.debug("getComponentInstancesFilteredByPropertiesAndInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigMgrServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigMgrServlet.java new file mode 100644 index 0000000000..164b1d7665 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigMgrServlet.java @@ -0,0 +1,125 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.servlets.BasicServlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/configmgr") +public class ConfigMgrServlet extends BasicServlet { + + private static Logger log = LoggerFactory.getLogger(ConfigMgrServlet.class.getName()); + + @GET + @Path("/get") + @Produces(MediaType.APPLICATION_JSON) + public String getConfig(@Context final HttpServletRequest request, @QueryParam("type") String type) { + + String result = null; + + ServletContext context = request.getSession().getServletContext(); + + ConfigurationManager configurationManager = (ConfigurationManager) context.getAttribute(Constants.CONFIGURATION_MANAGER_ATTR); + + if (type == null || type.equals("configuration")) { + + Configuration configuration = configurationManager.getConfiguration(); + if (configuration == null) { + log.warn("Configuration of type {} was not found", Configuration.class); + } else { + log.info("The value returned from getConfig is {}", configuration); + + result = gson.toJson(configuration); + + } + } + + return result; + + } + + @POST + @Path("/set1") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.APPLICATION_JSON) + public String setConfig1(@Context final HttpServletRequest request, Configuration configuration) { + + log.debug("{}", configuration); + + return "ok"; + + } + + @POST + @Path("/set2") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.APPLICATION_JSON) + public void setConfig2(@Context final HttpServletRequest request, Configuration configuration) { + + log.debug("{}", configuration); + + } + + @PUT + @Path("/setput1") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.APPLICATION_JSON) + public String setConfig3(@Context final HttpServletRequest request, Configuration configuration) { + + log.debug("{}", configuration); + + return "ok"; + + } + + @PUT + @Path("/setput2") + @Produces(MediaType.TEXT_PLAIN) + @Consumes(MediaType.APPLICATION_JSON) + public void setConfig4(@Context final HttpServletRequest request, Configuration configuration) { + + log.debug("{}", configuration); + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigServlet.java new file mode 100644 index 0000000000..2a3a87d942 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConfigServlet.java @@ -0,0 +1,81 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; + +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.common.api.ConfigurationSource; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.servlets.BasicServlet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/config") +public class ConfigServlet extends BasicServlet { + + private static Logger log = LoggerFactory.getLogger(ConfigServlet.class.getName()); + + @GET + @Path("/get") + @Produces(MediaType.APPLICATION_JSON) + public String getConfig(@Context final HttpServletRequest request) { + + String result = null; + + ServletContext context = request.getSession().getServletContext(); + + ConfigurationSource configurationSource = (ConfigurationSource) context.getAttribute(Constants.CONFIGURATION_SOURCE_ATTR); + if (configurationSource != null) { + Configuration configuration = configurationSource.getAndWatchConfiguration(Configuration.class, null); + + if (configuration == null) { + log.warn("Configuration of type {} was not found", Configuration.class); + } + log.debug("{}", configuration); + if (log.isInfoEnabled()) { + log.debug("Info level ENABLED..."); + } + log.info("The value returned from getConfig is {}", configuration); + + result = gson.toJson(configuration); + + } else { + log.warn("Source Configuration object was not initialized in the context."); + } + + return result; + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java new file mode 100644 index 0000000000..0603f267ab --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ConsumerServlet.java @@ -0,0 +1,227 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.ConsumerBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ConsumerDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/consumers") +@Api(value = "Consumer Servlet", description = "Consumer Servlet") +@Singleton +public class ConsumerServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(ConsumerServlet.class.getName()); + + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Consumer credentials", httpMethod = "POST", notes = "Returns created ECOMP consumer credentials", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Consumer credentials created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response createConsumer(@ApiParam(value = "Consumer Object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + try { + ConsumerBusinessLogic businessLogic = getConsumerBL(context); + + Either convertionResponse = convertJsonToObject(data, modifier, AuditingActionEnum.ADD_ECOMP_USER_CREDENTIALS); + + if (convertionResponse.isRight()) { + log.debug("failed to create Consumer"); + return buildErrorResponse(convertionResponse.right().value()); + } + + ConsumerDefinition consumer = convertionResponse.left().value(); + + Either actionResult = businessLogic.createConsumer(modifier, consumer); + + if (actionResult.isRight()) { + log.debug("failed to create Consumer"); + return buildErrorResponse(actionResult.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), actionResult.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create consumer"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create consumer"); + log.debug("create consumer failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + @GET + @Path("/{consumerId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Consumer", httpMethod = "GET", notes = "Returns consumer according to ConsumerID", response = ConsumerDefinition.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Consumer found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Consumer not found") }) + public Response getConsumer(@PathParam("consumerId") final String consumerId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ConsumerBusinessLogic businessLogic = getConsumerBL(context); + + Either actionResponse = businessLogic.getConsumer(consumerId, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get consumer"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Consumer"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); + log.debug("get consumer failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/{consumerId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Deletes Consumer", httpMethod = "DELETE", notes = "Returns deleted consumer according to ConsumerID", response = ConsumerDefinition.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "Consumer deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Consumer not found") }) + public Response deleteConsumer(@PathParam("consumerId") final String consumerId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ConsumerBusinessLogic businessLogic = getConsumerBL(context); + + Either actionResponse = businessLogic.deleteConsumer(consumerId, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to delete consumer"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Consumer"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Consumer"); + log.debug("delete consumer failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + private ConsumerBusinessLogic getConsumerBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + ConsumerBusinessLogic consumerBL = webApplicationContext.getBean(ConsumerBusinessLogic.class); + + return consumerBL; + } + + public Either convertJsonToObject(String data, User user, AuditingActionEnum actionEnum) { + ConsumerDefinition consumer = null; + Gson gson = new Gson(); + try { + log.trace("convert json to object. json=\n{}", data); + consumer = gson.fromJson(data, ConsumerDefinition.class); + if (consumer == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("object is null after converting from json"); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(user, actionEnum); + return Either.right(responseFormat); + } + } catch (Exception e) { + // INVALID JSON + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", data, e); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(user, actionEnum); + return Either.right(responseFormat); + } + return Either.left(consumer); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CsarBuildServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CsarBuildServlet.java new file mode 100644 index 0000000000..4ba6b7516d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/CsarBuildServlet.java @@ -0,0 +1,296 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import java.nio.charset.Charset; +import java.nio.charset.CharsetEncoder; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +//import org.openecomp.sdc.be.builders.tosca.api.TopologyService; +//import org.openecomp.sdc.be.tosca.parsers.ParserMode; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/services") +public class CsarBuildServlet extends ToscaDaoServlet { + + private static Logger log = LoggerFactory.getLogger(CsarBuildServlet.class.getName()); + + @GET + @Path("/{serviceName}/{serviceVersion}") + public Response getDefaultTemplate(@Context final HttpServletRequest request, @PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion) { + + return null;// buildToscaCsar(request, serviceName, serviceVersion); + + } + + @GET + @Path("/{serviceName}/{serviceVersion}/csar") + public Response getToscaCsarTemplate(@Context final HttpServletRequest request, @PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion) { + + return null; // buildToscaCsar(request, serviceName, serviceVersion); + + } + + /* + * private Response buildToscaCsar(final HttpServletRequest request, String serviceName, String serviceVersion) { log.debug("Building CSAR for service:{} , version:{}", serviceName, serviceVersion); ServletContext context = + * request.getSession().getServletContext(); ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream); String fileName = + * serviceName+"_"+serviceVersion+".zip"; + * + * IResourceUploader resourceUploader = getResourceUploader(context); TopologyService topologyService = getToscaYamlBuilder(context).getServiceYaml(serviceName, serviceVersion, ParserMode.CSAR, "Scripts"); try { + * + * + * //Add Service yml to Zip addZipEntry(zipOutputStream, "Definitions/"+serviceName+".yaml", topologyService.getTopologyServiceYaml()); + * + * //Add Resources to Zip addResourcesToZip(zipOutputStream, topologyService); + * + * //Add Artifacts to Zip addArtifactsToZip(serviceName, serviceVersion, zipOutputStream, resourceUploader); + * + * //Prepare Tosca metadata addToscaMetaToZip(zipOutputStream, topologyService, resourceUploader); + * + * } + * + * catch (IOException e) { log.error("Failed to create CSAR file", e); return null; } finally{ try { byteArrayOutputStream.close(); zipOutputStream.close(); } catch (IOException e) { log.error("Failed to close output srream", e); } + * + * } return buildResponse(fileName, byteArrayOutputStream); + * + * + * } + */ + + public static final String TOSCA_META_PATH = "TOSCA-Metadata/TOSCA.meta"; + // protected void addToscaMetaToZip(ZipOutputStream zipOutputStream, + // TopologyService topService, IResourceUploader resUploader) throws + // IOException { + // String serviceVersion = topService.getTopologyVersion(); + // String serviceName = topService.getTopologyName(); + // StringBuffer buff = new StringBuffer(); + // + // String[] serviceToscaMeta = prepareToscaMetaHeader(serviceName); + // + // for( String toAppend : serviceToscaMeta){ + // buff.append(toAppend); + // } + // + // List toscaMetaComponents = + // prepareToscaMetaComponents(topService.getDependenciesYamls().keySet()); + // for( String toAppend : toscaMetaComponents ){ + // buff.append(toAppend); + // } + // + // Either + // getServiceArtifactsCollectionStatus = + // Either.right(ResourceUploadStatus.ERROR);//resUploader.getServiceArtifactsCollection(serviceName, + // serviceVersion); + // if(getServiceArtifactsCollectionStatus.isLeft()){ + // List toscaMetaArtifacts = + // prepareToscaMetaArtifacts(getServiceArtifactsCollectionStatus.left().value()); + // for( String toAppend : toscaMetaArtifacts ){ + // buff.append(toAppend); + // } + // } + // + // addZipEntry(zipOutputStream, TOSCA_META_PATH, buff.toString()); + // } + + // protected List prepareToscaMetaArtifacts( + // ServiceArtifactsDataCollection serviceArtifactsDataCollection) { + // List artifactsForToscaMeta = new ArrayList(); + // Iterator>> nodeTemplateArtifactsItr = + // serviceArtifactsDataCollection.getServiceArtifactDataMap().entrySet().iterator(); + // while( nodeTemplateArtifactsItr.hasNext() ){ + // Entry> nodeNameArtifacts = + // nodeTemplateArtifactsItr.next(); + // String nodeName = nodeNameArtifacts.getKey(); + // Iterator artifactDataItr = + // nodeNameArtifacts.getValue().iterator(); + // while( artifactDataItr.hasNext() ){ + // ArtifactData artifactData = artifactDataItr.next(); + // artifactsForToscaMeta.add("\n"); + // artifactsForToscaMeta.add("Name: "+getArtifactPath(nodeName, + // artifactData)+"\n"); + // artifactsForToscaMeta.add("Content-Type: + // application/"+getAppliactionMime(artifactData.getArtifactName())+"\n"); + // } + // } + // return artifactsForToscaMeta; + // } + + // protected List prepareToscaMetaComponents(Set components) + // { + // Iterator resourceNameItr = components.iterator(); + // List componentsForToscaMeta = new ArrayList(); + // while( resourceNameItr.hasNext() ){ + // String resourceName = resourceNameItr.next(); + // componentsForToscaMeta.add("\n"); + // componentsForToscaMeta.add("Name: "+getResourcePath(resourceName)+"\n"); + // componentsForToscaMeta.add("Content-Type: + // application/vnd.oasis.tosca.definitions.yaml\n"); + // + // } + // return componentsForToscaMeta; + // } + + protected String[] prepareToscaMetaHeader(String serviceName) { + return new String[] { "TOSCA-Meta-File-Version: 1.0\n", "CSAR-Version: 1.1\n", "Created-By: INTERWISE\n", "\n", "Entry-Definitions: Definitions/" + serviceName + ".yaml\n", "\n", "Name: Definitions/" + serviceName + ".yaml\n", + "Content-Type: application/vnd.oasis.tosca.definitions.yaml\n" }; + } + + protected String getAppliactionMime(String fileName) { + String mimeType; + if (fileName.contains(".sh")) { + mimeType = "x-sh"; + } else if (fileName.contains(".yang")) { + mimeType = "yang"; + } + + else if (fileName.contains(".rar")) { + mimeType = "x-rar-compressed"; + } + + else if (fileName.contains(".zip")) { + mimeType = "zip"; + } + + else if (fileName.contains(".tar")) { + mimeType = "x-tar"; + } + + else if (fileName.contains(".7z")) { + mimeType = "x-7z-compressed"; + } + + else { + // Undefined + mimeType = "undefined"; + } + return mimeType; + } + + // protected void addResourcesToZip(ZipOutputStream zipOutputStream, + // TopologyService topService) throws IOException { + // Iterator> resourceNameDataItr = + // topService.getDependenciesYamls().entrySet().iterator(); + // while( resourceNameDataItr.hasNext() ){ + // Entry resourceNameData = resourceNameDataItr.next(); + // addZipEntry(zipOutputStream, getResourcePath(resourceNameData.getKey()), + // resourceNameData.getValue()); + // } + // } + + protected String getArtifactPath(String nodeTamplateName, ESArtifactData artifactData) { + // return "Scripts/"+nodeTamplateName+"/"+ + // artifactData.getArtifactName(); + return "Scripts/" + nodeTamplateName + "/" + artifactData.getId(); + } + + protected String getResourcePath(String resourceName) { + return "Definitions/" + resourceName + ".yaml"; + } + + // protected void addArtifactsToZip(String serviceName, String + // serviceVersion, ZipOutputStream zipOutputStream, IResourceUploader + // resourceUploader) + // throws IOException { + // //Add Artifacts to Zip + // Either + // getServiceArtifactsCollectionStatus = + // Either.right(ResourceUploadStatus.ERROR);//resourceUploader.getServiceArtifactsCollection(serviceName, + // serviceVersion); + // if(getServiceArtifactsCollectionStatus.isLeft()){ + // Iterator>> nodeTemplateArtifactsItr + // =getServiceArtifactsCollectionStatus.left().value().getServiceArtifactDataMap().entrySet().iterator(); + // while( nodeTemplateArtifactsItr.hasNext() ){ + // Entry> nodeTemplateArtifacts = + // nodeTemplateArtifactsItr.next(); + // String nodeTamplateName = nodeTemplateArtifacts.getKey(); + // List artifacts = nodeTemplateArtifacts.getValue(); + // for(ArtifactData artifactData : artifacts ){ + // addZipEntry(zipOutputStream, + // getArtifactPath(nodeTamplateName,artifactData), artifactData.getData()); + // } + // + // } + // } + // } + + // private Response buildResponse(String fileName, ByteArrayOutputStream + // fileOutputStream) { + // final InputStream inputStream = new + // ByteArrayInputStream(fileOutputStream.toByteArray()); + // + // StreamingOutput stream = new StreamingOutput() { + // public void write(OutputStream output) throws WebApplicationException { + // try { + // IOUtils.copy(inputStream, output); + // } catch (Exception e) { + // throw new WebApplicationException(e); + // } + // } + // }; + // + // return + // Response.ok(stream).type(MediaType.APPLICATION_OCTET_STREAM_TYPE).header("content-disposition","attachment; + // filename = "+fileName).build(); + // } + + // protected void addZipEntry(ZipOutputStream zipOutputStream, String + // filePath, String data) throws IOException { + // addZipEntry(zipOutputStream, filePath, encodeString(data)); + // } + + private byte[] encodeString(String data) throws CharacterCodingException { + Charset charset = Charset.forName("UTF-8"); + CharsetEncoder encoder = charset.newEncoder(); + ByteBuffer bb = encoder.encode(CharBuffer.wrap(data.toCharArray())); + byte[] ba = new byte[bb.limit()]; + bb.get(ba); + return ba; + } + + // private void addZipEntry(ZipOutputStream zipOutputStream, String + // filePath, byte[] data) throws IOException { + // log.debug("Adding to CSAR zip :{}", filePath); + // ZipEntry entry = new ZipEntry(filePath); + // zipOutputStream.putNextEntry(entry); + // zipOutputStream.write(data); + // zipOutputStream.closeEntry(); + // } + + @Override + public Logger getLogger() { + return log; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java new file mode 100644 index 0000000000..62a321fa5b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/DistributionServiceServlet.java @@ -0,0 +1,169 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.annotation.Resource; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.DistributionMonitoringBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.info.DistributionStatusListResponse; +import org.openecomp.sdc.be.info.DistributionStatusOfServiceListResponce; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Distribution Service Servlet", description = "Distribution Service Servlet") +@Singleton +public class DistributionServiceServlet extends BeGenericServlet { + private static Logger log = LoggerFactory.getLogger(DistributionServiceServlet.class.getName()); + + @Resource + private DistributionMonitoringBusinessLogic distributionMonitoringLogic; + + @GET + @Path("/services/{serviceUUID}/distribution") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Distributions", httpMethod = "GET", notes = "Returns list bases on the information extracted from Auditing Records according to service uuid", response = DistributionStatusListResponse.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) + public Response getServiceById(@PathParam("serviceUUID") final String serviceUUID, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + init(request); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + ResponseFormat responseFormat = null; + + try { + Either actionResponse = distributionMonitoringLogic.getListOfDistributionServiceStatus(serviceUUID, userId); + + if (actionResponse.isRight()) { + + responseFormat = actionResponse.right().value(); + response = buildErrorResponse(responseFormat); + } else { + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Distribution list for Service"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution list for Service"); + log.debug("failed to get service distribution statuses", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + + response = buildErrorResponse(responseFormat); + return response; + } + + } + + @GET + @Path("/services/distribution/{did}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Distributions", httpMethod = "GET", notes = "Return the list of distribution status objects", response = DistributionStatusListResponse.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Status not found") }) + public Response getListOfDistributionStatuses(@PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + init(request); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + ResponseFormat responseFormat = null; + + try { + Either actionResponse = distributionMonitoringLogic.getListOfDistributionStatus(did, userId); + + if (actionResponse.isRight()) { + + responseFormat = actionResponse.right().value(); + log.debug("failed to fount statuses for did {} {}", did, responseFormat); + response = buildErrorResponse(responseFormat); + } else { + + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + log.debug("success to fount statuses for did {} {}", did, actionResponse.left().value()); + response = buildOkResponse(responseFormat, actionResponse.left().value()); + + } + + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Distribution Status"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Distribution Status"); + log.debug("failed to get distribution status ", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + + response = buildErrorResponse(responseFormat); + return response; + } + + } + + private void init(HttpServletRequest request) { + if (distributionMonitoringLogic == null) { + distributionMonitoringLogic = getDistributionBL(request.getSession().getServletContext()); + } + } + + private DistributionMonitoringBusinessLogic getDistributionBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + DistributionMonitoringBusinessLogic distributionBl = webApplicationContext.getBean(DistributionMonitoringBusinessLogic.class); + return distributionBl; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java new file mode 100644 index 0000000000..433a1bfc58 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ElementServlet.java @@ -0,0 +1,611 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.clean.ComponentsCleanBusinessLogic; +import org.openecomp.sdc.be.components.impl.ElementBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.info.ArtifactTypesInfo; +import org.openecomp.sdc.be.model.ArtifactType; +import org.openecomp.sdc.be.model.Category; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.PropertyScope; +import org.openecomp.sdc.be.model.Tag; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.category.GroupingDefinition; +import org.openecomp.sdc.be.model.category.SubCategoryDefinition; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Path("/v1/") + +/**** + * + * UI oriented servlet - to return elements in specific format UI needs + * + * + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Api(value = "Element Servlet", description = "Element Servlet") +@Singleton +public class ElementServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(ElementServlet.class.getName()); + + /* + ****************************************************************************** + * NEW CATEGORIES category / \ subcategory subcategory / grouping + ******************************************************************************/ + + /* + * + * + * CATEGORIES + */ + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all component categories + @GET + @Path("/categories/{componentType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve the list of all resource/service/product categories/sub-categories/groupings", httpMethod = "GET", notes = "Retrieve the list of all resource/service/product categories/sub-categories/groupings.", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns categories Ok"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 400, message = "Invalid component type"), + @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getComponentCategories(@ApiParam(value = "allowed values are resources / services/ products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @Context final HttpServletRequest request) { + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either, ResponseFormat> either = elementBL.getAllCategories(componentType, userId); + if (either.isRight()) { + log.debug("No categories were found for type {}", componentType); + return buildErrorResponse(either.right().value()); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Component Categories"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Component Categories"); + log.debug("getComponentCategories failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @POST + @Path("/category/{componentType}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create new component category", httpMethod = "POST", notes = "Create new component category") + @ApiResponses(value = { @ApiResponse(code = 201, message = "Category created"), @ApiResponse(code = 400, message = "Invalid category data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), + @ApiResponse(code = 409, message = "Category already exists / User not permitted to perform the action"), @ApiResponse(code = 500, message = "General Error") }) + public Response createComponentCategory( + @ApiParam(value = "allowed values are resources /services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, + @ApiParam(value = "Category to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + CategoryDefinition category = RepresentationUtils.fromRepresentation(data, CategoryDefinition.class); + + Either createResourceCategory = elementBL.createCategory(category, componentType, userId); + if (createResourceCategory.isRight()) { + return buildErrorResponse(createResourceCategory.right().value()); + } + + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createResourceCategory.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create resource category"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); + log.debug("createResourceCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), + @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) + public Response deleteComponentCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either createResourceCategory = elementBL.deleteCategory(categoryUniqueId, componentType, userId); + + if (createResourceCategory.isRight()) { + return buildErrorResponse(createResourceCategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create resource category"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create resource category"); + log.debug("createResourceCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + /* + * + * + * SUBCATEGORIES + * + */ + + @POST + @Path("/category/{componentType}/{categoryId}/subCategory") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create new component sub-category", httpMethod = "POST", notes = "Create new component sub-category for existing category") + @ApiResponses(value = { @ApiResponse(code = 201, message = "Subcategory created"), @ApiResponse(code = 400, message = "Invalid subcategory data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), + @ApiResponse(code = 404, message = "Parent category wasn't found"), @ApiResponse(code = 409, message = "Subcategory already exists / User not permitted to perform the action"), @ApiResponse(code = 500, message = "General Error") }) + public Response createComponentSubCategory( + @ApiParam(value = "allowed values are resources / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, + @ApiParam(value = "Parent category unique ID", required = true) @PathParam(value = "categoryId") final String categoryId, @ApiParam(value = "Subcategory to be created. \ne.g. {\"name\":\"Resource-subcat\"}", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + SubCategoryDefinition subCategory = RepresentationUtils.fromRepresentation(data, SubCategoryDefinition.class); + + Either createSubcategory = elementBL.createSubCategory(subCategory, componentType, categoryId, userId); + if (createSubcategory.isRight()) { + return buildErrorResponse(createSubcategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createSubcategory.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create sub-category"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create sub-category"); + log.debug("createComponentSubCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), + @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) + public Response deleteComponentSubCategory(@PathParam(value = "categoryUniqueId") final String categoryUniqueId, @PathParam(value = "subCategoryUniqueId") final String subCategoryUniqueId, + @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either deleteSubResourceCategory = elementBL.deleteSubCategory(categoryUniqueId, subCategoryUniqueId, componentType, userId); + if (deleteSubResourceCategory.isRight()) { + return buildErrorResponse(deleteSubResourceCategory.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete component category"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component category"); + log.debug("deleteComponentSubCategory failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + /* + * GROUPINGS + */ + @POST + @Path("/category/{componentType}/{categoryId}/subCategory/{subCategoryId}/grouping") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create new component grouping", httpMethod = "POST", notes = "Create new component grouping for existing sub-category") + @ApiResponses(value = { @ApiResponse(code = 201, message = "Grouping created"), @ApiResponse(code = 400, message = "Invalid grouping data"), @ApiResponse(code = 403, message = "USER_ID header is missing"), + @ApiResponse(code = 404, message = "Parent category or subcategory were not found"), @ApiResponse(code = 409, message = "Grouping already exists / User not permitted to perform the action"), + @ApiResponse(code = 500, message = "General Error") }) + public Response createComponentGrouping(@ApiParam(value = "allowed values are products", allowableValues = ComponentTypeEnum.PRODUCT_PARAM_NAME, required = true) @PathParam(value = "componentType") final String componentType, + @ApiParam(value = "Parent category unique ID", required = true) @PathParam(value = "categoryId") final String grandParentCategoryId, + @ApiParam(value = "Parent sub-category unique ID", required = true) @PathParam(value = "subCategoryId") final String parentSubCategoryId, @ApiParam(value = "Subcategory to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + GroupingDefinition grouping = RepresentationUtils.fromRepresentation(data, GroupingDefinition.class); + + Either createGrouping = elementBL.createGrouping(grouping, componentType, grandParentCategoryId, parentSubCategoryId, userId); + if (createGrouping.isRight()) { + return buildErrorResponse(createGrouping.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, createGrouping.left().value()); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create grouping"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create grouping"); + log.debug("createComponentGrouping failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/category/{componentType}/{categoryUniqueId}/subCategory/{subCategoryUniqueId}/grouping/{groupingUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete component category", httpMethod = "DELETE", notes = "Delete component category", response = Category.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "Category deleted"), @ApiResponse(code = 403, message = "USER_ID header is missing"), @ApiResponse(code = 409, message = "User not permitted to perform the action"), + @ApiResponse(code = 404, message = "Category not found"), @ApiResponse(code = 500, message = "General Error") }) + public Response deleteComponentGrouping(@PathParam(value = "categoryUniqueId") final String grandParentCategoryUniqueId, @PathParam(value = "subCategoryUniqueId") final String parentSubCategoryUniqueId, + @PathParam(value = "groupingUniqueId") final String groupingUniqueId, @PathParam(value = "componentType") final String componentType, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either deleteGrouping = elementBL.deleteGrouping(grandParentCategoryUniqueId, parentSubCategoryUniqueId, groupingUniqueId, componentType, userId); + if (deleteGrouping.isRight()) { + return buildErrorResponse(deleteGrouping.right().value()); + } + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, null); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete component grouping"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete component grouping"); + log.debug("deleteGrouping failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all tags + @GET + @Path("/tags") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve all tags", httpMethod = "GET", notes = "Retrieve all tags", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns tags Ok"), @ApiResponse(code = 404, message = "No tags were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getTags(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getTags) Start handle request of {}", url); + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either, ActionStatus> either = elementBL.getAllTags(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No tags were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get All Tags"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Tags"); + log.debug("getAllTags failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all property scopes + @GET + @Path("/propertyScopes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve all propertyScopes", httpMethod = "GET", notes = "Retrieve all propertyScopes", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns propertyScopes Ok"), @ApiResponse(code = 404, message = "No propertyScopes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getPropertyScopes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getPropertyScopes) Start handle request of {}", url); + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either, ActionStatus> either = elementBL.getAllPropertyScopes(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No property scopes were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Property Scopes Categories"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property Scopes Categories"); + log.debug("getPropertyScopes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all artifact types + @GET + @Path("/artifactTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve all artifactTypes", httpMethod = "GET", notes = "Retrieve all artifactTypes", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns artifactTypes Ok"), @ApiResponse(code = 404, message = "No artifactTypes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getArtifactTypes(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getArtifactTypes) Start handle request of {}", url); + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either, ActionStatus> either = elementBL.getAllArtifactTypes(userId); + if (either.isRight() || either.left().value() == null) { + log.debug("No artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + + Integer defaultHeatTimeout = ConfigurationManager.getConfigurationManager().getConfiguration().getDefaultHeatArtifactTimeoutMinutes(); + ArtifactTypesInfo typesResponse = new ArtifactTypesInfo(); + typesResponse.setArtifactTypes(either.left().value()); + typesResponse.setHeatDefaultTimeout(defaultHeatTimeout); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), typesResponse); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Artifact Types"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); + log.debug("getArtifactTypes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all artifact types + @GET + @Path("/configuration/ui") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve all artifactTypes", httpMethod = "GET", notes = "Retrieve all artifactTypes", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns artifactTypes Ok"), @ApiResponse(code = 404, message = "No artifactTypes were found"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getConfiguration(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getConfiguration) Start handle request of {}", url); + + try { + ElementBusinessLogic elementBL = getElementBL(request.getSession().getServletContext()); + Either, ActionStatus> otherEither = elementBL.getAllArtifactTypes(userId); + Either defaultHeatTimeout = elementBL.getDefaultHeatTimeout(); + Either, ActionStatus> deploymentEither = elementBL.getAllDeploymentArtifactTypes(); + Either, ActionStatus> resourceTypesMap = elementBL.getResourceTypesMap(); + + if (otherEither.isRight() || otherEither.left().value() == null) { + log.debug("No other artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (deploymentEither.isRight() || deploymentEither.left().value() == null) { + log.debug("No deployment artifact types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (defaultHeatTimeout.isRight() || defaultHeatTimeout.left().value() == null) { + log.debug("heat default timeout was not found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else if (resourceTypesMap.isRight() || resourceTypesMap.left().value() == null) { + log.debug("No resource types were found"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT)); + } else { + Map artifacts = new HashMap(); + Map configuration = new HashMap(); + + artifacts.put("other", otherEither.left().value()); + artifacts.put("deployment", deploymentEither.left().value()); + configuration.put("artifacts", artifacts); + configuration.put("defaultHeatTimeout", defaultHeatTimeout.left().value()); + configuration.put("componentTypes", elementBL.getAllComponentTypesParamNames()); + configuration.put("roles", elementBL.getAllSupportedRoles()); + configuration.put("resourceTypes", resourceTypesMap.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), configuration); + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Artifact Types"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Artifact Types"); + log.debug("getArtifactTypes failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all followed resources and services + @GET + @Path("/followed") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve all followed", httpMethod = "GET", notes = "Retrieve all followed", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns followed Ok"), @ApiResponse(code = 404, message = "No followed were found"), @ApiResponse(code = 404, message = "User not found"), + @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getFollowedResourcesServices(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Response res = null; + User userData = null; + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + UserBusinessLogic userAdminManager = getUserAdminManager(request.getSession().getServletContext()); + + // Getting the user + Either either = userAdminManager.getUser(userId, false); + if (either.isRight()) { + // Couldn't find or otherwise fetch the user + return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } + + if (either.left().value() != null) { + userData = either.left().value(); + Either>, ResponseFormat> followedResourcesServices = getElementBL(request.getSession().getServletContext()).getFollowed(userData); + // res = + // buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + // followedResourcesServices.left().value()); + if (followedResourcesServices.isRight()) { + log.debug("failed to get followed resources services "); + return buildErrorResponse(followedResourcesServices.right().value()); + } + Object data = RepresentationUtils.toRepresentation(followedResourcesServices.left().value()); + res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); + } else { + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Followed Resources / Services Categories"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Followed Resources / Services Categories"); + log.debug("Getting followed resources/services failed with exception", e); + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return res; + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all certified resources and services and their last version + @GET + @Path("/screen") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve catalog resources and services", httpMethod = "GET", notes = "Retrieve catalog resources and services", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns resources and services Ok"), @ApiResponse(code = 404, message = "No resources and services were found"), @ApiResponse(code = 404, message = "User not found"), + @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getCatalogComponents(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Response res = null; + try { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + Either>, ResponseFormat> catalogData = getElementBL(request.getSession().getServletContext()).getCatalogComponents(userId); + + if (catalogData.isRight()) { + log.debug("failed to get catalog data"); + return buildErrorResponse(catalogData.right().value()); + } + Object data = RepresentationUtils.toRepresentation(catalogData.left().value()); + res = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), data); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Catalog Components"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Catalog Components"); + log.debug("Getting catalog components failed with exception", e); + res = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return res; + } + + @DELETE + @Path("/inactiveComponents/{componentType}") + public Response deleteMarkedResources(@PathParam("componentType") final String componentType, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + NodeTypeEnum nodeType = NodeTypeEnum.getByNameIgnoreCase(componentType); + if (nodeType == null) { + log.info("componentType is not valid: {}", componentType); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + } + + List componentsList = new ArrayList(); + componentsList.add(nodeType); + try { + ComponentsCleanBusinessLogic businessLogic = getComponentCleanerBL(context); + Map, ResponseFormat>> cleanComponentsResult = businessLogic.cleanComponents(componentsList); + Either, ResponseFormat> cleanResult = cleanComponentsResult.get(nodeType); + + if (cleanResult.isRight()) { + log.debug("failed to delete marked components of type {}", nodeType); + response = buildErrorResponse(cleanResult.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), cleanResult.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Marked Components"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Marked Components"); + log.debug("delete marked components failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/ecompPortalMenu") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve ecomp portal menu - MOC", httpMethod = "GET", notes = "Retrieve ecomp portal menu", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Retrieve ecomp portal menu") }) + public Response getListOfCsars(@Context final HttpServletRequest request) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + "[{\"menuId\":1,\"column\":2,\"text\":\"Design\",\"parentMenuId\":null,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":11,\"column\":1,\"text\":\"ProductDesign\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":12,\"column\":2,\"text\":\"Service\",\"parentMenuId\":1,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":21,\"column\":1,\"text\":\"ViewPolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":90,\"column\":1,\"text\":\"4thLevelApp1aR16\",\"parentMenuId\":21,\"url\":\"http://google.com\",\"appid\":null,\"roles\":null}]},{\"menuId\":22,\"column\":2,\"text\":\"UpdatePolicies\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null,\"children\":[{\"menuId\":91,\"column\":1,\"text\":\"4thLevelApp1bR16\",\"parentMenuId\":22,\"url\":\"http://jsonlint.com/\",\"appid\":null,\"roles\":null}]},{\"menuId\":23,\"column\":3,\"text\":\"UpdateRules\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":24,\"column\":4,\"text\":\"CreateSignatures?\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null},{\"menuId\":25,\"column\":5,\"text\":\"Definedata\",\"parentMenuId\":12,\"url\":\"\",\"appid\":null,\"roles\":null}]}]}]"); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java new file mode 100644 index 0000000000..bde8f93929 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/GroupServlet.java @@ -0,0 +1,182 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.GroupBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.info.GroupDefinitionInfo; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resource Group Servlet", description = "Resource Group Servlet") +@Singleton +public class GroupServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(GroupServlet.class.getName()); + + private Gson gson = new Gson(); + + @GET + @Path("/{containerComponentType}/{componentId}/groups/{groupId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get group artifacts ", httpMethod = "GET", notes = "Returns artifacts metadata according to groupId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "group found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Group not found") }) + public Response getGroupArtifactById(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId, @PathParam("groupId") final String groupId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + GroupBusinessLogic businessLogic = this.getGroupBL(context); + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + Either actionResponse = businessLogic.getGroupWithArtifactsById(componentTypeEnum, componentId, groupId, userId, false); + + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract {}", containerComponentType); + return buildErrorResponse(actionResponse.right().value()); + } + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "getGroupArtifactById"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("getGroupArtifactById"); + log.debug("getGroupArtifactById unexpected exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + @PUT + @Path("/{containerComponentType}/{componentId}/groups/{groupUniqueId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Group Metadata", httpMethod = "PUT", notes = "Returns updated group definition", response = GroupDefinition.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Group Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateGroupMetadata(@PathParam("containerComponentType") final String containerComponentType, @PathParam("componentId") final String componentId, @PathParam("groupUniqueId") final String groupUniqueId, + @ApiParam(value = "Service object to be Updated", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User user = new User(); + user.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + GroupBusinessLogic businessLogic = getGroupBL(context); + + Either convertResponse = parseToGroup(data); + if (convertResponse.isRight()) { + log.debug("failed to parse group"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + GroupDefinition updatedGroup = convertResponse.left().value(); + + // Update GroupDefinition + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(containerComponentType); + Either actionResponse = businessLogic.updateGroupMetadata(componentId, user, groupUniqueId, componentTypeEnum, updatedGroup, true); + + if (actionResponse.isRight()) { + log.debug("failed to update GroupDefinition"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + GroupDefinition group = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(group); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Group Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Group Metadata"); + log.debug("update group metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /** + * Convert data to GroupDefinition object + * + * @param groupJson + * @return + */ + public Either parseToGroup(String groupJson) { + try { + Gson gson = new GsonBuilder().setPrettyPrinting().create(); + GroupDefinition groupDefinition = gson.fromJson(groupJson, GroupDefinition.class); + return Either.left(groupDefinition); + } catch (Exception e) { + log.debug("Failed to parse json (group data) to GroupDefinition object"); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_CONTENT); + return Either.right(responseFormat); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java new file mode 100644 index 0000000000..e835c43e14 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/InputsServlet.java @@ -0,0 +1,320 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.List; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.InputsBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.ComponentInstInputsMap; +import org.openecomp.sdc.be.model.ComponentInstanceInput; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Input Catalog", description = "Input Servlet") +@Singleton +public class InputsServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(ProductServlet.class.getName()); + + @GET + @Path("/services/{componentId}/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Inputs only", httpMethod = "GET", notes = "Returns Inputs list", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getComponentInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, @QueryParam("fromId") String fromName, + @QueryParam("amount") int amount, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + InputsBusinessLogic businessLogic = getInputBL(context); + + Either, ResponseFormat> inputsResponse = businessLogic.getInputs(userId, componentId, fromName, amount); + if (inputsResponse.isRight()) { + log.debug("failed to get inputs {}", componentType); + return buildErrorResponse(inputsResponse.right().value()); + } + Object inputs = RepresentationUtils.toRepresentation(inputsResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), inputs); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Component Instance Inputs" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Inputs" + componentType); + log.debug("getInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{originComonentUid}/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get Inputs only", httpMethod = "GET", notes = "Returns Inputs list", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getComponentInstanceInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, + @PathParam("originComonentUid") final String originComonentUid, @Context final HttpServletRequest request, @QueryParam("fromName") String fromName, @QueryParam("amount") int amount, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + + Either, ResponseFormat> inputsResponse = businessLogic.getInputs(userId, originComonentUid, fromName, amount); + if (inputsResponse.isRight()) { + log.debug("failed to get component instance inputs {}", componentType); + return buildErrorResponse(inputsResponse.right().value()); + } + Object inputs = RepresentationUtils.toRepresentation(inputsResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), inputs); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Component Instance Inputs" + componentType); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Inputs" + componentType); + log.debug("getInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/componentInstances/{instanceId}/{inputId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get properties", httpMethod = "GET", notes = "Returns properties list", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getInputPropertiesForComponentInstance(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("instanceId") final String instanceId, + @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + + Either, ResponseFormat> inputPropertiesRes = businessLogic.getComponentInstancePropertiesByInputId(userId, instanceId, inputId); + if (inputPropertiesRes.isRight()) { + log.debug("failed to get properties of input: {}, with instance id: {}", inputId, instanceId); + return buildErrorResponse(inputPropertiesRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get properties by input id {}, for component instance {} ", inputId, instanceId); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Properites by input id: " + inputId + " for instance with id: " + instanceId); + log.debug("getInputPropertiesForComponentInstance failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/{componentType}/{componentId}/inputs/{inputId}/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get inputs", httpMethod = "GET", notes = "Returns inputs list", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response getInputsForComponentInput(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @PathParam("inputId") final String inputId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + + Either, ResponseFormat> inputsRes = businessLogic.getInputsForComponentInput(userId, componentId, inputId); + if (inputsRes.isRight()) { + log.debug("failed to get inputs of input: {}, with instance id: {}", inputId, componentId); + return buildErrorResponse(inputsRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputsRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get inputs by input id {}, for component {} ", inputId, componentId); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get inputs by input id: " + inputId + " for component with id: " + componentId); + log.debug("getInputsForComponentInput failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + public Either parseToComponentInstanceMap(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, ComponentInstInputsMap.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + @POST + @Path("/{componentType}/{componentId}/create/inputs") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create inputs on service", httpMethod = "POST", notes = "Return inputs list", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Component found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Component not found") }) + public Response createMultipleInputs(@PathParam("componentType") final String componentType, @PathParam("componentId") final String componentId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @ApiParam(value = "ComponentIns Inputs Object to be created", required = true) String componentInstInputsMapObj) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Either componentInstInputsMapRes = parseToComponentInstanceMap(componentInstInputsMapObj, modifier); + if (componentInstInputsMapRes.isRight()) { + log.debug("failed to parse componentInstInputsMap"); + response = buildErrorResponse(componentInstInputsMapRes.right().value()); + return response; + } + + ComponentTypeEnum componentTypeEnum = ComponentTypeEnum.findByParamName(componentType); + ComponentInstInputsMap componentInstInputsMap = componentInstInputsMapRes.left().value(); + + Either, ResponseFormat> inputPropertiesRes = businessLogic.createMultipleInputs(userId, componentId, componentTypeEnum, componentInstInputsMap, true, false); + if (inputPropertiesRes.isRight()) { + log.debug("failed to create inputs for service: {}", componentId); + return buildErrorResponse(inputPropertiesRes.right().value()); + } + Object properties = RepresentationUtils.toRepresentation(inputPropertiesRes.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), properties); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create inputs for service with id: {}", componentId); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create inputs for service with id: " + componentId); + log.debug("createMultipleInputs failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/{componentType}/{componentId}/delete/{inputId}/input") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Delete input from service", httpMethod = "DELETE", notes = "Delete service input", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Input deleted"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Input not found") }) + public Response deleteInput ( + @PathParam("componentType") final String componentType, + @PathParam("componentId") final String componentId, + @PathParam("inputId") final String inputId, + @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @ApiParam(value = "Service Input to be deleted", required = true) String componentInstInputsMapObj) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + InputsBusinessLogic businessLogic = getInputBL(context); + Either deleteInput = businessLogic.deleteInput(componentType, componentId, userId, inputId, true); + if (deleteInput.isRight()){ + ResponseFormat deleteResponseFormat = deleteInput.right().value(); + response = buildErrorResponse(deleteResponseFormat); + return response; + } + InputDefinition inputDefinition = deleteInput.left().value(); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), inputDefinition); + } catch (Exception e){ + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete input for service {} with id: {}", componentId, inputId); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete input for service + " + componentId + " + with id: " + inputId); + log.debug("Delete input failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + protected InputsBusinessLogic getInputBL(ServletContext context) { + + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + InputsBusinessLogic inputsBusinessLogic = webApplicationContext.getBean(InputsBusinessLogic.class); + return inputsBusinessLogic; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java new file mode 100644 index 0000000000..3f8bfd9149 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/LifecycleServlet.java @@ -0,0 +1,216 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.codehaus.jackson.map.ObjectMapper; +import org.openecomp.sdc.be.components.lifecycle.LifecycleBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoBase; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifeCycleTransitionEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Lifecycle Actions Servlet", description = "Lifecycle Actions Servlet") +@Singleton +public class LifecycleServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(LifecycleServlet.class.getName()); + + @POST + @Path("/{componentCollection}/{componentId}/lifecycleState/{lifecycleOperation}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Change Resource lifecycle State", httpMethod = "POST", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource state changed"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 409, message = "Resource already exist") }) + public Response changeResourceState(@ApiParam(value = "LifecycleChangeInfo - relevant for checkin, failCertification, cancelCertification", required = false) String jsonChangeInfo, + @ApiParam(value = "validValues: resources / services / products", allowableValues = ComponentTypeEnum.RESOURCE_PARAM_NAME + "," + ComponentTypeEnum.SERVICE_PARAM_NAME + "," + + ComponentTypeEnum.PRODUCT_PARAM_NAME) @PathParam(value = "componentCollection") final String componentCollection, + @ApiParam(allowableValues = "checkout, undoCheckout, checkin, certificationRequest, startCertification, failCertification, cancelCertification, certify", required = true) @PathParam(value = "lifecycleOperation") final String lifecycleTransition, + @ApiParam(value = "id of component to be changed") @PathParam(value = "componentId") final String componentId, @Context final HttpServletRequest request, + @ApiParam(value = "id of user initiating the operation") @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + LifecycleBusinessLogic businessLogic = getLifecycleBL(context); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + Response response = null; + + // get modifier from graph + log.debug("get modifier properties"); + Either eitherGetUser = getUser(request, userId); + if (eitherGetUser.isRight()) { + return eitherGetUser.right().value(); + } + User user = eitherGetUser.left().value(); + + String resourceIdLower = componentId.toLowerCase(); + log.debug("perform {} operation to resource with id {} ", lifecycleTransition, resourceIdLower); + Either validateEnum = validateTransitionEnum(lifecycleTransition, user); + if (validateEnum.isRight()) { + return validateEnum.right().value(); + } + + LifecycleChangeInfoWithAction changeInfo = new LifecycleChangeInfoWithAction(); + + try { + if (jsonChangeInfo != null && !jsonChangeInfo.isEmpty()) { + // Either changeInfoResult + // = + // getComponentsUtils().convertJsonToObjectUsingObjectMapper(jsonChangeInfo, + // user, LifecycleChangeInfo.class, + // AuditingActionEnum.CHECKOUT_RESOURCE, null); + ObjectMapper mapper = new ObjectMapper(); + changeInfo = new LifecycleChangeInfoWithAction(mapper.readValue(jsonChangeInfo, LifecycleChangeInfoBase.class).getUserRemarks()); + } + } + + catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInvalidJsonInput, "convertJsonToObject"); + BeEcompErrorManager.getInstance().logBeInvalidJsonInput("convertJsonToObject"); + log.debug("failed to convert from json {}", jsonChangeInfo, e); + ResponseFormat responseFormat = getComponentsUtils().getInvalidContentErrorAndAudit(user, AuditingActionEnum.CHECKOUT_RESOURCE); + return buildErrorResponse(responseFormat); + } + + try { + LifeCycleTransitionEnum transitionEnum = validateEnum.left().value(); + ComponentTypeEnum componentType = ComponentTypeEnum.findByParamName(componentCollection); + // if (componentType == ComponentTypeEnum.RESOURCE){ + // Either actionResponse = + // businessLogic.changeState(resourceIdLower, user, transitionEnum, + // changeInfo, false); + // + // if (actionResponse.isRight()){ + // log.info("failed to change resource state"); + // response = buildErrorResponse(actionResponse.right().value()); + // return response; + // } + // + // log.debug("change state successful !!!"); + // Object resource = + // RepresentationUtils.toRepresentation(actionResponse.left().value()); + // response = + // buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + // resource); + // return response; + // + // } else if (componentType == ComponentTypeEnum.SERVICE || + // componentType == ComponentTypeEnum.PRODUCT){ + if (componentType != null) { + Either actionResponse = businessLogic.changeComponentState(componentType, componentId, user, transitionEnum, changeInfo, false, true); + + if (actionResponse.isRight()) { + log.info("failed to change resource state"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + log.debug("change state successful !!!"); + Object value = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), value); + return response; + } else { + log.info("componentCollection \"{}\" is not valid. Supported componentCollection values are \"{}\", \"{}\" or \"{}\"", componentCollection, ComponentTypeEnum.RESOURCE_PARAM_NAME, ComponentTypeEnum.SERVICE_PARAM_NAME, + ComponentTypeEnum.PRODUCT_PARAM_NAME); + ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, AuditingActionEnum.CHECKOUT_RESOURCE); + return buildErrorResponse(error); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Change Lifecycle State"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Change Lifecycle State"); + log.debug("change lifecycle state failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private Either validateTransitionEnum(final String lifecycleTransition, User user) { + LifeCycleTransitionEnum transitionEnum = LifeCycleTransitionEnum.CHECKOUT; + try { + transitionEnum = LifeCycleTransitionEnum.getFromDisplayName(lifecycleTransition); + } catch (IllegalArgumentException e) { + log.info("state operation is not valid. operations allowed are: {}", LifeCycleTransitionEnum.valuesAsString()); + ResponseFormat error = getComponentsUtils().getInvalidContentErrorAndAudit(user, AuditingActionEnum.CHECKOUT_RESOURCE); + return Either.right(buildErrorResponse(error)); + } + return Either.left(transitionEnum); + } + + private LifecycleBusinessLogic getLifecycleBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + LifecycleBusinessLogic resourceBl = webApplicationContext.getBean(LifecycleBusinessLogic.class); + return resourceBl; + } + + protected Either getUser(final HttpServletRequest request, String userId) { + + Either eitherCreator = getUserAdminManager(request.getSession().getServletContext()).getUser(userId, false); + if (eitherCreator.isRight()) { + log.info("createResource method - user is not listed. userId={}", userId); + ResponseFormat errorResponse = getComponentsUtils().getResponseFormat(ActionStatus.MISSING_INFORMATION); + User user = new User("", "", userId, "", null, null); + + getComponentsUtils().auditResource(errorResponse, user, null, "", "", AuditingActionEnum.CHECKOUT_RESOURCE, null); + return Either.right(buildErrorResponse(errorResponse)); + } + return Either.left(eitherCreator.left().value()); + + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java new file mode 100644 index 0000000000..f4ac921cb7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ProductServlet.java @@ -0,0 +1,311 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.ProductBusinessLogic; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.Product; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Product Catalog", description = "Product Servlet") +@Singleton +public class ProductServlet extends BeGenericServlet { + private static Logger log = LoggerFactory.getLogger(ProductServlet.class.getName()); + + @POST + @Path("/products") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create product", httpMethod = "POST", notes = "Returns created product", response = Product.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Product created"), @ApiResponse(code = 403, message = "Restricted operation / Empty USER_ID header"), @ApiResponse(code = 400, message = "Invalid/missing content"), + @ApiResponse(code = 409, message = "Product already exists / User not found / Wrong user role") }) + public Response createProduct(@ApiParam(value = "Product object to be created", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) @ApiParam(value = "USER_ID of product strategist user", required = true) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ProductBusinessLogic businessLogic = getProductBL(context); + Product product = RepresentationUtils.fromRepresentation(data, Product.class); + Either actionResponse = businessLogic.createProduct(product, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to create product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); + return response; + + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Product"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Product"); + log.debug("create product failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/{productId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve product", httpMethod = "GET", notes = "Returns product according to productId", response = Product.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Product found"), @ApiResponse(code = 403, message = "Missing information"), @ApiResponse(code = 409, message = "Restricted operation"), + @ApiResponse(code = 500, message = "Internal Server Error"), @ApiResponse(code = 404, message = "Product not found"), }) + public Response getProductById(@PathParam("productId") final String productId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ProductBusinessLogic businessLogic = getProductBL(context); + log.trace("get product with id {}", productId); + Either actionResponse = businessLogic.getProduct(productId, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to get product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); + + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Product"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Product"); + log.debug("get product failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/productName/{productName}/productVersion/{productVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns product according to name and version", response = Product.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Product found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Product not found") }) + public Response getServiceByNameAndVersion(@PathParam("productName") final String productName, @PathParam("productVersion") final String productVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ProductBusinessLogic businessLogic = getProductBL(context); + Either actionResponse = businessLogic.getProductByNameAndVersion(productName, productVersion, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Product product = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(product); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get product by name and version"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get product by name and version"); + log.debug("get product failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @DELETE + @Path("/products/{productId}") + public Response deleteProduct(@PathParam("productId") final String productId, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ProductBusinessLogic businessLogic = getProductBL(context); + log.trace("delete product with id {}", productId); + Either actionResponse = businessLogic.deleteProduct(productId, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to delete product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object product = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), product); + return response; + + } catch (Throwable e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with error ", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/products/{productId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Product Metadata", httpMethod = "PUT", notes = "Returns updated product", response = Product.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Product Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateProductMetadata(@PathParam("productId") final String productId, @ApiParam(value = "Product object to be Updated", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + + try { + String productIdLower = productId.toLowerCase(); + ProductBusinessLogic businessLogic = getProductBL(context); + Product updatedProduct = RepresentationUtils.fromRepresentation(data, Product.class); + Either actionResponse = businessLogic.updateProductMetadata(productIdLower, updatedProduct, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to update product"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Product product = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(product); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Product Metadata"); + log.debug("update product metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/products/validate-name/{productName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "validate product name", httpMethod = "GET", notes = "checks if the chosen product name is available ", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) + public Response validateServiceName(@PathParam("productName") final String productName, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + ProductBusinessLogic businessLogic = getProductBL(context); + + Either, ResponseFormat> actionResponse = businessLogic.validateProductNameExists(productName, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get validate service name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Validate Service Name"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Product Name"); + log.debug("validate product name failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java new file mode 100644 index 0000000000..2c693c71a8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/PropertyServlet.java @@ -0,0 +1,562 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.lang.reflect.Type; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.json.simple.JSONObject; +import org.json.simple.parser.JSONParser; +import org.json.simple.parser.ParseException; +import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.PropertyConstraint; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.impl.UniqueIdBuilder; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintDeserialiser; +import org.openecomp.sdc.be.model.operations.impl.PropertyOperation.PropertyConstraintSerialiser; +import org.openecomp.sdc.be.resources.data.EntryData; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.reflect.TypeToken; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resource Property Servlet", description = "Resource Property Servlet") +@Singleton +public class PropertyServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(PropertyServlet.class.getName()); + + @POST + @Path("resources/{resourceId}/properties") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource Property", httpMethod = "POST", notes = "Returns created resource property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource property created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Resource property already exist") }) + public Response createProperty(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource property to be created", required = true) String data, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + log.debug("data is {}", data); + + try { + // convert json to PropertyDefinition + Either, ActionStatus> either = getPropertyModel(data); + if (either.isRight()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(either.right().value()); + return buildErrorResponse(responseFormat); + } + Map properties = either.left().value(); + if (properties == null || properties.size() != 1) { + log.info("Property conetnt is invalid - {}", data); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + return buildErrorResponse(responseFormat); + } + Entry entry = properties.entrySet().iterator().next(); + String propertyName = entry.getKey(); + PropertyDefinition newPropertyDefinition = entry.getValue(); + + // create the new property + PropertyBusinessLogic businessLogic = getPropertyBL(context); + Either, ResponseFormat> status = businessLogic.createProperty(resourceId, propertyName, newPropertyDefinition, userId); + if (status.isRight()) { + log.info("Failed to create Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + EntryData property = status.left().value(); + String name = property.getKey(); + PropertyDefinition propertyDefinition = property.getValue(); + + log.debug("Property {} created successfully with id {}", name, propertyDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.CREATED); + return buildOkResponse(responseFormat, propertyToJson(property)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Property"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Property"); + log.debug("create property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + @GET + @Path("resources/{resourceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource Property", httpMethod = "GET", notes = "Returns property of resource", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 404, message = "Resource property not found") }) + public Response getProperty(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId, @ApiParam(value = "proerty id to get", required = true) @PathParam("propertyId") final String propertyId, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + // + PropertyBusinessLogic businessLogic = getPropertyBL(context); + Either, ResponseFormat> status = businessLogic.getProperty(resourceId, propertyId, userId); + + if (status.isRight()) { + log.info("Failed to get Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + Entry property = status.left().value(); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, propertyToJson(property)); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Property"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property"); + log.debug("get property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + @DELETE + @Path("resources/{resourceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource Property", httpMethod = "DELETE", notes = "Returns deleted property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 204, message = "deleted property"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 404, message = "Resource property not found") }) + public Response deleteProperty(@ApiParam(value = "resource id of property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "Property id to delete", required = true) @PathParam("propertyId") final String propertyId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + try { + + // delete the property + PropertyBusinessLogic businessLogic = getPropertyBL(context); + Either, ResponseFormat> status = businessLogic.deleteProperty(resourceId, propertyId, userId); + if (status.isRight()) { + log.debug("Failed to delete Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + EntryData property = status.left().value(); + String name = property.getKey(); + PropertyDefinition propertyDefinition = property.getValue(); + + log.debug("Property {} deleted successfully with id {}", name, propertyDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT); + return buildOkResponse(responseFormat, propertyToJson(property)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Property"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Property"); + log.debug("delete property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + @PUT + @Path("resources/{resourceId}/properties/{propertyId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Property", httpMethod = "PUT", notes = "Returns updated property", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource property updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateProperty(@ApiParam(value = "resource id to update with new property", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "proerty id to update", required = true) @PathParam("propertyId") final String propertyId, @ApiParam(value = "Resource property to update", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + try { + // convert json to PropertyDefinition + Either, ActionStatus> either = getPropertyModel(data); + if (either.isRight()) { + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(either.right().value()); + return buildErrorResponse(responseFormat); + } + Map properties = either.left().value(); + if (properties == null || properties.size() != 1) { + log.info("Property conetnt is invalid - {}", data); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + return buildErrorResponse(responseFormat); + } + Entry entry = properties.entrySet().iterator().next(); + PropertyDefinition newPropertyDefinition = entry.getValue(); + + // update property + PropertyBusinessLogic businessLogic = getPropertyBL(context); + Either, ResponseFormat> status = businessLogic.updateProperty(resourceId, propertyId, newPropertyDefinition, userId); + if (status.isRight()) { + log.info("Failed to update Property. Reason - ", status.right().value()); + return buildErrorResponse(status.right().value()); + } + EntryData property = status.left().value(); + PropertyDefinition propertyDefinition = property.getValue(); + + log.debug("Property id {} updated successfully ", propertyDefinition.getUniqueId()); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + return buildOkResponse(responseFormat, propertyToJson(property)); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Property"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Property"); + log.debug("update property failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + + } + } + + // private String propertyToJsonUi(Map.Entry + // property) { + // String name = property.getKey(); + // PropertyDefinition propertyDefinition = property.getValue(); + // JSONObject root = new JSONObject(); + // root.put("type", propertyDefinition.getType()); + // root.put("source", propertyDefinition.getDefaultValue()); + // root.put("name", name); + // root.put("description", propertyDefinition.getDescription()); + // root.put("uniqueId", propertyDefinition.getUniqueId()); + // return root.toString(); + // + // } + // + + // private Either getJsonModel(String data){ + // Either uiPropertyEither = getUiProperty(data); + // if (uiPropertyEither.isRight()){ + // log.error("Property conetnt is invalid - {}",data); + // return Either.right(ActionStatus.INVALID_CONTENT); + // } + // UiProperty uiProperty = uiPropertyEither.left().value(); + // String json = convertUiPropertyToJsonModel(uiProperty); + // return Either.left(json); + // } + // + + // private String convertUiPropertyToJsonModel(UiProperty uiProperty) { + // JSONObject root = new JSONObject(); + // JSONObject propertyD = new JSONObject(); + // propertyD.put("type",uiProperty.getType()); + // propertyD.put("required",false); + // propertyD.put("description",uiProperty.getDescription()); + // propertyD.put("isPassword",false); + // propertyD.put("defaultValue",uiProperty.getSource()); + // JSONArray jsonArr = new JSONArray(); + // JSONArray jsonR = new JSONArray(); + // jsonR.add(100); + // jsonR.add(500); + // JSONObject o = new JSONObject(); + // o.put("inRange", jsonR); + // jsonArr.add(o); + // propertyD.put("constraints",jsonArr); + // root.put(uiProperty.getName(), propertyD); + // return root.toString(); + // } + + private Either, ActionStatus> getPropertyModel(String data) { + JSONParser parser = new JSONParser(); + JSONObject root; + try { + Map properties = new HashMap(); + root = (JSONObject) parser.parse(data); + + Set entrySet = root.entrySet(); + Iterator iterator = entrySet.iterator(); + while (iterator.hasNext()) { + Entry next = (Entry) iterator.next(); + String propertyName = (String) next.getKey(); + JSONObject value = (JSONObject) next.getValue(); + String jsonString = value.toJSONString(); + Either convertJsonToObject = convertJsonToObject(jsonString, PropertyDefinition.class); + if (convertJsonToObject.isRight()) { + return Either.right(convertJsonToObject.right().value()); + } + PropertyDefinition propertyDefinition = convertJsonToObject.left().value(); + // PropertyDefinition propertyDefinition = + // gson.fromJson(jsonString , PropertyDefinition.class); + String uniqueId = UniqueIdBuilder.buildPropertyUniqueId("resourceId", (String) propertyName); + propertyDefinition.setUniqueId(uniqueId); + properties.put(propertyName, propertyDefinition); + } + + // Set keySet = root.keySet(); + // for (Object propertyName : keySet){ + // JSONObject val = (JSONObject) root.get(propertyName); + // String jsonString = val.toJSONString(); + // Either convertJsonToObject = + // convertJsonToObject(jsonString, PropertyDefinition.class); + // if (convertJsonToObject.isRight()){ + // return Either.right(convertJsonToObject.right().value()); + // } + // PropertyDefinition propertyDefinition = + // convertJsonToObject.left().value(); + // //PropertyDefinition propertyDefinition = + // gson.fromJson(jsonString , PropertyDefinition.class); + // String uniqueId = + // UniqueIdBuilder.buildPropertyUniqueId("resourceId", + // (String)propertyName); + // propertyDefinition.setUniqueId(uniqueId); + // properties.put((String)propertyName,propertyDefinition); + // } + return Either.left(properties); + } catch (ParseException e) { + log.info("Property conetnt is invalid - {}", data); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } + + // private Either,ActionStatus> + // getProperty(String data){ + // Type constraintType = new TypeToken() {}.getType(); + // PropertyConstraintDeserialiser propertyConstraintDeserialiser = new + // PropertyConstraintDeserialiser(); + // Gson gson = new + // GsonBuilder().registerTypeAdapter(constraintType,propertyConstraintDeserialiser).create(); + // JSONParser parser = new JSONParser(); + // JSONObject root; + // try { + // Map properties = new + // HashMap(); + // root = (JSONObject) parser.parse(data); + // Set keySet = root.keySet(); + // for (Object propertyName : keySet){ + // JSONObject val = (JSONObject) root.get(propertyName); + // String jsonString = val.toJSONString(); + // PropertyDefinition propertyDefinition = gson.fromJson(jsonString , + // PropertyDefinition.class); + // String uniqueId = UniqueIdBuilder.buildPropertyUniqueId("resourceId", + // (String)propertyName); + // propertyDefinition.setUniqueId(uniqueId); + // properties.put((String)propertyName,propertyDefinition); + // } + // return Either.left(properties); + // } catch (ParseException e) { + // log.error("Property conetnt is invalid - {}",data); + // return Either.right(ActionStatus.INVALID_CONTENT); + // } + // } + // + // private Either getUiProperty(String data) { + // try{ + // Gson gson = new Gson(); + // UiProperty uiProperty = gson.fromJson(data, UiProperty.class); + // return Either.left(uiProperty); + // }catch(JsonSyntaxException e){ + // log.warn("Problem create UiProperty from {}",data); + // log.debug("Problem create UiProperty from {}",data,e); + // return Either.right(ActionStatus.INVALID_CONTENT); + // } + // } + + private String propertyToJson(Map.Entry property) { + // Type constraintType = new TypeToken() + // {}.getType(); + // Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new + // PropertyConstraintDeserialiser()).create(); + JSONObject root = new JSONObject(); + String propertyName = property.getKey(); + PropertyDefinition propertyDefinition = property.getValue(); + // String jsonPropertyDefinition = gson.toJson(propertyDefinition); + // root.put(propertyName, jsonPropertyDefinition); + JSONObject propertyDefinitionO = getPropertyDefinitionJSONObject(propertyDefinition); + root.put(propertyName, propertyDefinitionO); + propertyDefinition.getType(); + return root.toString(); + } + + private JSONObject getPropertyDefinitionJSONObject(PropertyDefinition propertyDefinition) { + + Either either = convertObjectToJson(propertyDefinition); + if (either.isRight()) { + return new JSONObject(); + } + String value = either.left().value(); + try { + JSONObject root = (JSONObject) new JSONParser().parse(value); + return root; + } catch (ParseException e) { + log.info("failed to convert input to json"); + log.debug("failed to convert to json", e); + return new JSONObject(); + } + + } + + // private JSONObject getPropertyDefinitionJSONObject(PropertyDefinition + // propertyDefinition) { + // JSONObject root = new JSONObject(); + // root.put("type", propertyDefinition.getType()); + // root.put("required", propertyDefinition.isRequired()); + // root.put("defaultValue", propertyDefinition.getDefaultValue()); + // root.put("description", propertyDefinition.getDescription()); + // root.put("isPassword", propertyDefinition.isPassword()); + // List constraints = + // propertyDefinition.getConstraints(); + // for (PropertyConstraint p : constraints){ + // p.toString(); + // } + // root.put("constraints", propertyDefinition.getConstraints()); + // return root; + // } + + private Either convertJsonToObject(String data, Class clazz) { + T t = null; + Type constraintType = new TypeToken() { + }.getType(); + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintDeserialiser()).create(); + try { + log.trace("convert json to object. json=\n{}", data); + t = gson.fromJson(data, clazz); + if (t == null) { + log.info("object is null after converting from json"); + return Either.right(ActionStatus.INVALID_CONTENT); + } + } catch (Exception e) { + // INVALID JSON + log.info("failed to convert from json"); + log.debug("failed to convert from json", e); + return Either.right(ActionStatus.INVALID_CONTENT); + } + return Either.left(t); + } + + private Either convertObjectToJson(PropertyDefinition propertyDefinition) { + Type constraintType = new TypeToken() { + }.getType(); + Gson gson = new GsonBuilder().registerTypeAdapter(constraintType, new PropertyConstraintSerialiser()).create(); + try { + log.trace("convert object to json. propertyDefinition={}", propertyDefinition.toString()); + String json = gson.toJson(propertyDefinition); + if (json == null) { + log.info("object is null after converting to json"); + return Either.right(ActionStatus.INVALID_CONTENT); + } + return Either.left(json); + } catch (Exception e) { + // INVALID JSON + log.info("failed to convert to json"); + log.debug("failed to convert fto json", e); + return Either.right(ActionStatus.INVALID_CONTENT); + } + + } + + private PropertyBusinessLogic getPropertyBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + PropertyBusinessLogic propertytBl = webApplicationContext.getBean(PropertyBusinessLogic.class); + return propertytBl; + } + + // private class UiProperty{ + // String type; + // String source; + // String name; + // String description; + // public String getType() { + // return type; + // } + // public void setType(String type) { + // this.type = type; + // } + // public String getSource() { + // return source; + // } + // public void setSource(String source) { + // this.source = source; + // } + // public String getName() { + // return name; + // } + // public void setName(String name) { + // this.name = name; + // } + // public String getDescription() { + // return description; + // } + // public void setDescription(String description) { + // this.description = description; + // } + // + // } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java new file mode 100644 index 0000000000..565911eaa9 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RepresentationUtils.java @@ -0,0 +1,124 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.IOException; + +import org.codehaus.jackson.JsonGenerationException; +import org.codehaus.jackson.map.DeserializationConfig; +import org.codehaus.jackson.map.JsonMappingException; +import org.codehaus.jackson.map.ObjectMapper; +import org.codehaus.jackson.map.SerializationConfig.Feature; +import org.codehaus.jackson.map.annotate.JsonSerialize; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; + +public class RepresentationUtils { + + private static Logger log = LoggerFactory.getLogger(RepresentationUtils.class.getName()); + + public static class ResourceRep { + + } + + /** + * Build Representation of given Object + * + * @param elementToRepresent + * @return + * @throws IOException + * @throws JsonGenerationException + * @throws JsonMappingException + */ + public static Object toRepresentation(T elementToRepresent) throws IOException, JsonGenerationException, JsonMappingException { + + // return theResource; + ObjectMapper mapper = new ObjectMapper(); + mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false); + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); + return mapper.writeValueAsString(elementToRepresent); + } + + public static T fromRepresentation(String json, Class clazz) { + ObjectMapper mapper = new ObjectMapper(); + T object = null; + mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + mapper.configure(Feature.FAIL_ON_EMPTY_BEANS, false); + mapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL); + try { + object = mapper.readValue(json, clazz); + } catch (Exception e) { + log.error("Error when parsing JSON of object of type {}", clazz.getSimpleName(), e); + } // return null in case of exception + + return object; + } + + public static ArtifactDefinition convertJsonToArtifactDefinition(String content, Class clazz) { + + JsonObject jsonElement = new JsonObject(); + ArtifactDefinition resourceInfo = null; + try { + Gson gson = new Gson(); + jsonElement = gson.fromJson(content, jsonElement.getClass()); + JsonElement artifactGroupValue = jsonElement.get(Constants.ARTIFACT_GROUP_TYPE_FIELD); + if (artifactGroupValue != null && !artifactGroupValue.isJsonNull()) { + String groupValueUpper = artifactGroupValue.getAsString().toUpperCase(); + if (!ArtifactGroupTypeEnum.getAllTypes().contains(groupValueUpper)) { + StringBuilder sb = new StringBuilder(); + for (String value : ArtifactGroupTypeEnum.getAllTypes()) { + sb.append(value).append(", "); + } + log.debug("artifactGroupType is {}. valid values are: {}", groupValueUpper, sb.toString()); + return null; + } else { + jsonElement.remove(Constants.ARTIFACT_GROUP_TYPE_FIELD); + jsonElement.addProperty(Constants.ARTIFACT_GROUP_TYPE_FIELD, groupValueUpper); + } + } + String payload = null; + JsonElement artifactPayload = jsonElement.get(Constants.ARTIFACT_PAYLOAD_DATA); + if (artifactPayload != null && !artifactPayload.isJsonNull()) { + payload = artifactPayload.getAsString(); + } + jsonElement.remove(Constants.ARTIFACT_PAYLOAD_DATA); + resourceInfo = gson.fromJson(jsonElement, clazz); + resourceInfo.setPayloadData(payload); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeArtifactInformationInvalidError, "Artifact Upload / Update"); + BeEcompErrorManager.getInstance().logBeArtifactInformationInvalidError("Artifact Upload / Update"); + log.debug("Failed to convert the content {} to object. {}", content.substring(0, Math.min(50, content.length())), e); + } + + return resourceInfo; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java new file mode 100644 index 0000000000..e853ee4f7f --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/RequirementsServlet.java @@ -0,0 +1,84 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonSyntaxException; +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +public class RequirementsServlet extends BeGenericServlet { + + private static Logger log = LoggerFactory.getLogger(RequirementsServlet.class.getName()); + + @PUT + @Path("resources/{resourceId}/requirements/{requirementId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Requirement", httpMethod = "PUT", notes = "Returns updated requirement", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource requirement updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateRequirement(@ApiParam(value = "resource id to update with new requirement", required = true) @PathParam("resourceId") final String resourceId, + @ApiParam(value = "requirement id to update", required = true) @PathParam("requirementId") final String requirementId, @ApiParam(value = "Resource property to update", required = true) String requirementData, + @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + // Convert RequirementDefinition from JSON + // TODO: it's going to be another object, probably. This is placeholder + // for sake of JSON validation + // RequirementDefinition requirementDefinition; + ResponseFormat responseFormat; + try { + // requirementDefinition = gson.fromJson(requirementData, + // RequirementDefinition.class); + // ..... + + // TODO pass real entity + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + } catch (JsonSyntaxException e) { + // INVALID JSON + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT); + return buildErrorResponse(responseFormat); + } catch (Exception e) { + log.debug("Unexpected error: {}", e); + responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceArtifactDownloadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceArtifactDownloadServlet.java new file mode 100644 index 0000000000..673187b0a1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceArtifactDownloadServlet.java @@ -0,0 +1,188 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.api.ResourceUploadStatus; +import org.openecomp.sdc.be.impl.DownloadArtifactLogic; +import org.openecomp.sdc.be.info.ArtifactAccessInfo; +import org.openecomp.sdc.be.resources.api.IResourceUploader; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.jcabi.aspects.Loggable; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/resources/available") +public class ResourceArtifactDownloadServlet extends ToscaDaoServlet { + + private static Logger log = LoggerFactory.getLogger(ResourceArtifactDownloadServlet.class.getName()); + + private Gson gson = new GsonBuilder().setPrettyPrinting().create(); + + // @GET + // @Path("/{resourceName}/{resourceVersion}/artifacts") + // @Produces(MediaType.APPLICATION_JSON) + // public Response getResourceArtifactList(@PathParam("resourceName") final + // String resourceName, + // @PathParam("resourceVersion") final String resourceVersion, + // @Context final HttpServletRequest request){ + // + // + // String url = request.getMethod() + " " + request.getRequestURI(); + // log.info("Start handle request of {}", url); + // + // Response response = null; + // + // // get artifact list from dao + // IResourceUploader resourceDao = + // getResourceUploader(request.getSession().getServletContext()); + // if (resourceDao == null){ + // log.error("resource dao cannot be found"); + // response = buildResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, + // "Resource dao cannot be found"); + // return response; + // } + // Either, ResourceUploadStatus> getArtifactsStatus = + // resourceDao.getArtifacts(resourceName, resourceVersion); + // + // response = + // getLogic(request.getSession().getServletContext()).createArtifactListResponse(resourceName, + // getArtifactsStatus, getServletPath(request)); + // + // log.info("Finish handle request of {} | result = {}", url, response.getStatus() ); + // return response; + // + // } + + @GET + @Path("/{resourceName}/{resourceVersion}/artifacts/{artifactName}") + // @Produces(MediaType.APPLICATION_OCTET_STREAM) + public Response getResourceArtifactByName(@PathParam("resourceName") final String resourceName, @PathParam("resourceVersion") final String resourceVersion, @PathParam("artifactName") final String artifactName, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + Response response = null; + try { + // get the artifact data + String artifactId = String.format(Constants.ARTIFACT_ID_FORMAT, resourceName, resourceVersion, artifactName); + + IResourceUploader resouceUploader = getResourceUploader(request.getSession().getServletContext()); + if (resouceUploader == null) { + return buildResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ""); + + } + Either getArtifactStatus = resouceUploader.getArtifact(artifactId); + + DownloadArtifactLogic logic = getLogic(request.getSession().getServletContext()); + if (logic == null) { + return buildResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, ""); + + } + response = logic.downloadArtifact(resourceName, resourceVersion, artifactName, getArtifactStatus, artifactId); + + log.info("Finish handle request of {} | result = {}", url, response.getStatus()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Resource Artifact By Name"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource Artifact By Name"); + log.debug("getResourceArtifactByName failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/{resourceName}/{resourceVersion}/artifacts/{artifactName}/metadata") + @Produces(MediaType.APPLICATION_JSON) + public Response getResourceArtifactMetadata(@PathParam("resourceName") final String resourceName, @PathParam("resourceVersion") final String resourceVersion, @PathParam("artifactName") final String artifactName, + @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + Response response = null; + try { + IResourceUploader resourceDao = getResourceUploader(request.getSession().getServletContext()); + if (resourceDao == null) { + log.error("resource dao cannot be found"); + response = buildResponse(HttpStatus.SC_INTERNAL_SERVER_ERROR, "Resource dao cannot be found"); + return response; + } + + String artifactId = String.format(Constants.ARTIFACT_ID_FORMAT, resourceName, resourceVersion, artifactName); + Either getArtifactStatus = resourceDao.getArtifact(artifactId); + + if (getArtifactStatus.isRight()) { + ResourceUploadStatus status = getArtifactStatus.right().value(); + if (status == ResourceUploadStatus.COMPONENT_NOT_EXIST) { + response = Response.status(HttpStatus.SC_NOT_FOUND).build(); + log.debug("Could not find artifact for with id: {}", artifactId); + } else { + response = Response.status(HttpStatus.SC_NO_CONTENT).build(); + log.debug("Could not find artifact for with id: {}", artifactId); + } + return response; + } else { + ESArtifactData artifactData = getArtifactStatus.left().value(); + log.debug("found artifact with id: {}", artifactId); + ArtifactAccessInfo artifactInfo = new ArtifactAccessInfo(artifactData); + String artifactDataJson = gson.toJson(artifactInfo); + response = Response.status(HttpStatus.SC_OK).entity(artifactDataJson).type(MediaType.APPLICATION_JSON_TYPE).build(); + + log.info("Finish handle request of {} | result = {}", url, response.getStatus()); + return response; + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Resource Artifact Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource Artifact Metadata"); + log.debug("getResourceArtifactMetadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + + } + + @Override + public Logger getLogger() { + return log; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java new file mode 100644 index 0000000000..5cd765abe0 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourceUploadServlet.java @@ -0,0 +1,180 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.File; + +import javax.annotation.Resource; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DefaultValue; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.glassfish.jersey.media.multipart.FormDataContentDisposition; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.ResourceImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +/** + * Root resource (exposed at "/" path) + */ +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/upload") +@Api(value = "Resources Catalog Upload", description = "Upload resource yaml") +@Singleton +public class ResourceUploadServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(ResourceUploadServlet.class.getName()); + public static final String NORMATIVE_TYPE_RESOURCE = "multipart"; + public static final String USER_TYPE_RESOURCE = "user-resource"; + public static final String USER_TYPE_RESOURCE_UI_IMPORT = "user-resource-ui-import"; + + public enum ResourceAuthorityTypeEnum { + NORMATIVE_TYPE_BE(NORMATIVE_TYPE_RESOURCE, true, false), USER_TYPE_BE(USER_TYPE_RESOURCE, true, true), USER_TYPE_UI(USER_TYPE_RESOURCE_UI_IMPORT, false, true); + + private String urlPath; + private boolean isBackEndImport, isUserTypeResource; + + public static ResourceAuthorityTypeEnum findByUrlPath(String urlPath) { + ResourceAuthorityTypeEnum found = null; + for (ResourceAuthorityTypeEnum curr : ResourceAuthorityTypeEnum.values()) { + if (curr.getUrlPath().equals(urlPath)) { + found = curr; + break; + } + } + return found; + } + + private ResourceAuthorityTypeEnum(String urlPath, boolean isBackEndImport, boolean isUserTypeResource) { + this.urlPath = urlPath; + this.isBackEndImport = isBackEndImport; + this.isUserTypeResource = isUserTypeResource; + } + + public String getUrlPath() { + return urlPath; + } + + public boolean isBackEndImport() { + return isBackEndImport; + } + + public boolean isUserTypeResource() { + return isUserTypeResource; + } + } + + @Resource + private ResourceImportManager resourceImportManager; + + @POST + @Path("/{resourceAuthority}") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource from yaml", httpMethod = "POST", notes = "Returns created resource", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Resource already exist") }) + public Response uploadMultipart( + @ApiParam(value = "validValues: normative-resource / user-resource", allowableValues = NORMATIVE_TYPE_RESOURCE + "," + USER_TYPE_RESOURCE + "," + + USER_TYPE_RESOURCE_UI_IMPORT) @PathParam(value = "resourceAuthority") final String resourceAuthority, + @ApiParam("FileInputStream") @FormDataParam("resourceZip") File file, @ApiParam("ContentDisposition") @FormDataParam("resourceZip") FormDataContentDisposition contentDispositionHeader, + @ApiParam("resourceMetadata") @FormDataParam("resourceMetadata") String resourceInfoJsonString, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + // updateResourse Query Parameter if false checks if already exist + @DefaultValue("true") @QueryParam("createNewVersion") boolean createNewVersion) { + + init(request.getSession().getServletContext()); + try { + + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // When we get an errorResponse it will be filled into the + // responseWrapper + validateAuthorityType(responseWrapper, resourceAuthority); + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.findByUrlPath(resourceAuthority); + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); + + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, file); + + // PayLoad Validations + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, createNewVersion, null); + } + + return responseWrapper.getInnerElement(); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Upload Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Upload Resource"); + log.debug("upload resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /********************************************************************************************************************/ + + private void init(ServletContext context) { + init(log); + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + resourceImportManager = webApplicationContext.getBean(ResourceImportManager.class); + resourceImportManager.init(context); + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java new file mode 100644 index 0000000000..e3d39610a8 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ResourcesServlet.java @@ -0,0 +1,692 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.FileNotFoundException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.http.HttpStatus; +import org.json.JSONObject; +import org.openecomp.sdc.be.components.impl.CsarValidationUtils; +import org.openecomp.sdc.be.components.impl.ImportUtils; +import org.openecomp.sdc.be.components.impl.ResourceBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datamodel.api.HighestFilterEnum; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.ResourceMetadataDefinition; +import org.openecomp.sdc.be.model.UploadResourceInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.servlets.ResourceUploadServlet.ResourceAuthorityTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Resources Catalog", description = "Resources Servlet") +@Singleton +public class ResourcesServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(ResourcesServlet.class.getName()); + + @POST + @Path("/resources") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource", httpMethod = "POST", notes = "Returns created resource", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Resource already exist") }) + public Response createResource(@ApiParam(value = "Resource object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(log); + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, null); + } + // UI Create + else { + + ResourceBusinessLogic businessLogic = getResourceBL(context); + + Either convertResponse = parseToResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Resource resource = convertResponse.left().value(); + Either actionResponse = businessLogic.createResource(resource, modifier, null, null); + + if (actionResponse.isRight()) { + log.debug("failed to create resource"); + response = buildErrorResponse(actionResponse.right().value()); + } else { + Object representation = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), representation); + } + responseWrapper.setInnerElement(response); + } + + return responseWrapper.getInnerElement(); + + // return response; + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Resource"); + log.debug("create resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + private boolean isUIImport(String data) { + boolean isUIImport; + try { + JSONObject json = new JSONObject(data); + String payloadName = json.getString(ImportUtils.Constants.UI_JSON_PAYLOAD_NAME); + isUIImport = payloadName != null && !payloadName.isEmpty(); + } catch (Exception e) { + log.debug("failed to parse json sent from client, json:{}", data); + isUIImport = false; + } + return isUIImport; + } + + private void performUIImport(Wrapper responseWrapper, String data, final HttpServletRequest request, String userId, String resourceUniqueId) throws FileNotFoundException { + + Wrapper userWrapper = new Wrapper<>(); + Wrapper uploadResourceInfoWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + String resourceInfoJsonString = data; + + ResourceAuthorityTypeEnum resourceAuthorityEnum = ResourceAuthorityTypeEnum.USER_TYPE_UI; + + commonGeneralValidations(responseWrapper, userWrapper, uploadResourceInfoWrapper, resourceAuthorityEnum, userId, resourceInfoJsonString); + + // TODO suspect next line is unnecessary + userWrapper.getInnerElement(); + if (!CsarValidationUtils.isCsarPayloadName(uploadResourceInfoWrapper.getInnerElement().getPayloadName())) { + fillPayload(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), resourceInfoJsonString, resourceAuthorityEnum, null); + + // PayLoad Validations + commonPayloadValidations(responseWrapper, yamlStringWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement()); + } + specificResourceAuthorityValidations(responseWrapper, uploadResourceInfoWrapper, yamlStringWrapper, userWrapper.getInnerElement(), request, resourceInfoJsonString, resourceAuthorityEnum); + + if (responseWrapper.isEmpty()) { + handleImport(responseWrapper, userWrapper.getInnerElement(), uploadResourceInfoWrapper.getInnerElement(), yamlStringWrapper.getInnerElement(), resourceAuthorityEnum, true, resourceUniqueId); + } + } + + public Either parseToResource(String resourceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.RESOURCE); + } + + public Either parseToLightResource(String resourceJson, User user) { + Either ret = getComponentsUtils().convertJsonToObjectUsingObjectMapper(resourceJson, user, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (ret.isLeft()) {// drop unwanted data (sent from UI in update flow) + ret.left().value().setRequirements(null); + ret.left().value().setCapabilities(null); + } + return ret; + } + + @DELETE + @Path("/resources/{resourceId}") + public Response deleteResource(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String resourceIdLower = resourceId.toLowerCase(); + ResourceBusinessLogic businessLogic = getResourceBL(context); + ResponseFormat actionResponse = businessLogic.deleteResource(resourceIdLower, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/resources/{resourceName}/{version}") + public Response deleteResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ResourceBusinessLogic businessLogic = getResourceBL(context); + ResponseFormat actionResponse = businessLogic.deleteResourceByNameAndVersion(resourceName, version, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete resource"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Resource"); + log.debug("delete resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Resource", httpMethod = "GET", notes = "Returns resource according to resourceId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Resource not found") }) + public Response getResourceById(@PathParam("resourceId") final String resourceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String resourceIdLower = resourceId.toLowerCase(); + ResourceBusinessLogic businessLogic = getResourceBL(context); + log.trace("get resource with id {}", resourceId); + Either actionResponse = businessLogic.getResource(resourceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get resource"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/resourceName/{resourceName}/resourceVersion/{resourceVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Resource by name and version", httpMethod = "GET", notes = "Returns resource according to resourceId", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Resource not found") }) + public Response getResourceByNameAndVersion(@PathParam("resourceName") final String resourceName, @PathParam("resourceVersion") final String resourceVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + ResourceBusinessLogic businessLogic = getResourceBL(context); + Either, ResponseFormat> actionResponse = businessLogic.getResourceByNameAndVersion(resourceName, resourceVersion, userId); + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Resource by name and version"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Resource by name and version"); + log.debug("get resource failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/resources/validate-name/{resourceName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "validate resource name", httpMethod = "GET", notes = "checks if the chosen resource name is available ", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource found"), @ApiResponse(code = 403, message = "Restricted operation") }) + public Response validateResourceName(@PathParam("resourceName") final String resourceName, @QueryParam("subtype") String resourceType, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + ResourceBusinessLogic businessLogic = getResourceBL(context); + + if (resourceType != null && !ResourceTypeEnum.contains(resourceType)) { + log.debug("invalid resource type received"); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.INVALID_CONTENT)); + return response; + + } + ResourceTypeEnum typeEnum = null; + if (resourceType != null) { + typeEnum = ResourceTypeEnum.valueOf(resourceType); + } + Either, ResponseFormat> actionResponse = businessLogic.validateResourceNameExists(resourceName, typeEnum, userId); + + if (actionResponse.isRight()) { + log.debug("failed to validate resource name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Validate Resource Name"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Resource Name"); + log.debug("validate resource name failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/resources/certified/abstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + // TODO: any validations??? + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + try { + + ResourceBusinessLogic businessLogic = getResourceBL(context); + + Either, ResponseFormat> actionResponse = businessLogic.getAllCertifiedResources(true, HighestFilterEnum.HIGHEST_ONLY, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get all abstract resources"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resources = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resources); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Certified Abstract Resources"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Abstract Resources"); + log.debug("getCertifiedAbstractResources failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/resources/certified/notabstract") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Response getCertifiedNotAbstractResources(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + // TODO: any vlidations??? + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + Response response = null; + + try { + + ResourceBusinessLogic businessLogic = getResourceBL(context); + + Either, ResponseFormat> actionResponse = businessLogic.getAllCertifiedResources(false, HighestFilterEnum.ALL, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get all non abstract resources"); + return buildErrorResponse(actionResponse.right().value()); + } + Object resources = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resources); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Certified Non Abstract Resources"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Certified Non Abstract Resources"); + log.debug("getCertifiedNotAbstractResources failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + + } + + @PUT + @Path("/resources/{resourceId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource Metadata", httpMethod = "PUT", notes = "Returns updated resource metadata", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource metadata updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content") }) + public Response updateResourceMetadata(@PathParam("resourceId") final String resourceId, @ApiParam(value = "Resource metadata to be updated", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ResourceBusinessLogic businessLogic = getResourceBL(context); + String resourceIdLower = resourceId.toLowerCase(); + Either updateInfoResource = getComponentsUtils().convertJsonToObjectUsingObjectMapper(data, modifier, Resource.class, AuditingActionEnum.UPDATE_RESOURCE_METADATA, ComponentTypeEnum.RESOURCE); + if (updateInfoResource.isRight()) { + log.debug("failed to parse resource metadata"); + response = buildErrorResponse(updateInfoResource.right().value()); + return response; + } + Either actionResponse = businessLogic.updateResourceMetadata(resourceIdLower, + updateInfoResource.left().value(), null, modifier, false); + + if (actionResponse.isRight()) { + log.debug("failed to update resource metadata"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Object resource = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), resource); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Resource Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource Metadata"); + log.debug("Update Resource Metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/resources/{resourceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Resource", httpMethod = "PUT", notes = "Returns updated resource", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Resource updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Resource already exist") }) + public Response updateResource(@ApiParam(value = "Resource object to be updated", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, + @PathParam(value = "resourceId") String resourceId) { + + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + init(log); + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + + Wrapper responseWrapper = new Wrapper<>(); + // UI Import + if (isUIImport(data)) { + performUIImport(responseWrapper, data, request, userId, resourceId); + } else { + + ResourceBusinessLogic businessLogic = getResourceBL(context); + + Either convertResponse = parseToLightResource(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse resource"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Resource resource = convertResponse.left().value(); + Either actionResponse = businessLogic.validateAndUpdateResourceFromCsar(resource, modifier, null, null, resourceId); + + if (actionResponse.isRight()) { + log.debug("failed to update resource"); + response = buildErrorResponse(actionResponse.right().value()); + } else { + Object representation = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + } + responseWrapper.setInnerElement(response); + } + + return responseWrapper.getInnerElement(); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Resource"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Resource"); + log.debug("update resource failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /* + * @GET + * + * @Path("/resources/latestversion/notabstract") + * + * @Consumes(MediaType.APPLICATION_JSON) + * + * @Produces(MediaType.APPLICATION_JSON) public Response getLatestVersionNotAbstractResources(@Context final HttpServletRequest request) { //TODO: any vlidations??? ServletContext context = request.getSession().getServletContext(); + * + * String url = request.getMethod() + " " + request.getRequestURI(); log.debug("(get) Start handle request of {}", url); Response response=null; + * + * try { + * + * ResourceBusinessLogic businessLogic = getResourceBL(context); + * + * Either, ResponseFormat> actionResponse = businessLogic.getLatestVersionResources(false, HighestFilterEnum.HIGHEST_ONLY); + * + * + * if (actionResponse.isRight()){ log.debug( "failed to get all non abstract resources"); return buildErrorResponse(actionResponse.right().value()); } return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), + * actionResponse.left().value()); + * + * } catch (Exception e){ BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeRestApiGeneralError, "Get Certified Non Abstract Resources"); log.debug("getCertifiedNotAbstractResources failed with exception", e); response = + * buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus. GENERAL_ERROR)); return response; + * + * } } + */ + public static List convertMapToList(Map properties) { + if (properties == null) { + return null; + } + + List definitions = new ArrayList<>(); + for (Entry entry : properties.entrySet()) { + String name = entry.getKey(); + PropertyDefinition propertyDefinition = entry.getValue(); + propertyDefinition.setName(name); + definitions.add(propertyDefinition); + } + + return definitions; + } + + @GET + @Path("/resources/csar/{csaruuid}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Resource", httpMethod = "POST", notes = "Returns resource created from csar uuid", response = Resource.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Resource retrieced"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response getResourceFromCsar(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @PathParam(value = "csaruuid") String csarUUID) { + + init(log); + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // retrieve user details + userId = (userId != null) ? userId : request.getHeader(Constants.USER_ID_HEADER); + User user = new User(); + user.setUserId(userId); + + log.debug("user id is {}", userId); + + Response response = null; + + try { + + ResourceBusinessLogic businessLogic = getResourceBL(context); + + Either eitherResource = businessLogic.getLatestResourceFromCsarUuid(csarUUID, user); + + // validate response + if (eitherResource.isRight()) { + log.debug("failed to get resource from csarUuid : {}", csarUUID); + // response = + // buildErrorResponse(eitherResource.right().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), eitherResource.right().value()); + } else { + Object representation = RepresentationUtils.toRepresentation(eitherResource.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), representation); + } + + return response; + + } catch (Exception e) { + log.debug("get resource by csar failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java new file mode 100644 index 0000000000..7e7068f5d7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ServiceServlet.java @@ -0,0 +1,728 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.text.MessageFormat; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.http.HttpStatus; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.components.lifecycle.LifecycleChangeInfoWithAction; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.Configuration; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.model.DistributionStatusEnum; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Service Catalog", description = "Service Servlet") +@Singleton +public class ServiceServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(ServiceServlet.class.getName()); + + @POST + @Path("/services") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Service", httpMethod = "POST", notes = "Returns created service", response = Service.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Service created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Service already exist") }) + public Response createService(@ApiParam(value = "Service object to be created", required = true) String data, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Either convertResponse = parseToService(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse service"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + + Service service = convertResponse.left().value(); + Either actionResponse = businessLogic.createService(service, modifier); + + if (actionResponse.isRight()) { + log.debug("Failed to create service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Object result = RepresentationUtils.toRepresentation(actionResponse.left().value()); + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), result); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Create Service"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create Service"); + log.debug("create service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + public Either parseToService(String serviceJson, User user) { + return getComponentsUtils().convertJsonToObjectUsingObjectMapper(serviceJson, user, Service.class, AuditingActionEnum.CREATE_RESOURCE, ComponentTypeEnum.SERVICE); + } + + @GET + @Path("/services/validate-name/{serviceName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "validate service name", httpMethod = "GET", notes = "checks if the chosen service name is available ", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) + public Response validateServiceName(@PathParam("serviceName") final String serviceName, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + + Either, ResponseFormat> actionResponse = businessLogic.validateServiceNameExists(serviceName, userId); + + if (actionResponse.isRight()) { + log.debug("failed to get validate service name"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), actionResponse.left().value()); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Validate Service Name"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); + log.debug("validate service name failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/audit-records/{componentType}/{componentUniqueId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "get component audit records", httpMethod = "GET", notes = "get audit records for a service or a resource", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation") }) + public Response getComponentAuditRecords(@PathParam("componentType") final String componentType, @PathParam("componentUniqueId") final String componentUniqueId, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + init(log); + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + Wrapper responseWrapper = new Wrapper(); + Wrapper uuidWrapper = new Wrapper(); + Wrapper versionWrapper = new Wrapper(); + Wrapper userWrapper = new Wrapper(); + Wrapper componentWrapper = new Wrapper(); + try { + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + validateComponentType(responseWrapper, componentWrapper, componentType); + } + + if (responseWrapper.isEmpty()) { + fillUUIDAndVersion(responseWrapper, uuidWrapper, versionWrapper, userWrapper.getInnerElement(), componentWrapper.getInnerElement(), componentUniqueId, context); + } + + if (responseWrapper.isEmpty()) { + Either>, ResponseFormat> eitherServiceAudit = getServiceBL(context).getComponentAuditRecords(versionWrapper.getInnerElement(), uuidWrapper.getInnerElement(), userId); + + if (eitherServiceAudit.isRight()) { + Response errorResponse = buildErrorResponse(eitherServiceAudit.right().value()); + responseWrapper.setInnerElement(errorResponse); + } else { + List> auditRecords = eitherServiceAudit.left().value(); + Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), auditRecords); + responseWrapper.setInnerElement(okResponse); + + } + } + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Validate Service Name"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Validate Service Name"); + log.debug("get Service Audit Records failed with exception", e); + Response errorResponse = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(errorResponse); + } + return responseWrapper.getInnerElement(); + } + + private void fillUUIDAndVersion(Wrapper responseWrapper, Wrapper uuidWrapper, Wrapper versionWrapper, User user, final ComponentTypeEnum componentTypeEnum, final String componentUniqueId, ServletContext context) { + + if (componentTypeEnum == ComponentTypeEnum.RESOURCE) { + Either eitherResource = getResourceBL(context).getResource(componentUniqueId, user); + if (eitherResource.isLeft()) { + uuidWrapper.setInnerElement(eitherResource.left().value().getUUID()); + versionWrapper.setInnerElement(eitherResource.left().value().getVersion()); + } else { + responseWrapper.setInnerElement(buildErrorResponse(eitherResource.right().value())); + } + + } else { + Either eitherService = getServiceBL(context).getService(componentUniqueId, user); + if (eitherService.isLeft()) { + uuidWrapper.setInnerElement(eitherService.left().value().getUUID()); + versionWrapper.setInnerElement(eitherService.left().value().getVersion()); + } else { + responseWrapper.setInnerElement(buildErrorResponse(eitherService.right().value())); + + } + } + } + + @DELETE + @Path("/services/{serviceId}") + public Response deleteService(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String serviceIdLower = serviceId.toLowerCase(); + ServiceBusinessLogic businessLogic = getServiceBL(context); + ResponseFormat actionResponse = businessLogic.deleteService(serviceIdLower, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete service"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Service"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); + log.debug("delete service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @DELETE + @Path("/services/{serviceName}/{version}") + public Response deleteServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("version") final String version, @Context final HttpServletRequest request) { + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + String userId = request.getHeader(Constants.USER_ID_HEADER); + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + ResponseFormat actionResponse = businessLogic.deleteServiceByNameAndVersion(serviceName, version, modifier); + + if (actionResponse.getStatus() != HttpStatus.SC_NO_CONTENT) { + log.debug("failed to delete service"); + response = buildErrorResponse(actionResponse); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.NO_CONTENT), null); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Delete Service"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Delete Service"); + log.debug("delete service failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @PUT + @Path("/services/{serviceId}/metadata") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Service Metadata", httpMethod = "PUT", notes = "Returns updated service", response = Service.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service Updated"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content") }) + public Response updateServiceMetadata(@PathParam("serviceId") final String serviceId, @ApiParam(value = "Service object to be Updated", required = true) String data, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + + try { + String serviceIdLower = serviceId.toLowerCase(); + ServiceBusinessLogic businessLogic = getServiceBL(context); + + Either convertResponse = parseToService(data, modifier); + if (convertResponse.isRight()) { + log.debug("failed to parse service"); + response = buildErrorResponse(convertResponse.right().value()); + return response; + } + Service updatedService = convertResponse.left().value(); + Either actionResponse = businessLogic.updateServiceMetadata(serviceIdLower, updatedService, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to update service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Service Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Metadata"); + log.debug("update service metadata failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + @GET + @Path("/services/{serviceId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to serviceId", response = Service.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) + public Response getServiceById(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + String serviceIdLower = serviceId.toLowerCase(); + ServiceBusinessLogic businessLogic = getServiceBL(context); + log.debug("get service with id {}", serviceId); + Either actionResponse = businessLogic.getService(serviceIdLower, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to get service"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Service"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service"); + log.debug("get service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @GET + @Path("/services/serviceName/{serviceName}/serviceVersion/{serviceVersion}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve Service", httpMethod = "GET", notes = "Returns service according to name and version", response = Service.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service found"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 404, message = "Service not found") }) + public Response getServiceByNameAndVersion(@PathParam("serviceName") final String serviceName, @PathParam("serviceVersion") final String serviceVersion, @Context final HttpServletRequest request, + @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + // get modifier id + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Either actionResponse = businessLogic.getServiceByNameAndVersion(serviceName, serviceVersion, userId); + + if (actionResponse.isRight()) { + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get Service by name and version"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Service by name and version"); + log.debug("get service failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + + } + } + + @POST + @Path("/services/{serviceId}/distribution-state/{state}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Update Service Distribution State", httpMethod = "POST", notes = "service with the changed distribution status") + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service distribution state changed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available for distribution"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) + public Response updateServiceDistributionState(@ApiParam(value = "DistributionChangeInfo - get comment out of body", required = true) LifecycleChangeInfoWithAction jsonChangeInfo, @PathParam("serviceId") final String serviceId, + @ApiParam(allowableValues = "approve, reject", required = true) @PathParam("state") final String state, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Either actionResponse = businessLogic.changeServiceDistributionState(serviceId, state, jsonChangeInfo, modifier); + + if (actionResponse.isRight()) { + log.debug("failed to Update Service Distribution State"); + response = buildErrorResponse(actionResponse.right().value()); + return response; + } + Service service = actionResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update Service Distribution State"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update Service Distribution State"); + log.debug("updateServiceDistributionState failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/distribution/{env}/activate") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Activate distribution", httpMethod = "POST", notes = "activate distribution") + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 409, message = "Service cannot be distributed due to missing deployment artifacts"), @ApiResponse(code = 404, message = "Requested service was not found"), + @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) + public Response activateDistribution(@PathParam("serviceId") final String serviceId, @PathParam("env") final String env, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Either distResponse = businessLogic.activateDistribution(serviceId, env, modifier, request); + + if (distResponse.isRight()) { + log.debug("failed to activate service distribution"); + response = buildErrorResponse(distResponse.right().value()); + return response; + } + Service service = distResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Activate Distribution"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Activate Distribution"); + log.debug("activate distribution failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/distribution/{did}/markDeployed") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Mark distribution as deployed", httpMethod = "POST", notes = "relevant audit record will be created") + @ApiResponses(value = { @ApiResponse(code = 200, message = "Service was marked as deployed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 403, message = "Service is not available"), + @ApiResponse(code = 400, message = "Invalid content / Missing content"), @ApiResponse(code = 404, message = "Requested service was not found"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) + public Response markDistributionAsDeployed(@PathParam("serviceId") final String serviceId, @PathParam("did") final String did, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Either distResponse = businessLogic.markDistributionAsDeployed(serviceId, did, modifier); + + if (distResponse.isRight()) { + log.debug("failed to mark distribution as deployed"); + response = buildErrorResponse(distResponse.right().value()); + return response; + } + Service service = distResponse.left().value(); + Object result = RepresentationUtils.toRepresentation(service); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), result); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Mark Distribution As Deployed"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Mark Distribution As Deployed"); + log.debug("mark distribution as deployed failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @POST + @Path("/services/{serviceId}/tempUrlToBeDeleted") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiResponses(value = { @ApiResponse(code = 200, message = "OK"), @ApiResponse(code = 500, message = "Internal Server Error. Please try again later.") }) + public Response tempUrlToBeDeleted(@PathParam("serviceId") final String serviceId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userId); + log.debug("modifier id is {}", userId); + + Response response = null; + try { + ServiceBusinessLogic businessLogic = getServiceBL(context); + Service service = (businessLogic.getService(serviceId, modifier)).left().value(); + Either res = (businessLogic.updateDistributionStatusForActivation(service, modifier, DistributionStatusEnum.DISTRIBUTED)); + + if (res.isRight()) { + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), null); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "tempUrlToBeDeleted"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("tempUrlToBeDeleted"); + log.debug("failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + } + } + + @GET + @Path("/services/toscatoheat/{artifactName}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_OCTET_STREAM) + @ApiOperation(value = "Download service artifact", httpMethod = "GET", notes = "Returns downloaded artifact", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Artifact downloaded"), @ApiResponse(code = 401, message = "Authorization required"), @ApiResponse(code = 403, message = "Restricted operation"), + @ApiResponse(code = 404, message = "Artifact not found") }) + public Response downloadServiceArtifact(@PathParam("artifactName") final String artifactName, @Context final HttpServletRequest request) { + Response response = null; + String instanceIdHeader = request.getHeader(Constants.X_ECOMP_INSTANCE_ID_HEADER); + String requestURI = request.getRequestURI(); + + try { + log.debug("artifact name = {}", artifactName); + ServletContext context = request.getSession().getServletContext(); + + Either executeCommand = executeCommand(artifactName); + + if (executeCommand.isRight()) { + log.debug("Failed to convert tosca {} to heat", artifactName); + ResponseFormat responseFormat = executeCommand.right().value(); + response = buildErrorResponse(responseFormat); + } else { + log.debug("Succeed to convert tosca {} to heat", artifactName); + byte[] value = executeCommand.left().value(); + InputStream is = new ByteArrayInputStream(value); + + Map headers = new HashMap<>(); + String heatFileName = null; + if (artifactName.indexOf(".") > -1) { + heatFileName = artifactName.substring(0, artifactName.indexOf(".")) + ".heat"; + } else { + heatFileName = artifactName + ".heat"; + } + headers.put(Constants.CONTENT_DISPOSITION_HEADER, getContentDispositionValue(heatFileName)); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.OK); + response = buildOkResponse(responseFormat, is, headers); + } + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "download heat artifact"); + log.error("download artifact failed with exception", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private Either executeCommand(String artifactName) { + + Configuration configuration = ConfigurationManager.getConfigurationManager().getConfiguration(); + String toscaFilesDir = configuration.getToscaFilesDir(); + if (toscaFilesDir == null) { + toscaFilesDir = "/apps/jetty/base/be/config/tosca"; + } + String heatTranslator = configuration.getHeatTranslatorPath(); + if (heatTranslator == null) { + heatTranslator = "/home/m98835/heat-translator-0.3.0/heat_translator.py"; + } + + log.debug("toscaFilesDir={}", toscaFilesDir); + log.debug("heatTranslator={}", heatTranslator); + + StringBuffer output = new StringBuffer(); + + String heatHeader = configuration.getHeatEnvArtifactHeader(); + String heatFooter = configuration.getHeatEnvArtifactFooter(); + + output.append(heatHeader + "\n"); + + MessageFormat mf = new MessageFormat("python {0} --template-file={1}/{2} --template-type=tosca"); + + log.debug("After creating message format"); + + Object[] objArray = { heatTranslator, toscaFilesDir, artifactName }; + String command = null; + try { + command = mf.format(objArray); + } catch (Exception e) { + log.debug("Failed to convert message format", e); + } + + log.debug("Going to run command {}", command); + + Process p; + try { + p = Runtime.getRuntime().exec(command); + int waitFor = p.waitFor(); + log.debug("waitFor = {}", waitFor); + + if (waitFor != 0) { + log.error("Failed running the command {}", command); + return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.ARTIFACT_NOT_FOUND, artifactName)); + } + + BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); + + String line = ""; + while ((line = reader.readLine()) != null) { + output.append(line + "\n"); + } + + } catch (Exception e) { + log.error("Failed running the command {} {}", command, e); + e.printStackTrace(); + return Either.right(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + output.append(heatFooter); + + return Either.left(output.toString().getBytes()); + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ToscaDaoServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ToscaDaoServlet.java new file mode 100644 index 0000000000..eea2bfdc42 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/ToscaDaoServlet.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import javax.servlet.ServletContext; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.impl.DownloadArtifactLogic; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.info.ServletJsonResponse; +import org.openecomp.sdc.be.resources.api.IResourceUploader; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.slf4j.Logger; +import org.springframework.web.context.WebApplicationContext; + +public abstract class ToscaDaoServlet extends BeGenericServlet { + public abstract Logger getLogger(); + + protected IResourceUploader getResourceUploader(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + + if (webApplicationContextWrapper == null) { + getLogger().error("Failed to get web application context from context."); + return null; + } + + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + + return webApplicationContext.getBean(IResourceUploader.class); + + } + + // protected IToscaYamlBuilder getToscaYamlBuilder(ServletContext context){ + // WebAppContextWrapper webApplicationContextWrapper = + // (WebAppContextWrapper) context + // .getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + // + // if (webApplicationContextWrapper == null) { + // getLogger().error("Failed to get web application context from context."); + // return null; + // } + // + // WebApplicationContext webApplicationContext = + // webApplicationContextWrapper + // .getWebAppContext(context); + // + // return webApplicationContext.getBean(IToscaYamlBuilder.class); + // + // } + + protected DownloadArtifactLogic getLogic(ServletContext context) { + DownloadArtifactLogic downloadLogic = (DownloadArtifactLogic) context.getAttribute(Constants.DOWNLOAD_ARTIFACT_LOGIC_ATTR); + + if (downloadLogic == null) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeInitializationError, "DownloadArtifactLogic from context"); + BeEcompErrorManager.getInstance().logBeInitializationError("DownloadArtifactLogic from context"); + return null; + } + return downloadLogic; + } + + protected Response buildResponse(int status, String errorMessage) { + + ServletJsonResponse jsonResponse = new ServletJsonResponse(); + jsonResponse.setDescription(errorMessage); + jsonResponse.setSource(Constants.CATALOG_BE); + + Response response = Response.status(status).entity(jsonResponse).build(); + + return response; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java new file mode 100644 index 0000000000..0825a25cbe --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesFetchServlet.java @@ -0,0 +1,122 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.util.Map; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.components.impl.PropertyBusinessLogic; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog") +@Api(value = "Types Fetch Servlet", description = "Types Fetch Servlet") +@Singleton +public class TypesFetchServlet extends AbstractValidationsServlet { + + private static Logger log = LoggerFactory.getLogger(TypesFetchServlet.class.getName()); + + @GET + @Path("dataTypes") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Get data types", httpMethod = "GET", notes = "Returns data types", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "datatypes"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 404, message = "Data types not found") }) + public Response getAllDataTypesServlet(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId) { + + Wrapper responseWrapper = new Wrapper(); + Wrapper userWrapper = new Wrapper(); + ServletContext context = request.getSession().getServletContext(); + + try { + init(log); + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + PropertyBusinessLogic businessLogic = getPropertyBL(context); + Either, ResponseFormat> allDataTypes = businessLogic.getAllDataTypes(); + + if (allDataTypes.isRight()) { + log.info("Failed to get all dara types. Reason - ", allDataTypes.right().value()); + Response errorResponse = buildErrorResponse(allDataTypes.right().value()); + responseWrapper.setInnerElement(errorResponse); + + // return buildErrorResponse(allDataTypes.right().value()); + } else { + Map dataTypes = allDataTypes.left().value(); + Response okResponse = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), dataTypes); + responseWrapper.setInnerElement(okResponse); + } + } + + return responseWrapper.getInnerElement(); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get all data types"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get Property"); + log.debug("get all data types failed with exception", e); + ResponseFormat responseFormat = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(responseFormat); + } + } + + private PropertyBusinessLogic getPropertyBL(ServletContext context) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + PropertyBusinessLogic propertytBl = webApplicationContext.getBean(PropertyBusinessLogic.class); + return propertytBl; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java new file mode 100644 index 0000000000..6ba8c521f1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/TypesUploadServlet.java @@ -0,0 +1,317 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.File; +import java.io.IOException; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.function.Supplier; +import java.util.stream.Collectors; + +import javax.annotation.Resource; +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.glassfish.jersey.media.multipart.FormDataParam; +import org.openecomp.sdc.be.components.impl.CapabilityTypeImportManager; +import org.openecomp.sdc.be.components.impl.CategoriesImportManager; +import org.openecomp.sdc.be.components.impl.DataTypeImportManager; +import org.openecomp.sdc.be.components.impl.GroupTypeImportManager; +import org.openecomp.sdc.be.components.impl.InterfaceLifecycleTypeImportManager; +import org.openecomp.sdc.be.components.impl.PolicyTypeImportManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum; +import org.openecomp.sdc.be.impl.WebAppContextWrapper; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupTypeDefinition; +import org.openecomp.sdc.be.model.PolicyTypeDefinition; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.datastructure.Wrapper; +import org.openecomp.sdc.common.datastructure.FunctionalInterfaces.ConsumerTwoParam; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.WebApplicationContext; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/catalog/uploadType") +@Api(value = "Catalog Types Upload", description = "Upload Type from yaml") +@Singleton +public class TypesUploadServlet extends AbstractValidationsServlet { + @Resource + private CapabilityTypeImportManager capabilityTypeImportManager; + + @Resource + private InterfaceLifecycleTypeImportManager interfaceLifecycleTypeImportManager; + + @Resource + private CategoriesImportManager categoriesImportManager; + + @Resource + private DataTypeImportManager dataTypeImportManager; + + @Resource + private GroupTypeImportManager groupTypeImportManager; + + @Resource + private PolicyTypeImportManager policyTypeImportManager; + + private static Logger log = LoggerFactory.getLogger(TypesUploadServlet.class.getName()); + + @POST + @Path("/capability") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Capability Type from yaml", httpMethod = "POST", notes = "Returns created Capability Type", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Capability Type created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Capability Type already exist") }) + public Response uploadCapabilityType(@ApiParam("FileInputStream") @FormDataParam("capabilityTypeZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + capabilityTypeImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> CapabilityTypeImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> capabilityTypeImportManager.createCapabilityTypes(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.CapabilityType.name()); + + } + + @POST + @Path("/interfaceLifecycle") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Interface Lyfecycle Type from yaml", httpMethod = "POST", notes = "Returns created Interface Lifecycle Type", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Interface Lifecycle Type created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Interface Lifecycle Type already exist") }) + public Response uploadInterfaceLifecycleType(@ApiParam("FileInputStream") @FormDataParam("interfaceLifecycleTypeZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + interfaceLifecycleTypeImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> InterfaceLifecycleTypeImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> interfaceLifecycleTypeImportManager.createLifecycleTypes(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "Interface Types"); + } + + @POST + @Path("/categories") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Categories from yaml", httpMethod = "POST", notes = "Returns created categories", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Categories created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Category already exist") }) + public Response uploadCategories(@ApiParam("FileInputStream") @FormDataParam("categoriesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + categoriesImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> CategoriesImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createElementsType(responseWrapper, () -> categoriesImportManager.createCategories(ymlPayload)); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, "categories"); + + } + + @POST + @Path("/datatypes") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create Categories from yaml", httpMethod = "POST", notes = "Returns created data types", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "Data types created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "Data types already exist") }) + public Response uploadDataTypes(@ApiParam("FileInputStream") @FormDataParam("dataTypesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + dataTypeImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> DataTypeImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createDataTypes(responseWrapper, ymlPayload); + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.DataType.getName()); + + } + + @POST + @Path("/grouptypes") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create GroupTypes from yaml", httpMethod = "POST", notes = "Returns created group types", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "group types created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "group types already exist") }) + public Response uploadGroupTypes(@ApiParam("FileInputStream") @FormDataParam("groupTypesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + groupTypeImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> GroupTypeImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createGroupTypes(responseWrapper, ymlPayload); + + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.GroupType.getName()); + } + + @POST + @Path("/policytypes") + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Create PolicyTypes from yaml", httpMethod = "POST", notes = "Returns created policy types", response = Response.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "policy types created"), @ApiResponse(code = 403, message = "Restricted operation"), @ApiResponse(code = 400, message = "Invalid content / Missing content"), + @ApiResponse(code = 409, message = "policy types already exist") }) + public Response uploadPolicyTypes(@ApiParam("FileInputStream") @FormDataParam("policyTypesZip") File file, @Context final HttpServletRequest request, @HeaderParam("USER_ID") String creator) { + + policyTypeImportManager = initElementTypeImportManager(request.getSession().getServletContext(), () -> PolicyTypeImportManager.class); + ConsumerTwoParam, String> createElementsMethod = (responseWrapper, ymlPayload) -> createPolicyTypes(responseWrapper, ymlPayload); + + return uploadElementTypeServletLogic(createElementsMethod, file, request, creator, NodeTypeEnum.PolicyType.getName()); + + } + + private Response uploadElementTypeServletLogic(ConsumerTwoParam, String> createElementsMethod, File file, final HttpServletRequest request, String creator, String elementTypeName) { + init(log); + String userId = initHeaderParam(creator, request, Constants.USER_ID_HEADER); + try { + Wrapper responseWrapper = new Wrapper<>(); + Wrapper userWrapper = new Wrapper<>(); + Wrapper yamlStringWrapper = new Wrapper<>(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + validateUserExist(responseWrapper, userWrapper, userId); + + if (responseWrapper.isEmpty()) { + validateUserRole(responseWrapper, userWrapper.getInnerElement()); + } + + if (responseWrapper.isEmpty()) { + validateDataNotNull(responseWrapper, file); + } + + if (responseWrapper.isEmpty()) { + fillZipContents(yamlStringWrapper, file); + } + + if (responseWrapper.isEmpty()) { + createElementsMethod.accept(responseWrapper, yamlStringWrapper.getInnerElement()); + } + + return responseWrapper.getInnerElement(); + + } catch (Exception e) { + log.debug("create {} failed with exception: {}", elementTypeName, e); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create " + elementTypeName); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + private void createElementsType(Wrapper responseWrapper, Supplier> elementsCreater) { + Either eitherResult = elementsCreater.get(); + if (eitherResult.isRight()) { + Response response = buildErrorResponse(eitherResult.right().value()); + responseWrapper.setInnerElement(response); + } else { + Response response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), eitherResult.left().value()); + responseWrapper.setInnerElement(response); + } + } + + // data types + private void createDataTypes(Wrapper responseWrapper, String dataTypesYml) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> dataTypeImportManager.createDataTypes(dataTypesYml); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.DATA_TYPE_ALREADY_EXIST, NodeTypeEnum.DataType.name()); + } + + // group types + private void createGroupTypes(Wrapper responseWrapper, String groupTypesYml) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> groupTypeImportManager.createGroupTypes(groupTypesYml); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.GROUP_TYPE_ALREADY_EXIST, NodeTypeEnum.GroupType.name()); + + } + + // policy types + private void createPolicyTypes(Wrapper responseWrapper, String policyTypesYml) { + final Supplier>, ResponseFormat>> generateElementTypeFromYml = () -> policyTypeImportManager.createPolicyTypes(policyTypesYml); + buildStatusForElementTypeCreate(responseWrapper, generateElementTypeFromYml, ActionStatus.POLICY_TYPE_ALREADY_EXIST, NodeTypeEnum.PolicyType.name()); + + } + + // data types + private void buildStatusForElementTypeCreate(Wrapper responseWrapper, Supplier>, ResponseFormat>> generateElementTypeFromYml, + ActionStatus alreadyExistStatus, String elementTypeName) { + + Either>, ResponseFormat> eitherResult = generateElementTypeFromYml.get(); + + if (eitherResult.isRight()) { + Response response = buildErrorResponse(eitherResult.right().value()); + responseWrapper.setInnerElement(response); + } else { + Object representation; + try { + List> list = eitherResult.left().value(); + ActionStatus status = ActionStatus.OK; + if (list != null) { + + // Group result by the right value - true or false. + // I.e., get the number of data types which are new and + // which are old. + Map>> collect = list.stream().collect(Collectors.groupingBy(ImmutablePair::getRight)); + if (collect != null) { + Set keySet = collect.keySet(); + if (keySet.size() == 1) { + Boolean isNew = keySet.iterator().next(); + if (isNew.booleanValue() == true) { + // all data types created at the first time + status = ActionStatus.CREATED; + } else { + // All data types already exists + + status = alreadyExistStatus; + } + } + } + } + representation = RepresentationUtils.toRepresentation(eitherResult.left().value()); + + Response response = buildOkResponse(getComponentsUtils().getResponseFormat(status), representation); + responseWrapper.setInnerElement(response); + + } catch (IOException e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Create " + elementTypeName); + log.debug("failed to convert {} to json", elementTypeName, e); + Response response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + responseWrapper.setInnerElement(response); + } + } + } + + private T initElementTypeImportManager(ServletContext context, Supplier> classGetter) { + WebAppContextWrapper webApplicationContextWrapper = (WebAppContextWrapper) context.getAttribute(Constants.WEB_APPLICATION_CONTEXT_WRAPPER_ATTR); + WebApplicationContext webApplicationContext = webApplicationContextWrapper.getWebAppContext(context); + T elementTypeImortManager = webApplicationContext.getBean(classGetter.get()); + return elementTypeImortManager; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java new file mode 100644 index 0000000000..c700c31a64 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/servlets/UserAdminServlet.java @@ -0,0 +1,516 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.servlets; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.List; + +import javax.inject.Singleton; +import javax.servlet.ServletContext; +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.be.user.UserBusinessLogic; +import org.openecomp.sdc.common.api.Constants; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.jcabi.aspects.Loggable; +import com.wordnik.swagger.annotations.Api; +import com.wordnik.swagger.annotations.ApiOperation; +import com.wordnik.swagger.annotations.ApiParam; +import com.wordnik.swagger.annotations.ApiResponse; +import com.wordnik.swagger.annotations.ApiResponses; + +import fj.data.Either; + +@Loggable(prepend = true, value = Loggable.DEBUG, trim = false) +@Path("/v1/user") +@Api(value = "User Administration", description = "User admininstarator operations") +@Singleton +public class UserAdminServlet extends BeGenericServlet { + + private static final String ROLE_DELIMITER = ","; + private static Logger log = LoggerFactory.getLogger(UserAdminServlet.class.getName()); + + /*************************************** + * API start + *************************************************************/ + + /* User by userId CRUD start */ + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve all user details + @GET + @Path("/{userId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "retrieve user details", httpMethod = "GET", notes = "Returns user details according to userId", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), + @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response get(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + UserBusinessLogic userAdminManager = getUserAdminManager(request.getSession().getServletContext()); + + try { + Either either = userAdminManager.getUser(userId, false); + + if (either.isRight()) { + return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } else { + if (either.left().value() != null) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get User"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User"); + log.debug("get user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // update user - internal API + /* + * @POST + * + * @Path("/{userId}") + * + * @Consumes(MediaType.APPLICATION_JSON) + * + * @Produces(MediaType.APPLICATION_JSON) + * + * @ApiOperation(value = "update user - internal API", notes = "Update user", response = User.class) + * + * @ApiResponses(value = { + * + * @ApiResponse(code = 200, message = "Update user OK"), + * + * @ApiResponse(code = 400, message = "Invalid Content."), + * + * @ApiResponse(code = 403, message = "Missing information/Restricted operation"), + * + * @ApiResponse(code = 404, message = "User not found"), + * + * @ApiResponse(code = 405, message = "Method Not Allowed"), + * + * @ApiResponse(code = 409, message = "User already exists"), + * + * @ApiResponse(code = 500, message = "Internal Server Error") }) public Response updateUser(@ApiParam(value="userId of user to get", required=true) @PathParam("userId") final String UserIdUpdateUser, + * + * @Context final HttpServletRequest request, + * + * @ApiParam(value="json describe the update user", required=true) String data, + * + * @HeaderParam(value = Constants.USER_ID_HEADER) String modifierAttId) { + * + * ServletContext context = request.getSession().getServletContext(); + * + * String url = request.getMethod() + " " + request.getRequestURI(); log.debug("Start handle request of {}", url); + * + * // get modifier id User modifier = new User(); modifier.setUserId(modifierAttId); log.debug("modifier id is {}", modifierAttId); + * + * Response response = null; + * + * try { UserAdminBuisinessLogic businessLogic = getUserAdminManager(context); User updateInfoUser = getComponentsUtils().convertJsonToObject(data, modifier, User.class, AuditingActionEnum.UPDATE_USER).left().value(); Either + * updateUserResponse = null;// businessLogic.updateUser(modifier, UserIdUpdateUser, updateInfoUser); + * + * if (updateUserResponse.isRight()) { log.debug("failed to update user metadata"); response = buildErrorResponse(updateUserResponse.right().value()); return response; } response = + * buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateUserResponse.left().value()); return response; + * + * } catch (Exception e) { BeEcompErrorManager.getInstance().processEcompError(EcompErrorName. BeRestApiGeneralError, "Update User Metadata"); log.debug("Update User Metadata failed with exception", e); response = + * buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus. GENERAL_ERROR)); return response; + * + * } } + * + */ + /* User userId CRUD end */ + + /* User role CRUD start */ + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // retrieve user role + @GET + @Path("/{userId}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "retrieve user role", notes = "Returns user role according to userId", response = String.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user role Ok"), @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), + @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getRole(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(getRole) Start handle request of {}", url); + + UserBusinessLogic userAdminManager = getUserAdminManager(request.getSession().getServletContext()); + + try { + Either either = userAdminManager.getUser(userId, false); + if (either.isRight()) { + return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(either.right().value(), userId)); + } else { + if (either.left().value() != null) { + String roleJson = ("{ \"role\" : \"" + either.left().value().getRole().toString() + "\" }"); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), roleJson); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get User Role"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User Role"); + log.debug("Get user role failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // update user role + @POST + @Path("/{userId}/role") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "update user role", notes = "Update user role", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Update user OK"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information/Restricted operation"), + @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "User already exists"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response updateUserRole(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String UserIdUpdateUser, @Context final HttpServletRequest request, + @ApiParam(value = "json describe the update role", required = true) String data, @HeaderParam(value = Constants.USER_ID_HEADER) String modifierUserId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(modifierUserId); + log.debug("modifier id is {}", modifierUserId); + + Response response = null; + + try { + UserBusinessLogic businessLogic = getUserAdminManager(context); + User updateInfoUser = getComponentsUtils().convertJsonToObject(data, modifier, User.class, AuditingActionEnum.UPDATE_USER).left().value(); + Either updateUserResponse = businessLogic.updateUserRole(modifier, UserIdUpdateUser, updateInfoUser.getRole()); + + if (updateUserResponse.isRight()) { + log.debug("failed to update user role"); + response = buildErrorResponse(updateUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), updateUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update User Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); + log.debug("Update User Role failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /* User role CRUD end */ + + /* New user CRUD start */ + @POST + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "add user", httpMethod = "POST", notes = "Provision new user", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 201, message = "New user created"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information"), + @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "User already exists"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response createUser(@Context final HttpServletRequest request, @ApiParam(value = "json describe the user", required = true) String newUserData, @HeaderParam(value = Constants.USER_ID_HEADER) String modifierAttId) { + + ServletContext context = request.getSession().getServletContext(); + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + // get modifier id + User modifier = new User(); + modifier.setUserId(modifierAttId); + log.debug("modifier id is {}", modifierAttId); + + Response response = null; + + try { + UserBusinessLogic businessLogic = getUserAdminManager(context); + User newUserInfo = getComponentsUtils().convertJsonToObject(newUserData, modifier, User.class, AuditingActionEnum.ADD_USER).left().value(); + Either createUserResponse = businessLogic.createUser(modifier, newUserInfo); + + if (createUserResponse.isRight()) { + log.debug("failed to create user"); + response = buildErrorResponse(createUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.CREATED), createUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Update User Metadata"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Update User Metadata"); + log.debug("Create User failed with exception", e); + response = buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + return response; + + } + } + + /* New user CRUD end */ + + /* User authorization start */ + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // User Authorization + @GET + @Path("/authorize") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + + @ApiOperation(value = "authorize", notes = "authorize user", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 403, message = "Restricted Access"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response authorize(@Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userId, @HeaderParam("HTTP_CSP_FIRSTNAME") String firstName, @HeaderParam("HTTP_CSP_LASTNAME") String lastName, + @HeaderParam("HTTP_CSP_EMAIL") String email) { + + try { + userId = (userId != null ? URLDecoder.decode(userId, "UTF-8") : null); + firstName = (firstName != null ? URLDecoder.decode(firstName, "UTF-8") : null); + lastName = (lastName != null ? URLDecoder.decode(lastName, "UTF-8") : null); + email = (email != null ? URLDecoder.decode(email, "UTF-8") : null); + } catch (UnsupportedEncodingException e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Authorize User - decode headers"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Authorize User - decode headers"); + ResponseFormat errorResponseWrapper = getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR); + return buildErrorResponse(errorResponseWrapper); + } + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User authUser = new User(); + authUser.setUserId(userId); + authUser.setFirstName(firstName); + authUser.setLastName(lastName); + authUser.setEmail(email); + log.debug("auth user id is {}", userId); + + Response response = null; + try { + UserBusinessLogic userAdminManager = getUserAdminManager(context); + Either authorize = userAdminManager.authorize(authUser); + + if (authorize.isRight()) { + log.debug("authorize user failed"); + response = buildErrorResponse(authorize.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), authorize.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get ASDC users"); + log.debug("authorize user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + /* User authorization end */ + + @GET + @Path("/admins") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "retrieve all administrators", httpMethod = "GET", notes = "Returns all administrators", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getAdminsUser(@PathParam("userId") final String userId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + UserBusinessLogic userAdminManager = getUserAdminManager(request.getSession().getServletContext()); + + try { + Either, ResponseFormat> either = userAdminManager.getAllAdminUsers(request.getSession().getServletContext()); + + if (either.isRight()) { + log.debug("Failed to get all admin users"); + return buildErrorResponse(either.right().value()); + } else { + if (either.left().value() != null) { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } else { + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get All Administrators"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get All Administrators"); + log.debug("get all admins failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/users") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "Retrieve the list of all active ASDC users or only group of users having specific roles.", httpMethod = "GET", notes = "Returns list of users with the specified roles, or all of users in the case of empty 'roles' header", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns users Ok"), @ApiResponse(code = 204, message = "No provisioned ASDC users of requested role"), @ApiResponse(code = 403, message = "Restricted Access"), + @ApiResponse(code = 400, message = "Missing content"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getUsersList(@Context final HttpServletRequest request, @ApiParam(value = "Any active user's USER_ID") @HeaderParam(Constants.USER_ID_HEADER) final String userId, + @ApiParam(value = "TESTER,DESIGNER,PRODUCT_STRATEGIST,OPS,PRODUCT_MANAGER,GOVERNOR, ADMIN OR all users by not typing anything") @QueryParam("roles") final String roles) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + log.debug("modifier id is {}", userId); + + List rolesList = new ArrayList<>(); + if (roles != null && !roles.trim().isEmpty()) { + String[] rolesArr = roles.split(ROLE_DELIMITER); + for (String role : rolesArr) { + rolesList.add(role.trim()); + } + } + + try { + UserBusinessLogic userAdminManager = getUserAdminManager(context); + Either, ResponseFormat> either = userAdminManager.getUsersList(userId, rolesList, roles); + + if (either.isRight()) { + log.debug("Failed to get ASDC users"); + return buildErrorResponse(either.right().value()); + } else { + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), either.left().value()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get ASDC users"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); + log.debug("get users failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + + } + + ///////////////////////////////////////////////////////////////////////////////////////////////////// + // delete user + @DELETE + @Path("/{userId}") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "delete user", notes = "Delete user", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Update deleted OK"), @ApiResponse(code = 400, message = "Invalid Content."), @ApiResponse(code = 403, message = "Missing information"), + @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), @ApiResponse(code = 409, message = "Restricted operation"), @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response deActivateUser(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request, @HeaderParam(value = Constants.USER_ID_HEADER) String userIdHeader) { + + ServletContext context = request.getSession().getServletContext(); + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("Start handle request of {}", url); + + User modifier = new User(); + modifier.setUserId(userIdHeader); + log.debug("modifier id is {}", userIdHeader); + + Response response = null; + try { + UserBusinessLogic userAdminManager = getUserAdminManager(context); + Either deactiveUserResponse = userAdminManager.deActivateUser(modifier, userId); + + if (deactiveUserResponse.isRight()) { + log.debug("Failed to deactivate user"); + response = buildErrorResponse(deactiveUserResponse.right().value()); + return response; + } + response = buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), deactiveUserResponse.left().value()); + return response; + + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeRestApiGeneralError, "Get ASDC users"); + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get ASDC users"); + log.debug("deactivate user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + + @GET + @Path("/{userId}/functionalmenu") + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @ApiOperation(value = "retrieve user details", httpMethod = "GET", notes = "Returns user details according to userId", response = User.class) + @ApiResponses(value = { @ApiResponse(code = 200, message = "Returns user Ok"), @ApiResponse(code = 404, message = "User not found"), @ApiResponse(code = 405, message = "Method Not Allowed"), + @ApiResponse(code = 500, message = "Internal Server Error") }) + public Response getFunctionalMenu(@ApiParam(value = "userId of user to get", required = true) @PathParam("userId") final String userId, @Context final HttpServletRequest request) { + + String url = request.getMethod() + " " + request.getRequestURI(); + log.debug("(get) Start handle request of {}", url); + + UserBusinessLogic userAdminManager = getUserAdminManager(request.getSession().getServletContext()); + + try { + Either functionalMenuResp = userAdminManager.getFunctionalMenu(userId); + + if (functionalMenuResp.isRight()) { + return buildErrorResponse(getComponentsUtils().getResponseFormatByUserId(functionalMenuResp.right().value(), userId)); + } else { + FunctionalMenuInfo functionalMenuInfo = functionalMenuResp.left().value(); + if (functionalMenuInfo != null && functionalMenuInfo.getFunctionalMenu() != null) { + log.debug("Functional menu fetched is {}", functionalMenuInfo.getFunctionalMenu()); + return buildOkResponse(getComponentsUtils().getResponseFormat(ActionStatus.OK), functionalMenuInfo.getFunctionalMenu()); + } else { + log.debug("Functional menu is null"); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().logBeRestApiGeneralError("Get User"); + log.debug("get user failed with unexpected error: {}", e); + return buildErrorResponse(getComponentsUtils().getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/switchover/detector/SwitchoverDetector.java b/catalog-be/src/main/java/org/openecomp/sdc/be/switchover/detector/SwitchoverDetector.java new file mode 100644 index 0000000000..4027144911 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/switchover/detector/SwitchoverDetector.java @@ -0,0 +1,315 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.switchover.detector; + +import java.net.InetAddress; +import java.util.Properties; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; + +import org.apache.commons.codec.binary.Base64; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.config.Configuration.SwitchoverDetectorConfig; +import org.openecomp.sdc.be.dao.rest.HttpRestClient; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("switchover-detector") +public class SwitchoverDetector { + + protected static String SWITCHOVER_DETECTOR_LOG_CONTEXT = "switchover.detector"; + + private static Logger switchoverLogger = LoggerFactory.getLogger(SWITCHOVER_DETECTOR_LOG_CONTEXT); + + private SwitchoverDetectorConfig switchoverDetectorConfig; + + private Properties authHeader = null; + + private long detectorInterval = 60; + + private int maxBeQueryAttempts = 3; + + private int maxFeQueryAttempts = 3; + + private Boolean beMatch = null; + + private Boolean feMatch = null; + + private static Logger logger = LoggerFactory.getLogger(SwitchoverDetector.class.getName()); + + private volatile String siteMode = SwitchoverDetectorState.UNKNOWN.getState(); + + private ScheduledFuture scheduledFuture = null; + + ScheduledExecutorService switchoverDetectorScheduler = Executors.newSingleThreadScheduledExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "Switchover-Detector-Task"); + } + }); + + SwitchoverDetectorScheduledTask switchoverDetectorScheduledTask = null; + + public enum SwitchoverDetectorState { + + UNKNOWN("unknown"), ACTIVE("active"), STANDBY("standby"); + + private String state; + + SwitchoverDetectorState(String state) { + this.state = state; + } + + public String getState() { + return state; + } + } + + public enum SwitchoverDetectorGroup { + + BE_SET("beSet"), FE_SET("feSet"); + + private String group; + + SwitchoverDetectorGroup(String group) { + this.group = group; + } + + public String getGroup() { + return group; + } + } + + public String getSiteMode() { + return siteMode; + } + + public void setSiteMode(String mode) { + this.siteMode = mode; + } + + private Boolean queryBe() { + return queryGss(switchoverDetectorConfig.getgBeFqdn(), switchoverDetectorConfig.getBeVip(), maxBeQueryAttempts); + } + + private Boolean queryFe() { + return queryGss(switchoverDetectorConfig.getgFeFqdn(), switchoverDetectorConfig.getFeVip(), maxFeQueryAttempts); + } + + private void setAuthorizationProperties() { + String userInfo = switchoverDetectorConfig.getChangePriorityUser() + ":" + switchoverDetectorConfig.getChangePriorityPassword(); + String auth = "Basic " + new String(new Base64().encode(userInfo.getBytes())); + authHeader = new Properties(); + authHeader.put("Authorization", auth); + } + + private void initializeSiteMode() { + while (siteMode == SwitchoverDetectorState.UNKNOWN.getState()) { + + beMatch = queryBe(); + feMatch = queryFe(); + + if (beMatch == feMatch && beMatch != null) { + if (beMatch) { + setSiteMode(SwitchoverDetectorState.ACTIVE.getState()); + } else { + setSiteMode(SwitchoverDetectorState.STANDBY.getState()); + } + } + } + } + + private Boolean queryGss(String fqdn, String vip, int maxAttempts) { + + Boolean result = null; + int attempts = 0; + + while (result == null && (++attempts < maxAttempts)) { + try { + InetAddress inetAddress = InetAddress.getByName(fqdn); + result = inetAddress.getHostAddress().equals(vip); + + } catch (Exception e) { + String message = e.getMessage(); + if (message == null) { + message = e.getClass().getName(); + } + switchoverLogger.debug("Error occured during switchover detector query, Result is {}", message); + } + } + if (null == result) { + BeEcompErrorManager.getInstance().logFqdnResolveError(SWITCHOVER_DETECTOR_LOG_CONTEXT, "host " + fqdn + " not resolved after " + attempts + " attempts"); + } + return result; + } + + public class SwitchoverDetectorScheduledTask implements Runnable { + + public SwitchoverDetectorScheduledTask() { + + } + + @Override + public void run() { + switchoverLogger.trace("Executing Switchover Detector Task - Start"); + + initializeSiteMode(); + + Boolean beRes = queryBe(); + Boolean feRes = queryFe(); + + Boolean updateRequired = siteMode == SwitchoverDetectorState.STANDBY.getState() && (beRes || feRes); + + updateSiteModeAndPriority(beRes && feRes, siteMode == SwitchoverDetectorState.STANDBY.getState(), updateRequired); + + beMatch = beRes; + feMatch = feRes; + } + + ExecutorService switchoverDetectorExecutor = Executors.newSingleThreadExecutor(new ThreadFactory() { + @Override + public Thread newThread(Runnable r) { + return new Thread(r, "Switchover-Detector-Thread"); + } + }); + + private void updateSiteModeAndPriority(Boolean bothMatch, Boolean previousModeStandby, Boolean updateRequired) { + if (bothMatch && previousModeStandby) { + logger.trace("Site switch over was done. Site is now in active mode"); + setSiteMode(SwitchoverDetectorState.ACTIVE.getState()); + BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode); + } else if (!bothMatch && !previousModeStandby) { + logger.trace("Site switch over was done. Site is now in stand-by mode"); + setSiteMode(SwitchoverDetectorState.STANDBY.getState()); + BeEcompErrorManager.getInstance().logSiteSwitchoverInfo(SWITCHOVER_DETECTOR_LOG_CONTEXT, siteMode); + } + if (updateRequired) { + changeSitePriority(SwitchoverDetectorGroup.BE_SET.getGroup()); + changeSitePriority(SwitchoverDetectorGroup.FE_SET.getGroup()); + publishNetwork(); + } + } + + private void changeSitePriority(String groupToSet) { + + String url = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityUrl(); + String body = switchoverDetectorConfig.getGroups().get(groupToSet).getChangePriorityBody(); + + HttpRestClient httpRestClient = new HttpRestClient(); + + try { + httpRestClient.doPUT(url, authHeader, body); + + } catch (Exception e) { + String message = e.getMessage(); + if (message == null) { + message = e.getClass().getName(); + } + switchoverLogger.error("Error occured during change site priority request, Result is {}", message); + } + + } + + private void publishNetwork() { + + String url = switchoverDetectorConfig.getPublishNetworkUrl(); + String body = switchoverDetectorConfig.getPublishNetworkBody(); + + HttpRestClient httpRestClient = new HttpRestClient(); + + try { + httpRestClient.doPOST(url, authHeader, body); + + } catch (Exception e) { + String message = e.getMessage(); + if (message == null) { + message = e.getClass().getName(); + } + switchoverLogger.error("Error occured during publish network request, Result is {}", message); + } + } + + } + + @PostConstruct + private void init() { + logger.info("Enter init method of SwitchoverDetector"); + + switchoverDetectorConfig = ConfigurationManager.getConfigurationManager().getConfiguration().getSwitchoverDetector(); + + if (!switchoverDetectorConfig.getEnabled()) { + logger.info("switchover detector service is disabled"); + return; + } + + Long detectorIntervalConfig = switchoverDetectorConfig.getInterval(); + if (detectorIntervalConfig != null) { + detectorInterval = detectorIntervalConfig.longValue(); + } + + Integer maxAttempts = switchoverDetectorConfig.getBeResolveAttempts(); + if (maxAttempts != null) { + maxBeQueryAttempts = maxAttempts.intValue(); + } + maxAttempts = switchoverDetectorConfig.getFeResolveAttempts(); + if (maxAttempts != null) { + maxFeQueryAttempts = maxAttempts.intValue(); + } + + setAuthorizationProperties(); + logger.info("switchover detector service is enabled, interval is {} seconds", detectorInterval); + + this.switchoverDetectorScheduledTask = new SwitchoverDetectorScheduledTask(); + startSwitchoverDetectorTask(); + logger.trace("Exit init method of SwitchoverDetector"); + + } + + @PreDestroy + private void destroy() { + + if (scheduledFuture != null) { + scheduledFuture.cancel(true); + scheduledFuture = null; + } + + if (switchoverDetectorScheduler != null) { + switchoverDetectorScheduler.shutdown(); + } + + } + + public void startSwitchoverDetectorTask() { + if (this.scheduledFuture == null) { + this.scheduledFuture = this.switchoverDetectorScheduler.scheduleAtFixedRate(switchoverDetectorScheduledTask, 0, detectorInterval, TimeUnit.SECONDS); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ArtifactTypes.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ArtifactTypes.java new file mode 100644 index 0000000000..85b4493c8e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ArtifactTypes.java @@ -0,0 +1,37 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.util.List; + +import org.openecomp.sdc.generator.data.ArtifactType; + +public class ArtifactTypes { + private List artifactTypes; + + public List getArtifactTypes() { + return artifactTypes; + } + + public void setArtifactTypes(List artifactTypes) { + this.artifactTypes = artifactTypes; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CSARTool.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CSARTool.java new file mode 100644 index 0000000000..7fecced358 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CSARTool.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import org.openecomp.sdc.be.model.Component; + +public class CSARTool { + public static byte[] createCsar(Component component) { + + final String TOSCA_META_VERSION = "1.0"; + final String CSAR_VERSION = component.getCsarVersion(); + final String CREATED_BY = component.getCreatorFullName(); + final String ENTRY_DEFINITIONS = component.getNormalizedName(); + + /* + * StringBuilder builder = new StringBuilder(); try( FileOutputStream f = new FileOutputStream("test.zip"); ZipOutputStream zip = new ZipOutputStream(new BufferedOutputStream(f)); ){ } + */ + + return null; + } + + public static String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) { + final String BLOCK_0_TEMPLATE = "TOSCA-Meta-File-Version: %s"; + + return null; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabiltyRequirementConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabiltyRequirementConvertor.java new file mode 100644 index 0000000000..d1f2557413 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CapabiltyRequirementConvertor.java @@ -0,0 +1,261 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.openecomp.sdc.be.model.CapabilityDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.resources.data.CapabilityData; +import org.openecomp.sdc.be.resources.data.RequirementData; +import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; +import org.openecomp.sdc.be.tosca.model.ToscaCapability; +import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate; +import org.openecomp.sdc.be.tosca.model.ToscaNodeType; +import org.openecomp.sdc.be.tosca.model.ToscaProperty; +import org.openecomp.sdc.be.tosca.model.ToscaRequirement; +import org.openecomp.sdc.be.tosca.model.ToscaTemplateCapability; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class CapabiltyRequirementConvertor { + private static CapabiltyRequirementConvertor instance; + + protected CapabiltyRequirementConvertor() { + + } + + public static synchronized CapabiltyRequirementConvertor getInstance() { + if (instance == null) { + instance = new CapabiltyRequirementConvertor(); + } + return instance; + } + + private static Logger log = LoggerFactory.getLogger(CapabiltyRequirementConvertor.class.getName()); + + public Either convertComponentInstanceCapabilties(ComponentInstance componentInstance, Map dataTypes, ToscaNodeTemplate nodeTemplate) { + + Map> capabilitiesInst = componentInstance.getCapabilities(); + if (capabilitiesInst != null && !capabilitiesInst.isEmpty()) { + Map capabilties = new HashMap<>(); + capabilitiesInst.entrySet().forEach(e -> { + List capList = e.getValue(); + if (capList != null && !capList.isEmpty()) { + capList.forEach(c -> { + convertOverridenProperties(componentInstance, dataTypes, capabilties, c); + }); + } + }); + if (capabilties != null && !capabilties.isEmpty()) { + nodeTemplate.setCapabilities(capabilties); + } + } + return Either.left(nodeTemplate); + } + + private void convertOverridenProperties(ComponentInstance componentInstance, Map dataTypes, Map capabilties, CapabilityDefinition c) { + List properties = c.getProperties(); + if (properties != null && !properties.isEmpty()) { + properties.stream().filter(p -> (p.getValueUniqueUid() != null)).forEach(p -> { + convertOverridenProperty(componentInstance, dataTypes, capabilties, c, p); + }); + } + } + + private void convertOverridenProperty(ComponentInstance componentInstance, Map dataTypes, Map capabilties, CapabilityDefinition c, ComponentInstanceProperty p) { + if (log.isDebugEnabled()) { + log.debug("Exist overriden property {} for capabity {} with value {}", p.getName(), c.getName(), p.getValue()); + } + ToscaTemplateCapability toscaTemplateCapability = capabilties.get(c.getName()); + if (toscaTemplateCapability == null) { + toscaTemplateCapability = new ToscaTemplateCapability(); + capabilties.put(c.getName(), toscaTemplateCapability); + } + Map toscaCapProp = toscaTemplateCapability.getProperties(); + if (toscaCapProp == null) { + toscaCapProp = new HashMap<>(); + } + Object convertedValue = convertInstanceProperty(dataTypes, componentInstance, p); + toscaCapProp.put(p.getName(), convertedValue); + toscaTemplateCapability.setProperties(toscaCapProp); + } + + private Object convertInstanceProperty(Map dataTypes, ComponentInstance componentInstance, ComponentInstanceProperty prop) { + log.debug("Convert property {} for instance {}", prop.getName(), componentInstance.getUniqueId()); + String propertyType = prop.getType(); + String innerType = null; + if (prop.getSchema() != null && prop.getSchema().getProperty() != null) { + innerType = prop.getSchema().getProperty().getType(); + } + Object convertedValue = PropertyConvertor.getInstance().convertToToscaObject(propertyType, prop.getValue(), innerType, dataTypes); + return convertedValue; + } + + public Either convertRequirements(Component component, ToscaNodeType nodeType) { + List> toscaRequirements = convertRequirementsAsList(component); + if (!toscaRequirements.isEmpty()) { + nodeType.setRequirements(toscaRequirements); + } + log.debug("Finish convert Requirements for node type"); + + return Either.left(nodeType); + } + + public Either convertRequirements(Component component, SubstitutionMapping substitutionMapping) { + Map toscaRequirements = convertRequirementsAsMap(component); + if (!toscaRequirements.isEmpty()) { + substitutionMapping.setRequirements(toscaRequirements); + } + log.debug("Finish convert Requirements for node type"); + + return Either.left(substitutionMapping); + } + + private List> convertRequirementsAsList(Component component) { + Map> requirements = component.getRequirements(); + List> toscaRequirements = new ArrayList<>(); + if (requirements != null) { + boolean isNodeType = ToscaUtils.isNodeType(component); + for (Map.Entry> entry : requirements.entrySet()) { + entry.getValue().stream().filter(r -> (!isNodeType || (isNodeType && component.getUniqueId().equals(r.getOwnerId())))).forEach(r -> { + ImmutablePair pair = convertRequirement(component, isNodeType, r); + Map requirement = new HashMap<>(); + + requirement.put(pair.left, pair.right); + toscaRequirements.add(requirement); + }); + + log.debug("Finish convert Requirements for node type"); + } + } else { + log.debug("No Requirements for node type"); + } + return toscaRequirements; + } + + private Map convertRequirementsAsMap(Component component) { + Map> requirements = component.getRequirements(); + Map toscaRequirements = new HashMap<>(); + if (requirements != null) { + boolean isNodeType = ToscaUtils.isNodeType(component); + for (Map.Entry> entry : requirements.entrySet()) { + entry.getValue().stream().filter(r -> (!isNodeType || (isNodeType && component.getUniqueId().equals(r.getOwnerId())))).forEach(r -> { + ImmutablePair pair = convertRequirement(component, isNodeType, r); + toscaRequirements.put(pair.left, pair.right); + }); + + log.debug("Finish convert Requirements for node type"); + } + } else { + log.debug("No Requirements for node type"); + } + return toscaRequirements; + } + + private ImmutablePair convertRequirement(Component component, boolean isNodeType, RequirementDefinition r) { + String name = r.getName(); + if (!isNodeType) { + name = r.getOwnerName() + "." + name; + } + log.debug("the requirement {} belongs to resource {} ", name, component.getUniqueId()); + ToscaRequirement toscaRequirement = new ToscaRequirement(); + + List occurences = new ArrayList<>(); + occurences.add(Integer.valueOf(r.getMinOccurrences())); + if (r.getMaxOccurrences().equals(RequirementData.MAX_OCCURRENCES)) { + occurences.add(r.getMaxOccurrences()); + } else { + occurences.add(Integer.valueOf(r.getMaxOccurrences())); + } + toscaRequirement.setOccurrences(occurences); + // toscaRequirement.setOccurrences(createOcurrencesRange(requirementDefinition.getMinOccurrences(), + // requirementDefinition.getMaxOccurrences())); + toscaRequirement.setNode(r.getNode()); + toscaRequirement.setCapability(r.getCapability()); + toscaRequirement.setRelationship(r.getRelationship()); + + ImmutablePair pair = new ImmutablePair(name, toscaRequirement); + return pair; + } + + public Map convertCapabilities(Component component, Map dataTypes) { + Map> capabilities = component.getCapabilities(); + Map toscaCapabilities = new HashMap<>(); + if (capabilities != null) { + boolean isNodeType = ToscaUtils.isNodeType(component); + for (Map.Entry> entry : capabilities.entrySet()) { + entry.getValue().stream().filter(c -> (!isNodeType || (isNodeType && component.getUniqueId().equals(c.getOwnerId())))).forEach(c -> { + convertCapabilty(component, toscaCapabilities, isNodeType, c, dataTypes); + + }); + } + } else { + log.debug("No Capabilities for node type"); + } + + return toscaCapabilities; + } + + private void convertCapabilty(Component component, Map toscaCapabilities, boolean isNodeType, CapabilityDefinition c, Map dataTypes) { + String name = c.getName(); + if (!isNodeType) { + name = c.getOwnerName() + "." + name; + } + log.debug("the capabilty {} belongs to resource {} ", name, component.getUniqueId()); + ToscaCapability toscaCapability = new ToscaCapability(); + toscaCapability.setDescription(c.getDescription()); + toscaCapability.setType(c.getType()); + + List occurences = new ArrayList<>(); + occurences.add(Integer.valueOf(c.getMinOccurrences())); + if (c.getMaxOccurrences().equals(CapabilityData.MAX_OCCURRENCES)) { + occurences.add(c.getMaxOccurrences()); + } else { + occurences.add(Integer.valueOf(c.getMaxOccurrences())); + } + toscaCapability.setOccurrences(occurences); + + toscaCapability.setValid_source_types(c.getValidSourceTypes()); + List properties = c.getProperties(); + if (properties != null && !properties.isEmpty()) { + Map toscaProperties = new HashMap<>(); + for (PropertyDefinition property : properties) { + ToscaProperty toscaProperty = PropertyConvertor.getInstance().convertProperty(dataTypes, property, true); + toscaProperties.put(property.getName(), toscaProperty); + } + toscaCapability.setProperties(toscaProperties); + } + toscaCapabilities.put(name, toscaCapability); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java new file mode 100644 index 0000000000..c8aa188e30 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/CsarUtils.java @@ -0,0 +1,649 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.io.IOException; +import org.apache.commons.codec.binary.Base64; +import java.util.Collection; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; + +import org.apache.commons.codec.digest.DigestUtils; +import org.apache.commons.io.output.ByteArrayOutputStream; +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic; +import org.openecomp.sdc.be.components.impl.ArtifactsBusinessLogic.ArtifactOperation; +import org.openecomp.sdc.be.components.impl.ServiceBusinessLogic; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.cassandra.ArtifactCassandraDao; +import org.openecomp.sdc.be.dao.cassandra.CassandraOperationStatus; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.Operation; +import org.openecomp.sdc.be.model.Service; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.model.operations.impl.DaoStatusConverter; +import org.openecomp.sdc.be.model.operations.impl.ServiceOperation; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +import org.openecomp.sdc.common.api.ArtifactGroupTypeEnum; +import org.openecomp.sdc.common.util.GeneralUtility; +import org.openecomp.sdc.common.util.ValidationUtils; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; + +import org.openecomp.sdc.generator.data.Artifact; +import org.openecomp.sdc.generator.data.ArtifactType; +import org.openecomp.sdc.generator.data.GenerationData; +import org.openecomp.sdc.generator.impl.ArtifactGenerationServiceImpl; +import com.google.gson.Gson; + +import fj.data.Either; + +/** + * @author tg851x + * + */ +@org.springframework.stereotype.Component("csar-utils") +public class CsarUtils { + private static Logger log = LoggerFactory.getLogger(ToscaExportHandler.class.getName()); + + @Autowired + private ArtifactCassandraDao artifactCassandraDao; + @Autowired + private ComponentsUtils componentsUtils; + @Autowired + private ToscaExportHandler toscaExportUtils; + @Autowired + private ArtifactsBusinessLogic artifactsBusinessLogic; + @Autowired + protected ServiceOperation serviceOperation; + + @javax.annotation.Resource + private ServiceBusinessLogic serviceBusinessLogic; + + private Gson gson = new Gson(); + + private static final String DEFINITIONS_PATH = "Definitions/"; + private static final String ARTIFACTS_PATH = "Artifacts/"; + private static final String TOSCA_META_PATH_FILE_NAME = "TOSCA-Metadata/TOSCA.meta"; + private static final String TOSCA_META_VERSION = "1.0"; + private static final String CSAR_VERSION = "1.1"; + + /** + * + * @param component + * @param getFromCS + * @param isInCertificationRequest + * @param shouldLock + * @param inTransaction + * @return + */ + public Either createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean shouldLock, boolean inTransaction) { + return createCsar(component, getFromCS, isInCertificationRequest, false, shouldLock, inTransaction); + } + + private Either createCsar(Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + final String CREATED_BY = component.getCreatorFullName(); + + String fileName; + Map toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + fileName = artifactDefinition.getArtifactName(); + + String toscaBlock0 = createToscaBlock0(TOSCA_META_VERSION, CSAR_VERSION, CREATED_BY, fileName); + + byte[] toscaBlock0Byte = toscaBlock0.getBytes(); + + Either generateCsarZipResponse = generateCsarZip(toscaBlock0Byte, component, getFromCS, isInCertificationRequest, mockGenerator, shouldLock, inTransaction); + + if (generateCsarZipResponse.isRight()) { + return Either.right(generateCsarZipResponse.right().value()); + } + + return Either.left(generateCsarZipResponse.left().value()); + } + + private Either generateCsarZip(byte[] toscaBlock0Byte, Component component, boolean getFromCS, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + + ZipOutputStream zip = null; + ByteArrayOutputStream out = null; + try { + out = new ByteArrayOutputStream(); + zip = new ZipOutputStream(out); + + zip.putNextEntry(new ZipEntry(TOSCA_META_PATH_FILE_NAME)); + zip.write(toscaBlock0Byte); + Either populateZip = populateZip(component, getFromCS, zip, isInCertificationRequest, mockGenerator, shouldLock, inTransaction); + if (populateZip.isRight()) { + log.debug("Failed to populate CSAR zip file {}", populateZip.right().value()); + return Either.right(populateZip.right().value()); + } + zip = populateZip.left().value(); + + zip.finish(); + byte[] byteArray = out.toByteArray(); + + return Either.left(byteArray); + } catch (IOException e) { + log.debug("createCsar failed IOexception", e); + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(responseFormat); + } finally { + try { + if (zip != null) { + zip.close(); + } + if (out != null) { + out.close(); + } + } catch (Exception e) { + log.error("Failed to close resources ", e); + } + } + } + + private Either populateZip(Component component, boolean getFromCS, ZipOutputStream zip, boolean isInCertificationRequest, boolean mockGenerator, boolean shouldLock, boolean inTransaction) { + + LifecycleStateEnum lifecycleState = component.getLifecycleState(); + String componentYaml = null; + Either exportComponent = null; + byte[] mainYaml = null; + // + List> dependencies = null; + List> generatorInputs = new LinkedList<>(); + + String fileName; + Map toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + fileName = artifactDefinition.getArtifactName(); + + if (getFromCS || !(lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + String esId = artifactDefinition.getEsId(); + Either fromCassandra = getFromCassandra(esId); + if (fromCassandra.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(fromCassandra.right().value()); + return Either.right(responseFormat); + } + mainYaml = fromCassandra.left().value(); + + } else { + exportComponent = toscaExportUtils.exportComponent(component); + if (exportComponent.isRight()) { + log.debug("exportComponent failed", exportComponent.right().value()); + ActionStatus convertedFromToscaError = componentsUtils.convertFromToscaError(exportComponent.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertedFromToscaError); + return Either.right(responseFormat); + } + ToscaRepresentation exportResult = exportComponent.left().value(); + componentYaml = exportResult.getMainYaml(); + mainYaml = componentYaml.getBytes(); + dependencies = exportResult.getDependencies(); + } + + try { + zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName)); + zip.write(mainYaml); + + generatorInputs.add(new ImmutablePair(component, mainYaml)); + + if (dependencies == null) { + Either dependenciesRes = toscaExportUtils.getDependencies(component); + if (dependenciesRes.isRight()) { + log.debug("Failed to retrieve dependencies for component {}, error {}", component.getUniqueId(), dependenciesRes.right().value()); + ActionStatus convertFromToscaError = componentsUtils.convertFromToscaError(dependenciesRes.right().value()); + ResponseFormat responseFormat = componentsUtils.getResponseFormat(convertFromToscaError); + return Either.right(responseFormat); + } + dependencies = dependenciesRes.left().value().getDependencies(); + } + if (dependencies != null && !dependencies.isEmpty()) { + for (Triple d : dependencies) { + String esId = d.getMiddle(); + Component childComponent = d.getRight(); + fileName = d.getLeft(); + Either entryData = getEntryData(esId, childComponent); + + if (entryData.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(entryData.right().value()); + return Either.right(responseFormat); + } + + byte[] content = entryData.left().value(); + zip.putNextEntry(new ZipEntry(DEFINITIONS_PATH + fileName)); + zip.write(content); + + generatorInputs.add(new ImmutablePair(childComponent, content)); + } + } + + List aiiArtifactList = new LinkedList<>(); + // Artifact Generation + if (component.getComponentType() == ComponentTypeEnum.SERVICE && (lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKIN || lifecycleState == LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT)) { + Either, ResponseFormat> handleAAIArtifacts = handleAAIArtifacts(component, zip, mockGenerator, shouldLock, inTransaction, generatorInputs); + + if (handleAAIArtifacts.isLeft()) { + aiiArtifactList = handleAAIArtifacts.left().value(); + } else { + log.debug("AAI Artifacts handling failed"); + return Either.right(handleAAIArtifacts.right().value()); + } + + if (isInCertificationRequest) { + Either handleAllAAIArtifactsInDataModel = handleAllAAIArtifactsInDataModel(component, aiiArtifactList, shouldLock, inTransaction); + + if (handleAllAAIArtifactsInDataModel.isRight()) { + log.debug("AAI Artifacts handling (create, update, delete) failed"); + return Either.right(handleAllAAIArtifactsInDataModel.right().value()); + } + } + + } + + // Collecting All Deployment Artifacts + Either collectAndWriteToScarDeploymentArtifacts = collectAndWriteToScarDeploymentArtifacts(zip, component, aiiArtifactList); + + if (collectAndWriteToScarDeploymentArtifacts.isRight()) { + return Either.right(componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR)); + } + } catch (IOException e) { + log.debug("Failed to create CSAR zip for component {}", component.getUniqueId(), e); + } + + return Either.left(zip); + } + + private Either collectAndWriteToScarDeploymentArtifacts(ZipOutputStream zip, Component component, List aiiArtifactList) throws IOException { + + Collection deploymentArtifactsToAdd = null; + Collection allArtifactsToAdd = new LinkedList<>(); + + if (component.getComponentType() == ComponentTypeEnum.SERVICE) { + Either getServiceResponse = serviceOperation.getService(component.getUniqueId()); + + if (getServiceResponse.isLeft()) { + Service service = getServiceResponse.left().value(); + + if (!aiiArtifactList.isEmpty()) { + deploymentArtifactsToAdd = service.getDeploymentArtifacts().values().stream().filter(e -> e.getGenerated() == null || !e.getGenerated()).collect(Collectors.toList()); + allArtifactsToAdd.addAll(aiiArtifactList); + allArtifactsToAdd.addAll(deploymentArtifactsToAdd); + } else { + allArtifactsToAdd.addAll(service.getDeploymentArtifacts().values()); + } + } + } + + if (!allArtifactsToAdd.isEmpty()) { + + for (ArtifactDefinition deploymentArtifactDefinition : allArtifactsToAdd) { + String artifactFileName = deploymentArtifactDefinition.getArtifactName(); + byte[] payloadData = deploymentArtifactDefinition.getPayloadData(); + + if (payloadData == null) { + String esId = deploymentArtifactDefinition.getEsId(); + if (esId != null) { + Either fromCassandra = getFromCassandra(esId); + + if (fromCassandra.isRight()) { + return Either.right(fromCassandra.right().value()); + } + payloadData = fromCassandra.left().value(); + } else { + log.debug("Artifact {} payload not supplied in ArtifactDefinition and not found in DB", artifactFileName); + continue; + } + } + + byte[] decodedPayload = null; + + if (Base64.isBase64(payloadData)) { + // decodedPayload = Base64.getDecoder().decode(payloadData); + decodedPayload = Base64.decodeBase64(payloadData); + } else { + decodedPayload = payloadData; + } + + zip.putNextEntry(new ZipEntry(ARTIFACTS_PATH + artifactFileName)); + zip.write(decodedPayload); + } + } + + return Either.left(zip); + } + + private Either, ResponseFormat> handleAAIArtifacts(Component component, ZipOutputStream zip, boolean mockGenerator, boolean shouldLock, boolean inTransaction, List> generatorInputs) { + + ComponentTypeEnum componentType = component.getComponentType(); + List generatedArtifacts = null; + List aaiArtifacts = null; + + if (componentType == ComponentTypeEnum.SERVICE && !generatorInputs.isEmpty()) { + List convertedGeneratorInputs = convertToGeneratorArtifactsInput(generatorInputs); + + Either, ResponseFormat> generatorResponse; + + if (mockGenerator) { + generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.OTHER, component); + } else { + generatorResponse = artifactGenerator(convertedGeneratorInputs, ArtifactType.AAI, component); + } + + if (generatorResponse.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), generatorResponse.toString()); + return Either.right(responseFormat); + } + + generatedArtifacts = generatorResponse.left().value(); + + aaiArtifacts = convertToArtifactDefinitionFromArtifactGeneratedData(generatedArtifacts); + + } + + return Either.left(aaiArtifacts); + } + + private Either handleAllAAIArtifactsInDataModel(Component component, List artifactsFromAAI, boolean shouldLock, boolean inTransaction) { + + Either handleAAIArtifactsResponse = null; + User lastComponentUpdater = null; + + List aaiArtifatcsToCreate = getAAIArtifatcsForCreate(artifactsFromAAI, component); + List aaiArtifatcsToDelete = getAAIArtifatcsForDelete(artifactsFromAAI, component); + List aaiArtifatcsToUpdate = getAAIArtifatcsForUpdate(artifactsFromAAI, component); + + String lastUpdaterUserId = component.getLastUpdaterUserId(); + Either validateUserExists = artifactsBusinessLogic.validateUserExists(lastUpdaterUserId, "CSAR creation util", true); + + if (validateUserExists.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), "User not found"); + return Either.right(responseFormat); + } + + lastComponentUpdater = validateUserExists.left().value(); + + handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToDelete, ArtifactOperation.Delete, lastComponentUpdater, shouldLock, inTransaction); + + if (handleAAIArtifactsResponse.isRight()) { + return handleAAIArtifactsResponse; + } + + handleAAIArtifactsResponse = handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToCreate, ArtifactOperation.Create, lastComponentUpdater, shouldLock, inTransaction); + + if (handleAAIArtifactsResponse.isRight()) { + return handleAAIArtifactsResponse; + } + + return handleAAIArtifactsInDataModelByOperationType(component, aaiArtifatcsToUpdate, ArtifactOperation.Update, lastComponentUpdater, shouldLock, inTransaction); + } + + private List getAAIArtifatcsForUpdate(List artifactsFromAAI, Component component) { + + Set componetDeploymentArtifactLables = component.getDeploymentArtifacts().keySet(); + Set componetInformationalArtifactLables = component.getArtifacts().keySet(); + + List artifactsAaiUpdate = artifactsFromAAI.stream().filter(e -> (componetDeploymentArtifactLables.contains(e.getArtifactLabel()) || componetInformationalArtifactLables.contains(e.getArtifactLabel()))) + .filter(e -> checkAaiForUpdate(component, e)).collect(Collectors.toList()); + + return artifactsAaiUpdate; + } + + private boolean checkAaiForUpdate(Component component, ArtifactDefinition artifactDefinition) { + ArtifactDefinition artifactDefinitionComp = component.getDeploymentArtifacts().get(artifactDefinition.getArtifactLabel()); + + if (artifactDefinitionComp == null) { + log.warn("Failed to get {} artifact", artifactDefinition.getArtifactLabel()); + return false; + } + + // Old Artifacts before the generated flag introduction if contains "aai" ignore case prefix updated + if (artifactDefinitionComp.getGenerated() == null) { + if (artifactDefinitionComp.getArtifactLabel().toLowerCase().startsWith("aai")) { + return true; + } else { + log.warn("The artifact {} flag is null but AAI prefix is abssent Not updated", artifactDefinition.getArtifactLabel()); + } + } else { + if (artifactDefinition.getGenerated()) { + return true; + } else { + log.warn("Generated artifact {} was already uploaded manually", artifactDefinition.getArtifactLabel()); + } + } + return false; + } + + private List getAAIArtifatcsForDelete(List artifactsFromAAI, Component component) { + + Set aaiLabels = artifactsFromAAI.stream().map(e -> e.getArtifactLabel()).collect(Collectors.toSet()); + + List artifactsForDeleteDeployment = component.getDeploymentArtifacts().values().stream(). + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + + List artifactsForDeleteInformational = component.getArtifacts().values().stream(). + // Filter Out Artifacts that are not contained in artifacts returned + // from AAI API + filter(e -> !aaiLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + + artifactsForDeleteDeployment.addAll(artifactsForDeleteInformational); + + return artifactsForDeleteDeployment.stream().filter(e -> (e.getGenerated() != null && e.getGenerated().equals(Boolean.TRUE)) || (e.getGenerated() == null && e.getArtifactLabel().toLowerCase().startsWith("aai"))).collect(Collectors.toList()); + } + + private List getAAIArtifatcsForCreate(List artifactsFromAAI, Component component) { + + Set componentDeploymentLabels = component.getDeploymentArtifacts().keySet(); + Set componentInfoLabels = component.getArtifacts().keySet(); + + // If the artifact label does not exist in the service - + // store the artifact (generate uuid and version, "generated" flag is TRUE) + return artifactsFromAAI.stream().filter(e -> !componentDeploymentLabels.contains(e.getArtifactLabel()) && !componentInfoLabels.contains(e.getArtifactLabel())).collect(Collectors.toList()); + } + + private Either handleAAIArtifactsInDataModelByOperationType(Component component, List generatedArtifactsDefinitions, ArtifactOperation operationType, User user, boolean shouldLock, + boolean inTransaction) { + + String componentUniqueId = component.getUniqueId(); + ComponentTypeEnum componentType = component.getComponentType(); + + for (ArtifactDefinition artDef : generatedArtifactsDefinitions) { + String data = gson.toJson(artDef); + String dataMD5 = GeneralUtility.calculateMD5ByString(data); + String artifactUniqueId = null; + + if (operationType.equals(ArtifactOperation.Update) || operationType.equals(ArtifactOperation.Delete)) { + String artifactLabel = artDef.getArtifactLabel(); + ArtifactDefinition artifactDefinition = component.getDeploymentArtifacts().get(artifactLabel); + if (artifactDefinition != null) { + artifactUniqueId = artifactDefinition.getUniqueId(); + } + } + + Either, ResponseFormat> validateAndHandleArtifact = artifactsBusinessLogic.validateAndHandleArtifact(componentUniqueId, componentType, operationType, artifactUniqueId, artDef, dataMD5, data, null, + null, null, user, component, shouldLock, inTransaction); + + if (validateAndHandleArtifact.isRight()) { + if (ArtifactOperation.Create == operationType || ArtifactOperation.Update == operationType) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, componentType.getValue(), component.getName(), validateAndHandleArtifact.right().value().toString()); + + Either.right(responseFormat); + } else { + log.warn("Generated artifact {} could not be deleted", artDef.getArtifactLabel()); + } + } + } + + return Either.left(ActionStatus.OK); + } + + private List convertToArtifactDefinitionFromArtifactGeneratedData(List generatorOutput) { + List artifactDefList = new LinkedList<>(); + + for (Artifact artifact : generatorOutput) { + ArtifactDefinition newEntry = new ArtifactDefinition(); + newEntry.setArtifactName(artifact.getName()); + newEntry.setArtifactType(artifact.getType()); + newEntry.setArtifactGroupType(ArtifactGroupTypeEnum.findType(artifact.getGroupType())); + newEntry.setDescription(artifact.getDescription()); + + // Normalizing the artifact label to match those stored in DB + String normalizeArtifactLabel = ValidationUtils.normalizeArtifactLabel(artifact.getLabel()); + newEntry.setArtifactLabel(normalizeArtifactLabel); + newEntry.setPayload(artifact.getPayload()); + newEntry.setArtifactChecksum(artifact.getChecksum()); + // Flag that set to true in case that the artifact is generated by AI&I generator + newEntry.setGenerated(Boolean.TRUE); + + artifactDefList.add(newEntry); + } + + return artifactDefList; + } + + // List> + // artifact stored by label + private List convertToGeneratorArtifactsInput(List> inputs) { + List listOfArtifactsInput = new LinkedList<>(); + for (ImmutablePair triple : inputs) { + Component component = triple.getLeft(); + + Map toscaArtifacts = component.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ToscaExportHandler.ASSET_TOSCA_TEMPLATE); + + String artifactName = artifactDefinition.getArtifactName(); + String artifactType = artifactDefinition.getArtifactType(); + String artifactGroupType = artifactDefinition.getArtifactGroupType().getType(); + String artifactDescription = artifactDefinition.getDescription(); + String artifactLabel = artifactDefinition.getArtifactLabel(); + byte[] right = triple.getRight(); + // The md5 calculated on the uncoded data + String md5Hex = DigestUtils.md5Hex(right); + // byte[] payload = Base64.getEncoder().encode(right); + byte[] payload = Base64.encodeBase64(right); + String artifactVersion = artifactDefinition.getArtifactVersion(); + + Artifact convertedArtifact = new Artifact(artifactType, artifactGroupType, md5Hex, payload); + convertedArtifact.setName(artifactName); + convertedArtifact.setDescription(artifactDescription); + convertedArtifact.setLabel(artifactLabel); + convertedArtifact.setVersion(artifactVersion); + + listOfArtifactsInput.add(convertedArtifact); + } + + return listOfArtifactsInput; + } + + private Either getEntryData(String esId, Component childComponent) { + byte[] content; + if (esId == null || esId.isEmpty()) { + Either exportRes = toscaExportUtils.exportComponent(childComponent); + if (exportRes.isRight()) { + log.debug("Failed to export tosca template for child component {} error {}", childComponent.getUniqueId(), exportRes.right().value()); + return Either.right(componentsUtils.convertFromToscaError(exportRes.right().value())); + } + content = exportRes.left().value().getMainYaml().getBytes(); + } else { + Either fromCassandra = getFromCassandra(esId); + if (fromCassandra.isRight()) { + return Either.right(fromCassandra.right().value()); + } else { + content = fromCassandra.left().value(); + } + } + return Either.left(content); + } + + private Either getFromCassandra(String esId) { + Either artifactResponse = artifactCassandraDao.getArtifact(esId); + + if (artifactResponse.isRight()) { + log.debug("In createCsar fetching of artifact from CS failed"); + log.debug("Failed to fetch from Cassandra by id {} error {} ", esId, artifactResponse.right().value()); + + StorageOperationStatus storageStatus = DaoStatusConverter.convertCassandraStatusToStorageStatus(artifactResponse.right().value()); + ActionStatus convertedFromStorageResponse = componentsUtils.convertFromStorageResponse(storageStatus); + return Either.right(convertedFromStorageResponse); + } else { + ESArtifactData artifactData = artifactResponse.left().value(); + return Either.left(artifactData.getDataAsArray()); + + } + } + + private String createToscaBlock0(String metaFileVersion, String csarVersion, String createdBy, String entryDef) { + final String BLOCK_0_TEMPLATE = "TOSCA-Meta-File-Version: %s\nCSAR-Version: %s\nCreated-By: %s\nEntry-Definitions: Definitions/%s\n"; + String readyBlock = String.format(BLOCK_0_TEMPLATE, metaFileVersion, csarVersion, createdBy, entryDef); + return readyBlock; + } + + private Either, ResponseFormat> artifactGenerator(List artifactList, ArtifactType type, Component component) { + + ArtifactGenerationServiceImpl artifactGenerationServiceImpl = new ArtifactGenerationServiceImpl(); + ArtifactTypes artifactTypes = new ArtifactTypes(); + List artifactTypesList = new LinkedList<>(); + ArtifactType otherType; + + if (type == null) { + otherType = ArtifactType.OTHER; + } else { + otherType = type; + } + + artifactTypesList.add(otherType); + artifactTypes.setArtifactTypes(artifactTypesList); + + String configJson = gson.toJson(artifactTypes); + GenerationData generatedArtifacts = artifactGenerationServiceImpl.generateArtifact(artifactList, configJson); + + Map> errorData = generatedArtifacts.getErrorData(); + + if (!errorData.isEmpty()) { + Set keySet = errorData.keySet(); + + for (String key : keySet) { + List errorList = errorData.get(key); + log.debug("The Artifact Generator Failed - {} with following: {}", key, errorList); + } + + ResponseFormat responseFormat = componentsUtils.getResponseFormat(ActionStatus.AAI_ARTIFACT_GENERATION_FAILED, component.getComponentType().getValue(), component.getName(), errorData.toString()); + return Either.right(responseFormat); + } + + return Either.left(generatedArtifacts.getResultData()); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java new file mode 100644 index 0000000000..544b85361d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/PropertyConvertor.java @@ -0,0 +1,189 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.io.StringReader; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.elements.SchemaDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.PropertyDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.tosca.ToscaPropertyType; +import org.openecomp.sdc.be.model.tosca.converters.ToscaMapValueConverter; +import org.openecomp.sdc.be.model.tosca.converters.ToscaValueConverter; +import org.openecomp.sdc.be.tosca.model.EntrySchema; +import org.openecomp.sdc.be.tosca.model.ToscaNodeType; +import org.openecomp.sdc.be.tosca.model.ToscaProperty; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.google.gson.JsonElement; +import com.google.gson.JsonParser; +import com.google.gson.JsonSyntaxException; +import com.google.gson.stream.JsonReader; + +import fj.data.Either; + +public class PropertyConvertor { + private static PropertyConvertor instance; + private JsonParser jsonParser = new JsonParser(); + private static Logger log = LoggerFactory.getLogger(PropertyConvertor.class.getName()); + + protected PropertyConvertor() { + + } + + public static synchronized PropertyConvertor getInstance() { + if (instance == null) { + instance = new PropertyConvertor(); + } + return instance; + } + + public Either convertProperties(Component component, ToscaNodeType toscaNodeType, Map dataTypes) { + + if (component instanceof Resource) { + Resource resource = (Resource) component; + List props = resource.getProperties(); + if (props != null) { + Map properties = new HashMap<>(); + + // take only the properties of this resource + props.stream().filter(p -> component.getUniqueId().equals(p.getParentUniqueId())).forEach(property -> { + ToscaProperty prop = convertProperty(dataTypes, property, false); + + properties.put(property.getName(), prop); + + }); + if (!properties.isEmpty()) { + toscaNodeType.setProperties(properties); + } + } + } + return Either.left(toscaNodeType); + } + + public ToscaProperty convertProperty(Map dataTypes, PropertyDefinition property, boolean isCapabiltyProperty) { + ToscaProperty prop = new ToscaProperty(); + + String innerType = null; + SchemaDefinition schema = property.getSchema(); + if (schema != null && schema.getProperty() != null && schema.getProperty().getType() != null && !schema.getProperty().getType().isEmpty()) { + innerType = schema.getProperty().getType(); + EntrySchema eschema = new EntrySchema(); + eschema.setType(innerType); + eschema.setDescription(schema.getProperty().getDescription()); + prop.setEntry_schema(eschema); + } + log.debug("try to convert property {} from type {} with default value {}", property.getName(), property.getType(), property.getDefaultValue()); + prop.setDefaultp(convertToToscaObject(property.getType(), property.getDefaultValue(), innerType, dataTypes)); + prop.setType(property.getType()); + prop.setDescription(property.getDescription()); + if (isCapabiltyProperty) { + prop.setStatus(property.getStatus()); + prop.setRequired(property.isRequired()); + } + return prop; + } + + public Object convertToToscaObject(String propertyType, String value, String innerType, Map dataTypes) { + log.debug("try to convert propertyType {} , value {}, innerType {}", propertyType, value, innerType); + if (value == null) { + return value; + } + + ToscaMapValueConverter mapConverterInst = ToscaMapValueConverter.getInstance(); + ToscaValueConverter innerConverter = null; + Boolean isScalar = true; + + ToscaPropertyType type = ToscaPropertyType.isValidType(propertyType); + if (type == null) { + log.debug("isn't prederfined type, get from all data types"); + DataTypeDefinition dataTypeDefinition = dataTypes.get(propertyType); + if (innerType == null) { + innerType = propertyType; + } + + if ((type = mapConverterInst.isScalarType(dataTypeDefinition)) != null) { + log.debug("This is scalar type. get suitable converter for type {}", type); + innerConverter = type.getValueConverter(); + } else { + isScalar = false; + } + } else { + ToscaPropertyType typeIfScalar = ToscaPropertyType.getTypeIfScalar(type.getType()); + if (typeIfScalar == null) { + isScalar = false; + } + + innerConverter = type.getValueConverter(); + if (ToscaPropertyType.STRING.equals(type) && value.startsWith("/")) { + return innerConverter.convertToToscaValue(value, innerType, dataTypes); + } + } + JsonElement jsonElement = null; + try { + StringReader reader = new StringReader(value); + JsonReader jsonReader = new JsonReader(reader); + jsonReader.setLenient(true); + + jsonElement = jsonParser.parse(jsonReader); + + if (value.equals("")) { + return value; + } + + if (jsonElement.isJsonPrimitive() && isScalar) { + log.debug("It's well defined type. convert it"); + ToscaValueConverter converter = type.getValueConverter(); + return converter.convertToToscaValue(value, innerType, dataTypes); + } else { + log.debug("It's data type or inputs in primitive type. convert as map"); + Object convertedValue; + if (innerConverter != null && (ToscaPropertyType.MAP.equals(type) || ToscaPropertyType.LIST.equals(type))) { + convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); + } else { + if (isScalar) { + // complex json for scalar type + convertedValue = mapConverterInst.handleComplexJsonValue(jsonElement); + } else { + if (innerConverter != null) { + convertedValue = innerConverter.convertToToscaValue(value, innerType, dataTypes); + } else { + convertedValue = mapConverterInst.convertDataTypeToToscaMap(innerType, dataTypes, innerConverter, isScalar, jsonElement); + } + } + } + return convertedValue; + } + + } catch (JsonSyntaxException e) { + log.debug("convertToToscaValue failed to parse json value :", e); + return null; + } + + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaError.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaError.java new file mode 100644 index 0000000000..94dd559d2d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaError.java @@ -0,0 +1,26 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +public enum ToscaError { + + NODE_TYPE_CAPABILITY_ERROR, NOT_SUPPORTED_TOSCA_TYPE, NODE_TYPE_REQUIREMENT_ERROR, GENERAL_ERROR +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java new file mode 100644 index 0000000000..1bf940ffc0 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaExportHandler.java @@ -0,0 +1,629 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.beans.IntrospectionException; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.commons.lang3.tuple.ImmutableTriple; +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.config.ConfigurationManager; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.be.datamodel.utils.ArtifactUtils; +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.model.ArtifactDefinition; +import org.openecomp.sdc.be.model.Component; +import org.openecomp.sdc.be.model.ComponentInstance; +import org.openecomp.sdc.be.model.ComponentInstanceProperty; +import org.openecomp.sdc.be.model.DataTypeDefinition; +import org.openecomp.sdc.be.model.GroupDefinition; +import org.openecomp.sdc.be.model.GroupProperty; +import org.openecomp.sdc.be.model.InputDefinition; +import org.openecomp.sdc.be.model.RequirementAndRelationshipPair; +import org.openecomp.sdc.be.model.RequirementCapabilityRelDef; +import org.openecomp.sdc.be.model.RequirementDefinition; +import org.openecomp.sdc.be.model.Resource; +import org.openecomp.sdc.be.model.cache.ApplicationDataTypeCache; +import org.openecomp.sdc.be.model.category.CategoryDefinition; +import org.openecomp.sdc.be.model.operations.api.IResourceOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.tosca.model.IToscaMetadata; +import org.openecomp.sdc.be.tosca.model.SubstitutionMapping; +import org.openecomp.sdc.be.tosca.model.ToscaCapability; +import org.openecomp.sdc.be.tosca.model.ToscaGroupTemplate; +import org.openecomp.sdc.be.tosca.model.ToscaMetadata; +import org.openecomp.sdc.be.tosca.model.ToscaNodeTemplate; +import org.openecomp.sdc.be.tosca.model.ToscaNodeType; +import org.openecomp.sdc.be.tosca.model.ToscaProperty; +import org.openecomp.sdc.be.tosca.model.ToscaTemplate; +import org.openecomp.sdc.be.tosca.model.ToscaTemplateRequirement; +import org.openecomp.sdc.be.tosca.model.ToscaTopolgyTemplate; +import org.openecomp.sdc.be.tosca.model.VfModuleToscaMetadata; +import org.openecomp.sdc.common.api.ArtifactTypeEnum; +import org.openecomp.sdc.common.api.Constants; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.yaml.snakeyaml.DumperOptions; +import org.yaml.snakeyaml.DumperOptions.FlowStyle; +import org.yaml.snakeyaml.Yaml; +import org.yaml.snakeyaml.introspector.BeanAccess; +import org.yaml.snakeyaml.introspector.Property; +import org.yaml.snakeyaml.introspector.PropertyUtils; +import org.yaml.snakeyaml.nodes.MappingNode; +import org.yaml.snakeyaml.nodes.Node; +import org.yaml.snakeyaml.nodes.NodeTuple; +import org.yaml.snakeyaml.nodes.Tag; +import org.yaml.snakeyaml.representer.Represent; +import org.yaml.snakeyaml.representer.Representer; + +import fj.data.Either; + +@org.springframework.stereotype.Component("tosca-export-handler") +public class ToscaExportHandler { + + @Autowired + private ApplicationDataTypeCache dataTypeCache; + + @Autowired + private IResourceOperation resourceOperation; + + private CapabiltyRequirementConvertor capabiltyRequirementConvertor = CapabiltyRequirementConvertor.getInstance(); + private PropertyConvertor propertyConvertor = PropertyConvertor.getInstance(); + + private static Logger log = LoggerFactory.getLogger(ToscaExportHandler.class.getName()); + + public static final String TOSCA_VERSION = "tosca_simple_yaml_1_0"; + public static final String SERVICE_NODE_TYPE_PREFIX = "org.openecomp.service."; + public static final String IMPORTS_FILE_KEY = "file"; + public static final String TOSCA_TEMPLATE_NAME = "-template.yml"; + public static final String ASSET_TOSCA_TEMPLATE = "assettoscatemplate"; + public static final String VF_MODULE_TYPE_KEY = "vf_module_type"; + public static final String VF_MODULE_DESC_KEY = "vf_module_description"; + public static final String VOLUME_GROUP_KEY = "volume_group"; + public static final String VF_MODULE_TYPE_BASE = "Base"; + public static final String VF_MODULE_TYPE_EXPANSION = "Expansion"; + + public Either exportComponent(Component component) { + + Either toscaTemplateRes = convertToToscaTemplate(component); + if (toscaTemplateRes.isRight()) { + return Either.right(toscaTemplateRes.right().value()); + } + + CustomRepresenter representer = new CustomRepresenter(); + DumperOptions options = new DumperOptions(); + options.setAllowReadOnlyProperties(false); + options.setPrettyFlow(true); + + options.setDefaultFlowStyle(FlowStyle.FLOW); + options.setCanonical(false); + + ToscaTemplate toscaTemplate = toscaTemplateRes.left().value(); + representer.addClassTag(toscaTemplate.getClass(), Tag.MAP); + + representer.setPropertyUtils(new UnsortedPropertyUtils()); + Yaml yaml = new Yaml(representer, options); + + String yamlAsString = yaml.dumpAsMap(toscaTemplate); + + StringBuilder sb = new StringBuilder(); + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactHeader()); + sb.append(yamlAsString); + sb.append(ConfigurationManager.getConfigurationManager().getConfiguration().getHeatEnvArtifactFooter()); + + ToscaRepresentation toscaRepresentation = new ToscaRepresentation(); + toscaRepresentation.setMainYaml(sb.toString()); + toscaRepresentation.setDependencies(toscaTemplate.getDependencies()); + + return Either.left(toscaRepresentation); + } + + public Either getDependencies(Component component) { + ToscaTemplate toscaTemplate = new ToscaTemplate(null); + Either>, ToscaError> fillImports = fillImports(component, toscaTemplate); + if (fillImports.isRight()) { + return Either.right(fillImports.right().value()); + } + return Either.left(fillImports.left().value().left); + } + + private Either convertToToscaTemplate(Component component) { + log.debug("start tosca export for {}", component.getUniqueId()); + ToscaTemplate toscaTemplate = new ToscaTemplate(TOSCA_VERSION); + + toscaTemplate.setMetadata(convertMetadata(component, false)); + + Map node_types = new HashMap<>(); + if (ToscaUtils.isNodeType(component)) { + log.debug("convert component as node type"); + return convertNodeType(component, toscaTemplate, node_types); + } else { + log.debug("convert component as topology template"); + return convertToscaTemplate(component, toscaTemplate); + } + + } + + private Either convertToscaTemplate(Component component, ToscaTemplate toscaNode) { + + Either>, ToscaError> importsRes = fillImports(component, toscaNode); + if (importsRes.isRight()) { + return Either.right(importsRes.right().value()); + } + toscaNode = importsRes.left().value().left; + + Map componentCache = importsRes.left().value().right; + Either, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll(); + if (dataTypesEither.isRight()) { + log.debug("Failed to retrieve all data types {}", dataTypesEither.right().value()); + return Either.right(ToscaError.GENERAL_ERROR); + } + Map dataTypes = dataTypesEither.left().value(); + + ToscaTopolgyTemplate topology_template = new ToscaTopolgyTemplate(); + + Either inputs = fillInputs(component, topology_template, dataTypes); + if (inputs.isRight()) { + return Either.right(inputs.right().value()); + } + topology_template = inputs.left().value(); + + List componentInstances = component.getComponentInstances(); + Map> componentInstancesProperties = component.getComponentInstancesProperties(); + List groups = component.getGroups(); + if (componentInstances != null && !componentInstances.isEmpty()) { + + Either, ToscaError> node_templates = convertNodeTemplates(component, componentInstances, componentInstancesProperties, componentCache, dataTypes); + if (node_templates.isRight()) { + return Either.right(node_templates.right().value()); + } + log.debug("node templates converted"); + + topology_template.setNode_templates(node_templates.left().value()); + } + if (groups != null && !groups.isEmpty()) { + Map groupsMap = new HashMap(); + for (GroupDefinition group : groups) { + ToscaGroupTemplate toscaGroup = convertGroup(group, component); + groupsMap.put(group.getName(), toscaGroup); + + } + topology_template.setGroups(groupsMap); + log.debug("groups converted"); + + } + + SubstitutionMapping substitutionMapping = new SubstitutionMapping(); + String toscaResourceName = null; + switch (component.getComponentType()) { + case RESOURCE: + toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName(); + break; + case SERVICE: + toscaResourceName = SERVICE_NODE_TYPE_PREFIX + component.getComponentMetadataDefinition().getMetadataDataDefinition().getSystemName(); + break; + default: + log.debug("Not supported component type {}", component.getComponentType()); + return Either.right(ToscaError.NOT_SUPPORTED_TOSCA_TYPE); + } + substitutionMapping.setNode_type(toscaResourceName); + + Either capabilities = convertCapabilities(component, substitutionMapping, dataTypes); + if (capabilities.isRight()) { + return Either.right(capabilities.right().value()); + } + substitutionMapping = capabilities.left().value(); + + Either requirements = capabiltyRequirementConvertor.convertRequirements(component, substitutionMapping); + if (requirements.isRight()) { + return Either.right(requirements.right().value()); + } + substitutionMapping = requirements.left().value(); + + topology_template.setSubstitution_mappings(substitutionMapping); + + toscaNode.setTopology_template(topology_template); + return Either.left(toscaNode); + } + + private Either fillInputs(Component component, ToscaTopolgyTemplate topology_template, Map dataTypes) { + if (log.isDebugEnabled()) + log.debug("fillInputs for component {}", component.getUniqueId()); + List inputDef = component.getInputs(); + Map inputs = new HashMap<>(); + + if (inputDef != null) { + inputDef.forEach(i -> { + ToscaProperty property = propertyConvertor.convertProperty(dataTypes, i, false); + inputs.put(i.getName(), property); + }); + if (inputs != null && !inputs.isEmpty()) { + topology_template.setInputs(inputs); + } + } + return Either.left(topology_template); + } + + private ToscaMetadata convertMetadata(Component component, boolean isInstance) { + ToscaMetadata toscaMetadata = new ToscaMetadata(); + toscaMetadata.setName(component.getComponentMetadataDefinition().getMetadataDataDefinition().getName()); + toscaMetadata.setInvariantUUID(component.getInvariantUUID()); + toscaMetadata.setUUID(component.getUUID()); + toscaMetadata.setDescription(component.getDescription()); + + List categories = component.getCategories(); + CategoryDefinition categoryDefinition = categories.get(0); + toscaMetadata.setCategory(categoryDefinition.getName()); + + if (isInstance) { + toscaMetadata.setVersion(component.getVersion()); + } + switch (component.getComponentType()) { + case RESOURCE: + Resource resource = (Resource) component; + toscaMetadata.setType(resource.getResourceType().name()); + toscaMetadata.setSubcategory(categoryDefinition.getSubcategories().get(0).getName()); + if (!isInstance) { + toscaMetadata.setResourceVendor(resource.getVendorName()); + toscaMetadata.setResourceVendorRelease(resource.getVendorRelease()); + } + break; + case SERVICE: + toscaMetadata.setType(component.getComponentType().getValue()); + if (!isInstance) { + toscaMetadata.setServiceEcompNaming(false); + toscaMetadata.setServiceHoming(false); + } + break; + default: + log.debug("Not supported component type {}", component.getComponentType()); + } + return toscaMetadata; + } + + private Either>, ToscaError> fillImports(Component component, ToscaTemplate toscaTemplate) { + Map componentCache = new HashMap<>(); + if (!ToscaUtils.isNodeType(component)) { + List componentInstances = component.getComponentInstances(); + if (componentInstances != null && !componentInstances.isEmpty()) { + List>> imports = new LinkedList>>(); + List> dependecies = new ArrayList<>(); + + componentInstances.forEach(ci -> { + createDependency(componentCache, imports, dependecies, ci); + }); + toscaTemplate.setImports(imports); + toscaTemplate.setDependencies(dependecies); + } + } else { + log.debug("currently imports supported for VF and service only"); + } + return Either.left(new ImmutablePair>(toscaTemplate, componentCache)); + } + + private void createDependency(Map componentCache, List>> imports, List> dependecies, ComponentInstance ci) { + Map files = new HashMap<>(); + Map> importsListMember = new HashMap<>(); + + Component componentRI = componentCache.get(ci.getComponentUid()); + if (componentRI == null) { + // all resource must be only once! + Either resource = resourceOperation.getResource(ci.getComponentUid(), true); + if (resource.isRight()) { + log.debug("Failed to fetch resource with id {} for instance {}"); + } + Resource fetchedComponent = resource.left().value(); + componentCache.put(fetchedComponent.getUniqueId(), fetchedComponent); + componentRI = fetchedComponent; + + Map toscaArtifacts = componentRI.getToscaArtifacts(); + ArtifactDefinition artifactDefinition = toscaArtifacts.get(ASSET_TOSCA_TEMPLATE); + if (artifactDefinition != null) { + String artifactName = artifactDefinition.getArtifactName(); + files.put(IMPORTS_FILE_KEY, artifactName); + importsListMember.put(ci.getComponentName(), files); + dependecies.add(new ImmutableTriple(artifactName, artifactDefinition.getEsId(), fetchedComponent)); + } + } + if (!importsListMember.isEmpty()) { + imports.add(importsListMember); + } + } + + private Either convertNodeType(Component component, ToscaTemplate toscaNode, Map node_types) { + log.debug("start convert node type for {}", component.getUniqueId()); + ToscaNodeType toscaNodeType = createNodeType(component); + + Either, TitanOperationStatus> dataTypesEither = dataTypeCache.getAll(); + if (dataTypesEither.isRight()) { + log.debug("Failed to fetch all data types :", dataTypesEither.right().value()); + return Either.right(ToscaError.GENERAL_ERROR); + } + + Map dataTypes = dataTypesEither.left().value(); + Either properties = propertyConvertor.convertProperties(component, toscaNodeType, dataTypes); + if (properties.isRight()) { + return Either.right(properties.right().value()); + } + toscaNodeType = properties.left().value(); + log.debug("Properties converted for {}", component.getUniqueId()); + + Either capabilities = convertCapabilities(component, toscaNodeType, dataTypes); + if (capabilities.isRight()) { + return Either.right(capabilities.right().value()); + } + toscaNodeType = capabilities.left().value(); + log.debug("Capabilities converted for {}", component.getUniqueId()); + + Either requirements = capabiltyRequirementConvertor.convertRequirements(component, toscaNodeType); + if (requirements.isRight()) { + return Either.right(requirements.right().value()); + } + toscaNodeType = requirements.left().value(); + log.debug("Requirements converted for {}", component.getUniqueId()); + + String toscaResourceName = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getToscaResourceName(); + node_types.put(toscaResourceName, toscaNodeType); + toscaNode.setNode_types(node_types); + log.debug("finish convert node type for {}", component.getUniqueId()); + return Either.left(toscaNode); + } + + private Either, ToscaError> convertNodeTemplates(Component component, List componentInstances, Map> componentInstancesProperties, + Map componentCache, Map dataTypes) { + log.debug("start convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType()); + Map node_templates = new HashMap<>(); + + for (ComponentInstance componentInstance : componentInstances) { + ToscaNodeTemplate nodeTemplate = new ToscaNodeTemplate(); + nodeTemplate.setType(componentInstance.getToscaComponentName()); + + Either requirements = convertComponentInstanceRequirements(component, componentInstance, component.getComponentInstancesRelations(), nodeTemplate); + if (requirements.isRight()) { + return Either.right(requirements.right().value()); + } + log.debug("Component instance Requirements converted for instance {}", componentInstance.getUniqueId()); + + nodeTemplate = requirements.left().value(); + + Component componentOfInstance = componentCache.get(componentInstance.getComponentUid()); + nodeTemplate.setMetadata(convertMetadata(componentOfInstance, true)); + + Either capabilties = capabiltyRequirementConvertor.convertComponentInstanceCapabilties(componentInstance, dataTypes, nodeTemplate); + if (capabilties.isRight()) { + return Either.right(requirements.right().value()); + } + log.debug("Component instance Capabilties converted for instance {}", componentInstance.getUniqueId()); + + nodeTemplate = capabilties.left().value(); + + if (componentInstancesProperties.containsKey(componentInstance.getUniqueId())) { + Map props = null; + List propList = componentInstancesProperties.get(componentInstance.getUniqueId()); + List collect = propList.stream().filter(e -> e.getValueUniqueUid() != null && !e.getValueUniqueUid().isEmpty()).collect(Collectors.toList()); + if (collect != null && !collect.isEmpty()) { + props = new HashMap(); + for (ComponentInstanceProperty prop : collect) { + Object convertedValue = convertInstanceProperty(dataTypes, componentInstance, prop); + props.put(prop.getName(), convertedValue); + } + } + if (props != null && !props.isEmpty()) { + nodeTemplate.setProperties(props); + } + } + node_templates.put(componentInstance.getName(), nodeTemplate); + } + log.debug("finish convert topology template for {} for type {}", component.getUniqueId(), component.getComponentType()); + return Either.left(node_templates); + } + + private Object convertInstanceProperty(Map dataTypes, ComponentInstance componentInstance, ComponentInstanceProperty prop) { + log.debug("Convert property {} for instance {}", prop.getName(), componentInstance.getUniqueId()); + String propertyType = prop.getType(); + String innerType = null; + if (prop.getSchema() != null && prop.getSchema().getProperty() != null) { + innerType = prop.getSchema().getProperty().getType(); + } + Object convertedValue = propertyConvertor.convertToToscaObject(propertyType, prop.getValue(), innerType, dataTypes); + return convertedValue; + } + + private ToscaGroupTemplate convertGroup(GroupDefinition group, Component component) { + ToscaGroupTemplate toscaGroup = new ToscaGroupTemplate(); + Map members = group.getMembers(); + toscaGroup.setType(group.getType()); + if (members != null) + toscaGroup.setMembers(new ArrayList(members.keySet())); + + boolean isVfModule = group.getType().equals(Constants.DEFAULT_GROUP_VF_MODULE) ? true : false; + IToscaMetadata toscaMetadata; + if (!isVfModule) { + toscaMetadata = new ToscaMetadata(); + } else { + toscaMetadata = new VfModuleToscaMetadata(); + Map properties = new HashMap<>(); + + for (GroupProperty gp : group.getProperties()) { + if (gp.getName().equals(Constants.IS_BASE)) { + Boolean isBase = Boolean.parseBoolean(gp.getValue()); + String type = isBase ? VF_MODULE_TYPE_BASE : VF_MODULE_TYPE_EXPANSION; + properties.put(VF_MODULE_TYPE_KEY, type); + break; + } + } + properties.put(VF_MODULE_DESC_KEY, group.getDescription()); + boolean isVolume = false; + List artifactsList = group.getArtifacts(); + if (artifactsList != null && !artifactsList.isEmpty()) { + + for (String artifactId : artifactsList) { + Map deploymentArtifacts = component.getDeploymentArtifacts(); + Optional findFirst = deploymentArtifacts.values().stream().filter(p -> p.getUniqueId().equals(artifactId)).findFirst(); + if (findFirst.isPresent()) { + ArtifactDefinition artifactDefinition = findFirst.get(); + if (artifactDefinition.getArtifactType().equalsIgnoreCase(ArtifactTypeEnum.HEAT_VOL.getType())) { + isVolume = true; + break; + } + } + } + } + properties.put(VOLUME_GROUP_KEY, isVolume); + toscaGroup.setProperties(properties); + } + toscaMetadata.setName(group.getName()); + toscaMetadata.setInvariantUUID(group.getInvariantUUID()); + toscaMetadata.setUUID(group.getGroupUUID()); + toscaMetadata.setVersion(group.getVersion()); + toscaGroup.setMetadata(toscaMetadata); + return toscaGroup; + } + + private ToscaNodeType createNodeType(Component component) { + ToscaNodeType toscaNodeType = new ToscaNodeType(); + if (ToscaUtils.isNodeType(component) && ((Resource) component).getDerivedFrom() != null) { + toscaNodeType.setDerived_from(((Resource) component).getDerivedFrom().get(0)); + } + toscaNodeType.setDescription(component.getDescription()); // or name?? + return toscaNodeType; + } + + private Either convertComponentInstanceRequirements(Component component, ComponentInstance componentInstance, List relations, ToscaNodeTemplate nodeTypeTemplate) { + + List instancesList = component.getComponentInstances(); + List> toscaRequirements = new ArrayList<>(); + Map> reqMap = componentInstance.getRequirements(); + + relations.stream().filter(p -> componentInstance.getUniqueId().equals(p.getFromNode())).forEach(req -> { + ComponentInstance toComponentInstance = instancesList.stream().filter(i -> req.getToNode().equals(i.getUniqueId())).findFirst().orElse(null); + if (toComponentInstance == null) { + log.debug("Faild to create relation between node {} to node {}", componentInstance.getName(), req.getToNode()); + return; + + } + RequirementAndRelationshipPair reqAndRelationshopPair = req.getRelationships().get(0); + ToscaTemplateRequirement toscaRequirement = new ToscaTemplateRequirement(); + toscaRequirement.setRelationship(reqAndRelationshopPair.getRelationship().getType()); + toscaRequirement.setNode(toComponentInstance.getName()); + Optional findAny = reqMap.values().stream().flatMap(e -> e.stream()).filter(e -> e.getName().equals(reqAndRelationshopPair.getRequirement())).findAny(); + if (findAny.isPresent()) { + RequirementDefinition regDefinition = findAny.get(); + toscaRequirement.setCapability(regDefinition.getCapability()); + } else { + log.debug("Faild to find relation between node {} to node {}", componentInstance.getName(), req.getToNode()); + return; + } + Map reqmap = new HashMap(); + reqmap.put(reqAndRelationshopPair.getRequirement(), toscaRequirement); + toscaRequirements.add(reqmap); + + }); + + if (!toscaRequirements.isEmpty()) { + nodeTypeTemplate.setRequirements(toscaRequirements); + } + log.debug("Finish convert Requirements for node type"); + return Either.left(nodeTypeTemplate); + } + + private Either convertCapabilities(Component component, SubstitutionMapping substitutionMapping, Map dataTypes) { + Map toscaCapabilities = capabiltyRequirementConvertor.convertCapabilities(component, dataTypes); + if (!toscaCapabilities.isEmpty()) { + substitutionMapping.setCapabilities(toscaCapabilities); + } + log.debug("Finish convert Capabilities for node type"); + + return Either.left(substitutionMapping); + } + + private Either convertCapabilities(Component component, ToscaNodeType nodeType, Map dataTypes) { + Map toscaCapabilities = capabiltyRequirementConvertor.convertCapabilities(component, dataTypes); + if (!toscaCapabilities.isEmpty()) { + nodeType.setCapabilities(toscaCapabilities); + } + log.debug("Finish convert Capabilities for node type"); + + return Either.left(nodeType); + } + + private static class CustomRepresenter extends Representer { + public CustomRepresenter() { + super(); + // null representer is exceptional and it is stored as an instance + // variable. + this.nullRepresenter = new RepresentNull(); + + } + + @Override + protected NodeTuple representJavaBeanProperty(Object javaBean, Property property, Object propertyValue, Tag customTag) { + if (propertyValue == null) { + return null; + } else { + // skip not relevant for Tosca property + if (property.getName().equals("dependencies")) { + return null; + } + NodeTuple defaultNode = super.representJavaBeanProperty(javaBean, property, propertyValue, customTag); + + return property.getName().equals("_defaultp_") ? new NodeTuple(representData("default"), defaultNode.getValueNode()) : defaultNode; + } + } + + @Override + protected MappingNode representJavaBean(Set properties, Object javaBean) { + // remove the bean type from the output yaml (!! ...) + if (!classTags.containsKey(javaBean.getClass())) + addClassTag(javaBean.getClass(), Tag.MAP); + + return super.representJavaBean(properties, javaBean); + } + + private class RepresentNull implements Represent { + public Node representData(Object data) { + // possible values are here http://yaml.org/type/null.html + return representScalar(Tag.NULL, ""); + } + } + } + + private static class UnsortedPropertyUtils extends PropertyUtils { + @Override + protected Set createPropertySet(Class type, BeanAccess bAccess) throws IntrospectionException { + Collection fields = getPropertiesMap(type, BeanAccess.FIELD).values(); + Set result = new LinkedHashSet(fields); + return result; + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java new file mode 100644 index 0000000000..6b1895b6ec --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaRepresentation.java @@ -0,0 +1,49 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.util.List; + +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.model.Component; + +public class ToscaRepresentation { + + private String mainYaml; + private List> dependencies; + + public String getMainYaml() { + return mainYaml; + } + + public void setMainYaml(String mainYaml) { + this.mainYaml = mainYaml; + } + + public List> getDependencies() { + return dependencies; + } + + public void setDependencies(List> dependancies) { + this.dependencies = dependancies; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaUtils.java new file mode 100644 index 0000000000..db03ad2307 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/ToscaUtils.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.be.datatypes.components.ResourceMetadataDataDefinition; +import org.openecomp.sdc.be.datatypes.enums.ComponentTypeEnum; +import org.openecomp.sdc.be.datatypes.enums.ResourceTypeEnum; +import org.openecomp.sdc.be.model.Component; + +public class ToscaUtils { + + public static boolean isNodeType(Component component) { + ComponentTypeEnum componentType = component.getComponentType(); + if (ComponentTypeEnum.RESOURCE.equals(componentType)) { + ResourceTypeEnum resourceType = ((ResourceMetadataDataDefinition) component.getComponentMetadataDefinition().getMetadataDataDefinition()).getResourceType(); + if (ResourceTypeEnum.CP.equals(resourceType) || ResourceTypeEnum.VL.equals(resourceType) || ResourceTypeEnum.VFC.equals(resourceType)) { + return true; + } + } + return false; + } + + public static Map objectToMap(Object objectToConvert, Class clazz) throws IllegalArgumentException, IllegalAccessException { + Map map = new HashMap<>(); + List fields = new ArrayList<>(); + + fields = getAllFields(fields, clazz); + + for (Field field : fields) { + field.setAccessible(true); + map.put(field.getName(), field.get(objectToConvert)); + } + return map; + } + + public static List getAllFields(List fields, Class type) { + fields.addAll(Arrays.asList(type.getDeclaredFields())); + + if (type.getSuperclass() != null) { + fields = getAllFields(fields, type.getSuperclass()); + } + return fields; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/EntrySchema.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/EntrySchema.java new file mode 100644 index 0000000000..0c586c7043 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/EntrySchema.java @@ -0,0 +1,43 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +public class EntrySchema { + private String type; + private String description; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/IToscaMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/IToscaMetadata.java new file mode 100644 index 0000000000..46f4fd032e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/IToscaMetadata.java @@ -0,0 +1,33 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +public interface IToscaMetadata { + + public void setName(String name); + + public void setInvariantUUID(String invariantUUID); + + public void setUUID(String uUID); + + public void setVersion(String version); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/SubstitutionMapping.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/SubstitutionMapping.java new file mode 100644 index 0000000000..0fd9daef7d --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/SubstitutionMapping.java @@ -0,0 +1,60 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.Map; + +public class SubstitutionMapping { + private String node_type; + + private Map capabilities; + private Map requirements; + + public SubstitutionMapping() { + super(); + // TODO Auto-generated constructor stub + } + + public String getNode_type() { + return node_type; + } + + public void setNode_type(String node_type) { + this.node_type = node_type; + } + + public Map getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map capabilities) { + this.capabilities = capabilities; + } + + public Map getRequirements() { + return requirements; + } + + public void setRequirements(Map requirements) { + this.requirements = requirements; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaCapability.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaCapability.java new file mode 100644 index 0000000000..2688e5e6b3 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaCapability.java @@ -0,0 +1,80 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaCapability { + + private String type; + private String description; + + private List occurrences; + + private List valid_source_types; + + private Map properties; + + public List getValid_source_types() { + return valid_source_types; + } + + public void setValid_source_types(List valid_source_types) { + this.valid_source_types = valid_source_types; + } + + public ToscaCapability() { + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public List getOccurrences() { + return occurrences; + } + + public void setOccurrences(List occurrences) { + this.occurrences = occurrences; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaGroupTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaGroupTemplate.java new file mode 100644 index 0000000000..b91cffa5be --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaGroupTemplate.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaGroupTemplate { + private String type; + List members; + private IToscaMetadata metadata; + private Map properties; + + public ToscaGroupTemplate() { + super(); + + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public List getMembers() { + return members; + } + + public void setMembers(List members) { + this.members = members; + } + + public IToscaMetadata getMetadata() { + return metadata; + } + + public void setMetadata(IToscaMetadata metadata) { + this.metadata = metadata; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaMetadata.java new file mode 100644 index 0000000000..38cd002726 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaMetadata.java @@ -0,0 +1,137 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +public class ToscaMetadata implements IToscaMetadata { + private String invariantUUID; + private String UUID; + private String version; + private String name; + private String description; + private String type; + private String category; + private String subcategory; + private String resourceVendor; + private String resourceVendorRelease; + private Boolean serviceEcompNaming; + private Boolean serviceHoming; + + public String getName() { + return name; + } + + @Override + public void setName(String name) { + this.name = name; + } + + public String getInvariantUUID() { + return invariantUUID; + } + + @Override + public void setInvariantUUID(String invariantUUID) { + this.invariantUUID = invariantUUID; + } + + public String getUUID() { + return UUID; + } + + @Override + public void setUUID(String uUID) { + UUID = uUID; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public String getSubcategory() { + return subcategory; + } + + public void setSubcategory(String subcategory) { + this.subcategory = subcategory; + } + + public String getResourceVendor() { + return resourceVendor; + } + + public void setResourceVendor(String resourceVendor) { + this.resourceVendor = resourceVendor; + } + + public String getResourceVendorRelease() { + return resourceVendorRelease; + } + + public void setResourceVendorRelease(String resourceVendorRelease) { + this.resourceVendorRelease = resourceVendorRelease; + } + + public Boolean isServiceEcompNaming() { + return serviceEcompNaming; + } + + public void setServiceEcompNaming(Boolean serviceEcompNaming) { + this.serviceEcompNaming = serviceEcompNaming; + } + + public Boolean isServiceHoming() { + return serviceHoming; + } + + public void setServiceHoming(Boolean serviceHoming) { + this.serviceHoming = serviceHoming; + } + + public String getVersion() { + return version; + } + + @Override + public void setVersion(String version) { + this.version = version; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java new file mode 100644 index 0000000000..b2d7ef5ab6 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeTemplate.java @@ -0,0 +1,73 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaNodeTemplate { + private String type; + private ToscaMetadata metadata; + private Map properties; + private List> requirements; + private Map capabilities; + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public List> getRequirements() { + return requirements; + } + + public void setRequirements(List> requirements) { + this.requirements = requirements; + } + + public Map getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map capabilities) { + this.capabilities = capabilities; + } + + public ToscaMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ToscaMetadata metadata) { + this.metadata = metadata; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeType.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeType.java new file mode 100644 index 0000000000..df9070f49c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaNodeType.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaNodeType { + public ToscaNodeType() { + } + + private ToscaMetadata metadata; + private String derived_from; + private String description; + + private Map properties; + private Map capabilities; + + private List> requirements; + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + + public Map getCapabilities() { + return capabilities; + } + + public void setCapabilities(Map capabilities) { + this.capabilities = capabilities; + } + + public List> getRequirements() { + return requirements; + } + + public void setRequirements(List> requirements) { + this.requirements = requirements; + } + + public String getDerived_from() { + return derived_from; + } + + public void setDerived_from(String derived_from) { + this.derived_from = derived_from; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public ToscaMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ToscaMetadata metadata) { + this.metadata = metadata; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java new file mode 100644 index 0000000000..8b5c60b1d4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaProperty.java @@ -0,0 +1,83 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +public class ToscaProperty { + + private String type; + private Object _defaultp_; + private String description; + private Boolean required; + private EntrySchema entry_schema; + private String status; + + public EntrySchema getEntry_schema() { + return entry_schema; + } + + public void setEntry_schema(EntrySchema entry_schema) { + this.entry_schema = entry_schema; + } + + public ToscaProperty() { + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public Object getDefaultp() { + return _defaultp_; + } + + public void setDefaultp(Object defaultp) { + this._defaultp_ = defaultp; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaRequirement.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaRequirement.java new file mode 100644 index 0000000000..21fdc9f722 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaRequirement.java @@ -0,0 +1,45 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaRequirement extends ToscaTemplateRequirement { + + private List occurrences; + + public ToscaRequirement() { + } + + public List getOccurrences() { + return occurrences; + } + + public void setOccurrences(List occurrences) { + this.occurrences = occurrences; + } + + public Map toMap() throws IllegalArgumentException, IllegalAccessException { + return super.toMap(); + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java new file mode 100644 index 0000000000..e80d52167c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplate.java @@ -0,0 +1,90 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +import org.apache.commons.lang3.tuple.Triple; +import org.openecomp.sdc.be.model.Component; + +public class ToscaTemplate { + private String tosca_definitions_version; + private ToscaMetadata metadata; + private List>> imports; + private Map node_types; + private ToscaTopolgyTemplate topology_template; + + private List> dependencies; + + public ToscaTemplate(String tosca_definitions_version) { + this.tosca_definitions_version = tosca_definitions_version; + } + + public Map getNode_types() { + return node_types; + } + + public void setNode_types(Map node_types) { + this.node_types = node_types; + } + + public List>> getImports() { + return imports; + } + + public void setImports(List>> imports) { + this.imports = imports; + } + + public String getTosca_definitions_version() { + return tosca_definitions_version; + } + + public void setTosca_definitions_version(String tosca_definitions_version) { + this.tosca_definitions_version = tosca_definitions_version; + } + + public ToscaMetadata getMetadata() { + return metadata; + } + + public void setMetadata(ToscaMetadata metadata) { + this.metadata = metadata; + } + + public ToscaTopolgyTemplate getTopology_template() { + return topology_template; + } + + public void setTopology_template(ToscaTopolgyTemplate topology_template) { + this.topology_template = topology_template; + } + + public List> getDependencies() { + return dependencies; + } + + public void setDependencies(List> dependencies) { + this.dependencies = dependencies; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateCapability.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateCapability.java new file mode 100644 index 0000000000..9adb9edfe1 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateCapability.java @@ -0,0 +1,46 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.List; +import java.util.Map; + +public class ToscaTemplateCapability { + private List valid_source_types; + private Map properties; + + public List getValid_source_types() { + return valid_source_types; + } + + public void setValid_source_types(List valid_source_types) { + this.valid_source_types = valid_source_types; + } + + public Map getProperties() { + return properties; + } + + public void setProperties(Map properties) { + this.properties = properties; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateRequirement.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateRequirement.java new file mode 100644 index 0000000000..71bae81f9c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTemplateRequirement.java @@ -0,0 +1,68 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.lang.reflect.Field; +import java.util.HashMap; +import java.util.Map; + +public class ToscaTemplateRequirement { + private String capability; + private String node; + private String relationship; + + public ToscaTemplateRequirement() { + } + + public String getCapability() { + return capability; + } + + public void setCapability(String capability) { + this.capability = capability; + } + + public String getNode() { + return node; + } + + public void setNode(String node) { + this.node = node; + } + + public String getRelationship() { + return relationship; + } + + public void setRelationship(String relationship) { + this.relationship = relationship; + } + + public Map toMap() throws IllegalArgumentException, IllegalAccessException { + Map map = new HashMap<>(); + Field[] fields = this.getClass().getDeclaredFields(); + for (Field field : fields) { + field.setAccessible(true); + map.put(field.getName(), field.get(this)); + } + return map; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java new file mode 100644 index 0000000000..6804bf6968 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/ToscaTopolgyTemplate.java @@ -0,0 +1,63 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +import java.util.Map; + +public class ToscaTopolgyTemplate { + private Map inputs; + private Map node_templates; + private Map groups; + private SubstitutionMapping substitution_mappings; + + public Map getNode_templates() { + return node_templates; + } + + public void setNode_templates(Map node_templates) { + this.node_templates = node_templates; + } + + public Map getGroups() { + return groups; + } + + public void setGroups(Map groups) { + this.groups = groups; + } + + public SubstitutionMapping getSubstitution_mappings() { + return substitution_mappings; + } + + public void setSubstitution_mappings(SubstitutionMapping substitution_mapping) { + this.substitution_mappings = substitution_mapping; + } + + public Map getInputs() { + return inputs; + } + + public void setInputs(Map inputs) { + this.inputs = inputs; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/VfModuleToscaMetadata.java b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/VfModuleToscaMetadata.java new file mode 100644 index 0000000000..5f978227ef --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/tosca/model/VfModuleToscaMetadata.java @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.tosca.model; + +public class VfModuleToscaMetadata implements IToscaMetadata { + + private String vfModuleModelName; + private String vfModuleModelInvariantUUID; + private String vfModuleModelUUID; + private String vfModuleModelVersion; + + @Override + public void setName(String name) { + vfModuleModelName = name; + } + + @Override + public void setInvariantUUID(String invariantUUID) { + vfModuleModelInvariantUUID = invariantUUID; + } + + @Override + public void setUUID(String uUID) { + vfModuleModelUUID = uUID; + } + + @Override + public void setVersion(String version) { + vfModuleModelVersion = version; + } + + public String getVfModuleModelName() { + return vfModuleModelName; + } + + public String getVfModuleModelInvariantUUID() { + return vfModuleModelInvariantUUID; + } + + public String getVfModuleModelUUID() { + return vfModuleModelUUID; + } + + public String getVfModuleModelVersion() { + return vfModuleModelVersion; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/user/IUserBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/user/IUserBusinessLogic.java new file mode 100644 index 0000000000..5cfa4a12da --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/user/IUserBusinessLogic.java @@ -0,0 +1,51 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.user; + +import java.util.List; + +import javax.servlet.ServletContext; + +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.exception.ResponseFormat; + +import fj.data.Either; + +public interface IUserBusinessLogic { + public Either getUser(String userId, boolean inTransaction); + + public Either createUser(User modifier, User newUser); + + public Either updateUserRole(User modifier, String userIdToUpdate, String userRole); + + public Either, ResponseFormat> getAllAdminUsers(ServletContext context); + + public Either, ResponseFormat> getUsersList(String userId, List roles, String rolesStr); + + public Either deActivateUser(User modifier, String userUniuqeIdToDeactive); + + public Either authorize(User authUser); + + public Either getFunctionalMenu(String userId); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/user/Role.java b/catalog-be/src/main/java/org/openecomp/sdc/be/user/Role.java new file mode 100644 index 0000000000..ab58ea7bf0 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/user/Role.java @@ -0,0 +1,29 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.user; + +/* + * Warning changing the order of the Enum variables changes the ordianl() function output + * which may result in ecompRole id change + */ +public enum Role { + ADMIN, TESTER, DESIGNER, GOVERNOR, OPS, PRODUCT_MANAGER, PRODUCT_STRATEGIST +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminAction.java b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminAction.java new file mode 100644 index 0000000000..ffc5e4f947 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminAction.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.user; + +public enum UserAdminAction { + + ADD_USER, UPDATE_USER, DELET_USER + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminValidator.java b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminValidator.java new file mode 100644 index 0000000000..8e736d4c0e --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserAdminValidator.java @@ -0,0 +1,69 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.user; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class UserAdminValidator { + + private Pattern emailPat; + private Pattern userIdPat; + private Matcher matcher; + + private static UserAdminValidator userAdminValidator = null; + + public static synchronized UserAdminValidator getInstance() { + if (userAdminValidator == null) { + userAdminValidator = new UserAdminValidator(); + } + return userAdminValidator; + } + + private static final String EMAIL_PATTERN = "^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$"; + + //private static final String USER_ID_PATTERN = "[mM]{1}[0-9]{5}|[a-zA-Z]{2}[0-9]{4}|[a-zA-Z]{2}[0-9]{4}|[a-zA-Z]{2}[0-9]{3}[a-zA-Z]{1}"; + private static final String USER_ID_PATTERN = "^[\\s\\w_.-]{1,50}$"; + + private UserAdminValidator() { + emailPat = Pattern.compile(EMAIL_PATTERN); + userIdPat = Pattern.compile(USER_ID_PATTERN); + } + + public boolean validateEmail(final String hex) { + matcher = emailPat.matcher(hex); + return matcher.matches(); + } + + public boolean validateUserId(String userId) { + matcher = userIdPat.matcher(userId); + return matcher.matches(); + } + + public boolean validateRole(String role) { + for (Role r : Role.values()) { + if (r.name().equals(role)) { + return true; + } + } + return false; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserBusinessLogic.java b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserBusinessLogic.java new file mode 100644 index 0000000000..8a910fc566 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/be/user/UserBusinessLogic.java @@ -0,0 +1,714 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.be.user; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.ServletContext; + +import org.apache.commons.lang3.tuple.ImmutablePair; +import org.apache.tinkerpop.gremlin.structure.Edge; +import org.openecomp.portalsdk.core.onboarding.ueb.FunctionalMenu; +import org.openecomp.portalsdk.core.onboarding.ueb.UebException; +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.config.BeEcompErrorManager.ErrorSeverity; +import org.openecomp.sdc.be.dao.api.ActionStatus; +import org.openecomp.sdc.be.dao.neo4j.GraphPropertiesDictionary; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.utils.UserStatusEnum; +import org.openecomp.sdc.be.impl.ComponentsUtils; +import org.openecomp.sdc.be.model.FunctionalMenuInfo; +import org.openecomp.sdc.be.model.LifecycleStateEnum; +import org.openecomp.sdc.be.model.User; +import org.openecomp.sdc.be.model.operations.api.IUserAdminOperation; +import org.openecomp.sdc.be.model.operations.api.StorageOperationStatus; +import org.openecomp.sdc.be.resources.data.auditing.AuditingActionEnum; +import org.openecomp.sdc.common.api.UserRoleEnum; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.kpi.api.ASDCKpiApi; +import org.openecomp.sdc.exception.ResponseFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import fj.data.Either; + +@Component("userBusinessLogic") +public class UserBusinessLogic implements IUserBusinessLogic { + + private static Logger log = LoggerFactory.getLogger(UserBusinessLogic.class.getName()); + private static UserAdminValidator userAdminValidator = UserAdminValidator.getInstance(); + + @Resource + private IUserAdminOperation userAdminOperation; + @Resource + private ComponentsUtils componentsUtils; + @Autowired + private TitanGenericDao titanDao; + + @Override + public Either getUser(String userId, boolean inTransaction) { + return userAdminOperation.getUserData(userId, inTransaction); + } + + @Override + public Either createUser(User modifier, User newUser) { + + ResponseFormat responseFormat; + String modifierUserId = modifier.getUserId(); + + if (modifierUserId == null) { + modifier.setUserId("UNKNOWN"); + log.debug("createUser method - user header is missing"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + + Either eitherCreator = getUser(modifierUserId, false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + log.debug("createUser method - user is not listed. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + + modifier = eitherCreator.left().value(); + if (!modifier.getRole().equals(UserRoleEnum.ADMIN.getName())) { + log.debug("createUser method - user is not admin={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + + // verify user not exist + User userFromDb = new User(); + // boolean isUserAlreadyExist = false; + Either eitherUserInDB = getUser(newUser.getUserId(), false); + if (eitherUserInDB.isRight()) { + ActionStatus status = eitherUserInDB.right().value(); + if (!ActionStatus.USER_NOT_FOUND.equals(status) && !ActionStatus.USER_INACTIVE.equals(status)) { + responseFormat = componentsUtils.getResponseFormat(eitherUserInDB.right().value(), newUser.getUserId()); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + } else {// User exist in DB + userFromDb = eitherUserInDB.left().value(); + // isUserAlreadyExist = true; + if (userFromDb.getStatus() == UserStatusEnum.ACTIVE) { + responseFormat = componentsUtils.getResponseFormatByUserId(ActionStatus.USER_ALREADY_EXIST, newUser.getUserId()); + log.debug("createUser method - user already exist with id: {}", modifier.getUserId(), userFromDb.getUserId()); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + } + + newUser.setStatus(UserStatusEnum.ACTIVE); + + // validate Email + if (newUser.getEmail() != null && !userAdminValidator.validateEmail(newUser.getEmail())) { + log.debug("createUser method - user has invalid email={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_EMAIL_ADDRESS, newUser.getEmail()); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + + // validate Role + if (newUser.getRole() == null || newUser.getRole().length() == 0) { + newUser.setRole(Role.DESIGNER.name()); + } else { + if (!userAdminValidator.validateRole(newUser.getRole())) { + log.debug("createUser method - user has invalid role={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_ROLE, newUser.getRole()); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + } + + // handle last login if user is import + if (newUser.getLastLoginTime() == null) { + newUser.setLastLoginTime(0L); + } + + Either addOrUpdateUserReq; + + if (ActionStatus.USER_INACTIVE.equals(eitherUserInDB.right().value())) { // user + // exist + // with + // inactive + // state + // - + // update + // user + // data + newUser.setLastLoginTime(0L); + addOrUpdateUserReq = userAdminOperation.updateUserData(newUser); + + } else { // user not exist - create new user + if (newUser.getUserId() != null && !userAdminValidator.validateUserId(newUser.getUserId())) { + log.debug("createUser method - user has invalid userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_USER_ID, newUser.getUserId()); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.ADD_USER); + return Either.right(responseFormat); + } + addOrUpdateUserReq = userAdminOperation.saveUserData(newUser); + } + + if (addOrUpdateUserReq.isRight() || addOrUpdateUserReq.left().value() == null) { + log.debug("createUser method - failed to create user"); + Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(addOrUpdateUserReq.right().value()))); + } + log.debug("createUser method - user created"); + User createdUser = addOrUpdateUserReq.left().value(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.CREATED); + handleAuditing(modifier, null, createdUser, responseFormat, AuditingActionEnum.ADD_USER); + return Either.left(createdUser); + } + + @Override + public Either updateUserRole(User modifier, String userIdToUpdate, String userRole) { + + ResponseFormat responseFormat; + String modifierUserId = modifier.getUserId(); + + if (modifierUserId == null) { + modifier.setUserId("UNKNOWN"); + log.debug("updateUserRole method - user header is missing"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + Either eitherCreator = getUser(modifierUserId, false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + log.debug("updateUserRole method - user is not listed. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + modifier = eitherCreator.left().value(); + if (!modifier.getRole().equals(UserRoleEnum.ADMIN.getName())) { + log.debug("updateUserRole method - user is not admin. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + if (modifier.getUserId().equals(userIdToUpdate)) { + log.debug("updateUserRole method - admin role can only be updated by other admin. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.UPDATE_USER_ADMIN_CONFLICT); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + Either userToUpdateReq = getUser(userIdToUpdate, false); + if (userToUpdateReq.isRight() || userToUpdateReq.left().value() == null) { + log.debug("updateUserRole method - user not found. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, userIdToUpdate); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + if (!userAdminValidator.validateRole(userRole)) { + log.debug("updateUserRole method - user has invalid role={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_ROLE, userRole); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + + User newUser = new User(); + newUser.setRole(userRole); + newUser.setUserId(userIdToUpdate); + User userToUpdate = userToUpdateReq.left().value(); + // if(!userRole.equals(UserRoleEnum.ADMIN.getName())){ //this is in + // comment until admin will be able to do do check-in/check-out from the + // UI + + Either, StorageOperationStatus> userPendingTasksReq = getPandingUserPandingTasksWithCommit(userToUpdate); + if (userPendingTasksReq.isRight()) { + log.debug("updateUserRole method - failed to get user pending tasks list", userIdToUpdate); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(userPendingTasksReq.right().value()))); + } + + List userPendingTasks = userPendingTasksReq.left().value(); + if (userPendingTasks.size() > 0) { + log.debug("updateUserRole method - User canot be updated, user have panding projects", userIdToUpdate); + String userTasksStatusForErrorMessage = getUserPandingTaskStatusByRole(UserRoleEnum.valueOf(userToUpdate.getRole())); + String userInfo = userToUpdate.getFirstName() + " " + userToUpdate.getLastName() + '(' + userToUpdate.getUserId() + ')'; + responseFormat = componentsUtils.getResponseFormat(ActionStatus.CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS, userInfo, userTasksStatusForErrorMessage); + handleAuditing(modifier, userToUpdate, userToUpdate, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.right(responseFormat); + } + // } + Either updateUserReq = userAdminOperation.updateUserData(newUser); + + if (updateUserReq.isRight() || updateUserReq.left().value() == null) { + log.debug("updateUser method - failed to update user data. userId={}", modifier.getUserId()); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(updateUserReq.right().value()))); + } + + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + User updatedUser = updateUserReq.left().value(); + handleAuditing(modifier, userToUpdate, updatedUser, responseFormat, AuditingActionEnum.UPDATE_USER); + return Either.left(updatedUser); + } + + @Override + public Either, ResponseFormat> getAllAdminUsers(ServletContext context) { + Either, ActionStatus> response = userAdminOperation.getAllUsersWithRole(Role.ADMIN.name(), null); + + if (response.isRight()) { + ResponseFormat responseFormat = componentsUtils.getResponseFormat(response.right().value()); + return Either.right(responseFormat); + } + return Either.left(response.left().value()); + } + + @Override + public Either, ResponseFormat> getUsersList(String modifierAttId, List roles, String rolesStr) { + ResponseFormat responseFormat; + User user = new User(); + if (modifierAttId == null) { + user.setUserId("UNKNOWN"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleGetUsersListAuditing(user, responseFormat, rolesStr); + return Either.right(responseFormat); + } + Either userResult = getUser(modifierAttId, false); + if (userResult.isRight()) { + user.setUserId(modifierAttId); + if (userResult.right().value().equals(ActionStatus.USER_NOT_FOUND)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + } else { + responseFormat = componentsUtils.getResponseFormat(userResult.right().value()); + } + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeUserMissingError, "Get users per roles", modifierAttId); + BeEcompErrorManager.getInstance().logBeUserMissingError("Get users per roles", modifierAttId); + + handleGetUsersListAuditing(user, responseFormat, rolesStr); + return Either.right(responseFormat); + } + user = userResult.left().value(); + Either, ResponseFormat> getResponse = null; + List resultList = new ArrayList<>(); + if (roles != null && !roles.isEmpty()) { + for (String role : roles) { + if (!userAdminValidator.validateRole(role)) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.INVALID_ROLE, role); + handleGetUsersListAuditing(user, responseFormat, rolesStr); + return Either.right(responseFormat); + } + getResponse = getUsersPerRole(role, user, rolesStr); + resultList.addAll(getResponse.left().value()); + } + } else { + rolesStr = "All"; + getResponse = getUsersPerRole(null, user, rolesStr); + resultList.addAll(getResponse.left().value()); + } + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleGetUsersListAuditing(user, responseFormat, rolesStr); + return Either.left(resultList); + } + + private Either, ResponseFormat> getUsersPerRole(String role, User user, String rolesStr) { + ResponseFormat responseFormat; + Either, ActionStatus> response = userAdminOperation.getAllUsersWithRole(role, UserStatusEnum.ACTIVE.name()); + if (response.isRight()) { + responseFormat = componentsUtils.getResponseFormat(response.right().value()); + handleGetUsersListAuditing(user, responseFormat, rolesStr); + return Either.right(responseFormat); + } + return Either.left(response.left().value()); + } + + private void handleGetUsersListAuditing(User user, ResponseFormat responseFormat, String details) { + componentsUtils.auditGetUsersList(AuditingActionEnum.GET_USERS_LIST, user, details, responseFormat); + } + + private void handleAuditing(User modifier, User userBefor, User userAfter, ResponseFormat responseFormat, AuditingActionEnum actionName) { + componentsUtils.auditAdminUserAction(actionName, modifier, userBefor, userAfter, responseFormat); + } + + private void handleUserAccessAuditing(User user, ResponseFormat responseFormat, AuditingActionEnum actionName) { + componentsUtils.auditUserAccess(actionName, user, responseFormat); + } + + @Override + public Either deActivateUser(User modifier, String userUniuqeIdToDeactive) { + + ResponseFormat responseFormat; + String userId = modifier.getUserId(); + + if (userId == null) { + modifier.setUserId("UNKNOWN"); + log.debug("deActivateUser method - user header is missing"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + Either eitherCreator = getUser(userId, false); + if (eitherCreator.isRight() || eitherCreator.left().value() == null) { + log.debug("deActivateUser method - user is not listed. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + modifier = eitherCreator.left().value(); + + if (!modifier.getRole().equals(UserRoleEnum.ADMIN.getName())) { + log.debug("deActivateUser method - user is not admin. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_OPERATION); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + if (modifier.getUserId().equals(userUniuqeIdToDeactive)) { + log.debug("deActivateUser deActivateUser - admin can only be deactivate by other admin. userId={}", modifier.getUserId()); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.DELETE_USER_ADMIN_CONFLICT); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + Either getUserToDeleteResponse = getUser(userUniuqeIdToDeactive, false); + if (getUserToDeleteResponse.isRight() || getUserToDeleteResponse.left().value() == null) { + log.debug("deActivateUser method - failed to get user by id {}", userUniuqeIdToDeactive); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, userUniuqeIdToDeactive); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(componentsUtils.getResponseFormat(getUserToDeleteResponse.right().value(), userUniuqeIdToDeactive)); + } + + User userToDeactivate = getUserToDeleteResponse.left().value(); + if (userToDeactivate.getStatus().equals(UserStatusEnum.INACTIVE)) { + log.debug("deActivateUser method - User already inactive", userUniuqeIdToDeactive); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.USER_NOT_FOUND, userUniuqeIdToDeactive); + handleAuditing(modifier, null, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + Either, StorageOperationStatus> userPendingTasksReq = getPandingUserPandingTasksWithCommit(userToDeactivate); + if (userPendingTasksReq.isRight()) { + log.debug("deActivateUser method - failed to get user pending tasks list", userUniuqeIdToDeactive); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(userPendingTasksReq.right().value()))); + } + + List userPendingTasks = userPendingTasksReq.left().value(); + if (userPendingTasks.size() > 0) { + log.debug("deActivateUser method - User canot be deleted, user have panding projects", userUniuqeIdToDeactive); + + String userTasksStatusForErrorMessage = getUserPandingTaskStatusByRole(UserRoleEnum.valueOf(userToDeactivate.getRole())); + String userInfo = userToDeactivate.getFirstName() + " " + userToDeactivate.getLastName() + '(' + userToDeactivate.getUserId() + ')'; + responseFormat = componentsUtils.getResponseFormat(ActionStatus.CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS, userInfo, userTasksStatusForErrorMessage); + handleAuditing(modifier, userToDeactivate, userToDeactivate, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.right(responseFormat); + } + + Either deactivateUserReq = userAdminOperation.deActivateUser(userToDeactivate); + if (deactivateUserReq.isRight()) { + log.debug("deActivateUser method - failed to deactivate user", userUniuqeIdToDeactive); + return Either.right(componentsUtils.getResponseFormat(componentsUtils.convertFromStorageResponse(deactivateUserReq.right().value()))); + } + User deactivateUser = deactivateUserReq.left().value(); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleAuditing(modifier, userToDeactivate, null, responseFormat, AuditingActionEnum.DELETE_USER); + return Either.left(deactivateUser); + } + + @Override + public Either authorize(User authUser) { + + ResponseFormat responseFormat; + + String userId = authUser.getUserId(); + + if (userId == null) { + authUser.setUserId("UNKNOWN"); + log.debug("deActivateUser method - user header is missing"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleUserAccessAuditing(authUser, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(responseFormat); + } + + Either eitherCreator = getUser(userId, false); + if (eitherCreator.isRight()) { + if (eitherCreator.right().value() == ActionStatus.USER_NOT_FOUND || eitherCreator.right().value() == ActionStatus.USER_INACTIVE) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_ACCESS); + handleUserAccessAuditing(authUser, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(responseFormat); + } else { + return Either.right(componentsUtils.getResponseFormatByUser(eitherCreator.right().value(), authUser)); + } + } else { + if (eitherCreator.left().value() == null) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(responseFormat); + } + } + + User user = eitherCreator.left().value(); + + String firstName = authUser.getFirstName(); + if (firstName != null && firstName.isEmpty() == false && !firstName.equals(user.getFirstName())) { + user.setFirstName(firstName); + } + + String lastName = authUser.getLastName(); + if (lastName != null && lastName.isEmpty() == false && !lastName.equals(user.getLastName())) { + user.setLastName(lastName); + } + + String email = authUser.getEmail(); + if (email != null && false == email.isEmpty() && !email.equals(user.getEmail())) { + user.setEmail(email); + } + + // last login time stamp handle + user.setLastLoginTime(); + + Either updateUserReq = userAdminOperation.updateUserData(user); + + if (updateUserReq.isRight()) { + responseFormat = componentsUtils.getResponseFormatByUser(eitherCreator.right().value(), user); + handleUserAccessAuditing(user, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(componentsUtils.getResponseFormatByUser(eitherCreator.right().value(), user)); + } + + User updatedUser = updateUserReq.left().value(); + + Long lastLoginTime = user.getLastLoginTime(); + if (lastLoginTime != null) { + updatedUser.setLastLoginTime(lastLoginTime); + } else { + updatedUser.setLastLoginTime(new Long(0)); + } + + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleUserAccessAuditing(updatedUser, responseFormat, AuditingActionEnum.USER_ACCESS); + ASDCKpiApi.countUsersAuthorizations(); + return Either.left(updatedUser); + } + + /* + * The method updates user credentials only, the role is neglected The role updated through updateRole method + */ + public Either updateUserCredentials(User updatedUserCred) { + + ResponseFormat responseFormat; + + String userId = updatedUserCred.getUserId(); + + if (userId == null) { + updatedUserCred.setUserId("UNKNOWN"); + log.debug("updateUserCredentials method - user header is missing"); + responseFormat = componentsUtils.getResponseFormat(ActionStatus.MISSING_INFORMATION); + handleUserAccessAuditing(updatedUserCred, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(responseFormat); + } + + Either eitherCreator = getUser(userId, false); + if (eitherCreator.isRight()) { + ActionStatus status = eitherCreator.right().value(); + if (status == ActionStatus.USER_NOT_FOUND || status == ActionStatus.USER_INACTIVE) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.RESTRICTED_ACCESS); + handleUserAccessAuditing(updatedUserCred, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(responseFormat); + } else { + return Either.right(componentsUtils.getResponseFormatByUser(status, updatedUserCred)); + } + } else { + if (eitherCreator.left().value() == null) { + responseFormat = componentsUtils.getResponseFormat(ActionStatus.GENERAL_ERROR); + return Either.right(responseFormat); + } + } + + User user = eitherCreator.left().value(); + + String firstName = updatedUserCred.getFirstName(); + if (firstName != null && firstName.isEmpty() == false && !firstName.equals(user.getFirstName())) { + user.setFirstName(firstName); + } + + String lastName = updatedUserCred.getLastName(); + if (lastName != null && lastName.isEmpty() == false && !lastName.equals(user.getLastName())) { + user.setLastName(lastName); + } + + String email = updatedUserCred.getEmail(); + if (email != null && false == email.isEmpty() && !email.equals(user.getEmail())) { + user.setEmail(email); + } + + if (updatedUserCred.getLastLoginTime() != null && user.getLastLoginTime() != null) { + if (updatedUserCred.getLastLoginTime() > user.getLastLoginTime()) { + user.setLastLoginTime(updatedUserCred.getLastLoginTime()); + } + } else if (updatedUserCred.getLastLoginTime() != null && user.getLastLoginTime() == null) { + user.setLastLoginTime(updatedUserCred.getLastLoginTime()); + } + + Either updateUserReq = userAdminOperation.updateUserData(user); + + if (updateUserReq.isRight()) { + responseFormat = componentsUtils.getResponseFormatByUser(eitherCreator.right().value(), user); + handleUserAccessAuditing(user, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.right(componentsUtils.getResponseFormatByUser(eitherCreator.right().value(), user)); + } + + User updatedUser = updateUserReq.left().value(); + + responseFormat = componentsUtils.getResponseFormat(ActionStatus.OK); + handleUserAccessAuditing(updatedUser, responseFormat, AuditingActionEnum.USER_ACCESS); + return Either.left(updatedUser); + } + + private Either, StorageOperationStatus> getPandingUserPandingTasksWithCommit(User user) { + + Either, StorageOperationStatus> result = null; + + try { + UserRoleEnum userRole = UserRoleEnum.valueOf(user.getRole()); + Map properties = new HashMap(); + switch (userRole) { + case DESIGNER: + case PRODUCT_STRATEGIST: + case PRODUCT_MANAGER: + properties.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + return userAdminOperation.getUserPandingTasksList(user, properties); + case TESTER: + properties.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + return userAdminOperation.getUserPandingTasksList(user, properties); + case ADMIN: + properties.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.CERTIFICATION_IN_PROGRESS.name()); + properties.put(GraphPropertiesDictionary.STATE.getProperty(), LifecycleStateEnum.NOT_CERTIFIED_CHECKOUT.name()); + return userAdminOperation.getUserPandingTasksList(user, properties); + default: + return Either.left(new ArrayList<>()); + } + } finally { + // commit will be perform outside!!! + if (result == null || result.isRight()) { + log.debug("getUserPandingTasksList failed to perform fetching"); + titanDao.rollback(); + } else { + titanDao.commit(); + } + } + } + + private String getUserPandingTaskStatusByRole(UserRoleEnum role) { + + switch (role) { + case DESIGNER: + case PRODUCT_STRATEGIST: + case PRODUCT_MANAGER: + return "checked-out"; + + case TESTER: + return "in-certification"; + case ADMIN: + return "in-certification/checked-out"; + default: + return ""; + } + } + + /** + * return the functional menu of a given user + * + * @param userId + * @param inTransaction + * @return + */ + public Either getFunctionalMenu(String userId) { + + boolean toCommit = false; + + FunctionalMenuInfo functionalMenuInfo = new FunctionalMenuInfo(); + + try { + + Either, ActionStatus> userResult = userAdminOperation.getUserDataWithFunctionalMenu(userId); + if (userResult.isRight()) { + ActionStatus actionStatus = userResult.right().value(); + if (actionStatus == ActionStatus.USER_NOT_FOUND) { + actionStatus = ActionStatus.INVALID_USER_ID; + } + return Either.right(actionStatus); + } + + ImmutablePair immutablePair = userResult.left().value(); + FunctionalMenuInfo currentFunctionalMenu = immutablePair.right; + String currentMenuStr = currentFunctionalMenu != null ? currentFunctionalMenu.getFunctionalMenu() : null; + + String functionalMenu = getFunctionalMenuFromUeb(userId); + + // functionalMenu can be null or since we catch UebException + if (functionalMenu != null && false == functionalMenu.isEmpty()) { + functionalMenuInfo.setFunctionalMenu(functionalMenu); + if (false == functionalMenu.equals(currentMenuStr)) { + log.debug("Going to update functional menu of user {}. Functional menu is {}", userId, functionalMenu); + userAdminOperation.createOrUpdateFunctionalMenu(userId, functionalMenu); + } + } else { + String menu = currentMenuStr; + if (menu == null) { + menu = "[]"; + } + log.debug("Fetch functional menu from old request. Functional menu is {}", menu); + functionalMenuInfo.setFunctionalMenu(menu); + } + + toCommit = true; + + } finally { + if (toCommit) { + titanDao.commit(); + } else { + titanDao.rollback(); + } + } + + return Either.left(functionalMenuInfo); + } + + private String getFunctionalMenuFromUeb(String userId) { + String functionalMenu = null; + try { + log.debug("Before calling to FunctionalMenu method for user {}", userId); + functionalMenu = FunctionalMenu.get(userId); + log.debug("Functional menu fetched is {}", functionalMenu); + + } catch (UebException e) { + log.debug("Failed to fetch 'functional menu' of user {} from ecomp portal(via UEB). {}", userId, e); + BeEcompErrorManager.getInstance().logInternalFlowError("FetchFunctionalMenu", "Failed to fetch 'functional menu'", ErrorSeverity.ERROR); + } + return functionalMenu; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ICommitHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ICommitHandler.java new file mode 100644 index 0000000000..e70b33a938 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ICommitHandler.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; + +public interface ICommitHandler extends IDBType { + DBActionCodeEnum doCommit(); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBAction.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBAction.java new file mode 100644 index 0000000000..a36e5fe1b5 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBAction.java @@ -0,0 +1,25 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +public interface IDBAction { + T doAction(); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBType.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBType.java new file mode 100644 index 0000000000..4c19e41609 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/IDBType.java @@ -0,0 +1,27 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; + +public interface IDBType { + DBTypeEnum getDBType(); +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ITransactionSdnc.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ITransactionSdnc.java new file mode 100644 index 0000000000..5a10e9029c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/ITransactionSdnc.java @@ -0,0 +1,40 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ESActionTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.TransactionCodeEnum; + +import fj.data.Either; + +public interface ITransactionSdnc { + TransactionCodeEnum finishTransaction(); + + Either invokeESAction(boolean isLastAction, ESActionTypeEnum esActiontype, ESArtifactData artifactData); + + Either invokeGeneralDBAction(boolean isLastAction, DBTypeEnum dbType, IDBAction dbAction, IDBAction dbRollbackAction); + + Either invokeTitanAction(boolean isLastAction, IDBAction dbAction); + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/RollbackHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/RollbackHandler.java new file mode 100644 index 0000000000..97a8083e88 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/RollbackHandler.java @@ -0,0 +1,121 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +import java.util.Stack; + +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.LogMessages; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class RollbackHandler implements IDBType { + private static Logger log = LoggerFactory.getLogger(RollbackHandler.class.getName()); + private Stack dbActionRollbacks; + + private Integer transactionId; + private String userId, actionType; + + protected RollbackHandler(Integer transactionId, String userId, String actionType) { + if (isRollbackForPersistenceData()) { + dbActionRollbacks = new Stack<>(); + } + this.transactionId = transactionId; + this.userId = userId; + this.actionType = actionType; + } + + public MethodActivationStatusEnum addRollbackAction(IDBAction rollbackAction) { + MethodActivationStatusEnum result = MethodActivationStatusEnum.SUCCESS; + if (isRollbackForPersistenceData()) { + dbActionRollbacks.push(rollbackAction); + } else { + result = MethodActivationStatusEnum.NOT_ALLOWED; + } + return result; + } + + public DBActionCodeEnum doRollback() { + DBActionCodeEnum result; + + try { + if (isRollbackForPersistenceData()) { + result = doPersistenceDataRollback(); + } else { + log.debug(LogMessages.ROLLBACK_NON_PERSISTENT_ACTION, getDBType().name(), transactionId, userId, actionType); + log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_NON_PERSISTENT_ACTION, getDBType().name(), transactionId, userId, actionType); + result = doNonPersistenceDataRollback(); + } + if (result != DBActionCodeEnum.SUCCESS) { + log.error(LogMessages.ROLLBACK_FAILED_ON_DB, transactionId, getDBType().name(), userId, actionType); + log.error(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_FAILED_ON_DB, transactionId, getDBType().name(), userId, actionType); + } + + } catch (Exception e) { + result = DBActionCodeEnum.FAIL_GENERAL; + log.error(LogMessages.ROLLBACK_FAILED_ON_DB_WITH_EXCEPTION, transactionId, getDBType().name(), e.getMessage(), userId, actionType); + log.debug(LogMessages.ROLLBACK_FAILED_ON_DB_WITH_EXCEPTION, transactionId, getDBType().name(), e.getMessage(), userId, actionType, e); + log.error(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_FAILED_ON_DB_WITH_EXCEPTION, transactionId, getDBType().name(), e.getMessage(), userId, actionType); + } + + return result; + } + + private DBActionCodeEnum doPersistenceDataRollback() { + DBActionCodeEnum result = DBActionCodeEnum.SUCCESS; + while (!dbActionRollbacks.empty()) { + log.debug(LogMessages.ROLLBACK_PERSISTENT_ACTION, getDBType().name(), transactionId, userId, actionType); + log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_PERSISTENT_ACTION, getDBType().name(), transactionId, userId, actionType); + IDBAction rollbackAction = dbActionRollbacks.pop(); + T rollbackResult = rollbackAction.doAction(); + if (!isRollbackResultValid(rollbackResult)) { + result = DBActionCodeEnum.FAIL_GENERAL; + } + } + return result; + } + + /** + * Override for specific logic + * + * @param + */ + public boolean isRollbackResultValid(T rollbackResult) { + return true; + } + + /** + * Override for specific logic + */ + public DBActionCodeEnum doNonPersistenceDataRollback() { + return DBActionCodeEnum.SUCCESS; + } + + protected abstract boolean isRollbackForPersistenceData(); + + /** + * Only Used for Unit Tests ! + */ + public static void setLog(Logger log) { + RollbackHandler.log = log; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/TransactionUtils.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/TransactionUtils.java new file mode 100644 index 0000000000..e90b9618d4 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/api/TransactionUtils.java @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.api; + +import org.slf4j.Marker; +import org.slf4j.MarkerFactory; + +public final class TransactionUtils { + + private TransactionUtils() { + + } + + public enum DBTypeEnum { + ELASTIC_SEARCH, TITAN, MYSTERY, SWIFT + } + + public enum TransactionCodeEnum { + ROLLBACK_SUCCESS, ROLLBACK_FAILED, SUCCESS, COMMIT_FAILED, MULTIPLE_LAST_ACTION, INTERNAL_ERROR, UNALLOWED_METHOD_USAGE, PREPARE_ROLLBACK_FAILED, TRANSACTION_CLOSED + } + + public enum TransactionStatusEnum { + OPEN, CLOSED, FAILED_ROLLBACK + } + + public enum DBActionCodeEnum { + SUCCESS, FAIL_GENERAL, FAIL_MULTIPLE_LAST_ACTION + } + + public enum ESActionTypeEnum { + ADD_ARTIFACT, UPDATE_ARTIFACT, REMOVE_ARTIFACT + } + + public enum ActionTypeEnum { + ADD_ARTIFACT, REMOVE_ARTIFACT, UPDATE_ARTIFACT, CREATE_RESOURCE, UPDATE_RESOURCE, DELETE_RESOURCE + } + + public static final int MAX_SIZE_TRANSACTION_LIST = 1000; + + public static final int TRANSACTION_ID_RESET_LIMIT = MAX_SIZE_TRANSACTION_LIST * 10; + + public static final String TRANSACTION_MARKER_STR = "TRANSACTION_MARKER"; + + public static final String DUMMY_USER = "udummy"; + + public static final Marker TRANSACTION_MARKER = MarkerFactory.getMarker(TRANSACTION_MARKER_STR); + + public static class LogMessages { + public static final String PRE_INVOKE_ACTION = "About to add Action to SdncTransaction ID:{} for DB:{}, user:{}, action:{}"; + public static final String INVOKE_ACTION = "invoking Action in SdncTransactionID:{}, on DB:{}, user:{}, action:{}"; + public static final String COMMIT_ACTION_ALL_DB = "Starting Commit for SdncTransactionID:{} for all DBs, user:{}, action:{}"; + public static final String COMMIT_ACTION_SPECIFIC_DB = "Starting Commit for SdncTransactionID:{} on DB:{}, user:{}, action:{}"; + public static final String COMMIT_ON_CLOSED_TRANSACTION = "Commit failed for SdncTransactionID:{} Transaction is in status:{}, user:{}, action:{}"; + public static final String ACTION_ON_CLOSED_TRANSACTION = "Action failed for SdncTransactionID:{} Transaction is already closed, user:{}, action:{}"; + public static final String DOUBLE_FINISH_FLAG_ACTION = "Transaction with SdncTransactionID:{} on DB:{} was called multiple times with last action flag, user:{}, action:{}"; + public static final String DB_ACTION_FAILED_WITH_EXCEPTION = "Action on DB:{} has failed for SdncTransactionID:{}, message:{}, user:{}, action:{}"; + public static final String ROLLBACK_SUCCEEDED_GENERAL = "Transaction rollback succeeded for SdncTransactionID:{}, user:{}, action:{}"; + public static final String ROLLBACK_FAILED_GENERAL = "Transaction rollback failed for SdncTransactionID:{}, user:{}, action:{}"; + public static final String ROLLBACK_FAILED_ON_DB = "Transaction rollback failed for SdncTransactionID:{} on DB:{}, user:{}, action:{}"; + public static final String ROLLBACK_FAILED_ON_DB_WITH_EXCEPTION = "Transaction rollback failed for SdncTransactionID:{} on DB:{}, exception message:{}, user:{}, action:{}"; + public static final String ROLLBACK_PERSISTENT_ACTION = "About To Rollback Action on DB{} for TransactionID:{} ... user:{}, action:{}"; + public static final String ROLLBACK_NON_PERSISTENT_ACTION = "About To Rollback Actions on DB{} for TransactionID:{} ... user:{}, action:{}"; + public static final String CREATE_ROLLBACK_HANDLER = "creating new Rollback Handler For DB:{} in SdncTransaction ID:{}, user:{}, action:{}"; + public static final String FAILED_CREATE_ROLLBACK = "failed to create new Rollback action For DB:{} with SdncTransactionID:{}, user:{}, action:{}"; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESAction.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESAction.java new file mode 100644 index 0000000000..33a8d1163b --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESAction.java @@ -0,0 +1,58 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.impl; + +import org.openecomp.sdc.be.dao.impl.ESCatalogDAO; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.be.resources.exception.ResourceDAOException; +import org.openecomp.sdc.common.transaction.api.IDBAction; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ESActionTypeEnum; + +public class ESAction implements IDBAction { + + private ESCatalogDAO esCatalogDao; + private ESArtifactData artifactData; + private ESActionTypeEnum esActionType; + + public ESAction(ESCatalogDAO esCatalogDao, ESArtifactData artifactData, ESActionTypeEnum esActiontype) { + this.esCatalogDao = esCatalogDao; + this.artifactData = artifactData; + this.esActionType = esActiontype; + } + + @Override + public DBActionCodeEnum doAction() { + DBActionCodeEnum result = DBActionCodeEnum.SUCCESS; + try { + if (esActionType == ESActionTypeEnum.ADD_ARTIFACT || esActionType == ESActionTypeEnum.UPDATE_ARTIFACT) { + esCatalogDao.writeArtifact(artifactData); + } else if (esActionType == ESActionTypeEnum.REMOVE_ARTIFACT) { + esCatalogDao.deleteArtifact(artifactData.getId()); + } + + } catch (ResourceDAOException daoException) { + result = DBActionCodeEnum.FAIL_GENERAL; + } + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESRollbackHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESRollbackHandler.java new file mode 100644 index 0000000000..b9fb0d31b7 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/ESRollbackHandler.java @@ -0,0 +1,92 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.impl; + +import org.openecomp.sdc.be.dao.api.ResourceUploadStatus; +import org.openecomp.sdc.be.dao.impl.ESCatalogDAO; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.transaction.api.RollbackHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ESActionTypeEnum; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; + +import fj.data.Either; + +public class ESRollbackHandler extends RollbackHandler { + + public ESRollbackHandler(Integer transactionId, String userId, String actionType) { + super(transactionId, userId, actionType); + } + + public DBTypeEnum getDBType() { + return DBTypeEnum.ELASTIC_SEARCH; + } + + protected boolean isRollbackForPersistenceData() { + return true; + } + + public boolean isRollbackResultValid(DBActionCodeEnum rollbackResult) { + return rollbackResult == DBActionCodeEnum.SUCCESS; + } + + public Either buildEsRollbackAction(ESCatalogDAO esCatalogDao, ESArtifactData artifactData, ESActionTypeEnum esActiontype) { + Either result; + + try { + ESAction esRollbackAction = null; + Either either = esCatalogDao.getArtifact(artifactData.getId()); + + switch (esActiontype) { + case ADD_ARTIFACT: + + if (either.isRight() && either.right().value() == ResourceUploadStatus.NOT_EXIST) { + esRollbackAction = new ESAction(esCatalogDao, artifactData, ESActionTypeEnum.REMOVE_ARTIFACT); + } + break; + case REMOVE_ARTIFACT: + if (either.isLeft()) { + esRollbackAction = new ESAction(esCatalogDao, artifactData, ESActionTypeEnum.ADD_ARTIFACT); + } + break; + case UPDATE_ARTIFACT: + + if (either.isLeft()) { + ESArtifactData originalArtifactData = either.left().value(); + esRollbackAction = new ESAction(esCatalogDao, originalArtifactData, ESActionTypeEnum.UPDATE_ARTIFACT); + } + break; + + } + if (esRollbackAction != null) { + result = Either.left(esRollbackAction); + } else { + result = Either.right(MethodActivationStatusEnum.FAILED); + } + } catch (Exception e) { + result = Either.right(MethodActivationStatusEnum.FAILED); + } + + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanCommitHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanCommitHandler.java new file mode 100644 index 0000000000..0d2ec387cf --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanCommitHandler.java @@ -0,0 +1,52 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.impl; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.common.transaction.api.ICommitHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; + +public class TitanCommitHandler implements ICommitHandler { + + private TitanGenericDao titanGenericDao; + + public TitanCommitHandler(TitanGenericDao titanGenericDao) { + this.titanGenericDao = titanGenericDao; + } + + @Override + public DBActionCodeEnum doCommit() { + DBActionCodeEnum result = DBActionCodeEnum.SUCCESS; + TitanOperationStatus titanStatus = titanGenericDao.commit(); + if (titanStatus != TitanOperationStatus.OK) { + result = DBActionCodeEnum.FAIL_GENERAL; + } + return result; + } + + @Override + public DBTypeEnum getDBType() { + return DBTypeEnum.TITAN; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanRollbackHandler.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanRollbackHandler.java new file mode 100644 index 0000000000..c0c686723c --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/impl/TitanRollbackHandler.java @@ -0,0 +1,55 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.impl; + +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.dao.titan.TitanOperationStatus; +import org.openecomp.sdc.common.transaction.api.RollbackHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; + +public class TitanRollbackHandler extends RollbackHandler { + + private TitanGenericDao titanGenericDao; + + public TitanRollbackHandler(Integer transactionId, String userId, String actionType, TitanGenericDao titanGenericDao) { + super(transactionId, userId, actionType); + this.titanGenericDao = titanGenericDao; + } + + public DBTypeEnum getDBType() { + return DBTypeEnum.TITAN; + } + + protected boolean isRollbackForPersistenceData() { + return false; + } + + public DBActionCodeEnum doNonPersistenceDataRollback() { + DBActionCodeEnum result = DBActionCodeEnum.SUCCESS; + TitanOperationStatus titanStatus = titanGenericDao.rollback(); + if (titanStatus != TitanOperationStatus.OK) { + result = DBActionCodeEnum.FAIL_GENERAL; + } + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/CommitManager.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/CommitManager.java new file mode 100644 index 0000000000..e802e58f27 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/CommitManager.java @@ -0,0 +1,87 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.mngr; + +import java.util.List; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.transaction.api.ICommitHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.LogMessages; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class CommitManager { + private List commitHandlers; + private Integer transactionId; + private String userId, actionType; + private static Logger log = LoggerFactory.getLogger(CommitManager.class.getName()); + + CommitManager(Integer transactionId, String userId, String actionType, List commitHandlers) { + this.commitHandlers = commitHandlers; + this.transactionId = transactionId; + this.userId = userId; + this.actionType = actionType; + + } + + public DBActionCodeEnum transactionCommit() { + log.debug(LogMessages.COMMIT_ACTION_ALL_DB, transactionId, userId, actionType); + DBActionCodeEnum commitResult = DBActionCodeEnum.SUCCESS; + ICommitHandler lastHandler = null; + try { + for (ICommitHandler handler : commitHandlers) { + lastHandler = handler; + log.debug(LogMessages.COMMIT_ACTION_SPECIFIC_DB, transactionId, handler.getDBType().name(), userId, actionType); + DBActionCodeEnum commitCode = handler.doCommit(); + if (commitCode == DBActionCodeEnum.FAIL_GENERAL) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "transactionCommit on DB " + handler.getDBType().name()); + BeEcompErrorManager.getInstance().logBeSystemError("transactionCommit on DB " + handler.getDBType().name()); + log.debug("Commit failed for SdncTransactionID:{} on DB:{}", transactionId, handler.getDBType().name()); + commitResult = DBActionCodeEnum.FAIL_GENERAL; + break; + } + log.debug("Commit succeeded for SdncTransactionID:{} on DB:{}", transactionId, handler.getDBType().name()); + } + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "transactionCommit - on DB " + getDBName(lastHandler)); + BeEcompErrorManager.getInstance().logBeSystemError("transactionCommit - on DB " + getDBName(lastHandler)); + log.debug("Commit failed for SdncTransactionID:{} on DB:{}, Exception message:{}", transactionId, getDBName(lastHandler), e.getMessage(), e); + log.info(TransactionUtils.TRANSACTION_MARKER, "Commit failed for SdncTransactionID:{} on DB:{}", transactionId, getDBName(lastHandler)); + commitResult = DBActionCodeEnum.FAIL_GENERAL; + } + return commitResult; + } + + private String getDBName(ICommitHandler lastHandler) { + String dbName = "Unknown"; + if (lastHandler != null) { + dbName = lastHandler.getDBType().name(); + } + return dbName; + } + + static void setLog(Logger log) { + CommitManager.log = log; + } +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/RollbackManager.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/RollbackManager.java new file mode 100644 index 0000000000..0641524038 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/RollbackManager.java @@ -0,0 +1,107 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.mngr; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.openecomp.sdc.common.transaction.api.RollbackHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; + +import fj.data.Either; + +public class RollbackManager { + private Map rollBackHandlersMap; + private Integer transactionId; + private String userId, actionType; + + RollbackManager(Integer transactionId, String userId, String actionType, List roleBackHandlers) { + this.transactionId = transactionId; + this.userId = userId; + this.actionType = actionType; + rollBackHandlersMap = new HashMap<>(); + for (RollbackHandler handler : roleBackHandlers) { + rollBackHandlersMap.put(handler.getDBType(), handler); + } + + } + + public DBActionCodeEnum transactionRollback() { + DBActionCodeEnum rollbackResult = DBActionCodeEnum.SUCCESS; + Iterator handlersItr = rollBackHandlersMap.values().iterator(); + while (handlersItr.hasNext()) { + RollbackHandler handler = handlersItr.next(); + DBActionCodeEnum rollbackCode = handler.doRollback(); + if (rollbackCode == DBActionCodeEnum.FAIL_GENERAL) { + rollbackResult = DBActionCodeEnum.FAIL_GENERAL; + } + } + + return rollbackResult; + } + + protected Either addRollbackHandler(RollbackHandler rollbackHandler) { + Either result; + if (rollBackHandlersMap.containsKey(rollbackHandler.getDBType())) { + result = Either.right(MethodActivationStatusEnum.NOT_ALLOWED); + } else { + rollBackHandlersMap.put(rollbackHandler.getDBType(), rollbackHandler); + result = Either.left(rollbackHandler); + } + return result; + + } + + protected Either createRollbackHandler(DBTypeEnum dbType) { + + final DBTypeEnum dbTypeFinal = dbType; + RollbackHandler rollbackHandler = new RollbackHandler(transactionId, userId, actionType) { + + @Override + public DBTypeEnum getDBType() { + return dbTypeFinal; + } + + @Override + protected boolean isRollbackForPersistenceData() { + return true; + } + }; + Either result = addRollbackHandler(rollbackHandler); + + return result; + } + + protected Either getRollbackHandler(DBTypeEnum dbType) { + Either result; + if (rollBackHandlersMap.containsKey(dbType)) { + result = Either.left(rollBackHandlersMap.get(dbType)); + } else { + result = Either.right(MethodActivationStatusEnum.NOT_FOUND); + } + return result; + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionManager.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionManager.java new file mode 100644 index 0000000000..c401586383 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionManager.java @@ -0,0 +1,98 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.mngr; + +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import javax.annotation.Resource; + +import org.openecomp.sdc.be.dao.impl.ESCatalogDAO; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.common.datastructure.CapList; +import org.openecomp.sdc.common.transaction.api.ITransactionSdnc; +import org.openecomp.sdc.common.transaction.api.TransactionUtils; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ActionTypeEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component("transactionManager") +public class TransactionManager { + + private static Logger log = LoggerFactory.getLogger(TransactionManager.class.getName()); + + private AtomicInteger transactionIDCounter = new AtomicInteger(0); + + private List transactions; + @Resource + private ESCatalogDAO esCatalogDao; + @Resource + private TitanGenericDao titanGenericDao; + + /** + * userId and actionType parameters are used only for logging purposes. + */ + public ITransactionSdnc getTransaction(String userId, ActionTypeEnum actionType) { + if (transactions == null) { + init(); + } + log.debug("TransactionManager creating new SdncTransaction"); + ITransactionSdnc tx = new TransactionSdncImpl(generateTransactionID(), userId, actionType, esCatalogDao, titanGenericDao); + transactions.add(tx); + + return tx; + + } + + private Integer generateTransactionID() { + boolean generatedSuccessfully = false; + int nextId = 0; + + while (!generatedSuccessfully) { + int prevId = transactionIDCounter.get(); + if (prevId > TransactionUtils.TRANSACTION_ID_RESET_LIMIT) { + resetTransactionId(); + } + nextId = prevId + 1; + generatedSuccessfully = transactionIDCounter.compareAndSet(prevId, nextId); + } + return nextId; + } + + private void resetTransactionId() { + + boolean resetSuccessfully = false; + while (!resetSuccessfully) { + int prevId = transactionIDCounter.get(); + resetSuccessfully = transactionIDCounter.compareAndSet(prevId, 0); + } + + } + + private synchronized void init() { + if (transactions == null) { + log.info("TransactionManager Initialized"); + transactions = new CapList<>(TransactionUtils.MAX_SIZE_TRANSACTION_LIST); + } + } + +} diff --git a/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionSdncImpl.java b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionSdncImpl.java new file mode 100644 index 0000000000..55eff24fa9 --- /dev/null +++ b/catalog-be/src/main/java/org/openecomp/sdc/common/transaction/mngr/TransactionSdncImpl.java @@ -0,0 +1,313 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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.openecomp.sdc.common.transaction.mngr; + +import java.util.ArrayList; +import java.util.List; + +import org.openecomp.sdc.be.config.BeEcompErrorManager; +import org.openecomp.sdc.be.dao.impl.ESCatalogDAO; +import org.openecomp.sdc.be.dao.titan.TitanGenericDao; +import org.openecomp.sdc.be.resources.data.ESArtifactData; +import org.openecomp.sdc.common.config.EcompErrorName; +import org.openecomp.sdc.common.transaction.api.ICommitHandler; +import org.openecomp.sdc.common.transaction.api.IDBAction; +import org.openecomp.sdc.common.transaction.api.ITransactionSdnc; +import org.openecomp.sdc.common.transaction.api.RollbackHandler; +import org.openecomp.sdc.common.transaction.api.TransactionUtils; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ActionTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBActionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.DBTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.ESActionTypeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.LogMessages; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.TransactionCodeEnum; +import org.openecomp.sdc.common.transaction.api.TransactionUtils.TransactionStatusEnum; +import org.openecomp.sdc.common.transaction.impl.ESAction; +import org.openecomp.sdc.common.transaction.impl.ESRollbackHandler; +import org.openecomp.sdc.common.transaction.impl.TitanCommitHandler; +import org.openecomp.sdc.common.transaction.impl.TitanRollbackHandler; +import org.openecomp.sdc.common.util.MethodActivationStatusEnum; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import fj.data.Either; + +public class TransactionSdncImpl implements ITransactionSdnc { + private boolean lastActionAlreadyCalled; + private RollbackManager rollbackManager; + private CommitManager commitManager; + private ESCatalogDAO esCatalogDao; + private TitanGenericDao titanGenericDao; + private Integer transactionId; + private TransactionStatusEnum status; + private String userId, actionType; + private static Logger log = LoggerFactory.getLogger(TransactionSdncImpl.class.getName()); + + TransactionSdncImpl(Integer transactionId, String userId, ActionTypeEnum actionTypeEnum, ESCatalogDAO esCatalogDao, TitanGenericDao titanGenericDao) { + this.esCatalogDao = esCatalogDao; + this.titanGenericDao = titanGenericDao; + this.transactionId = transactionId; + this.userId = userId; + actionType = actionTypeEnum.name(); + rollbackManager = new RollbackManager(transactionId, userId, actionType, initRollbackHandlers()); + commitManager = new CommitManager(transactionId, userId, actionType, initCommitHandlers()); + status = TransactionStatusEnum.OPEN; + + } + + private List initCommitHandlers() { + List commitHandlers = new ArrayList<>(); + commitHandlers.add(new TitanCommitHandler(titanGenericDao)); + return commitHandlers; + } + + private List initRollbackHandlers() { + List rolebackHandlers = new ArrayList<>(); + rolebackHandlers.add(new TitanRollbackHandler(transactionId, userId, actionType, titanGenericDao)); + rolebackHandlers.add(new ESRollbackHandler(transactionId, userId, actionType)); + return rolebackHandlers; + } + + private Either invokeAction(boolean isLastAction, IDBAction dbAction, DBTypeEnum dbType) { + + Either actionResult; + log.debug(LogMessages.INVOKE_ACTION, transactionId, dbType.name(), userId, actionType); + if (isLastAction) { + actionResult = getLastActionResult(dbAction, dbType); + } else { + actionResult = getActionResult(dbAction, dbType); + } + + Either result; + boolean isRollbackNedded = actionResult.isRight(); + if (isRollbackNedded) { + TransactionCodeEnum transactionCode = transactionRollback(); + result = Either.right(transactionCode); + } else { + result = Either.left(actionResult.left().value()); + } + return result; + } + + private TransactionCodeEnum transactionRollback() { + + TransactionCodeEnum result; + DBActionCodeEnum transactionRollback = rollbackManager.transactionRollback(); + if (transactionRollback == DBActionCodeEnum.SUCCESS) { + result = TransactionCodeEnum.ROLLBACK_SUCCESS; + log.info(LogMessages.ROLLBACK_SUCCEEDED_GENERAL, transactionId, userId, actionType); + log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_SUCCEEDED_GENERAL, transactionId, userId, actionType); + + } else { + result = TransactionCodeEnum.ROLLBACK_FAILED; + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "transactionCommit for transaction " + transactionId); + BeEcompErrorManager.getInstance().logBeSystemError("transactionCommit for transaction " + transactionId); + + log.info(LogMessages.ROLLBACK_FAILED_GENERAL, transactionId, userId, actionType); + log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.ROLLBACK_FAILED_GENERAL, transactionId, userId, actionType); + } + return result; + } + + public Either invokeTitanAction(boolean isLastAction, IDBAction dbAction) { + Either result; + if (status == TransactionStatusEnum.OPEN) { + result = invokeAction(isLastAction, dbAction, DBTypeEnum.TITAN); + } else { + result = handleActionOnClosedTransaction(); + } + updateTransactionStatus(result); + return result; + } + + public Either invokeGeneralDBAction(boolean isLastAction, DBTypeEnum dbType, IDBAction dbAction, IDBAction dbRollbackAction) { + + Either result; + MethodActivationStatusEnum addingHandlerResult; + if (status == TransactionStatusEnum.OPEN) { + log.debug(LogMessages.PRE_INVOKE_ACTION, transactionId, dbType.name(), userId, actionType); + Either eitherRollbackHandler = rollbackManager.getRollbackHandler(dbType); + + if (eitherRollbackHandler.isLeft()) { + RollbackHandler rollbackHandler = eitherRollbackHandler.left().value(); + addingHandlerResult = rollbackHandler.addRollbackAction(dbRollbackAction); + } else { + addingHandlerResult = addToNewRollbackHandler(dbType, dbRollbackAction); + } + + if (addingHandlerResult == MethodActivationStatusEnum.SUCCESS) { + result = invokeAction(isLastAction, dbAction, dbType); + } else { + result = Either.right(TransactionCodeEnum.PREPARE_ROLLBACK_FAILED); + } + } else { + result = handleActionOnClosedTransaction(); + } + updateTransactionStatus(result); + return result; + } + + private MethodActivationStatusEnum addToNewRollbackHandler(DBTypeEnum dbType, IDBAction dbRollbackAction) { + log.debug(LogMessages.CREATE_ROLLBACK_HANDLER, dbType.name(), transactionId, userId, actionType); + MethodActivationStatusEnum result; + + Either eitherRollbackHandler = rollbackManager.createRollbackHandler(dbType); + if (eitherRollbackHandler.isRight()) { + result = eitherRollbackHandler.right().value(); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "TransactionManager - addToNewRollbackHandler"); + BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - addToNewRollbackHandler"); + log.info(LogMessages.FAILED_CREATE_ROLLBACK, dbType.name(), transactionId, userId, actionType); + log.debug(TransactionUtils.TRANSACTION_MARKER, LogMessages.FAILED_CREATE_ROLLBACK, dbType.name(), transactionId, userId, actionType); + } else { + RollbackHandler rollbackHandler = eitherRollbackHandler.left().value(); + rollbackHandler.addRollbackAction(dbRollbackAction); + result = MethodActivationStatusEnum.SUCCESS; + } + + return result; + } + + public Either invokeESAction(boolean isLastAction, ESActionTypeEnum esActiontype, ESArtifactData artifactData) { + + Either result; + if (status == TransactionStatusEnum.OPEN) { + Either eitherEsHandler = rollbackManager.getRollbackHandler(DBTypeEnum.ELASTIC_SEARCH); + if (eitherEsHandler.isRight()) { + result = Either.right(TransactionCodeEnum.INTERNAL_ERROR); + } else { + ESRollbackHandler esHandler = (ESRollbackHandler) eitherEsHandler.left().value(); + + Either eitherEsRollbackAction = esHandler.buildEsRollbackAction(esCatalogDao, artifactData, esActiontype); + if (eitherEsRollbackAction.isLeft()) { + esHandler.addRollbackAction(eitherEsRollbackAction.left().value()); + result = invokeAction(isLastAction, new ESAction(esCatalogDao, artifactData, esActiontype), DBTypeEnum.ELASTIC_SEARCH); + } else { + result = Either.right(TransactionCodeEnum.PREPARE_ROLLBACK_FAILED); + } + + } + } else { + result = handleActionOnClosedTransaction(); + } + updateTransactionStatus(result); + return result; + } + + private void updateTransactionStatus(Either result) { + if (result.isRight()) { + updateTransactionStatus(result.right().value()); + } + + } + + private Either handleActionOnClosedTransaction() { + Either result = Either.right(TransactionCodeEnum.TRANSACTION_CLOSED); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "TransactionManager - handleActionOnClosedTransaction"); + log.debug(LogMessages.ACTION_ON_CLOSED_TRANSACTION, transactionId, userId, actionType); + log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.ACTION_ON_CLOSED_TRANSACTION, transactionId, userId, actionType); + return result; + } + + private Either getLastActionResult(IDBAction dataBaseAction, DBTypeEnum dbType) { + Either result; + if (isLastActionAlreadyCalled()) { + result = Either.right(DBActionCodeEnum.FAIL_MULTIPLE_LAST_ACTION); + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "TransactionManager - getLastActionResult"); + BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - getLastActionResult"); + log.debug(LogMessages.DOUBLE_FINISH_FLAG_ACTION, transactionId, dbType.name(), userId, actionType); + log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.DOUBLE_FINISH_FLAG_ACTION, transactionId, dbType.name(), userId, actionType); + } else { + setLastActionAlreadyCalled(true); + result = getActionResult(dataBaseAction, dbType); + } + return result; + } + + private Either getActionResult(IDBAction dataBaseAction, DBTypeEnum dbType) { + Either result; + try { + T doAction = dataBaseAction.doAction(); + result = Either.left(doAction); + } catch (Exception e) { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "TransactionManager - getActionResult"); + BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - getActionResult"); + log.debug(LogMessages.DB_ACTION_FAILED_WITH_EXCEPTION, dbType.name(), transactionId, e.getMessage(), userId, actionType, e); + log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.DB_ACTION_FAILED_WITH_EXCEPTION, dbType.name(), transactionId, e.getMessage(), userId, actionType); + + result = Either.right(DBActionCodeEnum.FAIL_GENERAL); + } + return result; + } + + public TransactionCodeEnum finishTransaction() { + TransactionCodeEnum result; + if (status == TransactionStatusEnum.OPEN) { + DBActionCodeEnum transactionCommit = commitManager.transactionCommit(); + if (transactionCommit == DBActionCodeEnum.SUCCESS) { + result = TransactionCodeEnum.SUCCESS; + status = TransactionStatusEnum.CLOSED; + } else { + result = transactionRollback(); + } + } else { + BeEcompErrorManager.getInstance().processEcompError(EcompErrorName.BeSystemError, "TransactionManager - finishTransaction"); + BeEcompErrorManager.getInstance().logBeSystemError("TransactionManager - finishTransaction"); + log.debug(LogMessages.COMMIT_ON_CLOSED_TRANSACTION, transactionId, status.name(), userId, actionType); + log.info(TransactionUtils.TRANSACTION_MARKER, LogMessages.COMMIT_ON_CLOSED_TRANSACTION, transactionId, status.name(), userId, actionType); + result = TransactionCodeEnum.TRANSACTION_CLOSED; + } + updateTransactionStatus(result); + return result; + } + + private void updateTransactionStatus(TransactionCodeEnum result) { + switch (result) { + case SUCCESS: + status = TransactionStatusEnum.CLOSED; + break; + case ROLLBACK_SUCCESS: + status = TransactionStatusEnum.CLOSED; + break; + case ROLLBACK_FAILED: + status = TransactionStatusEnum.FAILED_ROLLBACK; + break; + default: + break; + } + + } + + private boolean isLastActionAlreadyCalled() { + return lastActionAlreadyCalled; + } + + private void setLastActionAlreadyCalled(boolean lastAction) { + this.lastActionAlreadyCalled = lastAction; + } + + static void setLog(Logger log) { + TransactionSdncImpl.log = log; + } + + TransactionStatusEnum getStatus() { + return status; + } +} diff --git a/catalog-be/src/main/resources/application-context.xml b/catalog-be/src/main/resources/application-context.xml new file mode 100644 index 0000000000..da0a49f6e2 --- /dev/null +++ b/catalog-be/src/main/resources/application-context.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/catalog-be/src/main/resources/config/configuration.yaml b/catalog-be/src/main/resources/config/configuration.yaml new file mode 100644 index 0000000000..b8e80dc17c --- /dev/null +++ b/catalog-be/src/main/resources/config/configuration.yaml @@ -0,0 +1,478 @@ +identificationHeaderFields: + - HTTP_IV_USER + - HTTP_CSP_FIRSTNAME + - HTTP_CSP_LASTNAME + - HTTP_IV_REMOTE_ADDRESS + - HTTP_CSP_WSTYPE + + + +# catalog backend hostname +beFqdn: localhost + +# catalog backend http port +beHttpPort: 8080 + +# catalog backend http context +beContext: /sdc/rest/config/get + +# catalog backend protocol +beProtocol: http + +# catalog backend ssl port +beSslPort: 8443 + +version: 1.0 +released: 2012-11-30 + +titanCfgFile: /home/vagrant/catalog-be/config/catalog-be/titan.properties +titanInMemoryGraph: false +titanLockTimeout: 1800 +titanReconnectIntervalInSeconds: 3 +titanHealthCheckReadTimeout: 1 +esReconnectIntervalInSeconds: 3 +uebHealthCheckReconnectIntervalInSeconds: 15 +uebHealthCheckReadTimeout: 4 + +# Protocols +protocols: + - http + - https + +# Users +users: + tom: passwd + bob: passwd + +neo4j: + host: neo4jhost + port: 7474 + user: neo4j + password: "12345" + + +#Application-specific settings of ES +elasticSearch: + # Mapping of index prefix to time-based frame. For example, if below is configured: + # + # - indexPrefix: auditingevents + # creationPeriod: minute + # + # then ES object of type which is mapped to "auditingevents-*" template, and created on 2015-12-23 13:24:54, will enter "auditingevents-2015-12-23-13-24" index. + # Another object created on 2015-12-23 13:25:54, will enter "auditingevents-2015-12-23-13-25" index. + # If creationPeriod: month, both of the above will enter "auditingevents-2015-12" index. + # + # PLEASE NOTE: the timestamps are created in UTC/GMT timezone! This is needed so that timestamps will be correctly presented in Kibana. + # + # Legal values for creationPeriod - year, month, day, hour, minute, none (meaning no time-based behaviour). + # + # If no creationPeriod is configured for indexPrefix, default behavour is creationPeriod: month. + + indicesTimeFrequency: + - indexPrefix: auditingevents + creationPeriod: month + - indexPrefix: monitoring_events + creationPeriod: month + +artifactTypes: + - CHEF + - PUPPET + - SHELL + - YANG + - YANG_XML + - HEAT + - BPEL + - DG_XML + - MURANO_PKG + - WORKFLOW + - NETWORK_CALL_FLOW + - TOSCA_TEMPLATE + - TOSCA_CSAR + - AAI_SERVICE_MODEL + - AAI_VF_MODEL + - AAI_VF_MODULE_MODEL + - AAI_VF_INSTANCE_MODEL + - OTHER + +licenseTypes: + - User + - Installation + - CPU + +#Deployment artifacts placeHolder +resourceTypes: &allResourceTypes + - VFC + - CP + - VL + - VF + +# validForResourceTypes usage +# validForResourceTypes: +# - VF +# - VL +deploymentResourceArtifacts: +# heat: +# displayName: "Base HEAT Template" +# type: HEAT +# validForResourceTypes: *allResourceTypes +# heatVol: +# displayName: "Volume HEAT Template" +# type: HEAT_VOL +# validForResourceTypes: *allResourceTypes +# heatNet: +# displayName: "Network HEAT Template" +# type: HEAT_NET +# validForResourceTypes: *allResourceTypes + +deploymentResourceInstanceArtifacts: + heatEnv: + displayName: "HEAT ENV" + type: HEAT_ENV + description: "Auto-generated HEAT Environment deployment artifact" + fileExtension: "env" + +#tosca artifacts placeholders +toscaArtifacts: + assetToscaTemplate: + artifactName: -template.yml + displayName: Tosca Template + type: TOSCA_TEMPLATE + description: TOSCA representation of the asset + assetToscaCsar: + artifactName: -csar.csar + displayName: Tosca Model + type: TOSCA_CSAR + description: TOSCA definition package of the asset + + +#Informational artifacts placeHolder +excludeResourceCategory: + - Generic +informationalResourceArtifacts: + features: + displayName: Features + type: OTHER + capacity: + displayName: Capacity + type: OTHER + vendorTestResult: + displayName: Vendor Test Result + type: OTHER + testScripts: + displayName: Test Scripts + type: OTHER + cloudQuestionnaire: + displayName: Cloud Questionnaire (completed) + type: OTHER + HEATTemplateFromVendor: + displayName: HEAT Template from Vendor + type: HEAT + resourceSecurityTemplate: + displayName: Resource Security Template + type: OTHER + +excludeServiceCategory: + +informationalServiceArtifacts: + serviceArtifactPlan: + displayName: Service Artifact Plan + type: OTHER + summaryOfImpactsToECOMPElements: + displayName: Summary of impacts to ECOMP elements,OSSs, BSSs + type: OTHER + controlLoopFunctions: + displayName: Control Loop Functions + type: OTHER + dimensioningInfo: + displayName: Dimensioning Info + type: OTHER + affinityRules: + displayName: Affinity Rules + type: OTHER + operationalPolicies: + displayName: Operational Policies + type: OTHER + serviceSpecificPolicies: + displayName: Service-specific Policies + type: OTHER + engineeringRules: + displayName: Engineering Rules (ERD) + type: OTHER + distributionInstructions: + displayName: Distribution Instructions + type: OTHER + certificationTestResults: + displayName: TD Certification Test Results + type: OTHER + deploymentVotingRecord: + displayName: Deployment Voting Record + type: OTHER + serviceQuestionnaire: + displayName: Service Questionnaire + type: OTHER + serviceSecurityTemplate: + displayName: Service Security Template + type: OTHER + +serviceApiArtifacts: + configuration: + displayName: Configuration + type: OTHER + instantiation: + displayName: Instantiation + type: OTHER + monitoring: + displayName: Monitoring + type: OTHER + reporting: + displayName: Reporting + type: OTHER + logging: + displayName: Logging + type: OTHER + testing: + displayName: Testing + type: OTHER + + +additionalInformationMaxNumberOfKeys: 50 + +systemMonitoring: + enabled: false + isProxy: false + probeIntervalInSeconds: 15 + +defaultHeatArtifactTimeoutMinutes: 60 + +serviceDeploymentArtifacts: + YANG_XML: + acceptedTypes: + - xml + VNF_CATALOG: + acceptedTypes: + - xml + MODEL_INVENTORY_PROFILE: + acceptedTypes: + - xml + MODEL_QUERY_SPEC: + acceptedTypes: + - xml +#AAI Artifacts + AAI_SERVICE_MODEL: + acceptedTypes: + - xml + AAI_VF_MODULE_MODEL: + acceptedTypes: + - xml + AAI_VF_INSTANCE_MODEL: + acceptedTypes: + - xml + OTHER: + acceptedTypes: + +resourceDeploymentArtifacts: + HEAT: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + HEAT_VOL: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + HEAT_NESTED: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + HEAT_ARTIFACT: + acceptedTypes: + validForResourceTypes: *allResourceTypes + HEAT_NET: + acceptedTypes: + - yaml + - yml + validForResourceTypes: *allResourceTypes + YANG_XML: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VNF_CATALOG: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VF_LICENSE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + VENDOR_LICENSE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + MODEL_INVENTORY_PROFILE: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + MODEL_QUERY_SPEC: + acceptedTypes: + - xml + validForResourceTypes: *allResourceTypes + #APPC Artifatcs + APPC_CONFIG: + acceptedTypes: + validForResourceTypes: + - VF + #DCAE Artifacts + DCAE_TOSCA: + acceptedTypes: + - yml + - yaml + validForResourceTypes: + - VF + DCAE_JSON: + acceptedTypes: + - json + validForResourceTypes: + - VF + DCAE_POLICY: + acceptedTypes: + - emf + validForResourceTypes: + - VF + DCAE_DOC: + acceptedTypes: + validForResourceTypes: + - VF + DCAE_EVENT: + acceptedTypes: + validForResourceTypes: + - VF +#AAI Artifacts + AAI_VF_MODEL: + acceptedTypes: + - xml + validForResourceTypes: + - VF + AAI_VF_MODULE_MODEL: + acceptedTypes: + - xml + validForResourceTypes: + - VF + OTHER: + acceptedTypes: + validForResourceTypes: *allResourceTypes + +resourceInstanceDeploymentArtifacts: + HEAT_ENV: + acceptedTypes: + - env + VF_MODULES_METADATA: + acceptedTypes: + - json +#DCAE_VF Instance Artifacts + DCAE_INVENTORY_TOSCA: + acceptedTypes: + - yml + - yaml + DCAE_INVENTORY_JSON: + acceptedTypes: + - json + DCAE_INVENTORY_POLICY: + acceptedTypes: + - emf + DCAE_INVENTORY_DOC: + acceptedTypes: + DCAE_INVENTORY_BLUEPRINT: + acceptedTypes: + DCAE_INVENTORY_EVENT: + acceptedTypes: + + +resourceInformationalDeployedArtifacts: + + +requirementsToFulfillBeforeCert: + +capabilitiesToConsumeBeforeCert: + +unLoggedUrls: + - /sdc2/rest/healthCheck + +cleanComponentsConfiguration: + cleanIntervalInMinutes: 1440 + componentsToClean: + - Resource + - Service + +artifactsIndex: resources + +cassandraConfig: + cassandraHosts: ['localhost'] + localDataCenter: + reconnectTimeout : 30000 + authenticate: false + username: koko + password: bobo + ssl: false + truststorePath : /path/path + truststorePassword : 123123 + keySpaces: + - { name: sdcaudit, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + - { name: sdcartifact, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + - { name: sdccomponent, replicationStrategy: SimpleStrategy, replicationInfo: ['1']} + + +switchoverDetector: + gBeFqdn: + gFeFqdn: + beVip: 1.2.3.4 + feVip: 1.2.3.4 + beResolveAttempts: 3 + feResolveAttempts: 3 + enabled: false + interval: 60 + changePriorityUser: ecompasdc + changePriorityPassword: ecompasdc123 + publishNetworkUrl: "http://localhost/crt/CipDomain.ECOMP-ASDC-DEVST/config/update_network?user=root" + publishNetworkBody: '{"note":"publish network"}' + groups: + beSet: { changePriorityUrl: "http://localhost/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-BE.ecomp.idns.cip?user=root", + changePriorityBody: '{"name":"AIO-BE.ecomp.idns.cip","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-BE.ecomp.idns.cip","no_ad_redirection":false,"v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_be","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_be"],"failover_policy":["FAILALL"]},"comment":"AIO BE G-fqdn","intended_app_proto":"DNS"}'} + feSet: { changePriorityUrl: "http://cora.web/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-FE.ecomp.idns.cip?user=root", + changePriorityBody: '{"comment":"AIO G-fqdn","name":"AIO-FE.ecomp.idns.cip","v4groups":{"failover_groups":["/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_mg_fe","/crt/CipDomain.ECOMP-ASDC-DEVST/config/groups/group_bs_fe"],"failover_policy":["FAILALL"]},"no_ad_redirection":false,"intended_app_proto":"DNS","uri":"/crt/CipDomain.ECOMP-ASDC-DEVST/config/sites/AIO-FE.ecomp.idns.cip"}'} + + +heatEnvArtifactHeader: + "" +heatEnvArtifactFooter: + "" + +onboarding: + protocol: http + host: localhost + port: 8080 + downloadCsarUri: "/onboarding-api/v1.0/vendor-software-products/packages" + #downloadCsarUri: "/onboardingci/onbrest/onboarding-api/v1.0/vendor-software-products/packages" + +applicationL1Cache: + datatypes: + enabled: true + firstRunDelay: 10 + pollIntervalInSec: 60 + +applicationL2Cache: + enabled: true + catalogL1Cache: + enabled: true + resourcesSizeInCache: 300 + servicesSizeInCache: 200 + productsSizeInCache: 100 + queue: + syncIntervalInSecondes: 43200 + waitOnShutDownInMinutes: 10 + numberOfCacheWorkers: 4 + +toscaValidators: + stringMaxLength: 65536 +disableAudit: false \ No newline at end of file diff --git a/catalog-be/src/main/resources/config/distribution-engine-configuration.yaml b/catalog-be/src/main/resources/config/distribution-engine-configuration.yaml new file mode 100644 index 0000000000..8c56a26785 --- /dev/null +++ b/catalog-be/src/main/resources/config/distribution-engine-configuration.yaml @@ -0,0 +1,46 @@ +uebServers: + - uebsb91sfdc.it.att.com:3904 + - uebsb92sfdc.it.att.com:3904 + - uebsb93sfdc.it.att.com:3904 + +# prev Kansas City Sandbox uebPublicKey: 8F3MDAtMSBwwpSMy +uebPublicKey: sSJc5qiBnKy2qrlc + +# prev Kansas City Sandbox uebSecretKey: gzFmsTxSCtO5RQfAccM6PqqX +uebSecretKey: 4ZRPzNJfEUK0sSNBvccd2m7X + +distributionNotifTopicName: ASDC-DISTR-NOTIF-TOPIC +distributionStatusTopicName: ASDC-DISTR-STATUS-TOPIC + +initRetryIntervalSec: 5 +initMaxIntervalSec: 60 + +distribNotifServiceArtifactTypes: + info: + - MURANO-PKG + +distribNotifResourceArtifactTypes: + lifecycle: + - HEAT + - DG-XML + +environments: + - PROD + +distributionStatusTopic: + pollingIntervalSec: 60 + fetchTimeSec: 15 + consumerGroup: asdc + consumerId: asdc-id + +distributionNotificationTopic: + minThreadPoolSize: 0 + maxThreadPoolSize: 10 + maxWaitingAfterSendingSeconds: 5 + + +createTopic: + partitionCount: 1 + replicationCount: 1 + +startDistributionEngine: true \ No newline at end of file diff --git a/catalog-be/src/main/resources/config/ecomp-error-configuration.yaml b/catalog-be/src/main/resources/config/ecomp-error-configuration.yaml new file mode 100644 index 0000000000..9d7cd74a2b --- /dev/null +++ b/catalog-be/src/main/resources/config/ecomp-error-configuration.yaml @@ -0,0 +1,383 @@ +########################################### +# Note the conventions of the field values: +# type can be one of: CONFIG_ERROR, SYSTEM_ERROR, DATA_ERROR, CONNECTION_PROBLEM, AUTHENTICATION_PROBLEM +# severity can be one of: WARN, ERROR, FATAL +# alarmSeverity can be one of: CRITICAL,MAJOR,MINOR,INFORMATIONAL,NONE +# code is a unique integer in range of 3003-9999 (3000-3002 are occupied for internal usage) +# The above enumeration values are out-of-the-box and can be changed in code. +# In case of config and code mismatch, the appropriate error will be printed to log +# +## Range of BE codes - 3010-7999 + +errors: + + BeRestApiGeneralError: { + type: SYSTEM_ERROR, + code: ASDC_4000, + severity: ERROR, + description: "Unexpected error during BE REST API execution", + alarmSeverity: CRITICAL + } + + BeHealthCheckError: { + type: SYSTEM_ERROR, + code: ASDC_3010, + severity: ERROR, + description: "Error during BE Health Check", + alarmSeverity: CRITICAL + } + + BeInitializationError: { + type: SYSTEM_ERROR, + code: ASDC_4019, + severity: ERROR, + description: "Catalog-BE was not initialized properly", + alarmSeverity: CRITICAL + } + + BeResourceMissingError: { + type: SYSTEM_ERROR, + code: ASDC_3011, + severity: ERROR, + description: "Mandatory resource %s cannot be found in repository", + alarmSeverity: MAJOR + } + + BeServiceMissingError: { + type: SYSTEM_ERROR, + code: ASDC_3012, + severity: ERROR, + description: "Mandatory service %s cannot be found in repository", + alarmSeverity: MAJOR + } + + BeFailedAddingResourceInstanceError: { + type: SYSTEM_ERROR, + code: ASDC_3013, + severity: ERROR, + description: "Failed to add resource instance of resource %s to service %s", + alarmSeverity: MAJOR + } + + BeIncorrectServiceError: { + type: SYSTEM_ERROR, + code: ASDC_3014, + severity: ERROR, + description: "Service %s is not valid", + alarmSeverity: MAJOR + } + + BeRepositoryDeleteError: { + type: SYSTEM_ERROR, + code: ASDC_3015, + severity: ERROR, + description: "Failed to delete object %s from repository", + alarmSeverity: CRITICAL + } + + BeRepositoryQueryError: { + type: SYSTEM_ERROR, + code: ASDC_3016, + severity: ERROR, + description: "Failed to fetch from repository %s", + alarmSeverity: MAJOR + } + + BeInvalidConfigurationError: { + type: CONFIG_ERROR, + code: ASDC_3017, + severity: FATAL, + description: "Configuration parameter %s is invalid. Value configured is %s", + alarmSeverity: MAJOR + } + + BeUebConnectionError: { + type: CONNECTION_PROBLEM, + code: ASDC_4001, + severity: ERROR, + description: "Connection problem towards U-EB server. Reason: %s", + alarmSeverity: MAJOR + } + + BeUebSystemError: { + type: SYSTEM_ERROR, + code: ASDC_3019, + severity: ERROR, + description: "Error occured during access to U-EB Server. Operation: %s", + alarmSeverity: MAJOR + } + + BeUebObjectNotFoundError: { + type: DATA_ERROR, + code: ASDC_4005, + severity: ERROR, + description: "Error occured during access to U-EB Server. Data not found: %s", + alarmSeverity: MAJOR + } + + BeDistributionEngineSystemError: { + type: SYSTEM_ERROR, + code: ASDC_3021, + severity: ERROR, + description: "Error occured in Distribution Engine. Failed operation: %s", + alarmSeverity: MAJOR + } + + BeUebAuthenticationError: { + type: AUTHENTICATION_PROBLEM, + code: ASDC_4003, + severity: ERROR, + description: "Authentication problem towards U-EB server. Reason: %s", + alarmSeverity: MAJOR + } + + BeUebUnkownHostError: { + type: CONNECTION_PROBLEM, + code: ASDC_4002, + severity: ERROR, + description: "Connection problem towards U-EB server. Cannot reach host %s", + alarmSeverity: MAJOR + } + + BeDistributionEngineInvalidArtifactType: { + type: DATA_ERROR, + code: ASDC_4006, + severity: WARN, + description: "The artifact type %s does not appear in the list of valid artifacts %s", + alarmSeverity: MAJOR + } + BeInvalidTypeError: { + type: DATA_ERROR, + code: ASDC_4008, + severity: WARN, + description: "The type %s of %s is invalid", + alarmSeverity: MAJOR + } + BeInvalidValueError: { + type: DATA_ERROR, + code: ASDC_3028, + severity: WARN, + description: "The value %s of %s from type %s is invalid", + alarmSeverity: MAJOR + } + + BeFailedDeletingResourceInstanceError: { + type: SYSTEM_ERROR, + code: ASDC_3029, + severity: ERROR, + description: "Failed to delete resource instance %s from service %s", + alarmSeverity: MAJOR + } + + BeMissingConfigurationError: { + type: CONFIG_ERROR, + code: ASDC_3030, + severity: FATAL, + description: "Configuration parameter %s is missing", + alarmSeverity: MAJOR + } + + BeConfigurationInvalidListSizeError: { + type: CONFIG_ERROR, + code: ASDC_3031, + severity: FATAL, + description: "Configuration parameter %s is invalid. At least %s values shall be configured", + alarmSeverity: MAJOR + } + + ErrorConfigFileFormat: { + type: CONFIG_ERROR, + code: ASDC_3032, + severity: ERROR, + description: "Error element not found in YAML name: %s", + alarmSeverity: MAJOR + } + + BeMissingArtifactInformationError: { + type: DATA_ERROR, + code: ASDC_4010, + severity: ERROR, + description: "Artifact uploaded has missing information. Missing %s", + alarmSeverity: MAJOR + } + + BeArtifactMissingError: { + type: DATA_ERROR, + code: ASDC_4011, + severity: ERROR, + description: "Artifact %s requested is not found", + alarmSeverity: MAJOR + } + + BeArtifactPayloadInvalid: { + type: DATA_ERROR, + code: ASDC_4012, + severity: ERROR, + description: "Payload of artifact uploaded is invalid (invalid MD5 or encryption)", + alarmSeverity: MAJOR + } + + BeUserMissingError: { + type: DATA_ERROR, + code: ASDC_4009, + severity: ERROR, + description: "User %s requested is not found", + alarmSeverity: MAJOR + } + + BeArtifactInformationInvalidError: { + type: DATA_ERROR, + code: ASDC_4013, + severity: ERROR, + description: "Input for artifact metadata is invalid", + alarmSeverity: MAJOR + } + BeFailedAddingCapabilityTypeError: { + type: DATA_ERROR, + code: ASDC_4015, + severity: ERROR, + description: "Failed adding capability type", + alarmSeverity: CRITICAL + } + + BeCapabilityTypeMissingError: { + type: DATA_ERROR, + code: ASDC_4016, + severity: ERROR, + description: "Capability Type %s not found", + alarmSeverity: CRITICAL + } + + BeInterfaceMissingError: { + type: DATA_ERROR, + code: ASDC_4020, + severity: ERROR, + description: "Interface %s required is missing", + alarmSeverity: MAJOR + } + + BeDaoSystemError: { + type: SYSTEM_ERROR, + code: ASDC_4014, + severity: ERROR, + description: "Operation towards database failed", + alarmSeverity: CRITICAL + } + + BeSystemError: { + type: SYSTEM_ERROR, + code: ASDC_4017, + severity: ERROR, + description: "Unexpected error during operation", + alarmSeverity: CRITICAL + } + + BeFailedLockObjectError: { + type: SYSTEM_ERROR, + code: ASDC_4007, + severity: WARN, + description: "Failed to lock object for update", + alarmSeverity: CRITICAL + } + + BeInvalidJsonInput: { + type: SYSTEM_ERROR, + code: ASDC_4018, + severity: ERROR, + description: "Failed to convert json input to object", + alarmSeverity: MAJOR + } + + BeDistributionMissingError: { + type: DATA_ERROR, + code: ASDC_4021, + severity: ERROR, + description: "Distribution %s required is missing", + alarmSeverity: MAJOR + } + + BeHealthCheckRecovery: { + type: RECOVERY, + code: ASDC_4022, + severity: INFO, + description: "BE Health Check Recovery", + alarmSeverity: INFORMATIONAL + } + BeFailedCreateNodeError: { + type: DATA_ERROR, + code: ASDC_6000, + severity: ERROR, + description: "Failed to create node %s on graph. status is %s", + alarmSeverity: MAJOR + } + BeFailedUpdateNodeError: { + type: DATA_ERROR, + code: ASDC_6001, + severity: ERROR, + description: "Failed to update node %s on graph. Status is %s", + alarmSeverity: MAJOR + } + + BeFailedDeleteNodeError: { + type: DATA_ERROR, + code: ASDC_6002, + severity: ERROR, + description: "Failed to delete node %s on graph. Status is %s", + alarmSeverity: MAJOR + } + + BeFailedRetrieveNodeError: { + type: DATA_ERROR, + code: ASDC_6003, + severity: ERROR, + description: "Failed to retrieve node %s from graph. Status is %s", + alarmSeverity: MAJOR + } + + BeExecuteRollbackError: { + type: DATA_ERROR, + code: ASDC_6004, + severity: ERROR, + description: "Going to execute rollback on graph.", + alarmSeverity: MAJOR + } + + BeFailedFindParentError: { + type: DATA_ERROR, + code: ASDC_6005, + severity: ERROR, + description: "Failed to find parent node %s on graph. Status is %s", + alarmSeverity: MAJOR + } + + BeFailedFindAllNodesError: { + type: DATA_ERROR, + code: ASDC_6006, + severity: ERROR, + description: "Failed to fetch all nodes with type %s of parent node %s . Status is %s", + alarmSeverity: MAJOR + } + + BeFailedFindAssociationError: { + type: DATA_ERROR, + code: ASDC_6007, + severity: ERROR, + description: "Cannot find node with type %s associated with node %s . Status is %s", + alarmSeverity: MAJOR + } + + BeFailedFindAssociationError: { + type: DATA_ERROR, + code: ASDC_6008, + severity: ERROR, + description: "Cannot find node with type %s associated with node %s . Status is %s", + alarmSeverity: MAJOR + } + BeComponentCleanerSystemError: { + type: SYSTEM_ERROR, + code: ASDC_6009, + severity: ERROR, + description: "Error occured in Component Cleaner Task. Failed operation: %s", + alarmSeverity: MAJOR + } + \ No newline at end of file diff --git a/catalog-be/src/main/resources/config/error-configuration.yaml b/catalog-be/src/main/resources/config/error-configuration.yaml new file mode 100644 index 0000000000..0054ce2be9 --- /dev/null +++ b/catalog-be/src/main/resources/config/error-configuration.yaml @@ -0,0 +1,1694 @@ +# Errors +errors: + OK: { + code: 200, + message: "OK" + } + CREATED: { + code: 201, + message: "OK" + } + NO_CONTENT: { + code: 204, + message: "No Content" + } +#--------POL4050----------------------------- + NOT_ALLOWED: { + code: 405, + message: "Error: Method not allowed.", + messageId: "POL4050" + } +#--------POL5000----------------------------- + GENERAL_ERROR: { + code: 500, + message: "Error: Internal Server Error. Please try again later.", + messageId: "POL5000" + } +#---------POL5001------------------------------ + MISSING_X_ECOMP_INSTANCE_ID: { + code: 400 , + message: "Error: Missing 'X-ECOMP-InstanceID' HTTP header.", + messageId: "POL5001" + } +#---------POL5002------------------------------ + AUTH_REQUIRED: { + code: 401 , + message: "Error: Authentication is required to use the API.", + messageId: "POL5002" + } +#---------POL5003------------------------------ + AUTH_FAILED: { + code: 403 , + message: "Error: Not authorized to use the API.", + messageId: "POL5003" + } +#---------SVC4000----------------------------- + INVALID_CONTENT: { + code: 400, + message: "Error: Invalid content.", + messageId: "SVC4000" + }#---------SVC4000----------------------------- + INVALID_CONTENT: { + code: 400, + message: "Error: Invalid content.", + messageId: "SVC4000" + } +#---------SVC4002----------------------------- + MISSING_INFORMATION: { + code: 403, + message: "Error: Missing information.", + messageId: "SVC4002" + } +#---------SVC4003------------------------------ +# %1 - Users's USER_ID + USER_NOT_FOUND: { + code: 404, + message: "Error: User '%1' was not found.", + messageId: "SVC4003" + } +#---------SVC4004----------------------------- +# %1 - Users's email address + INVALID_EMAIL_ADDRESS: { + code: 400, + message: "Error: Invalid email address '%1'.", + messageId: "SVC4004" + } +#---------SVC4005------------------------------ +# %1 - role + INVALID_ROLE: { + code: 400, + message: "Error: Invalid role '%1'.", + messageId: "SVC4005" + } +#---------SVC4006------------------------------ +# %1 - Users's USER_ID + USER_ALREADY_EXIST: { + code: 409, + message: "Error: User with '%1' ID already exists.", + messageId: "SVC4006" + } +#---------SVC4007------------------------------ + DELETE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator can only be deleted by another administrator.", + messageId: "SVC4007" + } +#---------SVC4008----------------------------- +# %1 - Users's userId + INVALID_USER_ID: { + code: 400, + message: "Error: Invalid userId '%1'.", + messageId: "SVC4008" + } +#---------SVC4049------------------------------ +# %1 - service/resource + COMPONENT_MISSING_CONTACT: { + code: 400, + message: "Error: Invalid Content. Missing %1 contact id.", + messageId: "SVC4049" + } +#---------SVC4050----------------------------- +# %1 - Service/Resource/Additional parameter +# %2 - service/resource/label name + COMPONENT_NAME_ALREADY_EXIST: { + code: 409, + message: "Error: %1 with name '%2' already exists.", + messageId: "SVC4050" + } +#---------SVC4051------------------------------ +# %1 - resource/service + COMPONENT_MISSING_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Missing %1 category.", + messageId: "SVC4051" + } + +#---------SVC4052------------------------------ + COMPONENT_MISSING_TAGS: { + code: 400, + message: "Error: Invalid Content. At least one tag has to be specified.", + messageId: "SVC4052" + } + +#---------SVC4053------------------------------ +# %1 - service/resource + COMPONENT_MISSING_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. Missing %1 description.", + messageId: "SVC4053" + } +#---------SVC4054------------------------------ +# %1 - resource/service + COMPONENT_INVALID_CATEGORY: { + code: 400, + message: "Error: Invalid Content. Invalid %1 category.", + messageId: "SVC4054" + } +#---------SVC4055------------------------------ + MISSING_VENDOR_NAME: { + code: 400, + message: "Error: Invalid Content. Missing vendor name.", + messageId: "SVC4055" + } +#---------SVC4056------------------------------ + MISSING_VENDOR_RELEASE: { + code: 400, + message: "Error: Invalid Content. Missing vendor release.", + messageId: "SVC4056" + } + +#---------SVC4057------------------------------ + MISSING_DERIVED_FROM_TEMPLATE: { + code: 400, + message: "Error: Invalid Content. Missing derived from template specification.", + messageId: "SVC4057" + } + +#---------SVC4058------------------------------ +# %1 - service/resource + COMPONENT_MISSING_ICON: { + code: 400, + message: "Error: Invalid Content. Missing %1 icon.", + messageId: "SVC4058" + } +#---------SVC4059------------------------------ +# %1 - service/resource + COMPONENT_INVALID_ICON: { + code: 400, + message: "Error: Invalid Content. Invalid %1 icon.", + messageId: "SVC4059" + } +#---------SVC4060------------------------------ + PARENT_RESOURCE_NOT_FOUND: { + code: 400, + message: "Error: Invalid Content. Derived from resource template was not found.", + messageId: "SVC4060" + } +#---------SVC4061------------------------------ + MULTIPLE_PARENT_RESOURCE_FOUND: { + code: 400, + message: "Error: Invalid Content. Multiple derived from resource template is not allowed.", + messageId: "SVC4061" + } + +#---------SVC4062------------------------------ +# %1 - service/resource + MISSING_COMPONENT_NAME: { + code: 400, + message: "Error: Invalid Content. Missing %1 name.", + messageId: "SVC4062" + } +#---------SVC4063------------------------------ + #%1  -  resource/service name + RESOURCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource was not found.", + messageId: "SVC4063" + } + +#---------SVC4064------------------------------ +# %1 - Service/Resource + COMPONENT_INVALID_DESCRIPTION: { + code: 400, + message: "Error: Invalid Content. %1 description contains non-english characters.", + messageId: "SVC4064" + } +#---------SVC4065------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name length + COMPONENT_DESCRIPTION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 description exceeds limit of %2 characters.", + messageId: "SVC4065" + } +#---------SVC4066------------------------------ +# %1 - max length + COMPONENT_TAGS_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Tags overall length exceeds limit of %1 characters.", + messageId: "SVC4066" + } +#---------SVC4067------------------------------ +# %1 - max length + VENDOR_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor name exceeds limit of %1 characters.", + messageId: "SVC4067" + } +#---------SVC4068------------------------------ +# %1 - max length + VENDOR_RELEASE_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Vendor release exceeds limit of %1 characters.", + messageId: "SVC4068" + } + +#---------SVC4069------------------------------ +# %1 - Service/Resource/Product + COMPONENT_INVALID_CONTACT_ID: { + code: 400, + message: "Error: Invalid Content. %1 contact id should be in format 'mnnnnnn' or 'aannna' or 'aannnn', where m=m ,a=a-zA-Z and n=0-9", + messageId: "SVC4069" + } +#---------SVC4070------------------------------ +# %1 - Service/Resource + INVALID_COMPONENT_NAME: { + code: 400, + message: 'Error: Invalid Content. %1 name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4070" + } + +#---------SVC4071------------------------------ + INVALID_VENDOR_NAME: { + code: 400, + message: 'Error: Invalid Content. Vendor name is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4071" + } +#---------SVC4072------------------------------ + INVALID_VENDOR_RELEASE: { + code: 400, + message: 'Error: Invalid Content. Vendor release is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4072" + } +#---------SVC4073------------------------------ +# %1 - Service/Resource +# %2 - max resource/service name + COMPONENT_NAME_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 name exceeds limit of %2 characters.", + messageId: "SVC4073" + } +#---------SVC4080------------------------------ +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CHECKOUT_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for modification by %3 %4(%5).", + messageId: "SVC4080" + } +#---------SVC4081----------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_IN_CERT_IN_PROGRESS_STATE: { + code: 403, + message: "Error: Requested '%1' %2 is locked for certification by %3 %4(%5).", + messageId: "SVC4081" + } + +#-----------SVC4082--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_SENT_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is sent for certification by %3 %4(%5).", + messageId: "SVC4082" + } +#-----------SVC4083--------------------------- + COMPONENT_VERSION_ALREADY_EXIST: { + code: 409, + message: "Error: Version of this %1 was already promoted.", + messageId: "SVC4083" + } +#-----------SVC4084--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CHECKED_IN: { + code: 409, + message: "Error: The current version of '%1' %2 was already checked-in by %3 %4(%5).", + messageId: "SVC4084" + } +#-----------SVC4085--------------------------- +# %1 - resource/service/product name +# %2 - resource/service/product +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_CHECKOUT_BY_ANOTHER_USER: { + code: 403, + message: "Error: %1 %2 has already been checked out by %3 %4(%5).", + messageId: "SVC4085" + } +#-----------SVC4086--------------------------- +# %1  - resource/service name +# %2  - resource/service + COMPONENT_IN_USE: { + code: 403, + message: "Error: Requested '%1' %2 is in use by another user.", + messageId: "SVC4086" + } +#-----------SVC4087--------------------------- +# %1 - component name +# %2 - resource/service/product + COMPONENT_HAS_NEWER_VERSION: { + code: 409, + message: "Error: Checking out of the requested version of the '%1' %2 is not allowed as a newer version exists.", + messageId: "SVC4087" + } +#-----------SVC4088--------------------------- +# %1 - resource/service name +# %2 - resource/service +# %3 - First name of last modifier +# %4 - Last name of last modifier +# %5 - USER_ID of last modifier + COMPONENT_ALREADY_CERTIFIED: { + code: 403, + message: "Error: Requested %1 %2 has already been certified by %3 %4(%5).", + messageId: "SVC4088" + } +#-----------SVC4089--------------------------- +# %1 - resource/service name +# %2 - resource/service + COMPONENT_NOT_READY_FOR_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification.", + messageId: "SVC4089" + } +#-----------SVC4100--------------------------- +#%1 - property name + PROPERTY_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' property was not found.", + messageId: "SVC4100" + } +#-----------SVC4101--------------------------- +#%1 - property name + PROPERTY_ALREADY_EXIST: { + code: 409, + message: "Error: Property with '%1' name already exists.", + messageId: "SVC4101" + } + +#-----------SVC4102--------------------------- +# %1 - capability type name + CAPABILITY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Capability Type with name '%1' already exists.", + messageId: "SVC4102" + } +#-----------SVC4114--------------------------- + AUTH_FAILED_INVALIDE_HEADER: { + code: 400, + message: "Error: Invalid Authorization header.", + messageId: "SVC4114" + } +#-----------SVC4115--------------------------- +# %1 - capability type name + MISSING_CAPABILITY_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Capability Type '%1'.", + messageId: "SVC4115" + } + RESOURCE_INSTANCE_BAD_REQUEST: { + code: 400, + message: "Error: Invalid Content.", + messageId: "SVC4116" + } +#-----------SVC4117--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_MATCH_NOT_FOUND: { + code: 404, + message: "Error: Match not found between resource instance '%1' and resource instance '%2' for requirement '%3'.", + messageId: "SVC4117" + } +#-----------SVC4118--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_ALREADY_EXIST: { + code: 409, + message: "Error: Resource instances '%1' and '%2' are already associated with requirement '%3'.", + messageId: "SVC4118" + } +#-----------SVC4119--------------------------- +# %1 - resource instance name +# %2 - resource instance name +# %3 - requirement name + RESOURCE_INSTANCE_RELATION_NOT_FOUND: { + code: 404, + message: "Error: No relation found between resource instances '%1' and '%2' for requirement '%3'.", + messageId: "SVC4119" + } +#-----------SVC4120--------------------------- +# %1 - User's USER_ID + USER_INACTIVE: { + code: 404, + message: "Error: User %1 was not found.", + messageId: "SVC4120" + } +#-----------SVC4121--------------------------- +# %1 - User's USER_ID + USER_HAS_ACTIVE_ELEMENTS: { + code: 403, + message: "Error: User with %1 ID can not be deleted since it has active elements(resources/services/artifacts).", + messageId: "SVC4121" + } +#-----------SVC4122--------------------------- +# %1 - artifact type + ARTIFACT_TYPE_NOT_SUPPORTED: { + code: 400, + message: "Error: Invalid artifact type '%1'.", + messageId: "SVC4122" + } +#-----------SVC4123--------------------------- + ARTIFACT_LOGICAL_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Artifact logical name cannot be changed.", + messageId: "SVC4123" + } +#-----------SVC4124--------------------------- + MISSING_ARTIFACT_TYPE: { + code: 400, + message: "Error: Missing artifact type.", + messageId: "SVC4124" + } +#-----------SVC4125--------------------------- +# %1-artifact name + ARTIFACT_EXIST: { + code: 400, + message: "Error: Artifact '%1' already exists.", + messageId: "SVC4125" + } +#---------SVC4126------------------------------ +# %1 - resource/service/product/... +# %2 - field (tag, vendor name...) + INVALID_FIELD_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 format.", + messageId: "SVC4126" + } +#-----------SVC4127--------------------------- + ARTIFACT_INVALID_MD5: { + code: 400, + message: "Error: Invalid artifact checksum.", + messageId: "SVC4127" + } +#-----------SVC4128--------------------------- + MISSING_ARTIFACT_NAME: { + code: 400, + message: "Error: Invalid content. Missing artifact name.", + messageId: "SVC4128" + } +#-----------SVC4129--------------------------- + MISSING_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. Missing PROJECT_CODE number.", + messageId: "SVC4129" + } +#-----------SVC4130--------------------------- + INVALID_PROJECT_CODE: { + code: 400, + message: "Error: Invalid Content. PROJECT_CODE number must be numeric from 5 up to 10 digits.", + messageId: "SVC4130" + } +#-----------SVC4131--------------------------- +# %1-resource/service +# %2-srtifact/artifacts +# %3-semicolomn separated list of artifact + COMPONENT_MISSING_MANDATORY_ARTIFACTS: { + code: 403, + message: "Error: Missing mandatory informational %1 %2: [%3].", + messageId: "SVC4131" + } +#-----------SVC4132--------------------------- +# %1 - lifecycle type name + LIFECYCLE_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Lifecycle Type with name '%1' already exists.", + messageId: "SVC4132" + } +#-----------SVC4133--------------------------- +# %1 - service version +# %2 - service name + SERVICE_NOT_AVAILABLE_FOR_DISTRIBUTION: { + code: 403, + message: "Error: Version %1 of '%2' service is not available for distribution.", + messageId: "SVC4133" + } +#-----------SVC4134--------------------------- + MISSING_LIFECYCLE_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing interface life-cycle type.", + messageId: "SVC4134" + } +#---------SVC4135------------------------------ + SERVICE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service category cannot be changed once the service is certified.", + messageId: "SVC4135" + } +#---------SVC4136------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_AVAILABLE: { + code: 500, + message: "Error: Requested distribution environment '%1' is not available.", + messageId: "SVC4136" + } +#---------SVC4137------------------------------ +# %1 - distribution environment name + DISTRIBUTION_ENVIRONMENT_NOT_FOUND: { + code: 400, + message: "Error: Requested distribution environment '%1' was not found.", + messageId: "SVC4137" + } +#---------SVC4138------------------------------ + DISTRIBUTION_ENVIRONMENT_INVALID: { + code: 400, + message: "Error: Invalid distribution environment.", + messageId: "SVC4138" + } +#---------SVC4139------------------------------ +# %1 - service name + DISTRIBUTION_ARTIFACT_NOT_FOUND: { + code: 409, + message: "Error: Service '%1' cannot be distributed due to missing deployment artifacts.", + messageId: "SVC4139" + } +#---------SVC4200------------------------------ +# %1 - Service/Resource +# %2 - max icon name length + COMPONENT_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 icon name exceeds limit of %2 characters.", + messageId: "SVC4200" + } +#---------SVC4300------------------------------ + RESTRICTED_ACCESS: { + code: 403, + message: "Error: Restricted access.", + messageId: "SVC4300" + } +#---------SVC4301------------------------------ + RESTRICTED_OPERATION: { + code: 409, + message: "Error: Restricted operation.", + messageId: "SVC4301" + } +#---------SVC4500------------------------------ + MISSING_BODY: { + code: 400 , + message: "Error: Missing request body.", + messageId: "SVC4500" + } +#---------SVC4501------------------------------ + MISSING_PUBLIC_KEY: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'apiPublicKey'." , + messageId: "SVC4501" + } +#---------SVC4502------------------------------ + DISTRIBUTION_ENV_DOES_NOT_EXIST: { + code: 400 , + message: "Error: Invalid Body : Missing mandatory parameter 'distrEnvName'." , + messageId: "SVC4502" + } +#-----------SVC4503--------------------------- +# %1 - service name + SERVICE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' service was not found.", + messageId: "SVC4503" + } + +#---------SVC4504------------------------------ +# %1 - Service/Resource +# %2 - service/resource version + COMPONENT_VERSION_NOT_FOUND: { + code: 404, + message: "Error: %1 version %2 was not found.", + messageId: "SVC4504" + } +#-----------SVC4505--------------------------- + #%1-artifact name + + ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Artifact '%1' was not found.", + messageId: "SVC4505" + } +#---------SVC4506------------------------------ + MISSING_ENV_NAME: { + code: 400 , + message: "Error: Invalid Content. Missing mandatory parameter 'distrEnvName'.", + messageId: "SVC4506" + } +#---------SVC4507------------------------------ + COMPONENT_INVALID_TAGS_NO_COMP_NAME: { + code: 400, + message: "Error: Invalid Content. One of the tags should be the component name.", + messageId: "SVC4507" + } + +#---------SVC4508------------------------------ + SERVICE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Service name cannot be changed once the service is certified.", + messageId: "SVC4508" + } + +#---------SVC4509------------------------------ + SERVICE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the service is certified.", + messageId: "SVC4509" + } +#---------SVC4510------------------------------ +# %1 - icon name max length + SERVICE_ICON_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Icon name exceeds limit of %1 characters.", + messageId: "SVC4510" + } +#---------SVC4511------------------------------ + DISTRIBUTION_REQUESTED_NOT_FOUND: { + code: 404, + message: "Error: Requested distribution was not found.", + messageId: "SVC4511" + } +#---------SVC4512------------------------------ +# %1 - Distribution ID + DISTRIBUTION_REQUESTED_FAILED: { + code: 403, + message: "Error: Requested distribution '%1' failed.", + messageId: "SVC4512" + } +#---------SVC4513------------------------------ + RESOURCE_CATEGORY_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource category cannot be changed once the resource is certified.", + messageId: "SVC4513" + } +#---------SVC4514------------------------------ + RESOURCE_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Resource name cannot be changed once the resource is certified.", + messageId: "SVC4514" + } +#---------SVC4515------------------------------ + RESOURCE_ICON_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Icon cannot be changed once the resource is certified.", + messageId: "SVC4515" + } +#---------SVC4516------------------------------ + RESOURCE_VENDOR_NAME_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Vendor name cannot be changed once the resource is certified.", + messageId: "SVC4516" + } +#---------SVC4517------------------------------ + RESOURCE_DERIVED_FROM_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: Derived from resource template cannot be changed once the resource is certified.", + messageId: "SVC4517" + } +#---------SVC4518------------------------------ +# %1 - max length + COMPONENT_SINGLE_TAG_EXCEED_LIMIT: { + code: 400, + message: "Error: Invalid Content. Single tag exceeds limit of %1 characters.", + messageId: "SVC4518" + } +#---------SVC4519------------------------------ + INVALID_DEFAULT_VALUE: { + code: 400, + message: "Error: mismatch in data-type occurred for property %1. data type is %2 and default value found is %3.", + messageId: "SVC4519" + } +#---------SVC4520------------------------------ +# %1 - service or resource + ADDITIONAL_INFORMATION_MAX_NUMBER_REACHED: { + code: 409, + message: "Error: Maximal number of additional %1 parameters was reached.", + messageId: "SVC4520" + } +#---------SVC4521------------------------------ + ADDITIONAL_INFORMATION_EMPTY_STRING_NOT_ALLOWED: { + code: 400, + message: "Error: Invalid Content. The Additional information label and value cannot be empty.", + messageId: "SVC4521" + } +#---------SVC4522------------------------------ +# %1 - label/value +# %2 - Maximal length of %1 + ADDITIONAL_INFORMATION_EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. Additional information %1 exceeds limit of %2 characters.", + messageId: "SVC4522" + } +#---------SVC4523------------------------------ + ADDITIONAL_INFORMATION_KEY_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information label is not allowed to contain characters like <>:"\/|?* and space characters other than regular space.', + messageId: "SVC4523" + } +#---------SVC4524------------------------------ + ADDITIONAL_INFORMATION_NOT_FOUND: { + code: 409, + message: "Error: Requested additional information was not found.", + messageId: "SVC4524" + } +#---------SVC4525------------------------------ + ADDITIONAL_INFORMATION_VALUE_NOT_ALLOWED_CHARACTERS: { + code: 400, + message: 'Error: Invalid Content. Additional information contains non-english characters.', + messageId: "SVC4525" + } +#---------SVC4526------------------------------ + RESOURCE_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' resource instance was not found.", + messageId: "SVC4526" + } +#---------SVC4527------------------------------ + ASDC_VERSION_NOT_FOUND: { + code: 500, + message: 'Error: ASDC version cannot be displayed.', + messageId: "SVC4527" + } +#---------SVC4528------------------------------ +# %1-artifact url/artifact label/artifact description/VNF Service Indicator + MISSING_DATA: { + code: 400, + message: "Error: Invalid content. Missing %1.", + messageId: "SVC4528" + } +#---------SVC4529------------------------------ +# %1-artifact url/artifact label/artifact description/artifact name +# %2 - Maximal length of %1 + EXCEEDS_LIMIT: { + code: 400, + message: "Error: Invalid Content. %1 exceeds limit of %2 characters.", + messageId: "SVC4529" + } +#---------SVC4530------------------------------ + ARTIFACT_INVALID_TIMEOUT: { + code: 400, + message: "Error: Invalid Content. Artifact Timeout should be set to valid positive non-zero number of minutes.", + messageId: "SVC4530" + } +#---------SVC4531------------------------------ + SERVICE_IS_VNF_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: VNF Indicator cannot be updated for certified service.", + messageId: "SVC4531" + } + #---------SVC4532------------------------------ + RESOURCE_INSTANCE_NOT_FOUND_ON_SERVICE: { + code: 404, + message: "Error: Requested '%1' resource instance was not found on the service '%2.", + messageId: "SVC4532" + } + #---------SVC4533------------------------------ + # %1 - "HEAT"/"HEAT_ENV"/"MURANO_PKG"/"YANG_XML" + WRONG_ARTIFACT_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for %1 artifact type.", + messageId: "SVC4533" + } + +#---------SVC4534------------------------------ +# %1 - "HEAT"/"HEAT_ENV" + INVALID_YAML: { + code: 400, + message: "Error: Uploaded YAML file for %1 artifact is invalid.", + messageId: "SVC4534" + } + +#---------SVC4535------------------------------ +# %1 - "HEAT" + INVALID_DEPLOYMENT_ARTIFACT_HEAT: { + code: 400, + message: "Error: Invalid %1 artifact.", + messageId: "SVC4535" + } +#---------SVC4536------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "HEAT"/"HEAT_ENV"/"MURANO_PKG" +# %4 - "HEAT"/"HEAT_ENV"/"MURANO_PKG + DEPLOYMENT_ARTIFACT_OF_TYPE_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact of %3 type .Please delete or update an existing %4 artifact.", + messageId: "SVC4536" + } + +#---------SVC4537------------------------------ + MISSING_HEAT: { + code: 400, + message: "Error: Missing HEAT artifact. HEAT_ENV artifact cannot be uploaded without corresponding HEAT template.", + messageId: "SVC4537" + } +#---------SVC4538------------------------------ + MISMATCH_HEAT_VS_HEAT_ENV: { + code: 400, + message: "Error: Invalid artifact content. Parameter's set in HEAT_ENV '%1' artifact doesn't match the parameters in HEAT '%2' artifact.", + messageId: "SVC4538" + } +#---------SVC4539------------------------------ + INVALID_RESOURCE_PAYLOAD: { + code: 400, + message: "Error: Invalid resource payload.", + messageId: "SVC4539" + } +#---------SVC4540------------------------------ + INVALID_TOSCA_FILE_EXTENSION: { + code: 400, + message: "Error: Invalid file extension for TOSCA template.", + messageId: "SVC4540" + } +#---------SVC4541------------------------------ + INVALID_YAML_FILE: { + code: 400, + message: "Error: Invalid YAML file.", + messageId: "SVC4541" + } +#---------SVC4542------------------------------ + INVALID_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Invalid TOSCA template.", + messageId: "SVC4542" + } +#---------SVC4543------------------------------ + NOT_RESOURCE_TOSCA_TEMPLATE: { + code: 400, + message: "Error: Imported Service TOSCA template.", + messageId: "SVC4543" + } +#---------SVC4544------------------------------ + NOT_SINGLE_RESOURCE: { + code: 400, + message: "Error: Imported TOSCA template should contain one resource definition.", + messageId: "SVC4544" + } +#---------SVC4545------------------------------ + INVALID_RESOURCE_NAMESPACE: { + code: 400, + message: "Error: Invalid resource namespace.", + messageId: "SVC4545" + } +#---------SVC4546------------------------------ + RESOURCE_ALREADY_EXISTS: { + code: 400, + message: "Error: Imported resource already exists in ASDC Catalog.", + messageId: "SVC4546" + } +#---------SVC4549------------------------------ + INVALID_RESOURCE_CHECKSUM: { + code: 400, + message: "Error: Invalid resource checksum.", + messageId: "SVC4549" + } +#---------SVC4550------------------------------ + #%1  -  Consumer salt + INVALID_LENGTH: { + code: 400, + message: "Error: Invalid %1 length.", + messageId: "SVC4550" + } + #---------SVC4551------------------------------ + #%1  -  ECOMP User name + ECOMP_USER_NOT_FOUND: { + code: 404, + message: "Error: ECOMP User '%1' was not found.", + messageId: "SVC4551" + } +#---------SVC4552------------------------------ + CONSUMER_ALREADY_EXISTS: { + code: 409, + message: "Error: ECOMP User already exists.", + messageId: "SVC4552" + } +#---------SVC4553----------------------------- + #%1  -  Consumer name / Consumer password/ Consumer salt + INVALID_CONTENT_PARAM: { + code: 400, + message: "Error: %1 is invalid.", + messageId: "SVC4553" + } + #---------SVC4554------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_ARTIFACT_NOT_FOUND: { + code: 404, + message: "Error: Requested artifact doesn't belong to specified %1.", + messageId: "SVC4554" + } +#---------SVC4554------------------------------ +# %1 - "Service name" + SERVICE_DEPLOYMENT_ARTIFACT_NOT_FOUND: { + code: 403, + message: "Error: Requested '%1' service is not ready for certification. Service has to have at least one deployment artifact.", + messageId: "SVC4554" + } +#---------SVC4555------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_LENGTH: { + code: 400, + message: "Error: Invalid %1 %2 name length.", + messageId: "SVC4555" + } +#---------SVC4556------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category" + COMPONENT_ELEMENT_INVALID_NAME_FORMAT: { + code: 400, + message: "Error: Invalid %1 %2 name format.", + messageId: "SVC4556" + } +#---------SVC4557------------------------------ +#%1 - "Resource"/"Service"/"Product" +#%2 - "category name" + COMPONENT_CATEGORY_ALREADY_EXISTS: { + code: 409, + message: "Error: %1 category name '%2' already exists.", + messageId: "SVC4557" + } +#---------SVC4558------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + VALIDATED_RESOURCE_NOT_FOUND: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource.", + messageId: "SVC4558" + } +#---------SVC4559------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_ALREADY_VALIDATED_RESOURCE: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use already available validated resource version.", + messageId: "SVC4559" + } +#---------SVC4560------------------------------ +# %1 - "service"/"VF" +# %2 - "Resource name" + FOUND_LIST_VALIDATED_RESOURCES: { + code: 403, + message: "Error: Submit for Testing is not permitted as your '%1' includes non-validated '%2' resource. Please use one of available validated resource versions.", + messageId: "SVC4560" + } +#---------SVC4561------------------------------ +# %1 - "resource"/"product" +# %2 - "category" +# %3 - "category name" + COMPONENT_CATEGORY_NOT_FOUND: { + code: 404, + message: "Error: Requested %1 %2 '%3' was not found.", + messageId: "SVC4561" + } +#---------SVC4562------------------------------ +# %1 - "Resource"/"Product" +# %2 - "sub-category name" +# %3 - "category name" + COMPONENT_SUB_CATEGORY_EXISTS_FOR_CATEGORY: { + code: 409, + message: "Error: %1 sub-category '%2' already exists under '%3' category.", + messageId: "SVC4562" + } +#---------SVC4563------------------------------ +# %1 - "Product" +# %2 - "grouping name" +# %3 - "sub-category name" + COMPONENT_GROUPING_EXISTS_FOR_SUB_CATEGORY: { + code: 409, + message: "Error: %1 grouping '%2' already exists under '%3' sub-category.", + messageId: "SVC4563" + } +#---------SVC4564------------------------------ +# %1 - product name + PRODUCT_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' product was not found.", + messageId: "SVC4564" + } +#---------SVC4565------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") +# %3 - parameter name + INVALID_HEAT_PARAMETER_VALUE: { + code: 400, + message: "Error: Invalid %1 artifact. Invalid %2 value set for '%3' parameter.", + messageId: "SVC4565" + } +#---------SVC4566------------------------------ +# %1 - "HEAT" +# %2 - parameter type ("string" , "boolean" , "number") + INVALID_HEAT_PARAMETER_TYPE: { + code: 400, + message: "Error: Invalid %1 artifact. Unsupported '%2' parameter type.", + messageId: "SVC4566" + } +#---------SVC4567------------------------------ +# %1 - "YANG_XML" + INVALID_XML: { + code: 400, + message: "Error: Uploaded XML file for %1 artifact is invalid.", + messageId: "SVC4567" + } +#---------SVC4567------------------------------ +# %1 - "User Name and userId" +# %2 -"checked-out"/"in-certification" + CANNOT_DELETE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: User cannot be deleted. User '%1' has %2 projects.", + messageId: "SVC4567" + } +#---------SVC4568------------------------------ +# %1 - "User Name and userId" +# %2 -"checked-out"/"in-certification" + CANNOT_UPDATE_USER_WITH_ACTIVE_ELEMENTS: { + code: 409, + message: "Error: Role cannot be changed. User '%1' has %2 projects.", + messageId: "SVC4568" + } +#---------SVC4570------------------------------ + UPDATE_USER_ADMIN_CONFLICT: { + code: 409, + message: "Error: An administrator is not allowed to change his/her role.", + messageId: "SVC4570" + } +#---------SVC4571------------------------------ + SERVICE_CANNOT_CONTAIN_SUBCATEGORY: { + code: 400, + message: "Error: Sub category cannot be defined for service", + messageId: "SVC4571" + } +#---------SVC4572------------------------------ +# %1 - "Resource"/"Service" + COMPONENT_TOO_MUCH_CATEGORIES: { + code: 400, + message: "Error: %1 must have only 1 category", + messageId: "SVC4572" + } +#---------SVC4574------------------------------ + RESOURCE_TOO_MUCH_SUBCATEGORIES: { + code: 400, + message: "Error: Resource must have only 1 sub category", + messageId: "SVC4574" + } +#---------SVC4575------------------------------ + COMPONENT_MISSING_SUBCATEGORY: { + code: 400, + message: "Error: Missing sub category", + messageId: "SVC4575" + } + #---------SVC4576------------------------------ +# %1 - "component type" + UNSUPPORTED_ERROR: { + code: 400, + message: "Error : Requested component type %1 is unsupported.", + messageId: "SVC4576" + } + #---------SVC4577------------------------------ +# %1 - "resource type" + RESOURCE_CANNOT_CONTAIN_RESOURCE_INSTANCES: { + code: 409, + message: "Error : Resource of type %1 cannot contain resource instances.", + messageId: "SVC4577" + } +#---------SVC4578------------------------------ +# %1 - "Resource"/"Service" +# %2 - resource/service name +# %3 - "artifact name" + DEPLOYMENT_ARTIFACT_NAME_ALREADY_EXISTS: { + code: 400, + message: "Error: %1 '%2' already has a deployment artifact named '%3'.", + messageId: "SVC4578" + } +#---------SVC4579------------------------------ +# %1 - "Category"/"Sub-Category"/"Group" +# %2 - category/sub-category/grouping name. + INVALID_GROUP_ASSOCIATION: { + code: 400, + message: "Error: Invalid group association. %1 '%2' was not found.", + messageId: "SVC4579" + } +#---------SVC4580------------------------------ + EMPTY_PRODUCT_CONTACTS_LIST: { + code: 400, + message: "Error: Invalid content. At least one Product Contact has to be specified.", + messageId: "SVC4580" + } +#---------SVC4581------------------------------ +# %1 - userId + INVALID_PRODUCT_CONTACT: { + code: 400, + message: "Error: Invalid content. User '%1' cannot be set as Product Contact.", + messageId: "SVC4581" + } +#---------SVC4582------------------------------ +# %1 - Product +# %2 - "abbreviated"/"full" + MISSING_ONE_OF_COMPONENT_NAMES: { + code: 400, + message: "Error: Invalid content. Missing %1 %2 name.", + messageId: "SVC4582" + } +#---------SVC4583------------------------------ +# %1 - "Icon" +# %2 - "resource"/"service"/"product" + COMPONENT_PARAMETER_CANNOT_BE_CHANGED: { + code: 400, + message: "Error: %1 cannot be changed once the %2 is certified.", + messageId: "SVC4583" + } +#---------SVC4584------------------------------ +# %1 - service/VF name +# %2 - "service" /"VF" +# %3 - resource instance origin type +# %4 - resource instance name +# %5 - requirement/capability +# %6 - requirement/capability name +# %7 - "fulfilled" (for req)/"consumed (for cap)" + REQ_CAP_NOT_SATISFIED_BEFORE_CERTIFICATION: { + code: 403, + message: "Error: Requested '%1' %2 is not ready for certification. %3 '%4' has to have %5 '%6' %7.", + messageId: "SVC4584" + } +#---------SVC4585------------------------------ + INVALID_OCCURRENCES: { + code: 400, + message: "Error: Invalid occurrences format.", + messageId: "SVC4585" + } +#---------SVC4586------------------------------ +#---------SVC4586------------------------------ + INVALID_SERVICE_API_URL: { + code: 400, + message: 'Error: Invalid Service API URL. Please check whether your URL has a valid domain extension and does not contain the following characters - #?&@%+;,=$<>~^`\[]{}|"*!', + messageId: "SVC4586" + } +#---------SVC4587------------------------------ +# %1 - Data type name + DATA_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Data type %1 already exists.', + messageId: "SVC4587" + } +#---------SVC4588------------------------------ +# %1 - Data type name + DATA_TYPE_NOR_PROPERTIES_NEITHER_DERIVED_FROM: { + code: 400, + message: 'Error: Invalid Data type %1. Data type must have either a valid derived from declaration or at least one valid property', + messageId: "SVC4588" + } +#---------SVC4589------------------------------ +# %1 - Data type name + DATA_TYPE_PROPERTIES_CANNOT_BE_EMPTY: { + code: 400, + message: "Error: Invalid Data type %1. 'properties' parameter cannot be empty if provided.", + messageId: "SVC4589" + } +#---------SVC4590------------------------------ +# %1 - Property type name +# %2 - Property name + INVALID_PROPERTY_TYPE: { + code: 400, + message: "Error: Invalid Property type %1 in property %2.", + messageId: "SVC4590" + } +#---------SVC4591------------------------------ +# %1 - Property inner type +# %2 - Property name + INVALID_PROPERTY_INNER_TYPE: { + code: 400, + message: "Error: Invalid property inner type %1, in property %2", + messageId: "SVC4591" + } +#---------SVC4592------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" + COMPONENT_INSTANCE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' %2 was not found.", + messageId: "SVC4592" + } +#---------SVC4593------------------------------ +# %1 - component instance name +# %2 - "resource instance"/"service instance" +# %3 - "resource/"service"/"product" +# %4 - container name + COMPONENT_INSTANCE_NOT_FOUND_ON_CONTAINER: { + code: 404, + message: "Error: Requested '%1' %2 was not found on the %3 '%4'.", + messageId: "SVC4593" + } +#---------SVC4594------------------------------ +#%1 - requirement / capability +#%2 - requirement name + IMPORT_DUPLICATE_REQ_CAP_NAME: { + code: 400, + message: "Error: Imported TOSCA template contains more than one %1 named '%2'.", + messageId: "SVC4594" + } +#---------SVC4595------------------------------ +#%1 - requirement / capability +#%2 - requirement name +#%3 - parent containing the requirement + IMPORT_REQ_CAP_NAME_EXISTS_IN_DERIVED: { + code: 400, + message: "Error: Imported TOSCA template contains %1 '%2' that is already defined by derived template %3.", + messageId: "SVC4595" + } +#---------SVC4596------------------------------ +# %1 - Data type name + DATA_TYPE_DERIVED_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The ancestor data type %1 cannot be found in the system.", + messageId: "SVC4596" + } +#---------SVC4597------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROPERTY_ALREADY_DEFINED_IN_ANCESTOR: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties named %2 which are already defined in one of its ancestors.", + messageId: "SVC4597" + } +#---------SVC4598------------------------------ +# %1 - Data type name + DATA_TYPE_DUPLICATE_PROPERTY: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains duplicate property.", + messageId: "SVC4598" + } +#---------SVC4599------------------------------ +# %1 - Data type name +# %2 - Property names + DATA_TYPE_PROEPRTY_CANNOT_HAVE_SAME_TYPE_OF_DATA_TYPE: { + code: 400, + message: "Error: Invalid Content. The data type %1 contains properties %2 which their type is this data type.", + messageId: "SVC4599" + } +#---------SVC4600------------------------------ +# %1 - Data type name + DATA_TYPE_CANNOT_HAVE_PROPERTIES: { + code: 400, + message: "Error: Invalid Content. The data type %1 cannot have properties since it is of type scalar", + messageId: "SVC4600" + } +#---------SVC4601------------------------------ + NOT_TOPOLOGY_TOSCA_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file %1 cannot be modeled to VF as it does not contain 'topology_template.", + messageId: "SVC4601" + } +#---------SVC4602-------------------------------- +# %1 - yaml file name +# %2 - node_template label +# %3 - node_template type + INVALID_NODE_TEMPLATE: { + code: 400, + message: "Error: TOSCA yaml file '%1' contains node_template '%2' of type '%3' that does not represent existing VFC/CP/VL", + messageId: "SVC4602" + } +#---------SVC4603------------------------------ +# %1 - component type +# %2 - component name +# %3 - state + ILLEGAL_COMPONENT_STATE: { + code: 403, + message: "Error: Component instance of %1 can not be created because the component '%2' is in an illegal state %3.", + messageId: "SVC4603" + } +#---------SVC4604------------------------------ +# %1 - csar file name + CSAR_INVALID: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. 'TOSCA-Metadata/Tosca.meta' file must be provided.", + messageId: "SVC4604" + } +#---------SVC4605------------------------------ +# %1 - csar file name + CSAR_INVALID_FORMAT: { + code: 400, + message: "Error: TOSCA CSAR '%1' is invalid. Invalid 'TOSCA-Metadata/Tosca.meta' file format.", + messageId: "SVC4605" + } +#---------SVC4606------------------------------ +# %1 - property name +# %2 - property type +# %3 - property innerType +# %4 - default value is + INVALID_COMPLEX_DEFAULT_VALUE: { + code: 400, + message: "Error: Invalid default value of property %1. Data type is %2 with inner type %3 and default value found is %4.", + messageId: "SVC4606" + } +#---------SVC4607------------------------------ +# %1 - csar file name + CSAR_NOT_FOUND: { + code: 400, + message: "Error: TOSCA CSAR '%1' is not found.", + messageId: "SVC4607" + } +#---------SVC4608------------------------------ +# %1 - artifact name +# %2 - component type +# %3 - actual component type + MISMATCH_BETWEEN_ARTIFACT_TYPE_AND_COMPONENT_TYPE: { + code: 400, + message: "Error: Artifact %1 is only compatible with component of type %2, but component type is %3.", + messageId: "SVC4608" + } + +#---------SVC4609------------------------------ +# %1 - "INVALID_JSON" + INVALID_JSON: { + code: 400, + message: "Error: Uploaded JSON file for %1 artifact is invalid.", + messageId: "SVC4609" + } +#---------SVC4610------------------------------ +# %1 - csar file name +# %2 - missing file name + YAML_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error - TOSCA CSAR %1 is invalid. TOSCA-Metadata/Tosca.meta refers to file %2 that is not provided.", + messageId: "SVC4610" + } +#---------SVC4611------------------------------ +# %1 - group name + GROUP_MEMBER_EMPTY: { + code: 400, + message: "Error: Invalid Content. Group %1 member list was provided but does not have values", + messageId: "SVC4611" + } +#---------SVC4612------------------------------ +# %1 - group name + GROUP_TYPE_ALREADY_EXIST: { + code: 409, + message: 'Error: Group type %1 already exists.', + messageId: "SVC4612" + } +#---------SVC4613------------------------------ +# %1 - group name +# %2 - VF name(component name) +# %3 - actual component type [VF] + GROUP_ALREADY_EXIST: { + code: 409, + message: "Error: Group with name '%1' already exists in %2 %3.", + messageId: "SVC4613" + } +#---------SVC4614------------------------------ +# %1 - group type + GROUP_TYPE_IS_INVALID: { + code: 400, + message: "Error: Invalid content. Group type %1 does not exist", + messageId: "SVC4614" + } +#---------SVC4615------------------------------ +# %1 - group name + GROUP_MISSING_GROUP_TYPE: { + code: 400, + message: "Error: Invalid Content. Missing Group Type for group '%1'", + messageId: "SVC4615" + } +#---------SVC4616------------------------------ +# %1 - member name +# %2 - group name +# %3 - VF name +# %4 - component type [VF ] + GROUP_INVALID_COMPONENT_INSTANCE: { + code: 400, + message: "Error: Member '%1' listed in group '%2' is not part of '%3' %4.", + messageId: "SVC4616" + } +#---------SVC4617------------------------------ +# %1 - member name +# %2 - group name +# %3 - group type + GROUP_INVALID_TOSCA_NAME_OF_COMPONENT_INSTANCE: { + code: 400, + message: "Error: member %1 listed in group %2 is not part of allowed members of group type %3.", + messageId: "SVC4617" + } +#---------SVC4618------------------------------ +# %1 - missing file name +# %2 - csar file name + ARTIFACT_NOT_FOUND_IN_CSAR: { + code: 400, + message: "Error: artifact %1 is defined in CSAR %2 manifest but is not provided", + messageId: "SVC4618" + } +#---------SVC4619------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - existing artifact type + ARTIFACT_ALRADY_EXIST_IN_DIFFERENT_TYPE_IN_CSAR: { + code: 400, + message: "Error: artifact %1 in type %2 already exists in type %3.", + messageId: "SVC4619" + } +#---------SVC4620------------------------------ + FAILED_RETRIVE_ARTIFACTS_TYPES: { + code: 400, + message: "Error: Failed to retrieve list of suported artifact types.", + messageId: "SVC4620" + } +#---------SVC4621------------------------------ +# %1 - artifact name +# %2 - master + ARTIFACT_ALRADY_EXIST_IN_MASTER_IN_CSAR: { + code: 400, + message: "Error: artifact %1 already exists in master %2 .", + messageId: "SVC4621" + } +#---------SVC4622------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - master name +# %4 - master type + ARTIFACT_NOT_VALID_IN_MASTER: { + code: 400, + message: "Error: artifact %1 in type %2 can not be exists under master %3 in type %4.", + messageId: "SVC4622" + } +#---------SVC4623------------------------------ +# %1 - artifact name +# %2 - artifact type +# %3 - env name +# %4 - existing env + ARTIFACT_NOT_VALID_ENV: { + code: 400, + message: "Error: Artifact %1 in type %2 with env %3 already exists with another env %4", + messageId: "SVC4623" + } +#---------SVC4624------------------------------ +# %1 - groups names +# %2 - VF name +# %3 - component type [VF ] + GROUP_IS_MISSING: { + code: 400, + message: "Error: Invalid Content. The groups '%1' cannot be found under %2 %3.", + messageId: "SVC4624" + } +#---------SVC4625------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_ASSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already associated to group '%1'.", + messageId: "SVC4625" + } +#---------SVC4626------------------------------ +# %1 - groups name + GROUP_ARTIFACT_ALREADY_DISSOCIATED: { + code: 400, + message: "Error: Invalid Content. Artifact already dissociated from group '%1'.", + messageId: "SVC4626" + } +#---------SVC4627------------------------------ +# %1 - property name +# %2 - group name +# %3 - group type name + GROUP_PROPERTY_NOT_FOUND: { + code: 400, + message: "Error: property %1 listed in group %2 is not exist in group type %3.", + messageId: "SVC4627" + } +#---------SVC4628------------------------------ +# %1 - csarUUID +# %2 - VF name + VSP_ALREADY_EXISTS: { + code: 400, + message: "Error: The VSP with UUID %1 was already imported for VF %2. Please select another or update the existing VF.", + messageId: "SVC4628" + } +#---------SVC4629------------------------------ +# %1 - VF name + MISSING_CSAR_UUID: { + code: 400, + message: "Error: The Csar UUID or payload name is missing for VF %1.", + messageId: "SVC4629" + } +#---------SVC4630------------------------------ +# %1 - VF name +# %2 - new csarUUID +# %3 - old csarUUID + RESOURCE_LINKED_TO_DIFFERENT_VSP: { + code: 400, + message: "Error: Resource %1 cannot be updated using CsarUUID %2 since the resource is linked to a different VSP with csarUUID %3.", + messageId: "SVC4630" + } +#---------SVC4631------------------------------ +# %1 - policy name + POLICY_TYPE_ALREADY_EXIST: { + code: 409, + message: "Error: Policy type %1 already exists.", + messageId: "SVC4631" + } +#---------SVC4632------------------------------ +# %1 - target name +# %2 - policy type name + TARGETS_NON_VALID: { + code: 400, + message: "Error: target %1 listed in policy type %2 is not a group or resource.", + messageId: "SVC4632" + } +#---------SVC4633------------------------------ +# %1 - policy name + TARGETS_EMPTY: { + code: 400, + message: "Error: Invalid Content. Policy %1 target list was provided but does not have values", + messageId: "SVC4633" + } +#---------SVC4634------------------------------ + DATA_TYPE_CANNOT_BE_EMPTY: { + code: 500, + message: "Error: Data types are empty. Please import the data types.", + messageId: "SVC4634" + } +#---------SVC4635------------------------------ +# %1 - csar uuid + RESOURCE_FROM_CSAR_NOT_FOUND: { + code: 400, + message: "Error: resource from csar uuid %1 not found", + messageId: "SVC4635" + } +#---------SVC4636------------------------------ +# %1 - Data type name + DATA_TYPE_CANNOT_BE_UPDATED_BAD_REQUEST: { + code: 400, + message: 'Error: Data type %1 cannot be upgraded. The new data type does not contain old properties or the type of one of the properties has been changed.', + messageId: "SVC4636" + } +#-----------SVC4637--------------------------- +#%1 - attribute name + ATTRIBUTE_NOT_FOUND: { + code: 404, + message: "Error: Requested '%1' attribute was not found.", + messageId: "SVC4637" + } +#-----------SVC4638--------------------------- +#%1 - attribute name + ATTRIBUTE_ALREADY_EXIST: { + code: 409, + message: "Error: Attribute with '%1' name already exists.", + messageId: "SVC4638" + } +#-----------SVC4639--------------------------- +#%1 - property name + PROPERTY_NAME_ALREADY_EXISTS: { + code: 409, + message: "Error: Property with '%1' name and different type already exists.", + messageId: "SVC4639" + } +#-----------SVC4640--------------------------- +#%1 - property name + INVALID_PROPERTY: { + code: 409, + message: "Error: Invalid property received.", + messageId: "SVC4640" + } +#---------SVC4641----------------------------- +#%1 - invalid filter +#%2 - valid filters + INVALID_FILTER_KEY: { + code: 400, + message: "Error: The filter %1 is not applicable. Please use one of the following filters: %2", + messageId: "SVC4641" + } +#---------SVC4642----------------------------- +#%1 - asset type +#%2 - filter + NO_ASSETS_FOUND: { + code: 404, + message: "No %1 were found to match criteria %2", + messageId: "SVC4642" + } +#---------SVC4643------------------------------ +# %1 - "Resource"/"Product" +# %2 - "sub-category name" +# %3 - "category name" + COMPONENT_SUB_CATEGORY_NOT_FOUND_FOR_CATEGORY: { + code: 404, + message: "Error: %1 sub-category '%2' not found under category '%3'.", + messageId: "SVC4643" + } +#---------SVC4644------------------------------ +# %1 - Format + CORRUPTED_FORMAT: { + code: 400, + message: "Error: %1 format is corrupted.", + messageId: "SVC4644" + } +#---------SVC4645------------------------------ +# %1 - "groupType" + INVALID_VF_MODULE_TYPE: { + code: 400, + message: "Error: Invalid group type '%1' (should be VfModule).", + messageId: "SVC4645" + } +#---------SVC4646------------------------------ +# %1 - "groupName" + INVALID_VF_MODULE_NAME: { + code: 400, + message: "Error: Invalid Content. VF Module name '%1' contains invalid characters", + messageId: "SVC4646" + } + +#---------SVC4647------------------------------ +# %1 - "modifiedName" + INVALID_VF_MODULE_NAME_MODIFICATION: { + code: 400, + message: "Error: Invalid VF Module name modification, can not modify '%1'", + messageId: "SVC4647" + } +#---------SVC4648------------------------------ +# %1 - "inputId" +# %2 - "componentId" + INPUT_IS_NOT_CHILD_OF_COMPONENT: { + code: 400, + message: "Error: Input id: '%1' is not child of component id: '%2'", + messageId: "SVC4648" + } +#---------SVC4649------------------------------ +# %1 - "groupName" + GROUP_HAS_CYCLIC_DEPENDENCY: { + code: 400, + message: "Error: The group '%1' has cyclic dependency", + messageId: "SVC4649" + } +#---------SVC4650------------------------------ +# %1 - "Component Type" +# %2 - +# %3 - error description + AAI_ARTIFACT_GENERATION_FAILED: { + code: 500, + message: "Error: %1 %2 automatic generation of artifacts failed. Description: %3", + messageId: "SVC4650" + } diff --git a/catalog-be/src/main/resources/config/logback.xml b/catalog-be/src/main/resources/config/logback.xml new file mode 100644 index 0000000000..5d5e4c670d --- /dev/null +++ b/catalog-be/src/main/resources/config/logback.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/all.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + + + + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log + + + + + + AUDIT_MARKER + + NEUTRAL + DENY + + + + + + TRANSACTION_MARKER + + NEUTRAL + DENY + + + + + INFO + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/error.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log + + + + + + + TRANSACTION_MARKER + + NEUTRAL + DENY + + + + + + + e.level.toInt() <= DEBUG.toInt() + + + DENY + NEUTRAL + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/debug.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/audit.log + + + + + + AUDIT_MARKER + + DENY + ACCEPT + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/audit.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/transaction.log + + + + + + TRANSACTION_MARKER + + DENY + ACCEPT + + + + ${log.home}/${ECOMP-component-name}/${ECOMP-subcomponent-name}/transaction.log.%i + + 1 + 10 + + + + 20MB + + + ${default-log-pattern} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/catalog-be/src/main/resources/config/neo4j-errors-configuration.yaml b/catalog-be/src/main/resources/config/neo4j-errors-configuration.yaml new file mode 100644 index 0000000000..7a0d6dbfd4 --- /dev/null +++ b/catalog-be/src/main/resources/config/neo4j-errors-configuration.yaml @@ -0,0 +1,60 @@ +# Errors +errors: + Neo_ClientError_General_ReadOnly: "This is a read only database, writing or modifying the database is not allowed." + Neo_ClientError_LegacyIndex_NoSuchIndex: "The request (directly or indirectly) referred to a index that does not exist." + Neo_ClientError_Request_Invalid: "The client provided an invalid Request." + Neo_ClientError_Request_InvalidFormat: "The client provided a request that was missing required fields, or had values that are not allowed." + Neo_ClientError_Schema_ConstraintAlreadyExists: "Unable to perform operation because it would clash with a pre-existing constraint." + Neo_ClientError_Schema_ConstraintVerificationFailure: "Unable to create constraint because data that exists in the database violates it." + Neo_ClientError_Schema_ConstraintViolation: "A constraint imposed by the database was violated." + Neo_ClientError_Schema_IllegalTokenName: "A token name, such as a label, relationship type or property key, used is not valid. Tokens cannot be empty strings and cannot be null." + Neo_ClientError_Schema_IndexAlreadyExists: "Unable to perform operation because it would clash with a pre-existing index." + Neo_ClientError_Schema_IndexBelongsToConstraint: "A requested operation can not be performed on the specified index because the index is part of a constraint. If you want to drop the index, for instance, you must drop the constraint." + Neo_ClientError_Schema_IndexLimitReached: "The maximum number of index entries supported has been reached, no more entities can be indexed." + Neo_ClientError_Schema_LabelLimitReached: "The maximum number of labels supported has been reached, no more labels can be created." + Neo_ClientError_Schema_NoSuchConstraint: "The request (directly or indirectly) referred to a constraint that does not exist." + Neo_ClientError_Schema_NoSuchIndex: "The request (directly or indirectly) referred to an index that does not exist." + Neo_ClientError_Security_AuthenticationFailed: "The client provided an incorrect username and/or password." + Neo_ClientError_Security_AuthenticationRateLimit: "The client has provided incorrect authentication details too many times in a row." + Neo_ClientError_Security_AuthorizationFailed: "The client does not have privileges to perform the operation requested." + Neo_ClientError_Statement_ArithmeticError: "Invalid use of arithmetic, such as dividing by zero." + Neo_ClientError_Statement_ConstraintViolation: "A constraint imposed by the statement is violated by the data in the database." + Neo_ClientError_Statement_EntityNotFound: "The statement is directly referring to an entity that does not exist." + Neo_ClientError_Statement_InvalidArguments: "The statement is attempting to perform operations using invalid arguments" + Neo_ClientError_Statement_InvalidSemantics: "The statement is syntactically valid, but expresses something that the database cannot do." + Neo_ClientError_Statement_InvalidSyntax: "The statement contains invalid or unsupported syntax." + Neo_ClientError_Statement_InvalidType: "The statement is attempting to perform operations on values with types that are not supported by the operation." + Neo_ClientError_Statement_NoSuchLabel: "The statement is referring to a label that does not exist." + Neo_ClientError_Statement_NoSuchProperty: "The statement is referring to a property that does not exist." + Neo_ClientError_Statement_ParameterMissing: "The statement is referring to a parameter that was not provided in the Request." + Neo_ClientError_Transaction_ConcurrentRequest: "There were concurrent requests accessing the same transaction, which is not allowed." + Neo_ClientError_Transaction_EventHandlerThrewException: "A transaction event handler threw an exception. The transaction will be rolled back." + Neo_ClientError_Transaction_HookFailed: "Transaction hook failure." + Neo_ClientError_Transaction_InvalidType: "The transaction is of the wrong type to service the Request_ For instance, a transaction that has had schema modifications performed in it cannot be used to subsequently perform data operations, and vice versa." + Neo_ClientError_Transaction_MarkedAsFailed: "Transaction was marked as both successful and failed. Failure takes precedence and so this transaction was rolled back although it may have looked like it was going to be committed" + Neo_ClientError_Transaction_UnknownId: "The request referred to a transaction that does not exist." + Neo_ClientError_Transaction_ValidationFailed: "Transaction changes did not pass validation checks" + Neo_DatabaseError_General_CorruptSchemaRule: "A malformed schema rule was encountered. Please contact your support representative." + Neo_DatabaseError_General_FailedIndex: "The request (directly or indirectly) referred to an index that is in a failed state. The index needs to be dropped and recreated manually." + Neo_DatabaseError_General_UnknownFailure: "An unknown failure occurred." + Neo_DatabaseError_Schema_ConstraintCreationFailure: "Creating a requested constraint failed." + Neo_DatabaseError_Schema_ConstraintDropFailure: "The database failed to drop a requested constraint." + Neo_DatabaseError_Schema_IndexCreationFailure: "Failed to create an index." + Neo_DatabaseError_Schema_IndexDropFailure: "The database failed to drop a requested index." + Neo_DatabaseError_Schema_NoSuchLabel: "The request accessed a label that did not exist." + Neo_DatabaseError_Schema_NoSuchPropertyKey: "The request accessed a property that does not exist." + Neo_DatabaseError_Schema_NoSuchRelationshipType: "The request accessed a relationship type that does not exist." + Neo_DatabaseError_Schema_NoSuchSchemaRule: "The request referred to a schema rule that does not exist." + Neo_DatabaseError_Statement_ExecutionFailure: "The database was unable to execute the Statement." + Neo_DatabaseError_Transaction_CouldNotBegin: "The database was unable to start the Transaction." + Neo_DatabaseError_Transaction_CouldNotCommit: "The database was unable to commit the Transaction." + Neo_DatabaseError_Transaction_CouldNotRollback: "The database was unable to roll back the Transaction." + Neo_DatabaseError_Transaction_CouldNotWriteToLog: "The database was unable to write transaction to log." + Neo_DatabaseError_Transaction_ReleaseLocksFailed: "The transaction was unable to release one or more of its locks." + Neo_TransientError_General_DatabaseUnavailable: "The database is not currently available to serve your request, refer to the database logs for more details. Retrying your request at a later time may succeed." + Neo_TransientError_Network_UnknownFailure: "An unknown network failure occurred, a retry may resolve the issue." + Neo_TransientError_Schema_ModifiedConcurrently: "The database schema was modified while this transaction was running, the transaction should be retried." + Neo_TransientError_Security_ModifiedConcurrently: "The user was modified concurrently to this Request." + Neo_TransientError_Statement_ExternalResourceFailure: "The external resource is not available" + Neo_TransientError_Transaction_AcquireLockTimeout: "The transaction was unable to acquire a lock, for instance due to a timeout or the transaction thread being interrupted." + Neo_TransientError_Transaction_DeadlockDetected: "This transaction, and at least one more transaction, has acquired locks in a way that it will wait indefinitely, and the database has aborted it. Retrying this transaction will most likely be successful." \ No newline at end of file diff --git a/catalog-be/src/main/resources/config/titan.properties b/catalog-be/src/main/resources/config/titan.properties new file mode 100644 index 0000000000..7eb57235c7 --- /dev/null +++ b/catalog-be/src/main/resources/config/titan.properties @@ -0,0 +1,10 @@ +storage.backend=cassandra +storage.hostname=localhost +storage.port=9160 + +cache.db-cache = false +cache.db-cache-clean-wait = 20 +cache.db-cache-time = 180000 +cache.db-cache-size = 0.5 + +cache.tx-cache-size = 500000 diff --git a/catalog-be/src/main/resources/elasticsearch.yml b/catalog-be/src/main/resources/elasticsearch.yml new file mode 100644 index 0000000000..b4634c8213 --- /dev/null +++ b/catalog-be/src/main/resources/elasticsearch.yml @@ -0,0 +1,393 @@ + +cluster.name: elasticsearch_1_5_2 + +discovery.zen.ping.unicast.hosts: elasticsearch_host + +http.cors.enabled: true +#plugin.types: "DeleteByQueryPlugin" +#path.home: "/home/vagrant/catalog-be/config" + +elasticSearch.transportclient: true + +transport.client.initial_nodes: + - elasticsearch_host:9300 + +##################### Elasticsearch Configuration Example ##################### + +# This file contains an overview of various configuration settings, +# targeted at operations staff. Application developers should +# consult the guide at . +# +# The installation procedure is covered at +# . +# +# Elasticsearch comes with reasonable defaults for most settings, +# so you can try it out without bothering with configuration. +# +# Most of the time, these defaults are just fine for running a production +# cluster. If you're fine-tuning your cluster, or wondering about the +# effect of certain configuration option, please _do ask_ on the +# mailing list or IRC channel [http://elasticsearch.org/community]. + +# Any element in the configuration can be replaced with environment variables +# by placing them in ${...} notation. For example: +# +# node.rack: ${RACK_ENV_VAR} + +# For information on supported formats and syntax for the config file, see +# + + +################################### Cluster ################################### + +# Cluster name identifies your cluster for auto-discovery. If you're running +# multiple clusters on the same network, make sure you're using unique names. +# +# cluster.name: elasticsearch + + +#################################### Node ##################################### + +# Node names are generated dynamically on startup, so you're relieved +# from configuring them manually. You can tie this node to a specific name: +# +# node.name: "Franz Kafka" + +# Every node can be configured to allow or deny being eligible as the master, +# and to allow or deny to store the data. +# +# Allow this node to be eligible as a master node (enabled by default): +# +# node.master: true +# +# Allow this node to store data (enabled by default): +# +# node.data: true + +# You can exploit these settings to design advanced cluster topologies. +# +# 1. You want this node to never become a master node, only to hold data. +# This will be the "workhorse" of your cluster. +# +# node.master: false +# node.data: true +# +# 2. You want this node to only serve as a master: to not store any data and +# to have free resources. This will be the "coordinator" of your cluster. +# +# node.master: true +# node.data: false +# +# 3. You want this node to be neither master nor data node, but +# to act as a "search load balancer" (fetching data from nodes, +# aggregating results, etc.) +# +# node.master: false +# node.data: false + +# Use the Cluster Health API [http://localhost:9200/_cluster/health], the +# Node Info API [http://localhost:9200/_nodes] or GUI tools +# such as , +# , +# and +# to inspect the cluster state. + +# A node can have generic attributes associated with it, which can later be used +# for customized shard allocation filtering, or allocation awareness. An attribute +# is a simple key value pair, similar to node.key: value, here is an example: +# +# node.rack: rack314 + +# By default, multiple nodes are allowed to start from the same installation location +# to disable it, set the following: +# node.max_local_storage_nodes: 1 + + +#################################### Index #################################### + +# You can set a number of options (such as shard/replica options, mapping +# or analyzer definitions, translog settings, ...) for indices globally, +# in this file. +# +# Note, that it makes more sense to configure index settings specifically for +# a certain index, either when creating it or by using the index templates API. +# +# See and +# +# for more information. + +# Set the number of shards (splits) of an index (5 by default): +# +# index.number_of_shards: 5 + +# Set the number of replicas (additional copies) of an index (1 by default): +# +# index.number_of_replicas: 1 + +# Note, that for development on a local machine, with small indices, it usually +# makes sense to "disable" the distributed features: +# +index.number_of_shards: 1 +index.number_of_replicas: 0 + +# These settings directly affect the performance of index and search operations +# in your cluster. Assuming you have enough machines to hold shards and +# replicas, the rule of thumb is: +# +# 1. Having more *shards* enhances the _indexing_ performance and allows to +# _distribute_ a big index across machines. +# 2. Having more *replicas* enhances the _search_ performance and improves the +# cluster _availability_. +# +# The "number_of_shards" is a one-time setting for an index. +# +# The "number_of_replicas" can be increased or decreased anytime, +# by using the Index Update Settings API. +# +# Elasticsearch takes care about load balancing, relocating, gathering the +# results from nodes, etc. Experiment with different settings to fine-tune +# your setup. + +# Use the Index Status API () to inspect +# the index status. + + +#################################### Paths #################################### + +# Path to directory containing configuration (this file and logging.yml): +# +path.conf: /src/test/resources +#path.home: /src/test/resources + +# Path to directory where to store index data allocated for this node. +# +path.data: target/esdata +# +# Can optionally include more than one location, causing data to be striped across +# the locations (a la RAID 0) on a file level, favouring locations with most free +# space on creation. For example: +# +# path.data: /path/to/data1,/path/to/data2 + +# Path to temporary files: +# +path.work: /target/eswork + +# Path to log files: +# +path.logs: /target/eslogs + +# Path to where plugins are installed: +# +# path.plugins: /path/to/plugins + + +#################################### Plugin ################################### + +# If a plugin listed here is not installed for current node, the node will not start. +# +# plugin.mandatory: mapper-attachments,lang-groovy + + +################################### Memory #################################### + +# Elasticsearch performs poorly when JVM starts swapping: you should ensure that +# it _never_ swaps. +# +# Set this property to true to lock the memory: +# +# bootstrap.mlockall: true + +# Make sure that the ES_MIN_MEM and ES_MAX_MEM environment variables are set +# to the same value, and that the machine has enough memory to allocate +# for Elasticsearch, leaving enough memory for the operating system itself. +# +# You should also make sure that the Elasticsearch process is allowed to lock +# the memory, eg. by using `ulimit -l unlimited`. + + +############################## Network And HTTP ############################### + +# Elasticsearch, by default, binds itself to the 0.0.0.0 address, and listens +# on port [9200-9300] for HTTP traffic and on port [9300-9400] for node-to-node +# communication. (the range means that if the port is busy, it will automatically +# try the next port). + +# Set the bind address specifically (IPv4 or IPv6): +# +# network.bind_host: 192.168.0.1 + +# Set the address other nodes will use to communicate with this node. If not +# set, it is automatically derived. It must point to an actual IP address. +# +# network.publish_host: 192.168.0.1 + +# Set both 'bind_host' and 'publish_host': +# +# network.host: 192.168.0.1 + +# Set a custom port for the node to node communication (9300 by default): +# +# transport.tcp.port: 9300 + +# Enable compression for all communication between nodes (disabled by default): +# +# transport.tcp.compress: true + +# Set a custom port to listen for HTTP traffic: +# +# http.port: 9200 + +# Set a custom allowed content length: +# +# http.max_content_length: 100mb + +# Disable HTTP completely: +# +# http.enabled: false + + +################################### Gateway ################################### + +# The gateway allows for persisting the cluster state between full cluster +# restarts. Every change to the state (such as adding an index) will be stored +# in the gateway, and when the cluster starts up for the first time, +# it will read its state from the gateway. + +# There are several types of gateway implementations. For more information, see +# . + +# The default gateway type is the "local" gateway (recommended): +# +# gateway.type: local + +# Settings below control how and when to start the initial recovery process on +# a full cluster restart (to reuse as much local data as possible when using shared +# gateway). + +# Allow recovery process after N nodes in a cluster are up: +# +gateway.recover_after_nodes: 1 + +# Set the timeout to initiate the recovery process, once the N nodes +# from previous setting are up (accepts time value): +# +# gateway.recover_after_time: 5m + +# Set how many nodes are expected in this cluster. Once these N nodes +# are up (and recover_after_nodes is met), begin recovery process immediately +# (without waiting for recover_after_time to expire): +# +gateway.expected_nodes: 1 + + +############################# Recovery Throttling ############################# + +# These settings allow to control the process of shards allocation between +# nodes during initial recovery, replica allocation, rebalancing, +# or when adding and removing nodes. + +# Set the number of concurrent recoveries happening on a node: +# +# 1. During the initial recovery +# +# cluster.routing.allocation.node_initial_primaries_recoveries: 4 +# +# 2. During adding/removing nodes, rebalancing, etc +# +# cluster.routing.allocation.node_concurrent_recoveries: 2 + +# Set to throttle throughput when recovering (eg. 100mb, by default 20mb): +# +# indices.recovery.max_bytes_per_sec: 20mb + +# Set to limit the number of open concurrent streams when +# recovering a shard from a peer: +# +# indices.recovery.concurrent_streams: 5 + + +################################## Discovery ################################## + +# Discovery infrastructure ensures nodes can be found within a cluster +# and master node is elected. Multicast discovery is the default. + +# Set to ensure a node sees N other master eligible nodes to be considered +# operational within the cluster. Its recommended to set it to a higher value +# than 1 when running more than 2 nodes in the cluster. +# +# discovery.zen.minimum_master_nodes: 1 + +# Set the time to wait for ping responses from other nodes when discovering. +# Set this option to a higher value on a slow or congested network +# to minimize discovery failures: +# +# discovery.zen.ping.timeout: 3s + +# For more information, see +# + +# Unicast discovery allows to explicitly control which nodes will be used +# to discover the cluster. It can be used when multicast is not present, +# or to restrict the cluster communication-wise. +# +# 1. Disable multicast discovery (enabled by default): +# +# discovery.zen.ping.multicast.enabled: false +# +# 2. Configure an initial list of master nodes in the cluster +# to perform discovery when new nodes (master or data) are started: +# +# discovery.zen.ping.unicast.hosts: ["host1", "host2:port"] + +# EC2 discovery allows to use AWS EC2 API in order to perform discovery. +# +# You have to install the cloud-aws plugin for enabling the EC2 discovery. +# +# For more information, see +# +# +# See +# for a step-by-step tutorial. + +# GCE discovery allows to use Google Compute Engine API in order to perform discovery. +# +# You have to install the cloud-gce plugin for enabling the GCE discovery. +# +# For more information, see . + +# Azure discovery allows to use Azure API in order to perform discovery. +# +# You have to install the cloud-azure plugin for enabling the Azure discovery. +# +# For more information, see . + +################################## Slow Log ################################## + +# Shard level query and fetch threshold logging. + +#index.search.slowlog.threshold.query.warn: 10s +#index.search.slowlog.threshold.query.info: 5s +#index.search.slowlog.threshold.query.debug: 2s +#index.search.slowlog.threshold.query.trace: 500ms + +#index.search.slowlog.threshold.fetch.warn: 1s +#index.search.slowlog.threshold.fetch.info: 800ms +#index.search.slowlog.threshold.fetch.debug: 500ms +#index.search.slowlog.threshold.fetch.trace: 200ms + +#index.indexing.slowlog.threshold.index.warn: 10s +#index.indexing.slowlog.threshold.index.info: 5s +#index.indexing.slowlog.threshold.index.debug: 2s +#index.indexing.slowlog.threshold.index.trace: 500ms + +################################## GC Logging ################################ + +#monitor.jvm.gc.young.warn: 1000ms +#monitor.jvm.gc.young.info: 700ms +#monitor.jvm.gc.young.debug: 400ms + +#monitor.jvm.gc.old.warn: 10s +#monitor.jvm.gc.old.info: 5s +#monitor.jvm.gc.old.debug: 2s + diff --git a/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.yml b/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.yml new file mode 100644 index 0000000000..d8d9f20d40 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.yml @@ -0,0 +1,204 @@ +tosca.capabilities.Root: + description: The TOSCA root Capability Type all other TOSCA base Capability Types derive from +tosca.capabilities.Attachment: + derived_from: tosca.capabilities.Root +tosca.capabilities.Node: + derived_from: tosca.capabilities.Root +tosca.capabilities.Container: + derived_from: tosca.capabilities.Root + properties: + num_cpus: + type: integer + required: false + constraints: + - greater_or_equal: 1 + cpu_frequency: + type: scalar-unit.frequency + required: false + constraints: + - greater_or_equal: 0.1 GHz + disk_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB + mem_size: + type: scalar-unit.size + required: false + constraints: + - greater_or_equal: 0 MB +tosca.capabilities.Endpoint: + derived_from: tosca.capabilities.Root + properties: + protocol: + type: string + default: tcp + port: + type: PortDef + required: false + secure: + type: boolean + default: false + url_path: + type: string + required: false + port_name: + type: string + required: false + network_name: + type: string + required: false + default: PRIVATE + initiator: + type: string + default: source + constraints: + - valid_values: [ source, target, peer ] + ports: + type: map + required: false + constraints: + - min_length: 1 + entry_schema: + type: PortSpec + attributes: + ip_address: + type: string +tosca.capabilities.DatabaseEndpoint: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.Endpoint.Public: + derived_from: tosca.capabilities.Endpoint + properties: + # Change the default network_name to use the first public network found + network_name: PUBLIC + floating: + description: > + indicates that the public address should be allocated from a pool of floating IPs that are associated with the network. + type: boolean + default: false + status: experimental + dns_name: + description: The optional name to register with DNS + type: string + required: false + status: experimental +tosca.capabilities.Endpoint.Admin: + derived_from: tosca.capabilities.Endpoint + # Change Endpoint secure indicator to true from its default of false + properties: + secure: true +tosca.capabilities.Endpoint.Database: + derived_from: tosca.capabilities.Endpoint +tosca.capabilities.OperatingSystem: + derived_from: tosca.capabilities.Root + properties: + architecture: + type: string + required: false + type: + type: string + required: false + distribution: + type: string + required: false + version: + type: version + required: false +tosca.capabilities.Scalable: + derived_from: tosca.capabilities.Root + properties: + min_instances: + type: integer + default: 1 + max_instances: + type: integer + default: 1 + default_instances: + type: integer +tosca.capabilities.network.Bindable: + derived_from: tosca.capabilities.Node + + +tosca.capabilities.Container.Docker: + derived_from: tosca.capabilities.Container + properties: + version: + type: list + required: false + entry_schema: version + publish_all: + type: boolean + default: false + required: false + publish_ports: + type: list + entry_schema: PortSpec + required: false + expose_ports: + type: list + entry_schema: PortSpec + required: false + volumes: + type: list + entry_schema: string + required: false +tosca.capabilities.network.Linkable: + derived_from: tosca.capabilities.Root +tosca.capabilities.nfv.Metric: + derived_from: tosca.capabilities.Endpoint +org.openecomp.capabilities.Metric: + derived_from: tosca.capabilities.nfv.Metric + description: A node type that includes the Metric capability indicates that it can be monitored. + properties: + unit: + type: string + description: Unit of the metric value + required: true + status: SUPPORTED + description: + type: string + description: Description of the metric + required: false + status: SUPPORTED + type: + type: string + description: Type of the metric value, for an example, Cumulative, Delta, Gauge and etc. + required: true + status: SUPPORTED + category: + type: string + description: Category of the metric, for an example, compute, disk, network, storage and etc. + required: false + status: SUPPORTED + attributes: + value: + type: string + description: Runtime monitored value + status: SUPPORTED +org.openecomp.capabilities.metric.Ceilometer: + derived_from: org.openecomp.capabilities.Metric + description: A node type that includes the Metric capability indicates that it can be monitored using ceilometer. + properties: + name: + type: string + description: Ceilometer metric type name to monitor. (The name ceilometer is using) + required: true + status: SUPPORTED +org.openecomp.capabilities.metric.SnmpPolling: + derived_from: org.openecomp.capabilities.Metric + description: A node type that includes the Metric capability indicates that it can be monitored using snmp polling. + properties: + oid: + type: string + description: Object Id of the metric + required: true + status: SUPPORTED +org.openecomp.capabilities.metric.SnmpTrap: + derived_from: org.openecomp.capabilities.Metric + description: A node type that includes the Metric capability indicates that it can be monitored using snmp trap. + properties: + oid: + type: string + description: Object Id of the metric + required: true + status: SUPPORTED diff --git a/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.zip b/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.zip new file mode 100644 index 0000000000..add3a8ce1f Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/capability-types/capabilityTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.yml b/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.yml new file mode 100644 index 0000000000..9ddce45e4e --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.yml @@ -0,0 +1,116 @@ +services: + Mobility: + name: "Mobility" + icons: ['mobility'] + Network_L1_3: + name: "Network L1-3" + icons: ['network_l_1-3'] + Network_L4: + name: "Network L4+" + icons: ['network_l_4'] + VoIP_Call_Control: + name: "VoIP Call Control" + icons: ['call_controll'] +resources: + NetworkLayer23: + name: "Network L2-3" + subcategories: + Router: + name: "Router" + icons: ['router','vRouter'] + Gateway: + name: "Gateway" + icons: ['gateway'] + WAN_Connectors: + name: "WAN Connectors" + icons: ['network','connector','port'] + LAN_Connectors: + name: "LAN Connectors" + icons: ['network','connector','port'] + Infrastructure: + name: "Infrastructure" + icons: ['ucpe'] + NetworkLayer4: + name: "Network L4+" + subcategories: + Common_Network_Resources: + name: "Common Network Resources" + icons: ['network'] + ApplicationLayer4: + name: "Application L4+" + subcategories: + Border_Element: + name: "Border Element" + icons: ['borderElement'] + Application_Server: + name: "Application Server" + icons: ['applicationServer'] + Web_Server: + name: "Web Server" + icons: ['applicationServer'] + Call_Control: + name: "Call Control" + icons: ['call_controll'] + Media_Servers: + name: "Media Servers" + icons: ['applicationServer'] + Load_Balancer: + name: "Load Balancer" + icons: ['loadBalancer'] + Database: + name: "Database" + icons: ['database'] + Firewall: + name: "Firewall" + icons: ['firewall'] + Generic: + name: "Generic" + subcategories: + Infrastructure: + name: "Infrastructure" + icons: ['connector'] + Abstract: + name: "Abstract" + icons: ['objectStorage', 'compute'] + Network_Elements: + name: "Network Elements" + icons: ['network', 'connector'] + Database: + name: "Database" + icons: ['database'] + Rules: + name: "Rules" + icons: ['networkrules','securityrules'] + NetworkConnectivity: + name: "Network Connectivity" + subcategories: + ConnectionPoints: + name: "Connection Points" + icons: ['cp'] + VirtualLinks: + name: "Virtual Links" + icons: ['vl'] + DcaeComponent: + name: "DCAE Component" + subcategories: + Source: + name: "Source" + icons: ['dcae_source'] + Collector: + name: "Collector" + icons: ['dcae_collector'] + Utility: + name: "Utility" + icons: ['dcae_utilty'] + Microservice: + name: "Microservice" + icons: ['dcae_microservice'] + Analytics: + name: "Analytics" + icons: ['dcae_analytics'] + Database: + name: "Database" + icons: ['dcae_database'] + Policy: + name: "Policy" + icons: ['dcae_policy'] \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.zip b/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.zip new file mode 100644 index 0000000000..c04a2faefc Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/categories/categoryTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.yml b/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.yml new file mode 100644 index 0000000000..1fdc3a2cd2 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.yml @@ -0,0 +1,821 @@ +tosca.datatypes.Root: + description: The TOSCA root Data Type all other TOSCA base Data Types derive from + +integer: + derived_from: tosca.datatypes.Root + +string: + derived_from: tosca.datatypes.Root + +boolean: + derived_from: tosca.datatypes.Root + +float: + derived_from: tosca.datatypes.Root + +json: + derived_from: tosca.datatypes.Root + +list: + derived_from: tosca.datatypes.Root + +map: + derived_from: tosca.datatypes.Root + +tosca.datatypes.Credential: + derived_from: tosca.datatypes.Root + properties: + protocol: + type: string + required: false + token_type: + type: string + default: password + token: + type: string + keys: + type: map + required: false + entry_schema: + type: string + user: + type: string + required: false + +tosca.datatypes.TimeInterval: + derived_from: tosca.datatypes.Root + properties: + start_time: + type: timestamp + required: true + end_time: + type: timestamp + required: true + +tosca.datatypes.network.NetworkInfo: + derived_from: tosca.datatypes.Root + properties: + network_name: + type: string + network_id: + type: string + addresses: + type: list + entry_schema: + type: string + +tosca.datatypes.network.PortInfo: + derived_from: tosca.datatypes.Root + properties: + port_name: + type: string + port_id: + type: string + network_id: + type: string + mac_address: + type: string + addresses: + type: list + entry_schema: + type: string + +tosca.datatypes.network.PortDef: + derived_from: integer + constraints: + - in_range: [ 1, 65535 ] + +tosca.datatypes.network.PortSpec: + derived_from: tosca.datatypes.Root + properties: + protocol: + type: string + required: true + default: tcp + constraints: + - valid_values: [ udp, tcp, igmp ] + target: + type: tosca.datatypes.network.PortDef + target_range: + type: range + constraints: + - in_range: [ 1, 65535 ] + source: + type: tosca.datatypes.network.PortDef + source_range: + type: range + constraints: + - in_range: [ 1, 65535 ] + + + +org.openecomp.datatypes.heat.network.AddressPair: + derived_from: tosca.datatypes.Root + description: MAC/IP address pairs + properties: + mac_address: + type: string + description: MAC address + required: false + status: SUPPORTED + ip_address: + type: string + description: IP address + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.network.subnet.HostRoute: + derived_from: tosca.datatypes.Root + description: Host route info for the subnet + properties: + destination: + type: string + description: The destination for static route + required: false + status: SUPPORTED + nexthop: + type: string + description: The next hop for the destination + required: false + status: SUPPORTED + +org.openecomp.datatypes.heat.network.AllocationPool: + derived_from: tosca.datatypes.Root + description: The start and end addresses for the allocation pool + properties: + start: + type: string + description: Start address for the allocation pool + required: false + status: SUPPORTED + end: + type: string + description: End address for the allocation pool + required: false + status: SUPPORTED + +org.openecomp.datatypes.heat.network.neutron.Subnet: + derived_from: tosca.datatypes.Root + description: A subnet represents an IP address block that can be used for assigning IP addresses to virtual instances + properties: + tenant_id: + type: string + description: The ID of the tenant who owns the network + required: false + status: SUPPORTED + enable_dhcp: + type: boolean + description: Set to true if DHCP is enabled and false if DHCP is disabled + required: false + default: true + status: SUPPORTED + ipv6_address_mode: + type: string + description: IPv6 address mode + required: false + status: SUPPORTED + constraints: + - valid_values: + - dhcpv6-stateful + - dhcpv6-stateless + - slaac + ipv6_ra_mode: + type: string + description: IPv6 RA (Router Advertisement) mode + required: false + status: SUPPORTED + constraints: + - valid_values: + - dhcpv6-stateful + - dhcpv6-stateless + - slaac + value_specs: + type: map + description: Extra parameters to include in the request + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string + allocation_pools: + type: list + description: The start and end addresses for the allocation pools + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.AllocationPool + subnetpool: + type: string + description: The name or ID of the subnet pool + required: false + status: SUPPORTED + dns_nameservers: + type: list + description: A specified set of DNS name servers to be used + required: false + default: [ + ] + status: SUPPORTED + entry_schema: + type: string + host_routes: + type: list + description: The gateway IP address + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.subnet.HostRoute + ip_version: + type: integer + description: The gateway IP address + required: false + default: 4 + status: SUPPORTED + constraints: + - valid_values: + - '4' + - '6' + name: + type: string + description: The name of the subnet + required: false + status: SUPPORTED + prefixlen: + type: integer + description: Prefix length for subnet allocation from subnet pool + required: false + status: SUPPORTED + constraints: + - greater_or_equal: 0 + cidr: + type: string + description: The CIDR + required: false + status: SUPPORTED + gateway_ip: + type: string + description: The gateway IP address + required: false + status: SUPPORTED + +org.openecomp.datatypes.heat.novaServer.network.PortExtraProperties: + derived_from: tosca.datatypes.Root + description: Nova server network expand properties for port + properties: + port_security_enabled: + type: boolean + description: Flag to enable/disable port security on the port + required: false + status: SUPPORTED + mac_address: + type: string + description: MAC address to give to this port + required: false + status: SUPPORTED + admin_state_up: + type: boolean + description: The administrative state of this port + required: false + default: true + status: SUPPORTED + qos_policy: + type: string + description: The name or ID of QoS policy to attach to this port + required: false + status: SUPPORTED + allowed_address_pairs: + type: list + description: Additional MAC/IP address pairs allowed to pass through the port + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.AddressPair + binding:vnic_type: + type: string + description: The vnic type to be bound on the neutron port + required: false + status: SUPPORTED + constraints: + - valid_values: + - macvtap + - direct + - normal + value_specs: + type: map + description: Extra parameters to include in the request + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string +org.openecomp.datatypes.heat.novaServer.network.AddressInfo: + derived_from: tosca.datatypes.network.NetworkInfo + description: Network addresses with corresponding port id + properties: + port_id: + type: string + description: Port id + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.neutron.port.FixedIps: + derived_from: tosca.datatypes.Root + description: subnet/ip_address + properties: + subnet: + type: string + description: Subnet in which to allocate the IP address for this port + required: false + status: SUPPORTED + ip_address: + type: string + description: IP address desired in the subnet for this port + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.FileInfo: + derived_from: tosca.datatypes.Root + description: Heat File Info + properties: + file: + type: string + description: The required URI string (relative or absolute) which can be used to locate the file + required: true + status: SUPPORTED + file_type: + type: string + description: The type of the file + required: true + status: SUPPORTED + constraints: + - valid_values: + - base + - env + - volume + - network +org.openecomp.datatypes.heat.contrail.network.rule.PortPairs: + derived_from: tosca.datatypes.Root + description: source and destination port pairs + properties: + start_port: + type: string + description: Start port + required: false + status: SUPPORTED + end_port: + type: string + description: End port + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrail.network.rule.Rule: + derived_from: tosca.datatypes.Root + description: policy rule + properties: + src_ports: + type: list + description: Source ports + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrail.network.rule.PortPairs + protocol: + type: string + description: Protocol + required: false + status: SUPPORTED + dst_addresses: + type: list + description: Destination addresses + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrail.network.rule.VirtualNetwork + apply_service: + type: string + description: Service to apply + required: false + status: SUPPORTED + dst_ports: + type: list + description: Destination ports + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrail.network.rule.PortPairs + src_addresses: + type: list + description: Source addresses + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrail.network.rule.VirtualNetwork + direction: + type: string + description: Direction + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrail.network.rule.RuleList: + derived_from: tosca.datatypes.Root + description: list of policy rules + properties: + policy_rule: + type: list + description: Contrail network rule + required: false + status: SUPPORTED + entry_schema: + type: corg.openecomp.datatypes.heat.contrail.network.rule.Rule +org.openecomp.datatypes.heat.contrail.network.rule.VirtualNetwork: + derived_from: tosca.datatypes.Root + description: source and destination addresses + properties: + virtual_network: + type: string + description: Virtual network + required: false + status: SUPPORTED + +org.openecomp.datatypes.heat.network.neutron.SecurityRules.Rule: + derived_from: tosca.datatypes.Root + description: Rules Pairs + properties: + remote_group_id: + type: string + description: The remote group ID to be associated with this security group rule + required: false + status: SUPPORTED + protocol: + type: string + description: The protocol that is matched by the security group rule + required: false + status: SUPPORTED + constraints: + - valid_values: + - tcp + - udp + - icmp + ethertype: + type: string + description: Ethertype of the traffic + required: false + default: IPv4 + status: SUPPORTED + constraints: + - valid_values: + - IPv4 + - IPv6 + port_range_max: + type: integer + description: 'The maximum port number in the range that is matched by the + security group rule. ' + required: false + status: SUPPORTED + constraints: + - in_range: + - 0 + - 65535 + remote_ip_prefix: + type: string + description: The remote IP prefix (CIDR) to be associated with this security group rule + required: false + status: SUPPORTED + remote_mode: + type: string + description: Whether to specify a remote group or a remote IP prefix + required: false + default: remote_ip_prefix + status: SUPPORTED + constraints: + - valid_values: + - remote_ip_prefix + - remote_group_id + direction: + type: string + description: The direction in which the security group rule is applied + required: false + default: ingress + status: SUPPORTED + constraints: + - valid_values: + - egress + - ingress + port_range_min: + type: integer + description: The minimum port number in the range that is matched by the security group rule. + required: false + status: SUPPORTED + constraints: + - in_range: + - 0 + - 65535 +org.openecomp.datatypes.heat.substitution.SubstitutionFiltering: + derived_from: tosca.datatypes.Root + description: Substitution Filter + properties: + substitute_service_template: + type: string + description: Substitute Service Template + required: true + status: SUPPORTED + index_value: + type: integer + description: Index value of the substitution service template runtime instance + required: false + default: 0 + status: SUPPORTED + constraints: + - greater_or_equal: 0 + count: + type: string + description: Count + required: false + default: 1 + status: SUPPORTED + scaling_enabled: + type: boolean + description: Indicates whether service scaling is enabled + required: false + default: true + status: SUPPORTED + mandatory: + type: boolean + description: Mandatory + required: false + default: true + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.RefDataSequence: + derived_from: tosca.datatypes.Root + description: network policy refs data sequence + properties: + network_policy_refs_data_sequence_major: + type: integer + description: Network Policy ref data sequence Major + required: false + status: SUPPORTED + network_policy_refs_data_sequence_minor: + type: integer + description: Network Policy ref data sequence Minor + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.RefData: + derived_from: tosca.datatypes.Root + description: network policy refs data + properties: + network_policy_refs_data_sequence: + type: org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.RefDataSequence + description: Network Policy ref data sequence + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.ref.data.IpamSubnet: + derived_from: tosca.datatypes.Root + description: Network Ipam Ref Data Subnet + properties: + network_ipam_refs_data_ipam_subnets_subnet_ip_prefix_len: + type: string + description: Network ipam refs data ipam subnets ip prefix len + required: false + status: SUPPORTED + network_ipam_refs_data_ipam_subnets_subnet_ip_prefix: + type: string + description: Network ipam refs data ipam subnets ip prefix + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.ref.data.IpamSubnetList: + derived_from: tosca.datatypes.Root + description: Network Ipam Ref Data Subnet List + properties: + network_ipam_refs_data_ipam_subnets_subnet: + type: org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.ref.data.IpamSubnet + description: Network ipam refs data ipam subnets + required: false + status: SUPPORTED + network_ipam_refs_data_ipam_subnets_addr_from_start: + type: string + description: Network ipam refs data ipam subnets addr from start + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.IpamRefData: + derived_from: tosca.datatypes.Root + description: Network Ipam Ref Data + properties: + network_ipam_refs_data_ipam_subnets: + type: list + description: Network ipam refs data ipam subnets + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.ref.data.IpamSubnetList +org.openecomp.datatypes.heat.contrailV2.network.rule.SrcVirtualNetwork: + derived_from: tosca.datatypes.Root + description: source addresses + properties: + network_policy_entries_policy_rule_src_addresses_virtual_network: + type: string + description: Source addresses Virtual network + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.network.rule.DstVirtualNetwork: + derived_from: tosca.datatypes.Root + description: destination addresses + properties: + network_policy_entries_policy_rule_dst_addresses_virtual_network: + type: string + description: Destination addresses Virtual network + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.network.rule.DstPortPairs: + derived_from: tosca.datatypes.Root + description: destination port pairs + properties: + network_policy_entries_policy_rule_dst_ports_start_port: + type: string + description: Start port + required: false + status: SUPPORTED + network_policy_entries_policy_rule_dst_ports_end_port: + type: string + description: End port + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.network.rule.SrcPortPairs: + derived_from: tosca.datatypes.Root + description: source port pairs + properties: + network_policy_entries_policy_rule_src_ports_start_port: + type: string + description: Start port + required: false + status: SUPPORTED + network_policy_entries_policy_rule_src_ports_end_port: + type: string + description: End port + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.network.rule.ActionList: + derived_from: tosca.datatypes.Root + description: Action List + properties: + network_policy_entries_policy_rule_action_list_simple_action: + type: string + description: Simple Action + required: false + status: SUPPORTED + network_policy_entries_policy_rule_action_list_apply_service: + type: list + description: Apply Service + required: false + status: SUPPORTED + entry_schema: + type: string +org.openecomp.datatypes.heat.contrailV2.network.rule.ActionList: + derived_from: tosca.datatypes.Root + description: Action List + properties: + network_policy_entries_policy_rule_action_list_simple_action: + type: string + description: Simple Action + required: false + status: SUPPORTED + network_policy_entries_policy_rule_action_list_apply_service: + type: list + description: Apply Service + required: false + status: SUPPORTED + entry_schema: + type: string +org.openecomp.datatypes.heat.contrailV2.network.rule.Rule: + derived_from: tosca.datatypes.Root + description: policy rule + properties: + network_policy_entries_policy_rule_dst_addresses: + type: list + description: Destination addresses + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.DstVirtualNetwork + network_policy_entries_policy_rule_dst_ports: + type: list + description: Destination ports + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.DstPortPairs + network_policy_entries_policy_rule_protocol: + type: string + description: Protocol + required: false + status: SUPPORTED + network_policy_entries_policy_rule_src_addresses: + type: list + description: Source addresses + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.SrcVirtualNetwork + network_policy_entries_policy_rule_direction: + type: string + description: Direction + required: false + status: SUPPORTED + network_policy_entries_policy_rule_src_ports: + type: list + description: Source ports + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.SrcPortPairs + network_policy_entries_policy_rule_action_list: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.ActionList + description: Action list + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.network.rule.RuleList: + derived_from: tosca.datatypes.Root + description: list of policy rules + properties: + network_policy_entries_policy_rule: + type: list + description: Contrail network rule + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.Rule +org.openecomp.datatypes.heat.network.contrail.port.StaticRoute: + derived_from: tosca.datatypes.Root + description: static route + properties: + prefix: + type: string + description: Route prefix + required: false + status: SUPPORTED + next_hop: + type: string + description: Next hop + required: false + status: SUPPORTED + next_hop_type: + type: string + description: Next hop type + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.network.contrail.AddressPair: + derived_from: tosca.datatypes.Root + description: Address Pair + properties: + address_mode: + type: string + description: Address mode active-active or active-standy + required: false + status: SUPPORTED + constraints: + - valid_values: + - active-active + - active-standby + prefix: + type: string + description: IP address prefix + required: false + status: SUPPORTED + mac_address: + type: string + description: Mac address + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.network.contrail.InterfaceData: + derived_from: tosca.datatypes.Root + description: Interface Data + properties: + static_routes: + type: list + description: An ordered list of static routes to be added to this interface + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.contrail.port.StaticRoute + virtual_network: + type: string + description: Virtual Network for this interface + required: true + status: SUPPORTED + allowed_address_pairs: + type: list + description: List of allowed address pair for this interface + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.contrail.AddressPair + ip_address: + type: string + description: IP for this interface + required: false + status: SUPPORTED +org.openecomp.datatypes.heat.contrailV2.virtual.machine.interface.Properties: + derived_from: tosca.datatypes.Root + description: Virtual Machine Interface Properties. + properties: + virtual_machine_interface_properties_service_interface_type: + type: string + description: Service Interface Type. + required: false + status: SUPPORTED \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.zip b/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.zip new file mode 100644 index 0000000000..2249a8bd5c Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/data-types/dataTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.yml b/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.yml new file mode 100644 index 0000000000..1df2cbdd04 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.yml @@ -0,0 +1,30 @@ +org.openecomp.groups.heat.HeatStack: + derived_from: tosca.groups.Root + description: Grouped all heat resources which are in the same heat stack + properties: + heat_file: + type: string + description: Heat file which associate to this group/heat stack + required: true + status: SUPPORTED + description: + type: string + description: group description + required: true + status: SUPPORTED +org.openecomp.groups.VfModule: + derived_from: tosca.groups.Root + description: Grouped all heat resources which are in the same VF Module + properties: + isBase: + type: boolean + description: Whether this module should be deployed before other modules + required: true + default: false + status: SUPPORTED +tosca.groups.Root: + description: The TOSCA Group Type all other TOSCA Group Types derive from + interfaces: + Standard: + type: tosca.interfaces.node.lifecycle.Standard + diff --git a/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.zip b/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.zip new file mode 100644 index 0000000000..e386507c92 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/group-types/groupTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.json b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.json new file mode 100644 index 0000000000..40f96f466e --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.json @@ -0,0 +1,21 @@ +{ + "payloadName": "abstractSubstitute.yml", + "contactId": "jh0003", + "name": "AbstractSubstitute", + "description": "Abstract node to be derived by nested elements.", + "resourceIconPath": "defaulticon", + "resourceType": "VFC", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "AbstractSubstitute" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.yml b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.yml new file mode 100644 index 0000000000..48db2b609a --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: AbstractSubstituteGlobalTypes + template_version: 1.0.0 +description: Abstract Substitute Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.abstract.nodes.AbstractSubstitute: + derived_from: tosca.nodes.Root + properties: + service_template_filter: + type: org.openecomp.datatypes.heat.substitution.SubstitutionFiltering + description: Substitution Filter + required: true + status: SUPPORTED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.zip b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.zip new file mode 100644 index 0000000000..07e4941e6b Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/abstractSubstitute/abstractSubstitute.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.json b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.json new file mode 100644 index 0000000000..249ee0f959 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.json @@ -0,0 +1,20 @@ +{ + "payloadName": "cinderVolume.yml", + "contactId": "jh0003", + "name": "CinderVolume", + "description": "Represents a server-local block storage device that provides persistent storage to guest virtual machines. ", + "resourceIconPath": "objectStorage", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "CinderVolume" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.yml b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.yml new file mode 100644 index 0000000000..3bb227d1ec --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.yml @@ -0,0 +1,177 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: CinderVolumeGlobalTypes + template_version: 1.0.0 +description: Cinder Volume TOSCA Global Types +relationship_types: + org.openecomp.relationships.cinder.VolumeAttachesTo: + derived_from: tosca.relationships.AttachesTo + description: This type represents an attachment relationship for associating volume + properties: + volume_id: + type: string + description: The ID of the volume to be attached + required: true + status: SUPPORTED + location: + type: string + description: The location where the volume is exposed on the instance, mountpoint + required: false + status: SUPPORTED + instance_uuid: + type: string + description: The ID of the server to which the volume attaches + required: true + status: SUPPORTED + attributes: + show: + type: string + description: Detailed information about resource + status: SUPPORTED +node_types: + org.openecomp.resource.vfc.nodes.heat.cinder.Volume: + derived_from: tosca.nodes.BlockStorage + properties: + availability_zone: + type: string + description: The availability zone in which the volume will be created + required: false + status: SUPPORTED + image: + type: string + description: If specified, the name or ID of the image to create the volume from + required: false + status: SUPPORTED + metadata: + type: map + description: Key/value pairs to associate with the volume + required: false + status: SUPPORTED + entry_schema: + type: string + volume_type: + type: string + description: If specified, the type of volume to use, mapping to a specific backend + required: false + status: SUPPORTED + description: + type: string + description: A description of the volume + required: false + status: SUPPORTED + device_type: + type: string + description: Device type + required: false + status: SUPPORTED + constraints: + - valid_values: + - cdrom + - disk + disk_bus: + type: string + description: 'Bus of the device: hypervisor driver chooses a suitable default if omitted' + required: false + status: SUPPORTED + constraints: + - valid_values: + - ide + - lame_bus + - scsi + - usb + - virtio + backup_id: + type: string + description: If specified, the backup to create the volume from + required: false + status: SUPPORTED + source_volid: + type: string + description: If specified, the volume to use as source + required: false + status: SUPPORTED + boot_index: + type: integer + description: Integer used for ordering the boot disks + required: false + status: SUPPORTED + size: + type: scalar-unit.size + description: The requested storage size (default unit is MB) + required: false + status: SUPPORTED + constraints: + - greater_or_equal: 1 GB + read_only: + type: boolean + description: Enables or disables read-only access mode of volume + required: false + status: SUPPORTED + name: + type: string + description: A name used to distinguish the volume + required: false + status: SUPPORTED + scheduler_hints: + type: map + description: Arbitrary key-value pairs specified by the client to help the Cinder scheduler creating a volume + required: false + status: SUPPORTED + entry_schema: + type: string + swap_size: + type: scalar-unit.size + description: The size of the swap, in MB + required: false + status: SUPPORTED + delete_on_termination: + type: boolean + description: Indicate whether the volume should be deleted when the server is terminated + required: false + status: SUPPORTED + multiattach: + type: boolean + description: Whether allow the volume to be attached more than once + required: false + status: SUPPORTED + attributes: + display_description: + type: string + description: Description of the volume + status: SUPPORTED + attachments: + type: string + description: The list of attachments of the volume + status: SUPPORTED + entry_schema: + type: string + encrypted: + type: boolean + description: Boolean indicating if the volume is encrypted or not + status: SUPPORTED + show: + type: string + description: Detailed information about resource + status: SUPPORTED + created_at: + type: timestamp + description: The timestamp indicating volume creation + status: SUPPORTED + display_name: + type: string + description: Name of the volume + status: SUPPORTED + metadata_values: + type: map + description: Key/value pairs associated with the volume in raw dict form + status: SUPPORTED + entry_schema: + type: string + bootable: + type: boolean + description: Boolean indicating if the volume can be booted or not + status: SUPPORTED + status: + type: string + description: The current status of the volume + status: SUPPORTED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.zip b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.zip new file mode 100644 index 0000000000..88506743ac Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/cinderVolume/cinderVolume.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.json new file mode 100644 index 0000000000..5742445784 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.json @@ -0,0 +1,17 @@ +{ + "payloadName": "contrailAbstractSubstitute.yml", + "contactId": "jh0003", + "name": "ContrailAbstractSubstitute", + "description": "Abstract node to be derived by contrail nested elements when using Contrail Service Instance", + "resourceIconPath": "defaulticon", + "resourceType": "VFC", + "categories": [{ + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + }], + "tags": ["ContrailAbstractSubstitute"] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.yml new file mode 100644 index 0000000000..5bdee932a3 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.yml @@ -0,0 +1,137 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailAbstractSubstituteGlobalTypes + template_version: 1.0.0 +description: Contrail Abstract Substitute Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.abstract.nodes.contrail.AbstractSubstitute: + derived_from: org.openecomp.resource.abstract.nodes.AbstractSubstitute + properties: + availability_zone: + type: string + description: Availability zone to create servers in + required: false + status: SUPPORTED + static_routes_list: + type: list + description: Static routes enabled + required: false + status: SUPPORTED + entry_schema: + type: boolean + availability_zone_enable: + type: boolean + description: Indicates availability zone is enabled + required: false + default: false + status: SUPPORTED + service_template_name: + type: string + description: Service template name + required: false + status: SUPPORTED + ordered_interfaces: + type: boolean + description: Indicates if service interface are ordered + required: false + default: false + status: SUPPORTED + flavor: + type: string + description: flavor + required: false + status: SUPPORTED + image_name: + type: string + description: Image name + required: true + status: SUPPORTED + service_type: + type: string + description: Service type + required: true + status: SUPPORTED + constraints: + - valid_values: + - firewall + - analyzer + - source-nat + - loadbalancer + service_interface_type_list: + type: list + description: List of interface types + required: true + status: SUPPORTED + entry_schema: + type: string + constraints: + - valid_values: + - management + - left + - right + - other + service_instance_name: + type: string + description: Service instance name + required: true + status: SUPPORTED + interface_list: + type: list + description: List of interfaces + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.contrail.InterfaceData + service_mode: + type: string + description: Service mode + required: true + status: SUPPORTED + constraints: + - valid_values: + - transparent + - in-network + - in-network-nat + shared_ip_list: + type: list + description: Shared ips enabled + required: false + status: SUPPORTED + entry_schema: + type: boolean + attributes: + tenant_id: + type: string + description: Tenant id of the Service Instance + status: SUPPORTED + fq_name: + type: string + description: The FQ name of the service instance + status: SUPPORTED + service_template_name: + type: string + description: Service Template of the Service Instance + status: SUPPORTED + show: + type: string + description: All attributes + status: SUPPORTED + active_vms: + type: string + description: Number of service VMs active for this Service Instance + status: SUPPORTED + service_instance_name: + type: string + description: The name of the service instance + status: SUPPORTED + virtual_machines: + type: string + description: Service VMs for the Service Instance + status: SUPPORTED + status: + type: string + description: Status of the service instance + status: SUPPORTED \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.zip new file mode 100644 index 0000000000..6a2094bb9a Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailAbstractSubstitute/contrailAbstractSubstitute.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.json new file mode 100644 index 0000000000..144136acd1 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.json @@ -0,0 +1,15 @@ +{ + "payloadName": "contrailCompute.yml", + "contactId": "jh0003", + "name": "ContrailCompute", + "description": "Represents a virtual machine for contrail service template. The information provided will be used to create a VM that matches characteristics.", + "resourceIconPath": "compute", + "resourceType": "VFC", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Infrastructure" + }] + }], + "tags": ["ContrailCompute"] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.yml new file mode 100644 index 0000000000..d6ad4f953c --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.yml @@ -0,0 +1,89 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailComputeGlobalTypes + template_version: 1.0.0 +description: Contrail Compute TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vfc.nodes.heat.contrail.Compute: + derived_from: tosca.nodes.Compute + properties: + flavor: + type: string + description: flavor + required: false + status: SUPPORTED + image_name: + type: string + description: Image name + required: true + status: SUPPORTED + availability_zone: + type: string + description: Availability zone to create servers in + required: false + status: SUPPORTED + service_type: + type: string + description: Service type + required: true + status: SUPPORTED + constraints: + - valid_values: + - firewall + - analyzer + - source-nat + - loadbalancer + availability_zone_enable: + type: boolean + description: Indicates availability zone is enabled + required: false + default: false + status: SUPPORTED + service_template_name: + type: string + description: Service template name + required: false + status: SUPPORTED + service_instance_name: + type: string + description: Service instance name + required: true + status: SUPPORTED + service_mode: + type: string + description: Service mode + required: true + status: SUPPORTED + constraints: + - valid_values: + - transparent + - in-network + - in-network-nat + attributes: + tenant_id: + type: string + description: Tenant id of the VM + status: SUPPORTED + fq_name: + type: string + description: fq_name + status: SUPPORTED + show: + type: string + description: All attributes + status: SUPPORTED + active_vms: + type: string + description: Number of active VMs + status: SUPPORTED + virtual_machines: + type: string + description: VMs of this compute + status: SUPPORTED + status: + type: string + description: status of the compute + status: SUPPORTED \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.zip new file mode 100644 index 0000000000..c9e3c8a062 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailCompute/contrailCompute.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.json new file mode 100644 index 0000000000..e1987b9449 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.json @@ -0,0 +1,21 @@ +{ + "payloadName": "contrailNetworkRules.yml", + "contactId": "jh0003", + "name": "ContrailNetworkRules", + "description": "Configuration of policy rules to be applied over the network.", + "resourceIconPath": "networkrules", + "resourceType": "VFC", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Rules" + } + ] + } +], + "tags": [ + "ContrailNetworkRules" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.yml new file mode 100644 index 0000000000..b9d61e7769 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.yml @@ -0,0 +1,49 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailNetworkRuleGlobalType + template_version: 1.0.0 +description: Contrail Network Rule Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vfc.rules.nodes.heat.network.contrail.NetworkRules: + derived_from: tosca.nodes.Root + properties: + entries: + type: org.openecomp.datatypes.heat.contrail.network.rule.RuleList + description: A symbolic name for this contrail network rule + required: false + status: SUPPORTED + name: + type: string + description: A symbolic name for this contrail network rule + required: false + status: SUPPORTED + attributes: + tenant_id: + type: string + description: tenant_id + status: SUPPORTED + fq_name: + type: string + description: fq_name + status: SUPPORTED + show: + type: string + description: All attributes. + status: SUPPORTED + rules: + type: list + description: List of rules + status: SUPPORTED + entry_schema: + type: string + requirements: + - network: + capability: tosca.capabilities.Attachment + node: tosca.nodes.network.Network + relationship: org.openecomp.relationships.AttachesTo + occurrences: + - 0 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.zip new file mode 100644 index 0000000000..b687616cd8 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailNetworkRules/contrailNetworkRules.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.json new file mode 100644 index 0000000000..6edc7083b0 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.json @@ -0,0 +1,21 @@ +{ + "payloadName": "contrailPort.yml", + "contactId": "jh0003", + "name": "ContrailPort", + "description": "Represents a logical entity that associates between Compute and Network normative types for contrail.", + "resourceIconPath": "port", + "resourceType": "CP", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "ContrailPort" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.yml new file mode 100644 index 0000000000..a3e43a2fd1 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.yml @@ -0,0 +1,64 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailPortGlobalTypes + template_version: 1.0.0 +description: Contrail Port TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.cp.nodes.heat.network.contrail.Port: + derived_from: tosca.nodes.network.Port + properties: + static_routes: + type: list + description: An ordered list of static routes to be added to this interface + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.contrail.port.StaticRoute + virtual_network: + type: string + description: Virtual Network for this interface + required: true + status: SUPPORTED + static_route: + type: boolean + description: Static route enabled + required: false + default: false + status: SUPPORTED + allowed_address_pairs: + type: list + description: List of allowed address pair for this interface + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.contrail.AddressPair + shared_ip: + type: boolean + description: Shared ip enabled + required: false + default: false + status: SUPPORTED + ip_address: + type: string + description: IP for this interface + required: false + status: SUPPORTED + interface_type: + type: string + description: Interface type + required: true + status: SUPPORTED + constraints: + - valid_values: + - management + - left + - right + - other + attributes: + fq_name: + type: string + description: fq_name + status: SUPPORTED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.zip new file mode 100644 index 0000000000..f9e5c415ae Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailPort/contrailPort.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.json new file mode 100644 index 0000000000..13717b7da3 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.json @@ -0,0 +1,21 @@ +{ + "payloadName": "contrailV2NetworkRules.yml", + "contactId": "jh0003", + "name": "ContrailV2NetworkRules", + "description": "Configuration of policy rules to be applied over the network for contrail V2.", + "resourceIconPath": "networkrules", + "resourceType": "VFC", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Rules" + } + ] + } +], + "tags": [ + "ContrailV2NetworkRules" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.yml new file mode 100644 index 0000000000..ccc6d3a2ab --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailV2NetworkRuleGlobalType + template_version: 1.0.0 +description: Contrail V2 Network Rule Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vfc.rules.nodes.heat.network.contrailV2.NetworkRules: + derived_from: tosca.nodes.Root + properties: + name: + type: string + description: A symbolic name for this contrail v2 network rule + required: false + status: SUPPORTED + network_policy_entries: + type: org.openecomp.datatypes.heat.contrailV2.network.rule.RuleList + description: A symbolic name for this contrail v2 network rule + required: false + status: SUPPORTED + attributes: + fq_name: + type: string + description: fq_name + status: SUPPORTED + requirements: + - network: + capability: tosca.capabilities.Attachment + node: tosca.nodes.network.Network + relationship: org.openecomp.relationships.AttachesTo + occurrences: + - 0 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.zip new file mode 100644 index 0000000000..eac99b3b90 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2NetworkRules/contrailV2NetworkRules.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.json new file mode 100644 index 0000000000..5c7a725190 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.json @@ -0,0 +1,15 @@ +{ + "payloadName": "contrailV2VirtualMachineInterface.yml", + "contactId": "jh0003", + "name": "ContrailV2VirtualMachineInterface", + "description": "Represents a network interface. The interfaces are defined with specific MAC addresses and ports.", + "resourceIconPath": "network", + "resourceType": "VFC", + "categories": [{ + "name": "Generic", + "subcategories": [{ + "name": "Network Elements" + }] + }], + "tags": ["ContrailV2VirtualMachineInterface"] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.yml new file mode 100644 index 0000000000..ba324cf51a --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.yml @@ -0,0 +1,59 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailV2VirtualMachineInterfaceGlobalType + template_version: 1.0.0 +description: Contrail Virtual Machine Interface TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.cp.nodes.heat.contrailV2.VirtualMachineInterface: + derived_from: tosca.nodes.network.Port + properties: + virtual_machine_intefrace_mac_addresses: + type: list + description: List of mac addresses. + required: false + status: SUPPORTED + entry_schema: + type: string + name: + type: string + description: Virtual Machine Interface name + required: false + status: SUPPORTED + security_group_refs: + type: list + description: List of security groups. + required: false + status: SUPPORTED + entry_schema: + type: string + virtual_network_refs: + type: list + description: List of virtual networks. + required: false + status: SUPPORTED + entry_schema: + type: string + virtual_machine_interface_properties: + type: org.openecomp.datatypes.heat.contrailV2.virtual.machine.interface.Properties + description: virtual machine interface properties. + required: false + status: SUPPORTED + port_tuple_refs: + type: list + description: List of port tuples. + required: false + status: SUPPORTED + entry_schema: + type: string + attributes: + fq_name: + type: string + description: The FQ name of the Virtual Network. + status: SUPPORTED + show: + type: string + description: All attributes. + status: SUPPORTED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.zip new file mode 100644 index 0000000000..4b48a6838d Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualMachineInterface/contrailV2VirtualMachineInterface.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.json new file mode 100644 index 0000000000..c7802d2529 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.json @@ -0,0 +1,21 @@ +{ + "payloadName": "contrailV2VirtualNetwork.yml", + "contactId": "jh0003", + "name": "ContrailV2VirtualNetwork", + "description": "Represents a network service with optional subnets and advanced configurations for contrail V2.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "ContrailV2VirtualNetwork" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.yml new file mode 100644 index 0000000000..1ff1402411 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.yml @@ -0,0 +1,76 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailV2VirtualNetworkGlobalType + template_version: 1.0.0 +description: Contrail V2 Virtual Network Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vl.nodes.heat.network.contrailV2.VirtualNetwork: + derived_from: tosca.nodes.network.Network + properties: + network_ipam_refs_data: + type: list + description: IPAM references Data + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.IpamRefData + network_policy_refs_data: + type: list + description: Policy references data + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.contrailV2.virtual.network.rule.RefData + network_ipam_refs: + type: list + description: IPAM references + required: false + status: SUPPORTED + entry_schema: + type: string + network_policy_refs: + type: list + description: Policy references + required: false + status: SUPPORTED + entry_schema: + type: string + subnets: + type: map + description: Network related subnets + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + attributes: + fq_name: + type: string + description: fq_name + status: SUPPORTED + subnets_name: + type: list + description: Subnets name of this network + status: SUPPORTED + entry_schema: + type: string + subnets_show: + type: map + description: Detailed information about each subnet + status: SUPPORTED + entry_schema: + type: string + subnets: + type: map + description: Network related subnets + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + capabilities: + attachment: + type: tosca.capabilities.Attachment + occurrences: + - 1 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.zip new file mode 100644 index 0000000000..637e78da25 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailV2VirtualNetwork/contrailV2VirtualNetwork.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.json b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.json new file mode 100644 index 0000000000..523315edcb --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.json @@ -0,0 +1,21 @@ +{ + "payloadName": "contrailVirtualNetwork.yml", + "contactId": "jh0003", + "name": "ContrailVirtualNetwork", + "description": "Represents a network service with optional subnets and advanced configurations.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "ContrailVirtualNetwork" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.yml b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.yml new file mode 100644 index 0000000000..a5424c3c83 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.yml @@ -0,0 +1,84 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: ContrailVirtualNetworkGlobalType + template_version: 1.0.0 +description: Contrail Virtual Network Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vl.nodes.heat.network.contrail.VirtualNetwork: + derived_from: tosca.nodes.network.Network + properties: + shared: + type: string + description: Is virtual network shared + required: false + status: SUPPORTED + forwarding_mode: + type: string + description: forwarding mode of the virtual network + required: false + status: SUPPORTED + external: + type: string + description: Is virtual network external + required: false + status: SUPPORTED + allow_transit: + type: string + description: Whether this network should be transitive. + required: false + status: SUPPORTED + flood_unknown_unicast: + type: string + description: flood L2 packets on network + required: false + status: SUPPORTED + route_targets: + type: list + description: route targets associated with the virtual network + required: false + status: SUPPORTED + entry_schema: + type: string + subnets: + type: map + description: Network related subnets + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + attributes: + fq_name: + type: string + description: fq_name + status: SUPPORTED + show: + type: string + description: All attributes. + status: SUPPORTED + subnets_name: + type: list + description: Subnets name of this network + status: SUPPORTED + entry_schema: + type: string + subnets_show: + type: map + description: Detailed information about each subnet + status: SUPPORTED + entry_schema: + type: string + subnets: + type: map + description: Network related subnets + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + capabilities: + attachment: + type: tosca.capabilities.Attachment + occurrences: + - 1 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.zip b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.zip new file mode 100644 index 0000000000..17b32db41a Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/contrailVirtualNetwork/contrailVirtualNetwork.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.json b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.json new file mode 100644 index 0000000000..f6f0ecb308 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.json @@ -0,0 +1,21 @@ +{ + "payloadName": "eline.yml", + "contactId": "jh0003", + "name": "VL ELINE", + "description": "The node represents an E-Line virtual link entity.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Network Connectivity", + "subcategories": [ + { + "name": "Virtual Links" + } + ] + } +], + "tags": [ + "VL ELINE" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.yml b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.yml new file mode 100644 index 0000000000..21241369c7 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.vl.ELine: + derived_from: org.openecomp.resource.vl.VL + capabilities: + virtual_linkable: + type: tosca.capabilities.network.Linkable + occurrences: [0,2] diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.zip b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.zip new file mode 100644 index 0000000000..132c5eebc5 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/eline/eline.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.json b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.json new file mode 100644 index 0000000000..073e935871 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.json @@ -0,0 +1,21 @@ +{ + "payloadName": "neutronNet.yml", + "contactId": "jh0003", + "name": "NeutronNet", + "description": "Represents a network service with optional subnets and advanced configurations.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "NeutronNet" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.yml b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.yml new file mode 100644 index 0000000000..e80e2727c7 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.yml @@ -0,0 +1,97 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: NeutronNetGlobalTypes + template_version: 1.0.0 +description: Neutron Network TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vl.nodes.heat.network.neutron.Net: + derived_from: tosca.nodes.network.Network + properties: + dhcp_agent_ids: + type: list + description: The IDs of the DHCP agent to schedule the network + required: false + status: SUPPORTED + entry_schema: + type: string + tenant_id: + type: string + description: The ID of the tenant which will own the network + required: false + status: SUPPORTED + port_security_enabled: + type: boolean + description: Flag to enable/disable port security on the network + required: false + status: SUPPORTED + shared: + type: boolean + description: Whether this network should be shared across all tenants + required: false + default: false + status: SUPPORTED + admin_state_up: + type: boolean + description: A boolean value specifying the administrative status of the network + required: false + default: true + status: SUPPORTED + qos_policy: + type: string + description: The name or ID of QoS policy to attach to this network + required: false + status: SUPPORTED + subnets: + type: map + description: Network related subnets + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + value_specs: + type: map + description: Extra parameters to include in the request + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string + attributes: + qos_policy_id: + type: string + description: The QoS policy ID attached to this network + status: SUPPORTED + show: + type: string + description: Detailed information about resource + status: SUPPORTED + subnets_name: + type: list + description: Subnets name of this network + status: SUPPORTED + entry_schema: + type: string + subnets: + type: map + description: Network related subnets + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.Subnet + mtu: + type: scalar-unit.size + description: The maximum transmission unit size(in bytes) for the network + status: SUPPORTED + status: + type: string + description: The status of the network + status: SUPPORTED + capabilities: + attachment: + type: tosca.capabilities.Attachment + occurrences: + - 1 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.zip b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.zip new file mode 100644 index 0000000000..0cefe8a184 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/neutronNet/neutronNet.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.json b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.json new file mode 100644 index 0000000000..db782fa536 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.json @@ -0,0 +1,21 @@ +{ + "payloadName": "neutronPort.yml", + "contactId": "jh0003", + "name": "NeutronPort", + "description": "Represents a logical entity that associates between Compute and Network normative types.", + "resourceIconPath": "port", + "resourceType": "CP", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "NeutronPort" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.yml b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.yml new file mode 100644 index 0000000000..898615c6ce --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.yml @@ -0,0 +1,136 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: NeutronPortGlobalTypes + template_version: 1.0.0 +description: Neutron Port TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.cp.nodes.heat.network.neutron.Port: + derived_from: tosca.nodes.network.Port + properties: + port_security_enabled: + type: boolean + description: Flag to enable/disable port security on the network + required: false + status: SUPPORTED + device_id: + type: string + description: Device ID of this port + required: false + status: SUPPORTED + qos_policy: + type: string + description: The name or ID of QoS policy to attach to this network + required: false + status: SUPPORTED + allowed_address_pairs: + type: list + description: Additional MAC/IP address pairs allowed to pass through the port + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.AddressPair + binding:vnic_type: + type: string + description: The vnic type to be bound on the neutron port + required: false + status: SUPPORTED + constraints: + - valid_values: + - macvtap + - direct + - normal + value_specs: + type: map + description: Extra parameters to include in the request + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string + device_owner: + type: string + description: Name of the network owning the port + required: false + status: SUPPORTED + network: + type: string + description: Network this port belongs to + required: false + status: SUPPORTED + replacement_policy: + type: string + description: Policy on how to respond to a stack-update for this resource + required: false + default: AUTO + status: SUPPORTED + constraints: + - valid_values: + - REPLACE_ALWAYS + - AUTO + security_groups: + type: list + description: List of security group names or IDs + required: false + status: SUPPORTED + entry_schema: + type: string + fixed_ips: + type: list + description: Desired IPs for this port + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.neutron.port.FixedIps + mac_address: + type: string + description: MAC address to give to this port + required: false + status: SUPPORTED + admin_state_up: + type: boolean + description: A boolean value specifying the administrative status of the network + required: false + default: true + status: SUPPORTED + name: + type: string + description: A symbolic name for this port + required: false + status: SUPPORTED + attributes: + tenant_id: + type: string + description: Tenant owning the port + status: SUPPORTED + network_id: + type: string + description: Unique identifier for the network owning the port + status: SUPPORTED + qos_policy_id: + type: string + description: The QoS policy ID attached to this network + status: SUPPORTED + show: + type: string + description: Detailed information about resource + status: SUPPORTED + subnets: + type: list + description: Subnets of this network + status: SUPPORTED + entry_schema: + type: string + status: + type: string + description: The status of the network + status: SUPPORTED + capabilities: + attachment: + type: tosca.capabilities.Attachment + occurrences: + - 1 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.zip b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.zip new file mode 100644 index 0000000000..f120afb16e Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/neutronPort/neutronPort.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.json b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.json new file mode 100644 index 0000000000..007106b61e --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.json @@ -0,0 +1,24 @@ +{ + "payloadName": "novaServer.yml", + "contactId": "jh0003", + "name": "NovaServer", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "NovaServer" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.yml b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.yml new file mode 100644 index 0000000000..0ec79f5229 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.yml @@ -0,0 +1,249 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: NovaServerGlobalTypes + template_version: 1.0.0 +description: Nova Server TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +data_types: + org.openecomp.datatypes.heat.novaServer.network.PortExtraProperties: + derived_from: tosca.datatypes.Root + description: Nova server network expand properties for port + properties: + port_security_enabled: + type: boolean + description: Flag to enable/disable port security on the port + required: false + status: SUPPORTED + mac_address: + type: string + description: MAC address to give to this port + required: false + status: SUPPORTED + admin_state_up: + type: boolean + description: The administrative state of this port + required: false + default: true + status: SUPPORTED + qos_policy: + type: string + description: The name or ID of QoS policy to attach to this port + required: false + status: SUPPORTED + allowed_address_pairs: + type: list + description: Additional MAC/IP address pairs allowed to pass through the port + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.AddressPair + binding:vnic_type: + type: string + description: The vnic type to be bound on the neutron port + required: false + status: SUPPORTED + constraints: + - valid_values: + - macvtap + - direct + - normal + value_specs: + type: map + description: Extra parameters to include in the request + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string + org.openecomp.datatypes.heat.novaServer.network.AddressInfo: + derived_from: tosca.datatypes.network.NetworkInfo + description: Network addresses with corresponding port id + properties: + port_id: + type: string + description: Port id + required: false + status: SUPPORTED +node_types: + org.openecomp.resource.vfc.nodes.heat.nova.Server: + derived_from: tosca.nodes.Compute + properties: + admin_pass: + type: string + description: The administrator password for the server + required: false + status: SUPPORTED + availability_zone: + type: string + description: Availability zone to create servers in + required: false + status: SUPPORTED + image: + type: string + description: The ID or name of the image to boot with + required: false + status: SUPPORTED + image_update_policy: + type: string + description: Policy on how to apply an image-id update + required: false + default: REBUILD + status: SUPPORTED + constraints: + - valid_values: + - REBUILD_PRESERVE_EPHEMERAL + - REPLACE + - REBUILD + metadata: + type: json + description: Arbitrary JSON metadata to store for this server + required: false + status: SUPPORTED + contrail_service_instance_ind: + type: boolean + description: Nova server related to service instance indicator + required: false + default: false + status: SUPPORTED + user_data_update_policy: + type: string + description: Policy on how to apply a user_data update + required: false + default: REPLACE + status: SUPPORTED + constraints: + - valid_values: + - REPLACE + - IGNORE + flavor_update_policy: + type: string + description: Policy on how to apply a flavor update + required: false + default: RESIZE + status: SUPPORTED + constraints: + - valid_values: + - RESIZE + - REPLACE + user_data: + type: string + description: User data script to be executed by cloud-init + required: false + default: '' + status: SUPPORTED + flavor: + type: string + description: The ID or name of the flavor to boot onto + required: true + status: SUPPORTED + key_name: + type: string + description: Name of keypair to inject into the server + required: false + status: SUPPORTED + reservation_id: + type: string + description: A UUID for the set of servers being requested + required: false + status: SUPPORTED + security_groups: + type: list + description: List of security group names or IDs + required: false + default: [ + ] + status: SUPPORTED + entry_schema: + type: string + config_drive: + type: boolean + description: enable config drive on the server + required: false + status: SUPPORTED + personality: + type: map + description: A map of files to create/overwrite on the server upon boot + required: false + default: { + } + status: SUPPORTED + entry_schema: + type: string + software_config_transport: + type: string + description: How the server should receive the metadata required for software configuration + required: false + default: POLL_SERVER_CFN + status: SUPPORTED + constraints: + - valid_values: + - POLL_SERVER_CFN + - POLL_SERVER_HEAT + - POLL_TEMP_URL + - ZAQAR_MESSAGE + user_data_format: + type: string + description: How the user_data should be formatted for the server + required: false + default: HEAT_CFNTOOLS + status: SUPPORTED + constraints: + - valid_values: + - SOFTWARE_CONFIG + - RAW + - HEAT_CFNTOOLS + diskConfig: + type: string + description: Control how the disk is partitioned when the server is created + required: false + status: SUPPORTED + constraints: + - valid_values: + - AUTO + - MANUAL + name: + type: string + description: Server name + required: false + status: SUPPORTED + scheduler_hints: + type: map + description: Arbitrary key-value pairs specified by the client to help boot a server + required: false + status: SUPPORTED + entry_schema: + type: string + attributes: + accessIPv4: + type: string + description: The manually assigned alternative public IPv4 address of the server + status: SUPPORTED + addresses: + type: map + description: A dict of all network addresses with corresponding port_id + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.novaServer.network.AddressInfo + accessIPv6: + type: string + description: The manually assigned alternative public IPv6 address of the server + status: SUPPORTED + instance_name: + type: string + description: AWS compatible instance name + status: SUPPORTED + name: + type: string + description: Name of the server + status: SUPPORTED + show: + type: string + description: Detailed information about resource + status: SUPPORTED + console_urls: + type: string + description: URLs of servers consoles + status: SUPPORTED \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.zip b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.zip new file mode 100644 index 0000000000..aafefbc6b5 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/novaServer/novaServer.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.json b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.json new file mode 100644 index 0000000000..14d25a0ac2 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.json @@ -0,0 +1,21 @@ +{ + "payloadName": "securityRules.yml", + "contactId": "jh0003", + "name": "SecurityRules", + "description": "Configuration of policy rules to be applied on ports.", + "resourceIconPath": "securityrules", + "resourceType": "VFC", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Rules" + } + ] + } +], + "tags": [ + "SecurityRules" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.yml b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.yml new file mode 100644 index 0000000000..29e87e15fc --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.yml @@ -0,0 +1,42 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +metadata: + template_name: NeutronSecurityRulesGlobalTypes + template_version: 1.0.0 +description: Neutron Security Rules TOSCA Global Types +imports: + common_definitions: + file: CommonGlobalTypesServiceTemplate.yaml +node_types: + org.openecomp.resource.vfc.rules.nodes.heat.network.neutron.SecurityRules: + derived_from: tosca.nodes.Root + properties: + description: + type: string + description: Description of the security group + required: false + status: SUPPORTED + name: + type: string + description: A symbolic name for this security group, which is not required to be unique. + required: false + status: SUPPORTED + rules: + type: list + description: List of security group rules + required: false + status: SUPPORTED + entry_schema: + type: org.openecomp.datatypes.heat.network.neutron.SecurityRules.Rule + attributes: + show: + type: string + description: Detailed information about resource + status: SUPPORTED + requirements: + - port: + capability: tosca.capabilities.Attachment + node: org.openecomp.resource.cp.nodes.heat.network.neutron.Port + relationship: corg.openecomp.relationships.AttachesTo + occurrences: + - 0 + - UNBOUNDED diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.zip b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.zip new file mode 100644 index 0000000000..b1524a2d8f Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/securityRules/securityRules.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.json b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.json new file mode 100644 index 0000000000..5dd26b48ad --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.json @@ -0,0 +1,21 @@ +{ + "payloadName": "vl.yml", + "contactId": "jh0003", + "name": "VL", + "description": " Virtual link (VL) describes the basic topology of the connectivity as well as other required parameters (e.g. bandwidth and QoS class). ", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Network Connectivity", + "subcategories": [ + { + "name": "Virtual Links" + } + ] + } +], + "tags": [ + "VL" + ] +} diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.yml b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.yml new file mode 100644 index 0000000000..f2042f7798 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 + +node_types: + org.openecomp.resource.vl.VL: + derived_from: tosca.nodes.network.Network + properties: + vendor: + type: string + required: false + vl_name: + type: string + required: false + + capabilities: + virtual_linkable: + type: tosca.capabilities.network.Linkable + end_point: + type: tosca.capabilities.Endpoint \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.zip b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.zip new file mode 100644 index 0000000000..c1889a9803 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/heat-types/vl/vl.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.yml b/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.yml new file mode 100644 index 0000000000..1b67118934 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.yml @@ -0,0 +1,11 @@ +tosca.interfaces.node.lifecycle.Standard: + create: + description: Standard lifecycle create operation. + configure: + description: Standard lifecycle configure operation. + start: + description: Standard lifecycle start operation. + stop: + description: Standard lifecycle stop operation. + delete: + description: Standard lifecycle delete operation. \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.zip b/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.zip new file mode 100644 index 0000000000..9bcf93ab7d Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/interface-lifecycle-types/interfaceLifecycleTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.json b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.json new file mode 100644 index 0000000000..addef2ae4b --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.json @@ -0,0 +1,20 @@ +{ + "payloadName": "DBMS.yml", + "contactId": "jh0003", + "name": "DBMS", + "description": "Represents a typical relational, SQL Database Management System software component or service.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "DBMS" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.yml b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.yml new file mode 100644 index 0000000000..28919d38e4 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.DBMS: + derived_from: tosca.nodes.SoftwareComponent + properties: + root_password: + type: string + required: false + description: the optional root password for the DBMS service + port: + type: integer + required: false + description: the port the DBMS service will listen to for data and requests + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [ tosca.nodes.Database ] diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.zip b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.zip new file mode 100644 index 0000000000..7f88b3ba53 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/DBMS/DBMS.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.json b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.json new file mode 100644 index 0000000000..30e3d74bc9 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.json @@ -0,0 +1,20 @@ +{ + "payloadName": "blockStorage.yml", + "contactId": "jh0003", + "name": "BlockStorage", + "description": "Represents a server-local block storage device (i.e., not shared) offering evenly sized blocks of data from which raw storage volumes can be created.", + "resourceIconPath": "objectStorage", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "BlockStorage" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.yml b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.yml new file mode 100644 index 0000000000..a82965215f --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.BlockStorage: + derived_from: tosca.nodes.Root + properties: + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 1 MB + volume_id: + type: string + required: false + snapshot_id: + type: string + required: false + capabilities: + attachment: + type: tosca.capabilities.Attachment diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.zip b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.zip new file mode 100644 index 0000000000..b26f9e2c0e Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/blockStorage/blockStorage.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.json b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.json new file mode 100644 index 0000000000..31bb27be16 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.json @@ -0,0 +1,24 @@ +{ + "payloadName": "compute.yml", + "contactId": "jh0003", + "name": "Compute", + "description": "Represents a real or virtual machine or server. Information specified on the Compute + node will be used to find the machine that fits the given requirements in the cloud + available machines. If no sizing information are specified the cloud provider default + machine will be used. It is strongly recommended to specify the required CPUs and memory + at least.", + "resourceIconPath": "compute", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "Compute" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.yml b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.yml new file mode 100644 index 0000000000..00b07fb908 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.yml @@ -0,0 +1,35 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Compute: + derived_from: tosca.nodes.Root + attributes: + private_address: + type: string + public_address: + type: string + networks: + type: map + entry_schema: + type: tosca.datatypes.network.NetworkInfo + ports: + type: map + entry_schema: + type: tosca.datatypes.network.PortInfo + requirements: + - local_storage: + capability: tosca.capabilities.Attachment + node: tosca.nodes.BlockStorage + relationship: tosca.relationships.AttachesTo + occurrences: [0, UNBOUNDED] + capabilities: + host: + type: tosca.capabilities.Container + valid_source_types: [tosca.nodes.SoftwareComponent] + endpoint : + type: tosca.capabilities.Endpoint.Admin + os: + type: tosca.capabilities.OperatingSystem + scalable: + type: tosca.capabilities.Scalable + binding: + type: tosca.capabilities.network.Bindable diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.zip b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.zip new file mode 100644 index 0000000000..6c008e866f Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/compute/compute.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.json b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.json new file mode 100644 index 0000000000..cd0a1386be --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.json @@ -0,0 +1,20 @@ +{ + "payloadName": "containerApplication.yml", + "contactId": "jh0003", + "name": "Application", + "description": "Represents an application that requires Container-level virtualization technology.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Application" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.yml b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.yml new file mode 100644 index 0000000000..8813f26e04 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Container.Application: + derived_from: tosca.nodes.Root + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Container + relationship: tosca.relationships.HostedOn diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.zip b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.zip new file mode 100644 index 0000000000..cec3e5df6c Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/containerApplication/containerApplication.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.json b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.json new file mode 100644 index 0000000000..85a0c63257 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.json @@ -0,0 +1,20 @@ +{ + "payloadName": "containerRuntime.yml", + "contactId": "jh0003", + "name": "Runtime", + "description": "Represents operating system-level virtualization technology used to run multiple application services on a single Compute host.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Runtime" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.yml b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.yml new file mode 100644 index 0000000000..86a10a0185 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.yml @@ -0,0 +1,9 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Container.Runtime: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + host: + type: tosca.capabilities.Container + scalable: + type: tosca.capabilities.Scalable diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.zip b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.zip new file mode 100644 index 0000000000..c30aff4098 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/containerRuntime/containerRuntime.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/database/database.json b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.json new file mode 100644 index 0000000000..f9cf01eb04 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.json @@ -0,0 +1,20 @@ +{ + "payloadName": "database.yml", + "contactId": "jh0003", + "name": "Database", + "description": "Represents a logical database that can be managed and hosted by a DBMS node.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Database" + } + ] + } +], + "tags": [ + "Database" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/database/database.yml b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.yml new file mode 100644 index 0000000000..5166150c73 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.yml @@ -0,0 +1,27 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Database: + derived_from: tosca.nodes.Root + properties: + name: + type: string + description: the logical name of the database + port: + type: integer + description: the port the underlying database service will listen to for data + user: + type: string + description: the optional user account name for DB administration + required: false + password: + type: string + description: the optional password for the DB user account + required: false + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.DBMS + relationship: tosca.relationships.HostedOn + capabilities: + database_endpoint: + type: tosca.capabilities.Endpoint.Database diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/database/database.zip b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.zip new file mode 100644 index 0000000000..289e7e5ec1 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/database/database.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.json b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.json new file mode 100644 index 0000000000..d108ee1cbb --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.json @@ -0,0 +1,20 @@ +{ + "payloadName": "loadBalancer.yml", + "contactId": "jh0003", + "name": "LoadBalancer", + "description": "Represents logical function that be used in conjunction with a Floating Address to distribute an application’s traffic (load) across a number of instances of the application (e.g., for a clustered or scaled application).", + "resourceIconPath": "loadBalancer", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "LoadBalancer" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.yml b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.yml new file mode 100644 index 0000000000..d577a2aa83 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.yml @@ -0,0 +1,20 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.LoadBalancer: + derived_from: tosca.nodes.Root + properties: + # TBD + algorithm : + type: string + required: false + status: experimental + capabilities : + client: + type: tosca.capabilities.Endpoint.Public + occurrences: [0, UNBOUNDED] + description: the Floating (IP) client’s on the public network can connect to + requirements: + - application: + capability: tosca.capabilities.Endpoint + relationship: tosca.relationships.RoutesTo + occurrences: [0, UNBOUNDED] diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.zip b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.zip new file mode 100644 index 0000000000..3a847c6f56 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/loadBalancer/loadBalancer.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/network/network.json b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.json new file mode 100644 index 0000000000..4ba8311ce4 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.json @@ -0,0 +1,21 @@ +{ + "payloadName": "network.yml", + "contactId": "jh0003", + "name": "Network", + "description": "Represents a simple , logical network service.", + "resourceIconPath": "network", + "resourceType": "VL", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "Network" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/network/network.yml b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.yml new file mode 100644 index 0000000000..9a71e80600 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.yml @@ -0,0 +1,45 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.network.Network: + derived_from: tosca.nodes.Root + properties: + ip_version: + type: integer + required: false + default: 4 + constraints: + - valid_values: [ 4, 6 ] + cidr: + type: string + required: false + start_ip: + type: string + required: false + end_ip: + type: string + required: false + gateway_ip: + type: string + required: false + network_name: + type: string + required: false + network_id: + type: string + required: false + segmentation_id: + type: string + required: false + network_type: + type: string + required: false + physical_network: + type: string + required: false + dhcp_enabled: + type: boolean + required: false + default: true + capabilities: + link: + type: tosca.capabilities.network.Linkable diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/network/network.zip b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.zip new file mode 100644 index 0000000000..61788a9e39 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/network/network.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.json b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.json new file mode 100644 index 0000000000..dca5a4b89d --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.json @@ -0,0 +1,20 @@ +{ + "payloadName": "objectStorage.yml", + "contactId": "jh0003", + "name": "ObjectStorage", + "description": "Represents storage that provides the ability to store data as objects (or BLOBs of data) without consideration for the underlying filesystem or devices.", + "resourceIconPath": "objectStorage", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Infrastructure" + } + ] + } +], + "tags": [ + "ObjectStorage" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.yml b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.yml new file mode 100644 index 0000000000..9c338c3400 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.yml @@ -0,0 +1,18 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.ObjectStorage: + derived_from: tosca.nodes.Root + properties: + name: + type: string + size: + type: scalar-unit.size + constraints: + - greater_or_equal: 0 GB + maxsize: + type: scalar-unit.size + constraints: + - greater_or_equal: 0 GB + capabilities: + storage_endpoint: + type: tosca.capabilities.Endpoint diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.zip b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.zip new file mode 100644 index 0000000000..6b15346064 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/objectStorage/objectStorage.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/port/port.json b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.json new file mode 100644 index 0000000000..2475bef065 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.json @@ -0,0 +1,21 @@ +{ + "payloadName": "port.yml", + "contactId": "jh0003", + "name": "Port", + "description": "Represents a logical entity that associates between Compute and Network normative types.", + "resourceIconPath": "port", + "resourceType": "CP", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Network Elements" + } + ] + } +], + "tags": [ + "Port" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/port/port.yml b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.yml new file mode 100644 index 0000000000..2d1540b27b --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.yml @@ -0,0 +1,31 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.network.Port: + derived_from: tosca.nodes.Root + properties: + ip_address: + type: string + required: false + order: + type: integer + required: true + default: 0 + constraints: + - greater_or_equal: 0 + is_default: + type: boolean + required: false + default: false + ip_range_start: + type: string + required: false + ip_range_end: + type: string + required: false + requirements: + - link: + capability: tosca.capabilities.network.Linkable + relationship: tosca.relationships.network.LinksTo + - binding: + capability: tosca.capabilities.network.Bindable + relationship: tosca.relationships.network.BindsTo diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/port/port.zip b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.zip new file mode 100644 index 0000000000..0bf97333ce Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/port/port.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/root/root.json b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.json new file mode 100644 index 0000000000..48846bc8be --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.json @@ -0,0 +1,20 @@ +{ + "payloadName": "root.yml", + "contactId": "jh0003", + "name": "Root", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "Root" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/root/root.yml b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.yml new file mode 100644 index 0000000000..e9b1de9518 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.yml @@ -0,0 +1,23 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.Root: + description: The TOSCA Node Type all other TOSCA base Node Types derive from + attributes: + tosca_id: + type: string + tosca_name: + type: string + state: + type: string + capabilities: + feature: + type: tosca.capabilities.Node + requirements: + - dependency : + capability: tosca.capabilities.Node + node: tosca.nodes.Root + relationship: tosca.relationships.DependsOn + occurrences: [ 0, UNBOUNDED ] + interfaces: + Standard: + type: tosca.interfaces.node.lifecycle.Standard diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/root/root.zip b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.zip new file mode 100644 index 0000000000..b336a9dca3 Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/root/root.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.json b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.json new file mode 100644 index 0000000000..ab8eda95eb --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.json @@ -0,0 +1,20 @@ +{ + "payloadName": "softwareComponent.yml", + "contactId": "jh0003", + "name": "SoftwareComponent", + "description": "Represents a generic software component that can be managed and run by a Compute Node Type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "SoftwareComponent" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.yml b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.yml new file mode 100644 index 0000000000..a154632c74 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.yml @@ -0,0 +1,17 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.SoftwareComponent: + derived_from: tosca.nodes.Root + properties: + # domain-specific software component version + component_version: + type: version + required: false + admin_credential: + type: tosca.datatypes.Credential + required: false + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.Compute + relationship: tosca.relationships.HostedOn diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.zip b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.zip new file mode 100644 index 0000000000..f77816b83f Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/softwareComponent/softwareComponent.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.json b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.json new file mode 100644 index 0000000000..63c2936648 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.json @@ -0,0 +1,20 @@ +{ + "payloadName": "webApplication.yml", + "contactId": "jh0003", + "name": "WebApplication", + "description": "Represents a software application that can be managed and run by a Web Server node. Specific types of web applications such as Java, etc. could be derived from this type.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "WebApplication" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.yml b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.yml new file mode 100644 index 0000000000..5f9a775fe0 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.yml @@ -0,0 +1,15 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.WebApplication: + derived_from: tosca.nodes.Root + properties: + context_root: + type: string + capabilities: + app_endpoint: + type: tosca.capabilities.Endpoint + requirements: + - host: + capability: tosca.capabilities.Container + node: tosca.nodes.WebServer + relationship: tosca.relationships.HostedOn diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.zip b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.zip new file mode 100644 index 0000000000..0b1889bd8e Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/webApplication/webApplication.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.json b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.json new file mode 100644 index 0000000000..058af97664 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.json @@ -0,0 +1,20 @@ +{ + "payloadName": "webServer.yml", + "contactId": "jh0003", + "name": "WebServer", + "description": "Represents an abstract software component or service that is capable of hosting and providing management operations for one or more Web Application nodes.", + "resourceIconPath": "defaulticon", + "categories": [ + { + "name": "Generic", + "subcategories": [ + { + "name": "Abstract" + } + ] + } +], + "tags": [ + "WebServer" + ] +} \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.yml b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.yml new file mode 100644 index 0000000000..7c957b5247 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.yml @@ -0,0 +1,11 @@ +tosca_definitions_version: tosca_simple_yaml_1_0_0 +node_types: + tosca.nodes.WebServer: + derived_from: tosca.nodes.SoftwareComponent + capabilities: + # Private, layer 4 endpoints + data_endpoint: tosca.capabilities.Endpoint + admin_endpoint: tosca.capabilities.Endpoint.Admin + host: + type: tosca.capabilities.Container + valid_source_types: [ tosca.nodes.WebApplication ] \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.zip b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.zip new file mode 100644 index 0000000000..45bee47eff Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/normative-types/webServer/webServer.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.yml b/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.yml new file mode 100644 index 0000000000..ceb22da2af --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.yml @@ -0,0 +1,94 @@ +tosca.policies.Root: + description: The TOSCA Policy Type all other TOSCA Policy Types derive from +tosca.policies.Placement: + derived_from: tosca.policies.Root + description: The TOSCA Policy Type definition that is used to govern placement of TOSCA nodes or groups of nodes. +tosca.policies.Scaling: + derived_from: tosca.policies.Root + description: The TOSCA Policy Type definition that is used to govern scaling of TOSCA nodes or groups of nodes. +tosca.policies.Update: + derived_from: tosca.policies.Root + description: The TOSCA Policy Type definition that is used to govern update of TOSCA nodes or groups of nodes. +tosca.policies.Performance: + derived_from: tosca.policies.Root + description: The TOSCA Policy Type definition that is used to declare performance requirements for TOSCA nodes or groups of nodes. +org.openecomp.policies.placement.Antilocate: + derived_from: tosca.policy.placement + description: My placement policy for separation based upon container type value + properties: + name: + type: string + description: The name of the policy + required: false + status: SUPPORTED + container_type: + type: string + description: container type + required: false + status: SUPPORTED + constraints: + - valid_values: + - host + - region + - compute +org.openecomp.policies.placement.Colocate: + derived_from: tosca.policy.placement + description: Keep associated nodes (groups of nodes) based upon affinity value + properties: + name: + type: string + description: The name of the policy + required: false + status: SUPPORTED + affinity: + type: string + description: affinity + required: true + status: SUPPORTED + constraints: + - valid_values: + - host + - region + - compute +org.openecomp.policies.placement.valet.Diversity: + derived_from: tosca.policy.placement + description: Valet Diversity + properties: + level: + type: string + description: diversity + required: false + default: host + status: SUPPORTED + constraints: + - valid_values: + - host + - rack +org.openecomp.policies.placement.valet.Exclusivity: + derived_from: tosca.policy.placement + description: Valet Exclusivity + properties: + level: + type: string + description: exclusivity + required: false + default: host + status: SUPPORTED + constraints: + - valid_values: + - host + - rack +org.openecomp.policies.placement.valet.Affinity: + derived_from: tosca.policy.placement + description: Valet Affinity + properties: + level: + type: string + description: affinity + required: false + default: host + status: SUPPORTED + constraints: + - valid_values: + - host + - rack \ No newline at end of file diff --git a/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.zip b/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.zip new file mode 100644 index 0000000000..a6c38ef9de Binary files /dev/null and b/catalog-be/src/main/resources/import/tosca/policy-types/policyTypes.zip differ diff --git a/catalog-be/src/main/resources/import/tosca/users/importUsers.yaml b/catalog-be/src/main/resources/import/tosca/users/importUsers.yaml new file mode 100644 index 0000000000..368a2b06f3 --- /dev/null +++ b/catalog-be/src/main/resources/import/tosca/users/importUsers.yaml @@ -0,0 +1,13 @@ +--- +users: + jh0003: + firstName: Jimmy + lastName: Hendrix + role: ADMIN + email: admin@att.com + jh0006: + firstName: Jimmy + lastName: Hendrix + role: DESIGNER1 + email: admin@att.com + diff --git a/catalog-be/src/main/resources/jetty-ssl.xml b/catalog-be/src/main/resources/jetty-ssl.xml new file mode 100644 index 0000000000..9b375087f1 --- /dev/null +++ b/catalog-be/src/main/resources/jetty-ssl.xml @@ -0,0 +1,51 @@ + + + + + + + + + + / + + + / + + + + + + + SSL_RSA_WITH_DES_CBC_SHA + SSL_DHE_RSA_WITH_DES_CBC_SHA + SSL_DHE_DSS_WITH_DES_CBC_SHA + SSL_RSA_EXPORT_WITH_RC4_40_MD5 + SSL_RSA_EXPORT_WITH_DES40_CBC_SHA + SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA + SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA + + + + + + + + + + + + + + + + + + + SSLv3 + SSLv2 + + + + + diff --git a/catalog-be/src/main/resources/keystore/README.txt b/catalog-be/src/main/resources/keystore/README.txt new file mode 100644 index 0000000000..bbbbd07e27 --- /dev/null +++ b/catalog-be/src/main/resources/keystore/README.txt @@ -0,0 +1,16 @@ +keytool -genkeypair -keystore catalogbe.jks -alias catalogbe -keypass Aa123456 -storepass Aa123456 -keyalg RSA -keysize 2048 -validity 3650 -dname "CN=Catalog BE, OU=Development, O=AT&T, L=TLV, C=IL" + + +3650 – 10 years validity +Eyal Sofer – creator +Development – Organization unit +AT&T – Organization +TLV- City +IL – Country code + + +catalogbe.jks – name of keystore +Aa123456 - password + +#In order to generate the password OBF:..., run the following command: +java -cp ../jetty-distribution-9.2.7.v20150116/lib/jetty-http-9.2.7.v20150116.jar:../jetty-distribution-9.2.7.v20150116/lib/jetty-util-9.2.7.v20150116.jar org.eclipse.jetty.util.security.Password Aa123456 \ No newline at end of file diff --git a/catalog-be/src/main/resources/keystore/catalogbe.jks b/catalog-be/src/main/resources/keystore/catalogbe.jks new file mode 100644 index 0000000000..8493a46aca Binary files /dev/null and b/catalog-be/src/main/resources/keystore/catalogbe.jks differ diff --git a/catalog-be/src/main/resources/keystore/catalogbe.jks.pwd b/catalog-be/src/main/resources/keystore/catalogbe.jks.pwd new file mode 100644 index 0000000000..b113d7d888 --- /dev/null +++ b/catalog-be/src/main/resources/keystore/catalogbe.jks.pwd @@ -0,0 +1 @@ +OBF:1cp61iuj194s194u194w194y1is31cok \ No newline at end of file diff --git a/catalog-be/src/main/resources/portal.properties b/catalog-be/src/main/resources/portal.properties new file mode 100644 index 0000000000..33ae0dac94 --- /dev/null +++ b/catalog-be/src/main/resources/portal.properties @@ -0,0 +1,25 @@ +# Portal REST URL, ends "/auxapi" +ecomp_rest_url = https://localhost/ecompportal/auxapi + +# Java implementation of interface +portal.api.impl.class = org.openecomp.sdc.be.ecomp.EcompIntImpl + +# CSP-SSO URL +ecomp_redirect_url = https://localhost/ecomp_portal_ist/ecompportal/process_csp +# Cookie set by CSP-SSO +csp_cookie_name = attESSec +# CSP setting, most use PROD; DEV also recognized +csp_gate_keeper_prod_key = PROD + +# Comma-separated list of UEB server names +ueb_url_list = +# UEB topic where Portal listens +ecomp_portal_inbox_name = ECOMP-PORTAL-INBOX-TEST +# UEB key generated while on-boarding +ueb_app_key = app_key_here +# UEB secret generated while on-boarding +ueb_app_secret = app_secret_here +# UEB topic where App listens +ueb_app_mailbox_name = app_topic_name_here +# Consumer group name; most Apps should use {UUID} +ueb_app_consumer_group_name = {UUID} \ No newline at end of file diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importCategoryTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importCategoryTypes.py new file mode 100644 index 0000000000..aca21754e8 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importCategoryTypes.py @@ -0,0 +1,74 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement + +from importCommon import * +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importCategories(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/categories", "categoryTypes", "categoriesZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + errorAndExit(1, None) + else: + if (exitOnSuccess == True): + errorAndExit(0, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importCategories(beHost, bePort, adminUser, True, "../../../import/tosca/categories/") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importCommon.py b/catalog-be/src/main/resources/scripts/import/tosca/importCommon.py new file mode 100644 index 0000000000..acdb067849 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importCommon.py @@ -0,0 +1,43 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy + +############################################################################################################### +# +# +############################################################################################################### + +debugFlag = True + +def join_strings(lst): + concat = "" + for string in lst: + if (string != None): + if (type(string) == int): + string = str(string) + concat += (string + " ") + return concat + +def debug(desc, *args): + 'print only if debug enabled' + if (debugFlag == True): + print desc, join_strings(args) + +def log(desc, arg=None): + 'print log info' + print desc, arg + +def errorAndExit(errorCode, errorDesc): + if ( errorCode > 0 ): + print "status={0}. {1}".format(errorCode, '' if errorDesc == None else errorDesc) + else: + print "status={0}".format(errorCode) + sys.exit(errorCode) + +def printNameAndReturnCode(name, code): + print "{0:30} | {1:6}".format(name, code) + +def printFrameLine(): + print "----------------------------------------" diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importDataTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importDataTypes.py new file mode 100644 index 0000000000..5d7f5b7576 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importDataTypes.py @@ -0,0 +1,74 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement + +from importCommon import * +################################################################################################################################################ +# # +# Import tosca data types # +# # +# activation : # +# python importDataTypes.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importDataTypes.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importDataTypes(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/datatypes", "dataTypes", "dataTypesZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + errorAndExit(1, None) + else: + if (exitOnSuccess == True): + errorAndExit(0, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importDataTypes(beHost, bePort, adminUser, True, "../../../import/tosca/data-types/") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importGroupTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importGroupTypes.py new file mode 100644 index 0000000000..2b6a5db6f8 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importGroupTypes.py @@ -0,0 +1,74 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement + +from importCommon import * +################################################################################################################################################ +# # +# Import tosca data types # +# # +# activation : # +# python importGroupTypes.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importGroupTypes.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importGroupTypes(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/grouptypes", "groupTypes", "groupTypesZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + errorAndExit(1, None) + else: + if (exitOnSuccess == True): + errorAndExit(0, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importGroupTypes(beHost, bePort, adminUser, True, "../../../import/tosca/group-types/") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importHeatTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importHeatTypes.py new file mode 100644 index 0000000000..07eacf8d61 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importHeatTypes.py @@ -0,0 +1,113 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importCommon import * +from importNormativeTypes import * +import importCommon + +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def importHeatTypes(beHost, bePort, adminUser, fileDir, updateversion): + + heatTypes = [ "cinderVolume", +# "contrailVirtualNetwork", + "neutronNet", + "neutronPort", + "novaServer", + "vl", + "eline", + "abstractSubstitute", +# "contrailNetworkRules", +# "contrailPort", +# "contrailV2NetworkRules", +# "contrailV2VirtualNetwork", + "securityRules" +# "contrailAbstractSubstitute", +# "contrailCompute", +# "contrailV2VirtualMachineInterface" + ] + + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + results = [] + for heatType in heatTypes: + result = createNormativeType(beHost, bePort, adminUser, fileDir, heatType, updateversion) + results.append(result) + if ( result[1] == None or result[1] not in responseCodes) : + print "Failed creating heat type " + heatType + ". " + str(result[1]) + return results + + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + updateversion = 'true' + + try: + opts, args = getopt.getopt(argv,"i:p:u:v:h:",["ip=","port=","user=","updateversion="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-v", "--updateversion"): + if (arg.lower() == "false" or arg.lower() == "no"): + updateversion = 'false' + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + results = importHeatTypes(beHost, bePort, adminUser, "../../../import/tosca/heat-types/", updateversion) + + print "-----------------------------" + for result in results: + print "{0:20} | {1:6}".format(result[0], result[1]) + print "-----------------------------" + + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + failedNormatives = filter(lambda x: x[1] == None or x[1] not in responseCodes, results) + if (len(failedNormatives) > 0): + errorAndExit(1, None) + else: + errorAndExit(0, None) + + +if __name__ == "__main__": + main(sys.argv[1:]) + + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNodeType.py b/catalog-be/src/main/resources/scripts/import/tosca/importNodeType.py new file mode 100644 index 0000000000..f35cc7bcee --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNodeType.py @@ -0,0 +1,156 @@ +import pycurl +import sys, getopt, os +from StringIO import StringIO +import json +import copy +from importCommon import * +import importCommon +import zipfile +################################################################################################################################################ +# # +################################################################################################################################################ + +def createZipFromYml(ymlFile, zipFile): + zip = zipfile.ZipFile(zipFile, 'w', zipfile.ZIP_DEFLATED) + + zip.write(ymlFile, os.path.basename(ymlFile)) + zip.close() + +def createUserNormativeType(beHost, bePort, adminUser, fileDir, ELEMENT_NAME): + + try: + log("in create normative type ", ELEMENT_NAME) + debug("userId", adminUser) + debug("fileDir", fileDir) + + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/catalog/upload/multipart' + c.setopt(c.URL, url) + c.setopt(c.POST, 1) + + adminHeader = 'USER_ID: ' + adminUser + #c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + c.setopt(pycurl.HTTPHEADER, [adminHeader]) + + ymlFile = fileDir + ELEMENT_NAME + "/normative-types-new-" + ELEMENT_NAME + ".yml" + zipFile = fileDir + ELEMENT_NAME + "/normative-types-new-" + ELEMENT_NAME + ".zip" + debug(ymlFile) + debug(zipFile) + path = zipFile + debug("path=" + path) + CURRENT_JSON_FILE=fileDir + ELEMENT_NAME + "/" + ELEMENT_NAME + ".json" + debug(CURRENT_JSON_FILE) + jsonFile = open(CURRENT_JSON_FILE) + + debug("before load json") + json_data = json.load(jsonFile, strict=False) + debug(json_data) + + jsonAsStr = json.dumps(json_data) + debug(path) + send = [('resourceMetadata', jsonAsStr), ('resourceZip', (pycurl.FORM_FILE, path))] + debug(send) + c.setopt(pycurl.HTTPPOST, send) + + c.setopt(c.WRITEFUNCTION, buffer.write) + res = c.perform() + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + if (httpRes != None): + debug("http response=", httpRes) + #print('Status: ' + str(responseCode)) + debug(buffer.getvalue()) + c.close() + + return (ELEMENT_NAME, httpRes, buffer.getvalue()) + + except Exception as inst: + print("ERROR=" + str(inst)) + return (ELEMENT_NAME, None, None) + + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-l | --location=] [-e | --element=]' + print "----------------- Example -------------------" + print "python importNodeType.py -d false -l /home/vagrant/catalog-be-1604.0.2.15.6-SNAPSHOT/scripts/import/tosca/../../../import/tosca/user-normative-types/ -e root1" + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + debugf = None + location = None + element = None + + try: + opts, args = getopt.getopt(argv,"i:p:u:d:l:e:h",["ip=","port=","user=","location=","element=", "debug="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-l", "--location"): + location = arg + elif opt in ("-e", "--element"): + element = arg + elif opt in ("-d", "--debug"): + print arg + debugf = bool(arg.lower() == "true" or arg.lower() == "yes") + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + if (debugf != None): + print 'set debug mode to ' + str(debugf) + importCommon.debugFlag = debugf + + if (location == None): + print 'Missing file location' + usage() + sys.exit(3) + + if (element == None): + print 'Missing element name. E.g. root, compute, ...' + usage() + sys.exit(3) + + #pathdir = os.path.dirname(os.path.realpath(sys.argv[0])) + + #baseFileLocation = pathdir + "/../../../import/tosca/" + #fileDir = baseFileLocation + "user-normative-types/" + + #normativeType = "root1" + + result = createUserNormativeType(beHost, bePort, adminUser, location, element) + #result = createUserNormativeType(beHost, bePort, adminUser, fileDir, normativeType) + print "---------------------------------------" + print "{0:30} | {1:6}".format(result[0], result[1]) + print "---------------------------------------" + + if ( result[1] == None or result[1] not in [200, 201] ) : + print "Failed creating normative type " + element + ". " + str(result[1]) + errorAndExit(1, None) + + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py new file mode 100644 index 0000000000..ec9e93e6e4 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeAll.py @@ -0,0 +1,135 @@ +import pycurl +import sys, getopt, os +from StringIO import StringIO +import json +import copy +import time +#from importNormativeElements import createNormativeElement +from importNormativeElements import * +from importNormativeTypes import importNormativeTypes +from importHeatTypes import importHeatTypes +from importNormativeCapabilities import importNormativeCapabilities +from importCategoryTypes import importCategories +from importNormativeInterfaceLifecycleTypes import importNormativeInterfaceLifecycleType +from importDataTypes import importDataTypes +from importGroupTypes import importGroupTypes +from importPolicyTypes import importPolicyTypes +from importCommon import * +import importCommon + +################################################################################################################################################################################################# +# # +# Import all users from a given file # +# # +# activation : # +# python importNormativeAll.py [-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=] # +# [-v | --updateversion=] # +# # +# shortest activation (be host = localhost, be port = 8080, user = jh0003): # # # +# python importNormativeAll.py # +# # +################################################################################################################################################################################################# + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=] [-v | --updateversion=]' + +def handleResults(results, updateversion): + printFrameLine() + for result in results: + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + failedResults = filter(lambda x: x[1] == None or x[1] not in responseCodes, results) + if (len(failedResults) > 0): + errorAndExit(1, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + debugf = None + updateversion = 'true' + importCommon.debugFlag = False + + try: + opts, args = getopt.getopt(argv,"i:p:u:d:v:h",["ip=","port=","user=","debug=","updateversion="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-d", "--debug"): + print arg + debugf = bool(arg.lower() == "true" or arg.lower() == "yes") + elif opt in ("-v", "--updateversion"): + print arg + if (arg.lower() == "false" or arg.lower() == "no"): + updateversion = 'false' + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser, ', debug =', debugf, ', updateversion =', updateversion + + if (debugf != None): + print 'set debug mode to ' + str(debugf) + importCommon.debugFlag = debugf + + if ( beHost == None ): + usage() + sys.exit(3) + + print sys.argv[0] + pathdir = os.path.dirname(os.path.realpath(sys.argv[0])) + debug("path dir =" + pathdir) + + baseFileLocation = pathdir + "/../../../import/tosca/" + + fileLocation = baseFileLocation + "data-types/" + importDataTypes(beHost, bePort, adminUser, False, fileLocation) + + print 'sleep until data type cache is updated' + time.sleep( 70 ) + + fileLocation = baseFileLocation + "capability-types/" + importNormativeCapabilities(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "interface-lifecycle-types/" + importNormativeInterfaceLifecycleType(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "categories/" + importCategories(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "normative-types/" + results = importNormativeTypes(beHost, bePort, adminUser, fileLocation, updateversion) + handleResults(results, updateversion) + + fileLocation = baseFileLocation + "heat-types/" + resultsHeat = importHeatTypes(beHost, bePort, adminUser, fileLocation, updateversion) + handleResults(resultsHeat, updateversion) + + fileLocation = baseFileLocation + "group-types/" + importGroupTypes(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "policy-types/" + importPolicyTypes(beHost, bePort, adminUser, False, fileLocation) + + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeCapabilities.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeCapabilities.py new file mode 100644 index 0000000000..bda02ddda9 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeCapabilities.py @@ -0,0 +1,77 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement +from importCommon import * +import importCommon + +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importNormativeCapabilities(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/capability", "capabilityTypes", "capabilityTypeZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + importCommon.errorAndExit(1, None) + else: + if (exitOnSuccess == True): + importCommon.errorAndExit(0, None) + + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + importCommon.errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importNormativeCapabilities(beHost, bePort, adminUser, True, "../../../import/tosca/capability-types/") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeElements.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeElements.py new file mode 100644 index 0000000000..af643da4f4 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeElements.py @@ -0,0 +1,65 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importCommon import * +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def createNormativeElement(beHost, bePort, adminUser, fileDir, urlSuffix, ELEMENT_NAME, elementFormName): + + try: + log("in create normative element ", ELEMENT_NAME) + + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + urlSuffix + c.setopt(c.URL, url) + c.setopt(c.POST, 1) + + adminHeader = 'USER_ID: ' + adminUser + #c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + c.setopt(pycurl.HTTPHEADER, [adminHeader]) + + + path = fileDir + "/" + ELEMENT_NAME + ".zip" + debug(path) + + send = [(elementFormName, (pycurl.FORM_FILE, path))] + debug(send) + c.setopt(pycurl.HTTPPOST, send) + + #data = json.dumps(user) + #c.setopt(c.POSTFIELDS, data) + + #c.setopt(c.WRITEFUNCTION, lambda x: None) + c.setopt(c.WRITEFUNCTION, buffer.write) + #print("before perform") + res = c.perform() + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + if (httpRes != None): + debug("http response=", httpRes) + #print('Status: ' + str(responseCode)) + debug("response buffer", buffer.getvalue()) + c.close() + + return (ELEMENT_NAME, httpRes, buffer.getvalue()) + + except Exception as inst: + print("ERROR=" + str(inst)) + return (ELEMENT_NAME, None, None) + + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeInterfaceLifecycleTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeInterfaceLifecycleTypes.py new file mode 100644 index 0000000000..33f1cc42de --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeInterfaceLifecycleTypes.py @@ -0,0 +1,75 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement +from importCommon import * + +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importNormativeInterfaceLifecycleType(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/interfaceLifecycle", "interfaceLifecycleTypes", "interfaceLifecycleTypeZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + errorAndExit(1, None) + else: + if (exitOnSuccess == True): + errorAndExit(0, None) + + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importNormativeInterfaceLifecycleType(beHost, bePort, adminUser, True, "../../../import/tosca/interface-lifecycle-types//") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importNormativeTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeTypes.py new file mode 100644 index 0000000000..76bae682c0 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importNormativeTypes.py @@ -0,0 +1,159 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importCommon import * +import importCommon +################################################################################################################################################ +# # +# Import all users from a given file # +# # +# activation : # +# python importUsers.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# [-v | --updateversion=] # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsers.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def createNormativeType(beHost, bePort, adminUser, fileDir, ELEMENT_NAME, updateversion): + + try: + log("in create normative type ", ELEMENT_NAME) + debug("userId", adminUser) + debug("fileDir", fileDir) + + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/catalog/upload/multipart' + if updateversion != None: + url += '?createNewVersion=' + updateversion + c.setopt(c.URL, url) + c.setopt(c.POST, 1) + + adminHeader = 'USER_ID: ' + adminUser + #c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + c.setopt(pycurl.HTTPHEADER, [adminHeader]) + + + path = fileDir + ELEMENT_NAME + "/" + ELEMENT_NAME + ".zip" + debug(path) + CURRENT_JSON_FILE=fileDir + ELEMENT_NAME + "/" + ELEMENT_NAME + ".json" + #sed -i 's/"userId": ".*",/"userId": "'${ATT_UID}'",/' ${CURRENT_JSON_FILE} + + jsonFile = open(CURRENT_JSON_FILE) + + debug("before load json") + json_data = json.load(jsonFile, strict=False) + debug(json_data) + + jsonAsStr = json.dumps(json_data) + + send = [('resourceMetadata', jsonAsStr), ('resourceZip', (pycurl.FORM_FILE, path))] + debug(send) + c.setopt(pycurl.HTTPPOST, send) + + #data = json.dumps(user) + #c.setopt(c.POSTFIELDS, data) + + #c.setopt(c.WRITEFUNCTION, lambda x: None) + c.setopt(c.WRITEFUNCTION, buffer.write) + #print("before perform") + res = c.perform() + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + if (httpRes != None): + debug("http response=", httpRes) + #print('Status: ' + str(responseCode)) + debug(buffer.getvalue()) + c.close() + + return (ELEMENT_NAME, httpRes, buffer.getvalue()) + + except Exception as inst: + print("ERROR=" + str(inst)) + return (ELEMENT_NAME, None, None) + + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-v | --updateversion=]' + + +def importNormativeTypes(beHost, bePort, adminUser, fileDir, updateversion): + + normativeTypes = [ "root", "compute", "softwareComponent", "webServer", "webApplication", "DBMS", "database", "objectStorage", "blockStorage", "containerRuntime", "containerApplication", "loadBalancer", "port", "network"] + #normativeTypes = [ "root" ] + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + results = [] + for normativeType in normativeTypes: + result = createNormativeType(beHost, bePort, adminUser, fileDir, normativeType, updateversion) + results.append(result) + if ( result[1] == None or result[1] not in responseCodes ): + print "Failed creating normative type " + normativeType + ". " + str(result[1]) + return results + + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + updateversion = 'true' + + try: + opts, args = getopt.getopt(argv,"i:p:u:v:h:",["ip=","port=","user=","updateversion="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-v", "--updateversion"): + if (arg.lower() == "false" or arg.lower() == "no"): + updateversion = 'false' + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser, ', updateversion =', updateversion + + if ( beHost == None ): + usage() + sys.exit(3) + + results = importNormativeTypes(beHost, bePort, adminUser, "../../../import/tosca/normative-types/", updateversion) + + print "-----------------------------" + for result in results: + print "{0:20} | {1:6}".format(result[0], result[1]) + print "-----------------------------" + + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + failedNormatives = filter(lambda x: x[1] == None or x[1] not in responseCodes, results) + if (len(failedNormatives) > 0): + errorAndExit(1, None) + else: + errorAndExit(0, None) + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importPolicyTypes.py b/catalog-be/src/main/resources/scripts/import/tosca/importPolicyTypes.py new file mode 100644 index 0000000000..c01e159264 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importPolicyTypes.py @@ -0,0 +1,74 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +from importNormativeElements import createNormativeElement + +from importCommon import * +################################################################################################################################################ +# # +# Import tosca data types # +# # +# activation : # +# python importPolicyTypes.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importPolicyTypes.py [-f | --ifile= ] # +# # +################################################################################################################################################ + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ]' + + +def importPolicyTypes(beHost, bePort, adminUser, exitOnSuccess, fileDir): + result = createNormativeElement(beHost, bePort, adminUser, fileDir, "/sdc2/rest/v1/catalog/uploadType/policytypes", "policyTypes", "policyTypesZip") + + printFrameLine() + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + if ( result[1] == None or result[1] not in [200, 201, 409] ): + errorAndExit(1, None) + else: + if (exitOnSuccess == True): + errorAndExit(0, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:u:h:",["ip=","port=","user="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser + + if ( beHost == None ): + usage() + sys.exit(3) + + importPolicyTypes(beHost, bePort, adminUser, True, "../../../import/tosca/policy-types/") + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/importUsersFromYaml.py b/catalog-be/src/main/resources/scripts/import/tosca/importUsersFromYaml.py new file mode 100644 index 0000000000..8509855f38 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/importUsersFromYaml.py @@ -0,0 +1,221 @@ +import pycurl +import sys, getopt +from StringIO import StringIO +import json +import copy +import yaml + +######################################################################################################################################################## +# # +# Import all users from a given YAML file # +# # +# activation : # +# python importUsersFromYaml.py [-i | --ip=] [-p | --port= ] [-f | --ifile= ] # +# # +# shortest activation (be host = localhost, be port = 8080): # # +# python importUsersFromYaml.py [-f | --ifile= ] # +# # +# PyYAML module shall be added to python. # +# pip install PyYAML>=3.1.0 --proxy=http://one.proxy.att.com:8080 # +######################################################################################################################################################## + + +def importUsers(beHost, bePort, users, adminUser): + + result = [] + + for user in users: + + #print("Going to add user " + user['userId']) + + getRes = getUser(beHost, bePort, user) + userId = getRes[0] + error = getRes[1] + #print error + if ( error != None and error == 404 ): + res = createUser(beHost, bePort, user ,adminUser) + result.append(res) + else: + if ( error == 200 ): + curResult = (userId, 409) + result.append(curResult) + else: + result.append(getRes) + + return result + + +def getUser(beHost, bePort, user): + + if (user.get('userId') == None): + print "Ignoring record", user + return ('NotExist', 200) + userId = user['userId'] + try: + buffer = StringIO() + c = pycurl.Curl() + + #print type(userId) + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/user/' + str(userId) + c.setopt(c.URL, url) + + #adminHeader = 'USER_ID: ' + adminUser + c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json']) + c.setopt(c.WRITEFUNCTION, lambda x: None) + res = c.perform() + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + #print("After get response code") + responseCode = c.getinfo(c.RESPONSE_CODE) + + #print('Status: ' + str(responseCode)) + + c.close() + + return (userId, httpRes) + + except Exception as inst: + print(inst) + return (userId, None) + + + +def createUser(beHost, bePort, user, adminUser): + + if (user.get('userId') == None): + print "Ignoring record", user + return ('NotExist', 200) + + userId = user['userId'] + try: + buffer = StringIO() + c = pycurl.Curl() + + url = 'http://' + beHost + ':' + bePort + '/sdc2/rest/v1/user' + c.setopt(c.URL, url) + c.setopt(c.POST, 1) + + adminHeader = 'USER_ID: ' + adminUser + c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json', 'Accept: application/json', adminHeader]) + + data = json.dumps(user) + c.setopt(c.POSTFIELDS, data) + + c.setopt(c.WRITEFUNCTION, lambda x: None) + #print("before perform") + res = c.perform() + #print(res) + + #print("Before get response code") + httpRes = c.getinfo(c.RESPONSE_CODE) + #print("After get response code") + responseCode = c.getinfo(c.RESPONSE_CODE) + + #print('Status: ' + str(responseCode)) + + c.close() + + return (userId, httpRes) + + except Exception as inst: + print(inst) + return (userId, None) + + +def errorAndExit(errorCode, errorDesc): + if ( errorCode > 0 ): + print("status=" + str(errorCode) + ". " + errorDesc) + else: + print("status=" + str(errorCode)) + sys.exit(errorCode) + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-f | --ifile= ]' + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + inputfile = None + + adminUser = 'jh0003' + + try: + opts, args = getopt.getopt(argv,"i:p:f:h:",["ip=","port=","ifile="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-f", "--ifile"): + inputfile = arg + + print 'be host =',beHost,', be port =', bePort,', users file =',inputfile + + if ( inputfile == None ): + usage() + sys.exit(3) + + print 'Input file is ', inputfile + + + usersAsYamlFile = open(inputfile, 'r') + usersDoc = yaml.load(usersAsYamlFile) + print usersDoc + + cloneUsers = [] + for users in usersDoc.values(): + for x,y in users.items(): + copiedUser = y + copiedUser['userId'] = x + #print copiedUser + cloneUsers.append(copiedUser) + + print cloneUsers + + usersAsYamlFile.close() + + #activeUsers = filter(lambda x: x.get('status') == None or x['status'] == 'ACTIVE', cloneUsers) + + resultTable = importUsers(beHost, bePort, cloneUsers, adminUser) + + g = lambda x: x[1] != 201 and x[1] != 409 + + result = filter(g, resultTable) + + if ( len(result) > 0 ): + #print("ERROR: Failed to load the users " + ', '.join(map(lambda x: x[0],result))) + errorAndExit(3, "Failed to load the users " + ', '.join(map(lambda x: x[0],result))) + + g = lambda x: x[1] == 409 + result = filter(g, resultTable) + + print("-------------------------------------------") + print("Existing users: " + ', '.join(map(lambda x: x[0],result))) + + result = filter(lambda x: x[1] == 201, resultTable) + if ( len(result) == 0 ): + print("-------------------------------------------") + print("No NEW user was loaded. All users are already exist") + print("-------------------------------------------") + else: + print("-------------------------------------------") + print("Loaded users: " + ', '.join(map(lambda x: x[0],result))) + print("-------------------------------------------") + + errorAndExit(0, None) + + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py new file mode 100644 index 0000000000..e6bb620692 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormative.py @@ -0,0 +1,114 @@ +import pycurl +import sys, getopt, os +from StringIO import StringIO +import json +import copy +import time +from importCategoryTypes import importCategories +from importHeatTypes import importHeatTypes +from importNormativeCapabilities import importNormativeCapabilities +from importDataTypes import importDataTypes +from importGroupTypes import importGroupTypes +from importPolicyTypes import importPolicyTypes +from importCommon import * +import importCommon + +################################################################################################################################################################################################# +# # +# Upgrades the normative types # +# # +# activation : # +# python upgradeNormative.py [-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=] # +# # +# # +# shortest activation (be host = localhost, be port = 8080, user = jh0003): # # # +# python upgradeNormative.py # +# # +################################################################################################################################################################################################# + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=]' + +def handleResults(results, updateversion): + printFrameLine() + for result in results: + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + failedResults = filter(lambda x: x[1] == None or x[1] not in [200, 201, 409], results) + if (len(failedResults) > 0): + errorAndExit(1, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + debugf = None + updateversion = 'false' + importCommon.debugFlag = False + + try: + opts, args = getopt.getopt(argv,"i:p:u:d:h",["ip=","port=","user=","debug="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-d", "--debug"): + print arg + debugf = bool(arg.lower() == "true" or arg.lower() == "yes") + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser, ', debug =', debugf + + if (debugf != None): + print 'set debug mode to ' + str(debugf) + importCommon.debugFlag = debugf + + if ( beHost == None ): + usage() + sys.exit(3) + + print sys.argv[0] + pathdir = os.path.dirname(os.path.realpath(sys.argv[0])) + debug("path dir =" + pathdir) + + baseFileLocation = pathdir + "/../../../import/tosca/" + + fileLocation = baseFileLocation + "categories/" + importCategories(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "data-types/" + importDataTypes(beHost, bePort, adminUser, False, fileLocation) + + print 'sleep until data type cache is updated' + time.sleep( 70 ) + fileLocation = baseFileLocation + "capability-types/" + importNormativeCapabilities(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "group-types/" + importGroupTypes(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "policy-types/" + importPolicyTypes(beHost, bePort, adminUser, False, fileLocation) + + fileLocation = baseFileLocation + "heat-types/" + resultsHeat = importHeatTypes(beHost, bePort, adminUser, fileLocation, updateversion) + handleResults(resultsHeat, 'false') + + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersion.py b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersion.py new file mode 100644 index 0000000000..0f70174173 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersion.py @@ -0,0 +1,143 @@ +import pycurl +import sys, getopt, os +from StringIO import StringIO +import json +import copy +from importCommon import * +from importNormativeTypes import createNormativeType +import importCommon + +################################################################################################################################################################################################# +# # +# Upgrades the normative types # +# # +# activation : # +# python upgradeNormative.py [-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=] # +# # +# # +# shortest activation (be host = localhost, be port = 8080, user = jh0003): # # # +# python upgradeNormative.py # +# # +################################################################################################################################################################################################# + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=]' + +def handleResults(results, updateversion): + printFrameLine() + for result in results: + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + failedResults = filter(lambda x: x[1] == None or x[1] not in [200, 201, 409], results) + if (len(failedResults) > 0): + errorAndExit(1, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + debugf = None + updateversion = 'true' + importCommon.debugFlag = False + + try: + opts, args = getopt.getopt(argv,"i:p:u:d:h",["ip=","port=","user=","debug="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-d", "--debug"): + print arg + debugf = bool(arg.lower() == "true" or arg.lower() == "yes") + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser, ', debug =', debugf + + if (debugf != None): + print 'set debug mode to ' + str(debugf) + importCommon.debugFlag = debugf + + if ( beHost == None ): + usage() + sys.exit(3) + + print sys.argv[0] + pathdir = os.path.dirname(os.path.realpath(sys.argv[0])) + debug("path dir =" + pathdir) + + baseFileLocation = pathdir + "/../../../import/tosca/" + results = [] + + + ########################################################################## + #---------------------------------for release 1610---------------------- # + ########################################################################## + + fileLocation = baseFileLocation + "normative-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "compute", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "normative-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "network", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "abstractSubstitute", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "contrailAbstractSubstitute", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "contrailNetworkRules", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "novaServer", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "neutronPort", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "contrailVirtualNetwork", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "neutronNet", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "vl", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "contrailV2VirtualNetwork", updateversion) + results.append(result) + + fileLocation = baseFileLocation + "heat-types/" + result = createNormativeType(beHost, bePort, adminUser, fileLocation, "securityRules", updateversion) + results.append(result) + + handleResults(results, 'false') + + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersionAll.py b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersionAll.py new file mode 100644 index 0000000000..72198ceab6 --- /dev/null +++ b/catalog-be/src/main/resources/scripts/import/tosca/upgradeNormativeVersionAll.py @@ -0,0 +1,93 @@ +import pycurl +import sys, getopt, os +from StringIO import StringIO +import json +import copy +import time +from importNormativeTypes import importNormativeTypes +from importHeatTypes import importHeatTypes +from importCommon import * +import importCommon + +def usage(): + print sys.argv[0], '[-i | --ip=] [-p | --port= ] [-u | --user= ] [-d | --debug=] [-v | --updateversion=]' + +def handleResults(results, updateversion): + printFrameLine() + for result in results: + printNameAndReturnCode(result[0], result[1]) + printFrameLine() + + responseCodes = [200, 201] + + if(updateversion == 'false'): + responseCodes = [200, 201, 409] + + failedResults = filter(lambda x: x[1] == None or x[1] not in responseCodes, results) + if (len(failedResults) > 0): + errorAndExit(1, None) + +def main(argv): + print 'Number of arguments:', len(sys.argv), 'arguments.' + + beHost = 'localhost' + bePort = '8080' + adminUser = 'jh0003' + debugf = None + updateversion = 'true' + importCommon.debugFlag = False + + try: + opts, args = getopt.getopt(argv,"i:p:u:d:v:h",["ip=","port=","user=","debug=","updateversion="]) + except getopt.GetoptError: + usage() + errorAndExit(2, 'Invalid input') + + for opt, arg in opts: + #print opt, arg + if opt == '-h': + usage() + sys.exit(3) + elif opt in ("-i", "--ip"): + beHost = arg + elif opt in ("-p", "--port"): + bePort = arg + elif opt in ("-u", "--user"): + adminUser = arg + elif opt in ("-d", "--debug"): + print arg + debugf = bool(arg.lower() == "true" or arg.lower() == "yes") + elif opt in ("-v", "--updateversion"): + print arg + if (arg.lower() == "false" or arg.lower() == "no"): + updateversion = 'false' + + print 'be host =',beHost,', be port =', bePort,', user =', adminUser, ', debug =', debugf, ', updateversion =', updateversion + + if (debugf != None): + print 'set debug mode to ' + str(debugf) + importCommon.debugFlag = debugf + + if ( beHost == None ): + usage() + sys.exit(3) + + print sys.argv[0] + pathdir = os.path.dirname(os.path.realpath(sys.argv[0])) + debug("path dir =" + pathdir) + + baseFileLocation = pathdir + "/../../../import/tosca/" + + fileLocation = baseFileLocation + "normative-types/" + results = importNormativeTypes(beHost, bePort, adminUser, fileLocation, updateversion) + handleResults(results, updateversion) + + fileLocation = baseFileLocation + "heat-types/" + resultsHeat = importHeatTypes(beHost, bePort, adminUser, fileLocation, updateversion) + handleResults(resultsHeat, updateversion) + + errorAndExit(0, None) + +if __name__ == "__main__": + main(sys.argv[1:]) + diff --git a/catalog-be/src/main/resources/swagger/css/print.css b/catalog-be/src/main/resources/swagger/css/print.css new file mode 100644 index 0000000000..b4fc18036e --- /dev/null +++ b/catalog-be/src/main/resources/swagger/css/print.css @@ -0,0 +1,1155 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #8888ff; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + max-width: 960px; + margin-left: auto; + margin-right: auto; +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; +} +.swagger-section .api-popup-dialog { + z-index: 10000; + position: absolute; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + color: #777; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog p.error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog button.api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog button.api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +#header { + display: none; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + max-height: none; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 100px; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 100px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + display: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints { + display: block !important; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + display: block !important; +} diff --git a/catalog-be/src/main/resources/swagger/css/reset.css b/catalog-be/src/main/resources/swagger/css/reset.css new file mode 100644 index 0000000000..b2b078943c --- /dev/null +++ b/catalog-be/src/main/resources/swagger/css/reset.css @@ -0,0 +1,125 @@ +/* http://meyerweb.com/eric/tools/css/reset/ v2.0 | 20110126 */ +html, +body, +div, +span, +applet, +object, +iframe, +h1, +h2, +h3, +h4, +h5, +h6, +p, +blockquote, +pre, +a, +abbr, +acronym, +address, +big, +cite, +code, +del, +dfn, +em, +img, +ins, +kbd, +q, +s, +samp, +small, +strike, +strong, +sub, +sup, +tt, +var, +b, +u, +i, +center, +dl, +dt, +dd, +ol, +ul, +li, +fieldset, +form, +label, +legend, +table, +caption, +tbody, +tfoot, +thead, +tr, +th, +td, +article, +aside, +canvas, +details, +embed, +figure, +figcaption, +footer, +header, +hgroup, +menu, +nav, +output, +ruby, +section, +summary, +time, +mark, +audio, +video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, +aside, +details, +figcaption, +figure, +footer, +header, +hgroup, +menu, +nav, +section { + display: block; +} +body { + line-height: 1; +} +ol, +ul { + list-style: none; +} +blockquote, +q { + quotes: none; +} +blockquote:before, +blockquote:after, +q:before, +q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/catalog-be/src/main/resources/swagger/css/screen.css b/catalog-be/src/main/resources/swagger/css/screen.css new file mode 100644 index 0000000000..32b199b17b --- /dev/null +++ b/catalog-be/src/main/resources/swagger/css/screen.css @@ -0,0 +1,1256 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #8888ff; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + max-width: 960px; + margin-left: auto; + margin-right: auto; +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; +} +.swagger-section .api-popup-dialog { + z-index: 10000; + position: absolute; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + color: #777; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog p.error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog button.api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog button.api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +.swagger-section .access { + float: right; +} +.swagger-section .auth { + float: right; +} +.swagger-section #api_information_panel { + position: absolute; + background: #FFF; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + max-width: 300px; + line-height: 30px; + color: black; + padding: 5px; +} +.swagger-section #api_information_panel p .api-msg-enabled { + color: green; +} +.swagger-section #api_information_panel p .api-msg-disabled { + color: red; +} +.swagger-section .api-ic { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .ic-info { + background-position: 0 0; + width: 18px; + margin-top: -7px; + margin-left: 4px; +} +.swagger-section .ic-warning { + background-position: -60px 0; + width: 18px; + margin-top: -7px; + margin-left: 4px; +} +.swagger-section .ic-error { + background-position: -30px 0; + width: 18px; + margin-top: -7px; + margin-left: 4px; +} +.swagger-section .ic-off { + background-position: -90px 0; + width: 58px; + margin-top: -4px; + cursor: pointer; +} +.swagger-section .ic-on { + background-position: -160px 0; + width: 58px; + margin-top: -4px; + cursor: pointer; +} +.swagger-section #header { + background-color: #89bf04; + padding: 14px; +} +.swagger-section #header a#logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo_small.png) no-repeat left center; + padding: 20px 0 20px 40px; + color: white; +} +.swagger-section #header form#api_selector { + display: block; + clear: none; + float: right; +} +.swagger-section #header form#api_selector .input { + display: block; + clear: none; + float: left; + margin: 0 10px 0 0; +} +.swagger-section #header form#api_selector .input input#input_apiKey { + width: 200px; +} +.swagger-section #header form#api_selector .input input#input_baseUrl { + width: 400px; +} +.swagger-section #header form#api_selector .input a#explore { + display: block; + text-decoration: none; + font-weight: bold; + padding: 6px 8px; + font-size: 0.9em; + color: white; + background-color: #547f00; + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + -o-border-radius: 4px; + -ms-border-radius: 4px; + -khtml-border-radius: 4px; + border-radius: 4px; +} +.swagger-section #header form#api_selector .input a#explore:hover { + background-color: #547f00; +} +.swagger-section #header form#api_selector .input input { + font-size: 0.9em; + padding: 3px; + margin: 0; +} +.swagger-section #content_message { + margin: 10px 15px; + font-style: italic; + color: #999999; +} +.swagger-section #message-bar { + min-height: 30px; + text-align: center; + padding-top: 10px; +} diff --git a/catalog-be/src/main/resources/swagger/css/typography.css b/catalog-be/src/main/resources/swagger/css/typography.css new file mode 100644 index 0000000000..27c3751ac2 --- /dev/null +++ b/catalog-be/src/main/resources/swagger/css/typography.css @@ -0,0 +1,26 @@ +/* droid-sans-regular - latin */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 400; + src: url('../fonts/droid-sans-v6-latin-regular.eot'); /* IE9 Compat Modes */ + src: local('Droid Sans'), local('DroidSans'), + url('../fonts/droid-sans-v6-latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/droid-sans-v6-latin-regular.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/droid-sans-v6-latin-regular.woff') format('woff'), /* Modern Browsers */ + url('../fonts/droid-sans-v6-latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../fonts/droid-sans-v6-latin-regular.svg#DroidSans') format('svg'); /* Legacy iOS */ +} +/* droid-sans-700 - latin */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 700; + src: url('../fonts/droid-sans-v6-latin-700.eot'); /* IE9 Compat Modes */ + src: local('Droid Sans Bold'), local('DroidSans-Bold'), + url('../fonts/droid-sans-v6-latin-700.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */ + url('../fonts/droid-sans-v6-latin-700.woff2') format('woff2'), /* Super Modern Browsers */ + url('../fonts/droid-sans-v6-latin-700.woff') format('woff'), /* Modern Browsers */ + url('../fonts/droid-sans-v6-latin-700.ttf') format('truetype'), /* Safari, Android, iOS */ + url('../fonts/droid-sans-v6-latin-700.svg#DroidSans') format('svg'); /* Legacy iOS */ +} diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.eot b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.eot new file mode 100644 index 0000000000..d8524983ad Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.eot differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.svg b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.svg new file mode 100644 index 0000000000..a54bbbbf25 --- /dev/null +++ b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.svg @@ -0,0 +1,411 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.ttf b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.ttf new file mode 100644 index 0000000000..15896c441f Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.ttf differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff new file mode 100644 index 0000000000..67e3e25f83 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff2 b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff2 new file mode 100644 index 0000000000..1e726a7cfc Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-700.woff2 differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.eot b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.eot new file mode 100644 index 0000000000..ac2698e85a Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.eot differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.svg b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.svg new file mode 100644 index 0000000000..d9f2a214f9 --- /dev/null +++ b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.svg @@ -0,0 +1,403 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.ttf b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.ttf new file mode 100644 index 0000000000..fb8cea662b Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.ttf differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff new file mode 100644 index 0000000000..abf19899f7 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff differ diff --git a/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff2 b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff2 new file mode 100644 index 0000000000..9f93f74c3b Binary files /dev/null and b/catalog-be/src/main/resources/swagger/fonts/droid-sans-v6-latin-regular.woff2 differ diff --git a/catalog-be/src/main/resources/swagger/images/explorer_icons.png b/catalog-be/src/main/resources/swagger/images/explorer_icons.png new file mode 100644 index 0000000000..ed9d2fffb6 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/explorer_icons.png differ diff --git a/catalog-be/src/main/resources/swagger/images/favicon-16x16.png b/catalog-be/src/main/resources/swagger/images/favicon-16x16.png new file mode 100644 index 0000000000..66b1a5bfb9 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/favicon-16x16.png differ diff --git a/catalog-be/src/main/resources/swagger/images/favicon-32x32.png b/catalog-be/src/main/resources/swagger/images/favicon-32x32.png new file mode 100644 index 0000000000..32f319f89b Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/favicon-32x32.png differ diff --git a/catalog-be/src/main/resources/swagger/images/favicon.ico b/catalog-be/src/main/resources/swagger/images/favicon.ico new file mode 100644 index 0000000000..8b60bcf06a Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/favicon.ico differ diff --git a/catalog-be/src/main/resources/swagger/images/logo_small.png b/catalog-be/src/main/resources/swagger/images/logo_small.png new file mode 100644 index 0000000000..5496a65579 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/logo_small.png differ diff --git a/catalog-be/src/main/resources/swagger/images/pet_store_api.png b/catalog-be/src/main/resources/swagger/images/pet_store_api.png new file mode 100644 index 0000000000..f9f9cd4aeb Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/pet_store_api.png differ diff --git a/catalog-be/src/main/resources/swagger/images/throbber.gif b/catalog-be/src/main/resources/swagger/images/throbber.gif new file mode 100644 index 0000000000..0639388924 Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/throbber.gif differ diff --git a/catalog-be/src/main/resources/swagger/images/wordnik_api.png b/catalog-be/src/main/resources/swagger/images/wordnik_api.png new file mode 100644 index 0000000000..dca4f1455a Binary files /dev/null and b/catalog-be/src/main/resources/swagger/images/wordnik_api.png differ diff --git a/catalog-be/src/main/resources/swagger/index.html b/catalog-be/src/main/resources/swagger/index.html new file mode 100644 index 0000000000..0e9a9e8de3 --- /dev/null +++ b/catalog-be/src/main/resources/swagger/index.html @@ -0,0 +1,123 @@ + + + + Swagger UI + + + + + + + + + + + + + + + + + + + + + + + + +
 
+
+ + diff --git a/catalog-be/src/main/resources/swagger/lib/backbone-min.js b/catalog-be/src/main/resources/swagger/lib/backbone-min.js new file mode 100644 index 0000000000..f082fcffca --- /dev/null +++ b/catalog-be/src/main/resources/swagger/lib/backbone-min.js @@ -0,0 +1,35 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 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========================================================= + */ + +// Backbone.js 1.1.2 + +(function(t,e){if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){t.Backbone=e(t,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore");e(t,exports,i)}else{t.Backbone=e(t,{},t._,t.jQuery||t.Zepto||t.ender||t.$)}})(this,function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.push;var o=n.slice;var h=n.splice;e.VERSION="1.1.2";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var u=e.Events={on:function(t,e,i){if(!c(this,"on",t,[e,i])||!e)return this;this._events||(this._events={});var r=this._events[t]||(this._events[t]=[]);r.push({callback:e,context:i,ctx:i||this});return this},once:function(t,e,r){if(!c(this,"once",t,[e,r])||!e)return this;var s=this;var n=i.once(function(){s.off(t,n);e.apply(this,arguments)});n._callback=e;return this.on(t,n,r)},off:function(t,e,r){var s,n,a,o,h,u,l,f;if(!this._events||!c(this,"off",t,[e,r]))return this;if(!t&&!e&&!r){this._events=void 0;return this}o=t?[t]:i.keys(this._events);for(h=0,u=o.length;h").attr(t);this.setElement(r,false)}else{this.setElement(i.result(this,"el"),false)}}});e.sync=function(t,r,s){var n=T[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||M()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}if(a.type==="PATCH"&&k){a.xhr=function(){return new ActiveXObject("Microsoft.XMLHTTP")}}var h=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,h,s);return h};var k=typeof window!=="undefined"&&!!window.ActiveXObject&&!(window.XMLHttpRequest&&(new XMLHttpRequest).dispatchEvent);var T={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var $=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var S=/\((.*?)\)/g;var H=/(\(\?)?:\w+/g;var A=/\*\w+/g;var I=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend($.prototype,u,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);n.execute(s,a);n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)});return this},execute:function(t,e){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(I,"\\$&").replace(S,"(?:$1)?").replace(H,function(t,e){return e?t:"([^/?]+)"}).replace(A,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var N=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var R=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var P=/msie [\w.]+/;var C=/\/$/;var j=/#.*$/;N.started=false;i.extend(N.prototype,u,{interval:50,atRoot:function(){return this.location.pathname.replace(/[^\/]$/,"$&/")===this.root},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getFragment:function(t,e){if(t==null){if(this._hasPushState||!this._wantsHashChange||e){t=decodeURI(this.location.pathname+this.location.search);var i=this.root.replace(C,"");if(!t.indexOf(i))t=t.slice(i.length)}else{t=this.getHash()}}return t.replace(R,"")},start:function(t){if(N.started)throw new Error("Backbone.history has already been started");N.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.options.pushState&&this.history&&this.history.pushState);var r=this.getFragment();var s=document.documentMode;var n=P.exec(navigator.userAgent.toLowerCase())&&(!s||s<=7);this.root=("/"+this.root+"/").replace(O,"/");if(n&&this._wantsHashChange){var a=e.$('

Id`W(A8Bq#TwqeQ!0a+5zA;-X!?HGqEIe}mT+?3&v{}_7GFjGQb@-w +xR#W2Q|(yof0HE09NkBbiA~0lmdhFabNB%FuvzAlw+p-{5h6MS +ijhBQL!s%BC3SMYuYRRN19|SIdWCopJtGA9`I|uHmu}jNB>U^nu~aw-^D$aHRY +sz~W6sk#==_6@x!?xnd_mlPgp<3_xVGC#oVEad|H1eJ-4P#{N_3s?|YpPPON`!EUW<#}i?c6 +|=waJA$J^H<>AWp+!V-=GM&YVm)Uk>zwy;x0&_D>FQ)5PF+*=KGTfz?Ro0aA#{UdODjgQ++I>v)jW~T +SBT$_J#ky%<7G}nj}2``QK=91it^7DN>Qc3c}f_PTdL9PRJdnLYh`?;Dch2Askg)rFg$qjrp?(X){XGx#uZrH4R#MhQz`2& +?#IL(M7aq$j%hDfULxF;f}J+)5gADfGBZ!G4P_G#8cZ2v&(4YyD6W0`PvcR%r7SS&RO%m +cEoo{f4FNX|%4WN-+A{e@`njdCL{TuJv!b6MK6?8NTX!|K%S?rm$Cj^#c(il)wpLdsXK%2$4QMTc&E@ +RfahZcKihOGBSzfi9dF;}FLuoVm;+{Mp~H557+9@+J+pQN1JfFdl5``H=c&$`OTu?@Y`+Nzolg{fa`f +!m|(ao2zse?An=U+OE0HVM}dTFk`a$7h+}K(LVX_MEieYp8Q*l^C#xXUmD|Q^Mt@iioiGqXE2OIIT9l +nl0X>>SSBdJ5e%@!DeCLh%0P)HEaZ8dfkGM(dlo?njZaQqxMD1u7HMVBL7V1ZnkS%xY$}MsGSG+twh6 +EpfRPf#lU2e^^)Iq1tT@H$FcO*$KqzzR&&(5I!A@>vVDq5)v|4#8kCEbV^#L$FK<^|2eYik(li5_;B8 +N8v777?`ghFcto0fusdjk^&rKa_0+?0&^%c69j%oFK$T4$U1=wA3_F6VmxXcXrEW9EtZ|C=ZOoO$xsC +-5ILPu9fdY$@lVX|HTB!w}Wvyz%zLmQSfZmO-sHZ5Wd=|-1>C8Y`X^S$&oU2&TU>bT +{x_I!R^o_iz4Nv33n?N)8-`=!|Q%zD2J@1wAr`vKDB_N}sqgkK+aGb +iOh%eJbHhK=Ox&c-;aBq_WQbEJOaKGW;JG*7Desfkc7rqf+6DFTI2L1J-M7cM1sFfH +e2i2&9=9L_h2{SYT)Uc>9GAW8M^Um3;zAy9{Rr0q)kof7o?zXiW2~c5|m>!-)e!A<~+4?y`Cu8bbrt* +Pq|gs_@=F|XmVRWYsujzK?zT&a +0xZ9DHjnOq^5+*@#!(q(>>i5g3%dDUs_iX_boS`X{V7@jfa%fMmC}j9#st=OU6Z;a-tDaLZM-~_buz+K-$g;2N+;T8j%f;|gEP_S| +T-z7JDu{Rtmyn<+ygFuKq&A;crUMHDkUPQs#H66{skq~`NF10dz)FCA{PaB&H-&zDGM`F$P0{RVs&Jc +5h6R;R)pa><dg17e@&+dGObSs1z6_zceXu0My{{9|cg*>)!mb0E#H|-!0rmrj^?gzyHX)McpoaEl1 +nMt&8gRt>3;cMH^Q{N+ezAQRwS3G^#^F-+Y*uU~6gv{l(8jB#QuWP|~{XrsPk6o9>ZsjhZ@~15fMLw% +q8V{=Nh+LDs5%)+8Aad0kkadIlXA_Upw>D9N-g74NCGgZ14A{wRL(srulbuHAcI|wuMaJJ)cb|S +04uHi!Ht-EQ^iw>*SZg}!3f+qBXAgsthdIp-f!?0zjb=t$Jf|ofXU%inp*bc9$sEzp)EM?jSnLDcU1~ +-t65*0M?T^fJOwui{+T1cccDk{z_MLgnSH>m58i6YObA*mLf%Nq?Sch608q2y>dz#m-n6bJyvn^4{yE +)g%O+c)rtf-o65zC(Hsg%2kTN8e6=&gwGY0?+Pa!TqJJyG5BsydV55~67_3ok&6$*SKf%k06=(=sC+y +dT*~TgC|Z7M!)E3mW!+_QL$^eL;Trh56b0g8c3a^RxE_`P~=hXYUL0!wd6O5geEuP4ms6G`@}OwQh%e +MxPC8>}`>oCg?3Y`ue(@h?ikduHf0p#MUL}Y1lHZOErq<%H^%BPTd=}hUu^Zt8MnbQ&oo*(h`v|hr7+ +$HLpGxN89`C3@cIL^leq09q$JR!`;QZxmXC-879ije0LA-e1v>1tMgG+$NavkPTzySn(S6)2hIVyfd6 +5&fbw4dvo`vkf1K-7UmwMb%W46NDs;tIJu_eVPebmn47DmTh8)Sk;thnO)-yKQxmf64gw5?XmH{3n#V +~Yvx0@M$8d$WPajHF3C`y&gMN6LDaf9!+8h7N96u}dtFv%g1%C)z_*VRUt(O1)dT*ei7pamxxTFmEt% +BiUP#&I@Wf3ay`na^VFA2X?bW~2NEj*{&E`YluC|AD9e7a3IlCd2#6oO-W6I(7f2wiQXEG>4PuSGHA_ +LC*{^ExaXgX!CH9oiSScSk;#4=dB8$)3nDPi +IIV_F2yb1+5+V6O7IR@mkVWNL)9@9Y(@qf}J4%w8_uD>U4{OA`r+4-%*0; +VC;1F-?2H7uZ+&$v^hszdRzMijLysVC;rOIvX->okcu;Wkp%6Br8@GPzGr!OTrAd;*1tN~=3=eYTX(5 +6K5>=SydZ1zVLkf$+76g|v5cCKNl8-|M)P(!^~T*^b6D0bqreEa8}*E_@_5=Vv5r{Y=FLhlGvpSi=gP +;)QN3^YxhzV?^LlppnqP8gvsP14Y{!y+Ug-Gr!ng7Kqve?3@xwQ)Ni(Hr5hOG-K{#%jL7$$g^WrB +jFVL_9r$whEtf^~el^>WSngt8dRxz=5&mkQa``TGvK=d-RT*&2DY(s10qIx4Wf{h4XZSD|c%xUF!CMK +=^Ua%_vcEi-XOdXZ~F~tF20o&Ky~u!ZbUc+(*Xp)xjxUA>nH=vL8IPidO1;Cg=7sbj9AJ3<77{k<|mu +TeT)3d04_P5%Mjm{Df+~DgE_zV95JIFc(-|sHO6cd%5b&veNVRu;Od4^ZBpRt)$6;CUr4VVNtAaQ@iy +CI*U@H;gS%%W{hx{uXSQj19IktrA?c{?XY66ZF1Z_?KwHLIRReQ;eWpNe@d=niuZifpfO{P(XdIRMj>qOE03YDMs7I +#=CWx2;CZW`+<-L0eaaH$yS=4{2_Mfe=n_6qBzjmLtQna0)2n0b%fx?GCm`9V=dVo|Ma_}yXMUot_AS +G%=)XJ$wom>W^M&#LU|x8hP|X9=6_x$I~tx)KlvM%0LLb(TabPl}aj-0&=p(Lz()c=wpgS0q>HDD9fC +)?Kz39V>L@-#0jfsJWNz36@>`W3QdJ-FyBx2FpBs9RAKG_{Vy9r|q9!{Y}h;peT~Ym@g9^rzKDv3DYL +H1ZF1!R!kXK$%uL_1Ur>CLZ^)M>?b8)Nx1SDM`2bwmBDQKJb}p{aM4o)qaZ8`7X~vdjE>+e>^O1Aktrn3+Qt9Twjq^!hBi`pY7G9F!5NDS?LxVwI{J +|yMDG&Xv_|NhJ%@R@A$Lm#&%r>4;lpma8Hlb712V1H}^NeId)pg=}E2>yxAFC;H)CS3$N$+H;Uxyo}uSqsz^kz5JYuD(CjePTcjvW-Z*hh)jA4rvg@sm{JF=y2H-iuBiEe^J7iT9$SU(9u7}a*+HW6`QYE9cm#Gt_(al#Bb=HTp +CNziY@&JY4SP4Rbt@`~K-K3*641;x?GDxX+7MQyGuTO$mVKsS_+$Rekg7p1hf8VzwRcpj`fcel07hB= +R(o!})U!p=!Yci`J87;Iso8kJ5J4vTHw*NAYY9!~14wb;Po}>XT(QvIE4={{EM)bwGY9!23le%gL`72 +YEv0f+Bx}maz#03QGzWgmak$NG(xfM8(^O`UXuWUo%;s=}JJhzu6sGuSg0o>Ak_{>c-f3SRa#y?(%0m +)ZtgH1^fUBlFzm02Sw$%edcIJ1&D+Z*h$NjBWQ07WuevxYGk?ZF}m>hJ0I>d!C_h+-vQY(q&#ry8CH^ +y4VqI$><<@_XGQA9o;i4zLUka5Vk5YO&OndKs*oma3Pm$iv=tdG506fjs#9cIM%ke?*>`(}AH^$|aY<{X=AbQavWr6u-)AK%iuz1brcr;(exG%M2n865zS +SED=MX2KGX=t|yPg0VgSzC`}ETKL<(aGB8E%42rB0fqNB>{B`Nx6{7Zx$d9p=qI(yzv$$bDf{fSi3Br +o6h37wax6@drzYTMro??fXwYpQFOuZz`Wo3(LOg=94oE_FD%YAMQ;t0b!va7yk_?oqBnr7J<=~oK4DN +RHvo&5hEI|$=WfnoXn-P!@VZH(dE2D$&fZ~AK%%_qb;1D&H&mf7ZOko6v0uH5c@$cKH!Q(ZBIyDqfu2y~`o?$P0M(!6f-= +;zHPknb9QU@sVDSW0~KQMl@lg65O!9(gTX{u*@uqr$m9RXG2#!1-JC4^e1Lz;KaAHB;q769v!so7*>Z +UEgwDHlGTak +{Vz=``9gRzFduvuAW?_2?==EUr+78=V*7l&Wv38DJ&FXP>snk06w36=RC6b|2=o~pw@%3QqhowYjyH@ +DZ^Kd*QzSiUNI~BCLYC?l#6=)%_Jz~-<;C6Em$$`T8*{(w0J2@YhvH+6WjL<#t-0y-JUCnP;dPO3&|C +VSr^y##;o{oB#?`&P+yY4h+3_rpTx34z6d#wO2NhR;9mtl6!@$1nHO}57>CXy^`6`xgmHJAg#+Qi23N +k-4+r&=~NX1||VHIIZ0DqLBjNb(^Xaa$%=QGl)uo-EWg^Guek=LltO-i6l1oSUeEnK}6QaFy_9CtA-3 +!d|q%&@Jq|)Dt!!5{4$I8xf)Pbq)+SK6~6A+7`RWfzWu(x^e$eApYkO_@9H`&sTrDQ0mK~eDt)oDa&C +d7CFT=6B<@E0=7LmRWhQcC@N@4;sx>bo_6W9#RE2NQwQ`0j93ydM44sK!3T~4;Q=%RKJ6ZnQ`6$wX)8 +MNXWl)SB~HUYCrQJadl3frntbzCv%%Oi1^Qv(de8&xZV<4?b_trjrjf?)^KFXEojAUV-}dXhzbiLbZDnV!CxgtcQpiiKp;SNxh<8 +qq&M=W;f3Rgc8qIX3*Ny+*OlHX@}ejm)56bt)=>YD_OV76gtGaNTJ!0krw)tQxC3pb9P&qQ)ewfZYtk +f`s0;+hUo*V&%<|>@772rt@d(y50xs+2v&BCTDVxmpr5|70j3>!1k9t$m>-rc?S?us=I +zcL#eGZd5;|$Hrr4@B+a?hnjxM*Ef1JE^VTYM&x;E~E +RPR;hu@q=CGS}g&0H@#pN{QvP=kYgeC9*P4=bvWigd574P-9lv-LT+-o15uu5d1=R^jNLF2z+NvcHl8 +%%|zAQ{=tIjL5%xS3VB$0`#wZ{A$~~uZnm7D>{3}-jBnZQ~x(NYP#%?ec`_M-h65FV%fC605w%=Bc@c +=7zQMO*_ljb3IKYhG+c5+!UdvV=fX~fZqN+oppw%HQxt<2!ENNGN(8T^Rg)CDU9x!ELxGsKApKb`ESt +cv3d&7|4I(%anDEL>5K6z*Pe`Y=wQyAtJJnj90GXS1_W_^{Zh%cB0&b7LE)bgbCCcDNKEKX|g+_1xXB +)mvE}P~%e6uZEc974J7SprpcNd1~Xv5Ox-oVVJ^$W%P}+oh92s9NtXoA>PrhN(i`Y +hAdvLURCuZ5_a`&5v72A3ksyG=8*IUl046_|QKx?9Zb{es|bEtCfoUSS(fan!9<}dr}$A4ua5+*|3!o +`MEQC+h5MOa4W-|FCUKT;a!7>(mh^V0ZozF)8J#}!Fvr)JjLg;Hm{wk6*1u*@4MN?jRhrPs?`~FHwTF +kPHZn2^bxtMTXfE-$+dbuQYQ3<*t?#(=De-YtxnX>9U+SKxjDoE+KU=D?C4N)haa7q&ps`>U>0^#Rk!{fwTi44qK7>O&HdnVzJl3o13wksP1C%3X_EkCn;~SMy-bH&0jZm +JIi?184zgqDa^eOBiZdx7H>%+2*Xdhv6?5SMB(Za4M%@Jo +VjTtNH&!uCf4>X{5S=Bvc%sCv$G~Vj|3f&z_H@IFr?rGQch>*mJU6i?$1tN?MQiUXU%pqk8 +g=v#n1V5jZ=QaVEa{roX7bL^`g7T4A(Y@A3K5=RcW)%*tojjmfGY+8>Nj~5Vu=X#=;)Z7y +e*G-rIKk0XS+L*j>%(uSzp|dd{jx&XX;asMO~opwZsiu6C*9uTN)y}CK)eD>wkcv<>8)Pk5Tg*wEA)C +Z;CbNm#m-VWHL_rX7OdR|=C4@F@osjX?XCWDR&ef2|gQL#;#-us@oG;SkU +tT(82xo`6cqNa*^4`&3X+ThZ*#G9g$<$I-N%IKjeoDWD@DopKbWHN+SsVm6&B;=K~_RBo2epivPglV6 +L3W$yAAW|_XqD?ssdI^~-Fa(7nQm@*;gUy=3WFO&7E;_Hv(1?Lm%$u60y?lW$c8}cKryar$1VlSU@Ma +hsJc;ha_|V8hb%L1z%uP9|q>f?fc%S-?sJfcS*7i>I}%YNwS}ZsfhYM=vVJMKn&QIqd~xM99Q8#7 +u5JRF!O0%EdMZVyc&4@RErkIWstuVnAzlnTJ2i4;N^{dEbQiSN0!WRlUN*^m0Ntg)3I!C{j=EUdAQ9V +&V{XKsHAq=-8ggaj&k*yXX|(;vETdGcysnSq|+~RV=V5=inh!M>)l)4+vEJCpDFZtD@}KMRQ;YKkKvi +$@$@Z-&Y7akvIDJL9Aos6wx%CKylsXk4Md)NUXRr5`D +WItROFolZBU8xxZSx&H{=rZjG+-BmiOjtgX--t1(IZb~LDzcb)!g-yVVVU58MHOkCd4sv +s#;~avDM*>_W_rUC2{gmH?SOfhwzPdv|V_*&Wr-t)4 +>Yz84+KyjNG$BlTr&9sT2KP24znjUGaym(`3ungO;yRQ8&<>W;HMWbMwPuH9kSKSad1lD3pZTtHA%Mk +g!D5n)!wuDtDV?$k$S;aZsNV@EnIHLq|rS!dfUWgmMxxP-EgBxEsn54T|}lxSkkqA@A9#}nD9GgWW3- +DWv12TLARVQH+=mfsEYl2b_Gy6KKUWl#~)9_yXPpE@k0s?~vV>$4pchxGrY?$4SP#oDe>_?%yHpBu61 +yE|eZ(2EKJA_!;niXb38zkV~xrm|U?Syk`z#QS{_l^LrLrnpk(xVkY$kgx(X5$yS%ng0USKNCg&NAm7 +}xz@f&ir2(boG4V^HQ?SB%*0jTsP+Fa-E4K$ +L?9@3aOIYvLXy0Puql$PQ8X!?3f=LyVENU9=?mt?;x=9g%AY8hSA;ato +OJt>7s;1{Uyf;t`N#ba`sUrh{~MWyEx(e8X|>uOJ +^(e=6Tl4h`N8NJ?n&X4vo{JKGkFpjB7Qu|U(rsu%HH}ny+y0m|!n1OUsOGgA|KT}V4tmjJ;JC3gjSi9 +OiZQ;bm5W1LFgvkKWe5E$>2Q@(Co0)PXyK;Cnj +Fo%{OtS4KiZ7d;t%sK@RxOa9}-;<+0Id)`ubhbcHGVtcS&+lnGWG7(vl$xbFaZwphn$A`cuvFyi!q%B +p0=Hb_M19V)+dIGVn*NiL$yse_ME6bM6ao*e|8P^CiZ^M*V4LS>15k4QG=dRq>WJa +T3h~6|WlwKn5uZFA*Y!ejqjIL8c+I2$_VEy`geD*ySTAA1|3<&Gk=(`>*Rv4@C_KcQ>I7g$kRT2q2oM +th<=_}(*bxTqJlTMlOgAB`0AMsI`LB6>0*DFerWyThA%id +`TQ=+{87;3KGpKEpEd0aPQOpgQ_3R6}2Km45}*3wMXUrYFyDKckF#?gY4Mg)jUbuAyHI=#xAZz}zf0VJ4+~Vo#*ee>F*$$FW+(UCLWk`FRU{anDzkO+sdxA +q_HtGG^QMD1f+F5M(!4|G0Q3*1;;uC2`rwBjvnuDC{BvfSDwkT*kY`AaIeQUFmAOBXHz@n68gNeDl%2 +$jiNcr8m74D@pmhk<(puOi6!GVb>FqR?i^mofx1C)=Gq2%+jEIuJN6xx6vdwtJ+0enmzBEO^s0IhsfK +wUWv>a4nk`wKoT~1Ex@jojkUM>jenuO@Rt(Qhx!ZcXU<^tUQspvOdL$!$ty}Wx*&!i)PKHP>SG?`|HZrcfwuVDJNYhRKq-Qv5C;2@ +vKUi<1`%yTNMyXVz!QM^Yvzx~pCzNv6fhC-^jBnv5dTaD4C&1p6bGsFnrkE2){~Dm!XWXvRu9~*x3rz +a{+s?v4uaksLg~#ynn;1aT10`Gd=P^mfZSU6^kydtgs~VPHo?STmT5hRQs7#^x}<=}6dHgc1-6kM=@> +*3MD)kd;R!N){Oc&GWVxN`{DQLBiXX{AJvhTi%A^~3CSEBm)O-f +r?79Ro$Zg4v(V?!*)J!2^>+QeB*tIug`Wqze(Em-PWRM>UF&zpl2vii(#}pK)2&WQSGj`p9&h2g;&Vz +Oj>dvZl3$*lNTR%@z-~ip4WQIkd%>F5E*#tA8Q$(x)k^5_;2w`D0THKyi|kaMk?35^bu|h{$GhJ`i+! +PpFu>V!IJ|8-vGv}}WDXX*M&i!nDCCH@qyq~bi!xBj>+K}D$sQxc#6`5*A>Un&sjMP#bQ{o~oG64X?= +s>AqDvi*dAQGyp13>Q6cu`h6q8farFizu)x)3CBKed=>Myo$TkP!&VsVY4no3?f6TcyGrk8w=KFjgG- +;uTPfLKC&`e}>kBT;92UVkqSj<~Sl4_%MouzpnPQeFvhe=mb +4lg1|#?j>k&5iscRz4QUkjpDskojh6}mL8mr)apWFAzvdfnI#I-|$s*bOgKy=Wfn8T0J%Pls<=nYj|Rj*R>{(Zt#$Xe*nnWmKORJ- +R0C%)bwm-v^rZLfc>6Zu9(DnQ>Al5Y_; +fY(rv1woP+k|lz#$I^SCdhb*6bZ}ii;F)*r=KIe)k@;N$9&`&Kbv0L?FJZ1dP=@Dv6&gd>n1hVQ^Clk +JzdO1)H}s6xa*mEsYaAz9L=B&((U^m%X;&?zYUp%mJl+;w@3_@0bWyhTq^EPYr}UEcHbuR_kx=9{|hV +{w&7zCEv&e{8Hs;;Y||fb@Na{Ue{|KiUJ&2EJbb4~iQ*Vb6D&rd6i$!?je@^$gk*7&!cY<;5R4_Lj{* +k3I*Gw}FwmezLG}(@+kk8M7CA&9oLHj>Bn0r!e5@aZZJy&S0+xx=jrPHUWFJTq(4dbG=HQ4;9CGt%#S +y@3VSzT)F9L=j1*M2Ju%Iw70=-58*w)`?(9Ilz1+fho0Re6{0c8K|h#%U#_4W@QJ9gk>CMr|4_aB?wn1}@w4E8 +`&rWwOwr9+uC7~`Mrygfl@Rp&`(v6|ZC>cmS5Aq1u-A8QxuY$%5pyKYK6iXCu$ddz84#U#Y_tgN(>KJjo`PDvopfr*F}?S>G11AKH|Kug2~;lU-`!C9ipS<%Hch3uhu8 +3cK($z3!nEaBk`v3kaXh87fR0*O=?4dFyS??E|NAi2n({%>9T;V|{$rRzRQ!;|(8#aY0T>oQvPX7tiP +xq#Z8}b#;6FVpH&Jwi+u;FK_&Ht}QdW`^)cp@ygh_7eV`1=?yUMNOzgMW^}K4C4=AKHTd%!HF+F4$JE +b5ckN?8M^8#qJh6xQ#IM(Bcan4xhWwDsq&c1*M{6MnD@Ov$AsoRb@9jB>`PU$Y>aZ}kHI6H%ny>LbK~ +5~?q%n6f7Gwvd2m;GWj!KT`jOoR!%`Dbj5%$zEcerMN8@ZoinL3ttVwosGcnHXz!i#%&Xo9_ShTfMeU +a0PF2=-U%9chi;a`1z6_-|e +C)n5FklfQ!^f*|M*bJKJinhruBssqe~HZfr^Nxh9%rzxl^N0qr +K*Hu@L^KNIZcRLX+BGZuhmGWsj1Syy2;A0up=*IqN@C=rg&-)p+wufnB#SXZTXG`<$bO8vp!~qh7v!9r{YJlyv@| +zzx=pp0|iB#PU(D6#mX-8736-XB5W7GrllYeAjlzyVzw$ZC|9lpyq)qu;uwuvi$9Fdf9o!hj9a?FXc( +LR#v~oAv<3VM{buK;;_r$b63~2|ud6``iv*@+AX8#01HuurF(C3qX +sraiWS{?M);pSYuE?n`X3et +#;NQR6yIbO3Rl*2U}^oL@4%h%xe$^&1(%I0eHrzfoLvHtRQiPzbTyJjehAxl29~Q!oyx3Plx;Zm4Dtke +V<=1T@oj`gXoj7#!PE$8E{oJl-l?Y$VeXm1@_Oe<)ce}jV}Me{@5`^w!JvmthCpC8QH}2*K`2T&o|#| +z`Be9Agm_@AN&3Un|eOYfc_>*fFdW!03b*)08Ai5`ZO9Gf`n=Pd+S<)tcU&;nJC&o1xzv_fQAWDEgFC +ovyD)Ja_BazjFVfY69J~^nscpKh-2VyWXs4_Xo*u$t=$}pz#XiR$%ZRv{SjJx&@p}faXwl4fGoN02*2 +OZzqTIN4gLD<>tFVBXzS0ckn#yyR`^%|8UFegv;bL`Z;$2Q-^t&FmS5hH +ko?j3v^?45N{?_W4S-ooF1Nzea=aSzFRiO>gC&>Ve##3;(Y2DQXHp2}ShKe0?dI2ZbQ@&`H6{Wp-q!3 +lb#x)_p-iEiJAomxcdkBAuLZdKTgQYdHG3ET#88{}ndNfNc!^!V{=RjHLwuQ{L?lJ-(v;n~MJK}ObgkcE +b2=|p5nJ7)T1YE%%~;eff%fm&PuseG!p+my5hw`58Qw_&!Yx)@-A<2(%N8inhLh_b`UE?s%!AgR!i0L +Esm$q2(yhd;38_V$o|Et#T*SFOoPBScyNh5jd)=Z^-L3bRBJdEWk@v)cs_) +%TWoI0Rjj4#ELd-u=&n0Td6DtfU&{`O@I;@N`f|CvgRDW>b3zg?B*BFrht1IVj!;p> +MSH6;Hr83eyr(+NGS>`as;-G1a17DbYt^`TdNQa0kJjO=(*@0X)$sDG8*)c99H??z)qs^10`Jd#+qFt(Y>(|5Bh-zr})7H1-tk!ha2bSy7qj(SG$bOUi5;)~>^^Bu1f`3}i+Qc`J_lySF&g +L$kTa!Yqjv+jK58}_MyI0gMfRdo|K%t1nT<-1QGZLx@zMJm_;Mf3sN2e{e3?k}Y=$-OL{d^8YY`yPuC +9W$r)UEJX$Sq>N2!syNn?(IWP>Ns$MJv>6CPe+!S?MPNVh_-vhJ^p+p(_3d2lB$@lJZge1YkHv5PV+k +GPYe^*-8LGc9m1ef3_1I{7W~k~rahnE+^W+Ua@GiD5G;l)Pe&p|*_uXgzBxSM2e1)&nz)b!)*IpXv2c +UBMDflHhx_Y4PjMzrM0%~>S?3P8a#H7l&#O?rpa&Y;EAKr~Id$HPZWnu;vsY|s??Wkj=Y9P6IO=ScQD +rjk2j+_Fvzxkha*r{wrE$_(d;z^8Ra1wZTVKh^I6Axe7N%AL@efvhp!rpuf(yy}{ZY|Cgu1zdQL4m=1jh>Y2o8x4fL_TiPEiZociMM!dDw9T)DYwnlf +sD8Tc%%}c|Q-M6n=5flV3v&=JQ*I!dTaU_D^$wGNNd*+g^c{H-vyz)TJcM;qMcG>xN13}4_nWk=P1}e +Ql>X_e4nHJsbjx|9r#PbgKPN-y+@1cO%rHGU>buehyR&ZL5Ea~conjr-b@x|NA{DL_Bwug^hmkEclHk +a&Xnl(2Jr|Ph`Qau#YLUdlvV`tj=yT4r-IWEKb+K6r>23HtapnmbZlDHajjQ6Kt!k+ZY=R6c>In%8DP +?)$qPH#-AW}U}79}kJ!^=?fjaU`wByU`)z6+Zf?dNIW=r7_YM&Coke$rE`^?;d5Y%JX3;&*jx3QItO? +`8bRHMTcLwS)P?+9zdpwT@H8I_HKGi(fDhUkXpy~@3;8u{F!jk;mT!%dtdhK`n=)K4(UpI)MZa8F;PC +c(6h3Vx;dk@NW8IV@f0L!n5P}s@KdA=?m92*zQSIw +70ty>Z2tW_%Z&U21|cCNB`qhzYUoFMy8H$N=qRF=6-PsR7%+dq}yvW5^bh2>k(#4*;(Sh5&dDvgm2m$ +=qB<(prCxa#ye}+0=ktH2w^C83#cL>?G&V7jGFkwPyS8Fgl(fq_~y_@VqgSmjoc{E^W6OQP%x~t#!l4 +cOSAp}Ufs0TqfOWy-9FU%PIL<7On}xpv&or+|3&_&)+&cv$aMKr$h7}AA=7u{hu?-wzs=V3pR)D+NB( +ht%GN);8|d5H`Sxzskmy$#yYMMvS3$-O7(~M2$R~cb=^2aX>AF79$0V6Xv9zw7$g2*$G?N2OGsW@K}TKo-Lpk!pt5H9wluv8nIysbS9)5v@6M+(5T5tX#yUaP55OUDnMj +#ym96VVvok=|vAh+9`7>pj0F0Bd6S?eaUj-cnL49(+1NCY7@fiuat}H69zB+Zb2DwG)9^_k%|JtfvFu +XEKKL;A#UR3W?~iozTNMQ7DY*)k0Er_{kNk9jmsvF6W{vFQ5D#_^9MVA-``G`z26?y7VdC-Vy=Pgl+@ +@%A*i2APS`8zKx!76#cn+}@*P5z-bYoVc7sK$j>HXxN-Ql}CP9v5PWV7n?O>sDcvap8hGfCbrg3P7{e +s1osYo;7yd2ytFDRErhKJR|RcKc*zSDD^5gC_1yK4qPQ5q}>y;x@Qg85bl-8t^%H_I4F+`+7molR=GX +BO5$e_T+rzk1ED^a$r?|*Bf@Dp=phaR`!PEj7;@@&m7;^@ +u0!$WfSf4?_C+zg7j7_c0W}_n^*67Y33W%_jARH)-BQxE~e}+6%=IfzB5dFI$I%azAyD5){Z?gg#7Vf +q|z%o)(wZM_ZK2mJ}S-(TBSJ4x3Xqn00#d7>M+i9aCF|QQvQ +M=IyLlBc3XI +oTbbK=B`)G-c-|BGES!&cCwbYB%Nn&Dp1cVI6UTrw4%x+MVa_Au2dUZ=CR?%3z&)%%8ezoxL!h757*ay +o?hky=v1XoA*JrAMfEs>X)m3Wv;LD*?EpP$ke#Q@q9T2&%2H77Ts}f(=_CD^_aA}lgb-T4eoOZ_Eb3U +g=zQBR2L~i^MuB>wR>FtKBKH$gO(`x&-qn6Udivr!hta559fanQvJ`Y_?1`oPgeW0oC^UeJ_xgswqsB +gq6jcXwMI6{rjY`g+}o@48uWZT^o6saZWW=RAO(zoV=%-W1)%B`g&^#Sh^>eegVW-TGKPeppH2n8niA +i}&1oF;+9T?}c(7Rv#@kv5xR^*bP0mf`Ki&l5){qelqer00zeZi4tHN#~Y}*V08*U$MlOs<4D19l`AP +B4GKLug=AEhr%7X`+&xp(1>u$=1fFX>Bcjjg_fKi#+IL0?Y%TXV@5?z8wX7<|6YXOY98zY1I$uG!Lbw +t?4*wiUR%)`iZECa07b-B~w+_s6>0qXc=1CdVR+p0)0+AZN72&Cv>#2a6`2QspI5nx;928wD3aYbt36WT +RZiWDVU$B{3dSnG*N>I&)n%3vB6+iS@Q^$}pISRa&Vvj1E)1_d{#UX9b<{_rBOk37KBfQ4{*ZQB(=KaSboZqr +@LW;rJ^|Kl_)??vY8t18NF)Dm;6Zo^Hp4WecQ(o`qiGHr%NXLaOxnfpKA +H1elUqXqnWM7N_5&)k2h4Ado_f)>zh6Li=)_SkMw6PVV9?G8n;uPT->-MvbQ9NaUEv!i@>vE%-mx&5U +_bCK$;frbuU9VdIl&Q +F5kdr^Rkmjw%xrT_m6WU%^J~e;gZsz2d*Y#y=M*VhV7l@Mtr5*(QsT6ciCq1hi+6O{aea7K8xZ`0!(m +6o%Xk;?iwoECh84dK*PUQ&3%?KCz`YTiq3_(9PQg-Kbg2uk2)27{#|P3>j>L2gEiLO#xtB?=1z^z5r* +j&B_f&!E)=*D}Xa7!1MJ?h5*9|$TkO^;+s?(1q=chI7~8}r +{ciJ?mjLsF0r)*i%F;5O!l<4$PfG~vO88&&P`!x@B&)F@}_M +()xhsYFF!-mDYy})Fz6H(|WwAHEodBSk!?jLu`AV&}A*!la+iKVRY?ZNY|oH;NletEhLJ@t15Ezx_Bo +lHF8o=Yko)~8~TYEM^LId;QJ!l1)+H|RrKjok%7@li9f@r^T;gfhXID(>gzcqtTqYAyefo3Yd(ZQSM7 +YkJ>GJhOK!#8>L;Wbqy!Is_j+2W*_)&jY`cMZWgQv0e!rl1q(wlFc +CoM(j+?#G8Fh7W?5y*R304my$Xeds6!*DV#Jk!C<@2kYO +%U%-dBrR3zadFG(H&1Nk5=SFEx^B%MQ0|exJw)KQ(cCo +R=VOZyEE#@oZ)wL7%Nxlbh&t#Utv9_QtfEt`^6)#(O6mxto-pxn8qghz-MjH7|Sgc{S;`GyB-N*Aht0 +7opC>SV?v-m_IFtmiIN!(O!CP;FPT`LTSUK)vdo3TR5ci8X=$T7_VkGJNuo+L1M05TzYm$`)D>NLkZP +$7w@Rk`h-kPFxW(@VB=}utPko7A;tQ5I9?O%P8V}^^k+}pwSTwOr^& +@5PVq>dpKT*QY^rWg2(RFjgHaQ=`MS*s04hUsPKjpzomw|kk1NN=tGFxP<#M#%D*@);b@aPtoYYn?|M +{3j8rat)oLqG=(u +FgHs5>AQ-{0>t85|kR(OY?1#1=YpjH#TLWsF^knhPpZC*f=Qa^TCqOEm+#GQc>|?VfWQ*5AFxAOK;A% +ie*dnt}u7hiE2PQUCFwco&fOnQ4paMeuiiH3=Rsm=wt*4SCphqA9kiKJLV67B}Aig6bP_>CkU@F2gVD +%UQLF*t3F@7DKDHop<T{9zA>oaG|0tCWf +AyzmC>O +%fIRa6mHR?UVJY~uL56?HL6snv#4QT=?u9FOqtfuO`6@De}lV+{!eayld}CkxqWc=(6_h$_Xkyl!C^^ +vUs87nD}|{L(v!@#dxH>Un|VZCCn6yN8)cl|G3KD&#HKyl#(s}Ar$dgs_0&;Yf6sGILV}7~rd!b%Tgy +62?hZANOlSqpk;Wbn!(c3&kPm26MNin7Gl{C-JS_5rx;@g@|zW{F0_})_##U|=Ir7zcKRv)vU(-VKDY?0i<2rFi3$OfQ!{?_{?PUTo{#9-|V&d|4eU&F#fng +`dQ(I<|_E6gER}HorqUXjqt|Az!oeWo$X6K#FU_sHbC{Bvfw#TS9pUOd?^T`x391`T7s`i*V(~at5?X*nZcsF`cuj8OA)qk*FohHQe#Um=Ss^c0ZYNT~|!|JbZe +CWj?)4k#Ksx3EjO|aQ(U+ul6`<_j2yE$2BzED}I0*hwDm1$8SW$m%|BtKFPFyz-g!)?_CrcICSDuGZvhhg~_*Zxa{m}$LA9Lh*&Xy3WvpH@P*#h%k +p%O?a@EL$i%*GiaPDR_$jwBL=U*e?r7FKx>IuZC&UWPlvkNhDQ_4>rf0t%PvezQuAWq0I1Ewv-ZKMQe +jc^Rh(>6)6GOkzI4;D?lipZ2idP;8+Pp-B#Z5xgeaIeSd)8pQ$hh~gaJVM1;YW@!(*UYP9R|J6Wv7ESKPo-K$>6^a1bZJN(c +ppK>?VcTLs})3hXO}uE3TiK#gU+s}KWfG0awGUR)hxQ}#oJjmYp5ry>8*6G(T%a{yyoci1^f~Q0vxEKUEp{UUH6nDi_JuqzIWFyL7Xub*HoDp&I@xoGxzWAvmc!nUsV=Y +J3Qtb%(dc(q=C~iUBL+6lwK4;jsD1N5krgSOzcwOL!*aoh1mwR?sl+7jdQqr+$vymUC+BgP|kjoSXtJ +e(Tj&&taQgAnwXp;Oqs~(v8-uG}*EAEXp^vmLOT^+MXw#f1Yqu63tT1-WoHpFU=hW5@EV_FS(4*yDr< +d-}Hs8{hby^F4W3-_&bxr8T^G@7FnHW;Da(hIszg!|6ROmE*4LuPfDVaZFfQ*PdK&zS*apIf#m3GUJ$3;&YoF-5(@{p%ew!r2~E8DAI2=;3sA&1kN3$s +c1w4tZEH>dx%yXVKm!V1fNbpU7$i~{4T{mg{uKp1S%TRp-y25{08k9nK#)&LBLSd=6WiDvwhiHd^aa@ +rXW0##{)h(BRzsbdKNYFzAM%yGnM)z`g`m7X$rlSh6hM6{dhojEl6jyw3lQ^@Dpb-kR2XQ*al5RaGlPT_ZFk~>ih)x}q}ay7FLAifjjHD=Z?7xd~eGZvP2ML>;aM#krOnr6FyPjWy +b&Y`*ptxmPMo)KMha8m8z8b$))8a!k~@W>CA@xt=CJn+h0NcZs@&KL38K2T!sE3Pm~kFh!INzZ37RTi +pe6qjAn5s;VZE~8d~w5z6SqOvkY2zKyZT5%tE*m?Ixdp%M+ylEHLL)j(QE4d6ZqS4x0BKj8eK9>o*&! +{|N4D7n@8r=Lok<6Kk>ET5d2j+r<0;{f&57c6A#WCKKPd?v!^}NfNsDzS*Iv%2w!+pHe-ON-En1Si^W +h5?<=+M=Pd43ht8byI0eo(H0DqcFO3*|Cq+7b;@)5NhzS#GRP<}VD>zt4`KFX>V82?@dS2MvyMUjO0Rj)l_bn6WuP@O|=21D0dcz@=cvLjyj>LP8I?XIN4)o(X2z*s +P3-7G~p#1$e()sHlJC*Ald>{q*H4hWykl_X)q>SBj*ZK7Hyl~4JI!&p^x!PQI@9}zZGb!%#k}mL;%h( +L9P;-42n9|PnIr$a}`n_Xf+2RKnXQX$&x6wE9a5*`}1f0LV7k1bS19Kr`HNZ|c^u6e(1+qG1n0me$84 +cm)i7h%b7&Gc6)Gwa*`nM>+%T0V6p%^=Yx2AUp-@0d*>6)$xGaG}}55o|0v^svUTe|wRXsHA11d0)c*-P#9*@D5#^=UegQJobP;8#6ahD9ct|HNJeh;Vo +xMY;zDQH04Zo>objH$t)wlp5BtF~EZHJl`yj9rQ^@>c70;Dy;gz~;{uzyA`R|M}HFAoS-2{uxNeo2OJ +50~g*kaa-Y;qJa}67_Q#y2*Gm;J-EhBQ~3Lpj1MDG!4hW;8s +Kf$*lNS2E*aj6ONLtpPYi#S#UNWFRr%-+SU;uEUuA6y1gIZ4r1VLQx+5(SNuk|!S*!}h&S)#HLY7wpF +zNa3G+vgHUI?7$)7-a_kRtfpPHb40qO8BgY{294Skl;{MSGYr9b$<|5KobwhR9SPy_YDFG`r2g6f5bJ +G1{Uz#95EyW}U0I3AI`_>PD~F!gIpYQsT%9?e}$Abp@vQfe0W)X<=)#OH*J-|d)A@qDpvvum&~lOVhlT&l6w_WrOhnP5+H(Hk +?B;U1mXOQsuSja_59EhrsX}g0>1R|S +?Z0pFKyu+Y1cAcM-0Zw3nIu)m;F%YtAbpNua`$~Kt9uHX=2r}2nkmoLlW0X1MlO(^(ip#<|YNI`2)ij +gkd4I#|tr}nbkkYBPlNk!OZ;F`gZn!kRr9^(u%iao&PKC1L5WU2NP%Y~u-XxY*wI%H2Ub}~FsYUJsEl +d5_%Fc}0ELGVvtJ=gn>dy@NzVgul3PcJ$6lve}0)~grI@=d)P8nk@Jf3oNky#vTOA_?Ki`<8BQ~HN{F);iR$f+1k)4)-!FrjRzy}<;)B)biJfk84 +13|U9yf5QO075ZtS>{ntk>-`|WL<@{iuK*qsV4y5rFW#J~*QHnJ#<#BE`X9ED=u!&wFu|KK0IPwa<|a +=7(r^}hv^7azGxR82Q|v$Dwz=VU|0mpr|F7Y8p$Xa-+>So6&Nlt%4d0-T0q#@%Ru_Q{hx7@z#ZUGeXH +lB91^l^^x?Kd2w*SFO@EHr=)NfUhKkTE@0sGXfO6WZ-^~%5L0LLdu0i?y}LPoD(bl+6I)yY2S7kmR5Eci^}@=*8W32NiSVgq!xJs-6)qovWD4 +-C+N4+t=B3q4agQRJjL@>D;^ICsW>!EutS{ghW+VK9)LCMrS41|Ph41Xq +W1aYy!Zhx1&_K6dhc$s3KQ^1jG}PBO|iys&CZ$(-dv=oupxg+_NfwRKM@Y-8=4#ki*{*ylsfAW!@45X +9bW2TtO;IP4bc@>bf*V|YFJkfWjJwTRljv#H^cT140nJ@)mAMImomm^(Y8r}=s==`p645}{^KP;mX>@0s#5R>u!Vb8+rK6ZS*kn3 +*Nb4q{u(pB6E1u3ORz4at-Y)Hiwok_hwIUm7=818PN$npEg?hVsHZH8D5CgsG!n)$jEC&StOUh;{+RO +6nu7fC&`0clpcw1cKbo@jBGsp?dos}jjO+iR~#VeN?Fp*>K-bmZ|wT%(wzV2`BJE20+7^%B8cH|Nm{i +h1>AYdu!%Uj93~cWz#AxasU;w+__soGTi8W@qx&k@xY|=2CLvAAcLW&AxJi_|g8!A>-?LpFwyNv;NH` +KVba-;@f_Ln0VOvFtBwxZ(sfB3IO3Q8T1LTNA;z=H_Nxks<(JsR$I}v5&npzyc}gw}QE +zP4;@t*4aG9P|NVl3G*I#F!hdstuR7anzWxLgLyNY2(%JrWEZUAi;NZ`(z(M~(_1lVF* +7aPgj^^*798$l^eotQ=I(}==aUsUj7hmt$v7m2O{(B4j5DP%RlT{rs1udL2<-iNYl+o#Yf2WeiKa0?| +1`VYa*sG!9K|CFad!CIbxW|*X?n2K4a=amjo%m=C;9VYaN5|T~I4M4#cvNiOD234cl*##kiO~C8mzb4 +>f%-U@>(K^6n%vdnc#S;w&}}BBGA|q|?NSrsJLVT-P~3t{`}6)1_$**XR>(GyGCd*y7 +QT;&{JQifj~DvNHmI1q5%2E+{Lu<9eETz2tP%XOO&;CqE)$Ki}hVCi(Lo5#3YZTr8}V9$__Q6Goi%a^ +BT({Rn$9`u~`Fvn^MVWLxx|ugJ%Hhwk2@Z)%M5KqndrBoK|@jb2C~kU&E4^~arPRzze(X095$?m0DTW +rPSiM~>SxvuV?w`NPjH{65(>UF#yxctuw>_EgVJTNdC!oDV`PR9QU5=0LB9en}mh))PX$k31~YA@nTfEY3ygtJyl^a6v$vc~(2N5YoZ#;XnBGV_&u{Y)*5L%d>+r> +-|B!wL=-qB!7}NY7{4Ng&@RZH@yN6yhybE4g_&hHFsKS7Mu22*=p@3d>BJw9ucs{SfbEQ|YQbBlIA({ +eSBGqmHsJ8!RR#tPD8)bFR_QDW=Hxc|iA_-w)vF}ab4<`Uyhg5+9FSm&Cpa5@XHJ{uki{Ky(uuo^;>m +9h*1osP-)rbIm4|{U=;Hu!3tRlcU@P}%Cy}`CeSPEEzyPc-|`5j4A{RohV{gMX|UrsPzb+y7`EIfv=A +o;*mILJCaD@ry{+vqY>qWxqo&y +W1p*C3SB@t;xx1>28**6R@OUR@+)+IiG~c1PL)_+FF7r$>ts2WF5xo9 +p`nh4mX*nXk}lF4p@B)&3gs{dmkz@a;tPhl?P>UyyW)UA8k`Q1X28Ub +F7X@9EF&PMPWb%Tn*zO*kY1@<;+hlR4K@gNawQpl$l +xEvz+gX_C2^ySnW>E4bEnanaqD8=k6!@%+Fw$nUY69ln7vHM8SwqLe8P3zipwq>Y){&7H`;16s+@its +Fk-A;KJmbw-~E>@4!DvB<|2@>h=GS0cl3-EY?<9BDG>|E?Usm9v!buAFOkKezI( +AyN!f0%u1?y0H~_@tmFGu(V#7$h`vZw_S@cwH(ym_7sM8_~-k#X|WpU6;gF9>=5o0f=)K0*nY-}@StU +|Z9n*4ypTgzh7PF|`Rk;n2vJ1^100YlE+*2aRXhU!vBC`48!dX$t}kw?%dsdzxMnt +L_m`d-q1!OQvp@CE_Ln?G8_kDrjzuZCt1}wQO%!Ne!mamY2=4D->(fr0XQ_yUGtA0;Z?W%V1H*Kr1I? +*DK9(y^GXXvb(+M5~z*G87AO{GHSQbQB4+8)A5*&&65%djLHu2xRsVvARR<}TOiA6dz6@_TiJ(e#q9R +Y&0nz1=&Q%;PW8ug;AGVCVocyj|5BPGikg&@Nua1TnpRZ`y5@tyXF8fQ+fh9&wq5GK!%k%YsG +|Qd`y;-f#@&0G=rf5uIx1^+FAtM$IWE&nIKs15X!nX6O~N}?2`8Z{zS;SGUwWmtaxyP4$k!F-cNZAs> +k9L}z%)NDZ7*6z61iTT@f;DVdvm+2(#_yL!bRZN!A>^8WE;f5kYY~_R|MIs8{NLTk|L&Fc{pjiXCeKf22!E)1z)Q-QHqh@#$_-f2gcDwwxOzFJ=N+m0| +=F>p|Q+dDP-j^m>!l-bozY^V6xs^uFhjLN!DBjM+r^P5WBcwMn_^P9;F +O_vJ6QU3Xe=p4?uhB;Yt57($4ytpoJ3MaK+)D-+ZkJ$#ymO>#8BUP9iKnQiVm%JDN4)s +@Hk__!qJ18I^=X}Re45_`lCKwHQ||t^@FI6>@*}~T#JVlUJQ#%u-~8|(i~-1@#*n+?3>-WAe5#g4q=# +GjQpYFnnt#AcrZ6lEyd{-x)v)!5!^{>FUyb%Zrq5F(biFuajjR4zBQ#SHsJi~W|OURRUHjqx2dO8ORb +YPHS38Rp7(^-q8PNhbNymFMF^X1pA5IKPndNT$Ah3BFS2{&S7GXl^7bYg33~tcVHxpnz_K5X`4N_V?n +g&5-&QdYvsxoDBQTDHoPQ`#Jrhgv6k-~37Hp(*Nc~K{7gxY?n7x7$MhqmRG9>IIht0iiBUrHqqhE0b& +quuVUtlQ6hGnTAU>U~FMArmrHv-^A&5$vg&zQw%ZW +=gcGD=?f{*lYBGg(MD}2eU{LFQ4h)Pkkw=GX=$7@=CwUcP;ZZ6pPvDoh9^>Msn#{-4!mC?9NKG$@3g> +U22c-r+hrnnzcgslJwaLh+}inpj>ZkG(VmL%I~JLCB9c-hPD&pSmhwoRQ^Ddq9OAf~s&rg1niiiZdC@ +Q>1}iuCmJpgtW +V+|}r_gLMOERs4UrYY{SJY|eAv@KPhbk}$=%T=!570t(QtA<(mk)-%YnA3vB=|0j+O@lPY4qk^SI@Ok8oNPf{Gv?gNRw9X(KimqZOdMXS*S8aI1HyTMzQ6F{HX^R}!w9wEz()^F^y!$oxN7 +K^KLHZbO{BuO>hC6>ADy$$~0_+ObpO{icIPbmMK+#_GYMuniMp`och_~!`48OG*hKBfYm2k%Sb4n=4v +$b0AzN-=1PqBM$R`4pw8-W2ZVh!`4u7uZq&^0~lH5eFLsujC^Yr>8IEmR2~FS%$gX6DY= +W$2H3&8lOwpSp}cVHQf;s=hT`*owR7XvXM6fnD}#TW==jtY?c+YkThhYX^AlL>R?ojst8i$%*vJz-?D +PkRhu(EGP=vWBE#8@Ne-kAj*3HVZ+OjJn?sbENKcXC?PBnw*_`;riK34c8Wf^Cj#}|(_ZL6*#pp(d+2Pu<=jQA_Qgj +)&Tk2Y*d`&+QDG=l#VjOKs^E>IWYf8J*DqWS}F_STSiAOBGUhe9$xTX8$xaIcoIlc&DeA;zJNHNHnRn +Mb;j&_M~b4tBuu6^Jnv1KLljXtycBgWk9^w@D>A)>StctNAoc3n1VZW}t?A(MKz7fXK#PM2N0%1g&w+ +u}fBYvCR}mS|)x)pfe;m=ms$(Z2Al!p;)0Nwl=wkuiEg{1HPfeG>-Hvzc&M`%rZCu@%rYv$^FlB`C~+ +w>$r+b$#x1a&zv<;NH8}^`^7SX9nzoUKQ19I89h{sW5T_+&jm7l1${pw`)ipRaj=x0Po~tEwbT!#)}n +UvlcTsd!x<|YlPf;M}yHrWuf1(DLwQB-pYOR55tVx|FxIJt?|O;`tM8D!_@D4FJveXalgE!e<2nXdF* +q$<$ve!H*p&CyMOc +%kYi4k0y)!AdP|7NZ~|m|Os?AkYb>w+d`;pyxfhq6Ubw4c3 +<;FQM9rn21@EBWqyLCk$fN@JhTo;ein;OJ!;<+z8u6>c9br_lB%Eu3 +;!I3Ps*UjVXU>Ma6KDJ`aLS8%+9NOJ*=rv$Zi%g ++0HNtmWQO<9Od*aB;nlo>YljpFDs1_T`a;p8)B*J=N9_K;1cO|oqWbJI#f^p0W|+gcBvZruk3^=zH>b;Cw_dNz6aXO;_o#;r|2x&e`{t6}qCdnc>N@;I1s8lgo4XX}P&bHV;d)GFv%+!$Khj|P_gO81fq@emm>(JjHJAhz5m~nunkR)FZO#*-wdDwgj7j=cwwBLC%@=yNC=QB&+lS> +{Cl}YHQ(>$!#!h;;^a#~BCvV~R>%>8~<>}HM?y?EYz|y1eM`ZMMy0x6rXma~_Vm*t|TMYN9RO}v$J1a +9CLO8YOG|=5nb;~%d_*i%SI!JfL}iBIx`?WnS8nI<9C)sw-Fhr$!+gVLjRL4#Rwl1|s-9bqrQ7?+teTy_&7oSI(WT~pV-2?}2%U +Z!61?V{27(=KSvWZE2Y)_Bu=m>_o?`9bu-ek-gM3rpKy#jCG5&fzrtDc^$p%!d`CsmZC;Me{tgOY!h= +Y06+=bn`-RL64sH4{j93ylhHb!#o<0~ +;qV>fRAtYH#Vlh3X0cuZc>sh;JjuzHAZ%?PGdaTIj*vHsrRBvQP?xeL$Ct}uKc8q=zgolKz%o|Ce=kq +z`)9BG2w;6Y%#uX+Mc_81cqoxXC5~$HmZ}7)8j3vMA>f^%BmKTaa*EHgs>1+b-T4he59X>Ng28fAf&_ +l9+%Kfz7(#8E^+mUea3C2uM_&@AhpM*wXH40ev0h&)T +C_RiOu$m-^VHsyO(+bd8fIs5?m3%K90Ty>`ZW}<%gi^53Co>t9i=l%9t^iI6{RIj-5x}10v99k=29#a(7tipzxH2hQa_uB +t==#yOEeG-}1OTYYH@6P*TN4AI~{pw2z?1<+Q_AxkEML3s&P!;?c&x|$iZtR0We`9k#F(*}4ML>pEmMu^{6AknVp558ZMZWhYcTs$I+6+N@%2t=`wB9H +A-k}OdjI@Q;lu6FTqpbMAzhDE*&QA;Dz>zIpGMKSNj)$z27V=;(NS>NZ&Q_90#MGvw#mv=@jk(hDO^p +g{Ev(p+db>KSW*zsm6*7u)Shz^Pk|~~8jKnn=YsOYj^#a{rnd-)A~&L~P$|V)ZURykIqwVRgPgd&r>M@zXZQ6wB?nh{Z+R4BeJ*Nv +;DTADO-adUWFNcCHkG=HJU6JgMAWYp|Cx5&+~>f49K?l9CqD&Wi%>%8xtXz1IH@zp<_Ed5{2s`-)zH! +@j#M!%3{N7;P?9q)KAoceUoQ*HlS@(CM+Id^tgaM6*n8MTYMK8c=d{eV6S=y3l9>7K~qOrMTOJri!-v +kJ?^X6dI-hPve$CoDzdp;_ldabZF%g?p=^)iuF(D6(DOHq%EPKIV(xy>y_Kd+HIhZSjSEA&G_*p;RE< +46Q&UOXqb(25LfT`?os)0k!SIqsZuE(Ej7MAfs7NWUO-(d%CtA_Cm-oCRw8wgIAKZC|dk=QVE4s>7T; +9fP5=)|EoO0W7^r;}mi(+Z0^pMtxKO#)X%R?-;=foXiR%w&d&RABczZwTS%F@NM^Ci(-u!N}5n^I`Cs +qzCQv&xaew|QqHrJm#Y2HV_4-VX=gBu@_^IW64E$<;$#XSlvSuE^z5QUY(-+pKXJB-Obeec2t)|JWzZ#~`(YSwj#GA?c?$4hKIB1eXG4|VRGlxOT1H2Moh#=PvgMJ51{0pD+&%laA3G_$ +kSt6hPzRe9jCx+u$Uk|u1bON)#z*E6unBt8ID4_>@vWSJ@JbKpS12zcwXY5aHZh&{jvCzIk?qCA#R-Q +xErj&rOKwvGC2zo|PIgf-}psH&QeKugsfMElc4;Z$Tg+hR^D{~Ghg}^bySZL9+zjc@7H6#H(x4#NFy0 +LP;55Y-aOr4DEC)qOuIKi`p^n6j +B=cFiNwtd`8T@Ti=&R+R*xQRqnzuueZ5M$xOvi>_l3bBGoS6j&z+Q5ql4mW_v*+1btlWoBY^J7ym)154t$)T-Z#|3Qlgi*-?j6LGR>kgSO +r_#ZgDn@mdC8URrB+W|1|WOWhmpmqONO@?=D2&H*fCmCn;WxcBKDL>h>a?E#h!cdE +SGoYQMVrwqWbLN%7Y9%+&~L8K8Q&RII}PIgI9s4{t|vu2Rk!X!{A?qpjky{PZIWDr|eHN7Wt=B_ScO4 +B?}CEa~ZKP-2hYdHhXwBFGGQif@eo#E+@7IfXr|(sh=ix6{Jan=0ej;fPBhnD$g?y0M60JyV1O6E?=(1jmvu1qxBsOP=9s$3poJ=236n(>DX!B$-N +s=gKkbdc-njGFZ|LiVzHA=*r=rp;j*V48s#c;F>Z4Wvtz319)ehI`hD7$k=oVDC80>PE(VWEwOFP+qI10rE7Y5> +s7%_*0>$4P4R;H!VbnYci#CvsdvVy)k`D_q!BYGa#iM!p=LRRyPBI_!JK1%inpk|uNl;|M{~IY9_x)2 +AKaadd;1{M@xnew_4<$Bs-pTUN^O`9SrInG ++BJ4=hlzHyJTq=QJk;pR3yMA5?4tC3gHP*D?S2uRkQ-;l<|G{;^j?Xl0MtAMPF;XuEp{c#H +ke+|JP49{axi*K#=w!++nq?AFg&v81WLc&h(nCw;Ty@PwaE_nj@r2!_Ntk|J@IC25vpDGH+*ieYG|?T +$gQcl6u1C@{kjHOtB}unP`7r@+VvGQkoKnt0%(LIK)zu6m@uHS`n_ex6#=+mOnyQaInA&nB_c`deVbZi^pTKCbnu~Jb$&fj#!`Q=p>4qth$VJE}tWvNx +=fr5$+z@k2n5$?iE=_8(Fd%EjZp5uwYqdeF|Oz1ZQEcojCGJO11WS#=YV{`E)NFSM{59T +s<^b4uYbDfg!HQ5$Cc_o1p4v4lgRqKV+MnU4*OI?9W7^l_jIlpg%KPMpq4wLiIdLXZ2@bAw-6yS5Po~ +w!XUez2NsWOkTY8Ai%xj`|dxi0F}+eTj9Z8uWf!t>0PTiJW?(}h8SR81dA-F?tc>>Ne;>}?_GVJ7K}; +3qm4+B=^qBc5k(H4!ardF5KJ`A9B&;i9SZhG~$00&0i_707Gt7FP%PbYt&!ak-FuvD=hAjmVT0Kk^7K +G^!FpgI90kgDe(X#X|S?V(f0wj^11(lBgNRJ8Ryhq!MP_WmErO_QE{!ocx>xB>VQLPbD-YboaZLxED-@CU>$Yu4D_o>s7L6^IwNlkHa;k~ +Xq8RaS!QPLO=!)C*CJ96BO=PObj9szqzw-RQvjfL~waF&LgO9+pScDM2Vkh67krJmz)@m$}IIWYMfMh +*t_pl!x`?#tUNra^!^egm_sd +4&(D^jhNfJiYY%{hOA*4r27mG!aW+f|TMAc-wQo&TJbXyNTysPQc2r6_p{a3uDdSkL9!ZDAIs@^8!8K +3kY}+7c)%wvgw*f5!?c{UiTGe^n`AnM(%bxJmru~?-ak3&*}Emrwa+!C)LyHtuO@p934{qCR2Ouf#8N{G +U18_c5s(mxD@ZvxJ11h#bIqlpH|*^*h#x6&sv$_+Ds%(>>1@8zQYA`XDkV%&M%6$bac;FrQZs`!+vi}*x@IQCrkEr4Oq<_4h^lz~PgOVtY<1~X39FAicOHu@eam=?;$_Zq +^0CbR1P?RZ-A=f5jAyR&%*rBg2O^oj3<^-&U*M8t|EE6DN>$13Y#Vgr6g%NU^fRF*)WW>O*IiwK9P!x)r^TUw#&Ov#JJb^h_E` +~7!7K8YR`1>G13Ui3q_$Tb3Zvb|fg6pz&*UO)c2Hm2n?mfcny~}sxv00d>uO90t4H?AY7Eu%n +AGmf4B9&9!JK%?a0=+#jWaXo!?vxXjs8g#-iD6+yJLSFI`Z$1{cY&TzdQD~p(AkYztM^2$*~5xWA;tX +vQ$y6E(mb(bM(Ol>>|t8i@_|teRy}uaP`Ow?NDjMtv{y1+E<;KCw4`fS5CMthWya#R9nUXS +7o)`;niO$uIlxJhHp%^Z2l?8X|S4e3wzIAdjh7QMYp%-=7P#IYqsBB&!Kk=rbyie))8c>DiKUeA`h5r +e6$y&#k)=Y20J{#yu+H^H9XWm)x=XC;jD*&GeA>0Ks}S9>ySE>qn{bP}Su8Rn=k}v@=(RY`sc9TAU$u +!#3iHM)DN{KcdJ-?Z-a>(mm&SGTG1Q_8hj!1#EYZ;JvYl;GkC!PaptLJl_Dt`ouRMbR{63_?2)N++WH +UgQ2|bhrk_$zhFq&&-0GBI7%I6kL4O|4i|q*kJyDdQ_Px63}m^Cvk~)4@xC%V#diYbp3Cjn9~z^hvFm +-?Au4OK#u{3xgo`EPX)b_i~ +aL)zigjZQwnrmSQIiM>f*6Xy3jS3Yn4}6)w06uDd5%gxSw@t{p87fRZ|!=|KD6tT=JdmbQKPLd7Rm9dFVB}!ym|gg^wcHKsH=?0ZHo%Zdo+goJ+i(UrLE53Hw`OjVET|V;HIexs_-;#f06ngsEEbN$aFl~TybKf2k>N~O7+*y +HxkO7b08~=Xo*ptDm`D-4XdrPY)kfz0wbCY5eX7Cw&7GlO=D?1v4no#ji^3UKDI0f?y7!DBzJ+pUTWS +(;z1|I;JcnNJ}b5r36h8iF?f(U6AoJ6@;-j2JMv)jL6Tn`GgH>vk82x1SgpyKfQ0Dp7I1t +p2)xX*rA0VkFl?VWzQ%OSOhZ*Ec@OFi(=;Bu=JYBfLLIf8_P|m^inuye%fY#CnE_E!Y|J9T7FW3H40K +NceDcwYKjIMDY(?xh9HhOVQthI_B!g85J_lj4FE5ZaOEzz3Wr&igK;;`eNk?Ws(UnqA>SZ8d+lvNhv +HhuCXelhr~Q#{}SacS?iCm95SwpJ3IPx_dzEBxvj+A=vw?J#;C^}J}-$_<--nT6Z+$&QGwJaOf +vT(bsW-T}EaQc_9bnvXFpR>D!M>XH$?*@)C)rzKA;dySe=9qu@qtYxMm>liw49;s`1SOJfg8b +{2)ajgO>?Fql(p{W5<`dzGTijBSNk1lX>na&12<@dDGhfy~KK?o?}Wl^Q-Z^NV42p;$;%1NQ?6NE_&* +=dq_47Iz$^yzds(*h8<~E4kC`b&d8<)36fj<-QV&G`1#w(-b9wrKg>0?^ISk9k9W_Ol+!NP91 +9+CGT*SdtVNwyUXcr@e~jAC5@94nkF1G9JIQ#yHjPJ) +;!I(7_ifKq*we%3#H=Pi@`%Gv1A%I3v>AA&_$`5II7-_JwOEi0pRigU&FJaq +@1TxGqW)5d$@b>5&)*gY=(Q_pfz$D2m`jlo+;Syk*JcE5PIBbrgU@*f1;0=?)ObV0;z#$%E0mw=J7PL +HP(1QORXyN{kf)=n6l5e2pVB^n60Nc^ZW`lg(`E!Td*U}~@c$$(-&OwbS`Mm8Ua9VIkj*>v +x8Qd^fJ|h6UEtKQ(}a@d{)PSXgtwLVFEZl*xKyUC{O2f95K#61$bQV;#0W_RsC3?6YiFSnG4s7vAHFB +1XB;oM=^uyFDSgbg|!aI@a&}zl#1kwBmcja12P$DJ@g`sWBQl{!tId}CQD~gSO;~n;mZW&IJ8;9M3YHIxU~1bsSHS8^kjUY}D55(Ia`CC;sT +hFG1;7P-BND%S%U^6I9yg?YVO;s)SW?Xwk?HyCMm|jrU~@lN`O7>9UgWAjXHcYz6y=>x4v3S)+XIbS* +M%#!`L$jBptSuH_XNDoFDja{Wt|LB5mfy1O#CbSu`XWXF?&G-??E8vpV199Lk3Iv?mZCVmk0_kBQwio +#Vg_nL5d|5L2?(tEgG^s?1s<$O&Gv=kKd@q>=hti@f56?Pkwlq05OsIA4<&LNt8bu1i#D^)V|{?U$S!ASL;&NS=8RmYa}V~L-z*3PU)1f +J#ER}gQgE_VO$SDmh~*}ipm{tgW_55?HUvk>%cO$A-A+WLT2qqG5&Sv7McAXJY1;gU(;j%>O@Ee1kS`N1II_-Np}B`ig3B>RW~gOV5R6>70Y%=926LN)b^BjGut*X#xW?F#{ +n_{(Vo62x0}u#RM3LA|NXSry%A)XM!f|3o=*Y5ityfKv|+3Mn)LO_57)FZWfkI=94lRyf*+z&J20#OwFU&2GYWqkEiWGFmTL +|=mzM-TbXuS1iER7-v85*&2OuwOgi&e@HlnELiHfjvH?&!7QuY7cc3uYuINO(`SSH^l<*^vq64(I6pp{-%= +A-_lCsu1}7!i)$&Dr8y{m;x@H^ijygwKib@HYDq@fIzVJ-#4Tas^M2zDtg9sU7V!&dd5y{--97M)M0#5b$Ay*ONNrJAx9wAputi;Ssmnke%;`q%OuD1XX^F;oKyLzM+a8(zIVq?=}x9+P6-(rb +Mc~{e-lL%e3Wy!RMdR=S{;)9y_WrAwrZTC&^g;!v#==)HS^$Fu3p9r>^CIv0uPK8Zc1?PvhnpcyVwtSB5>8CriN9hobT`=p;BF<0~|^PWs_(;&#l;b0=pJ35xkKk)NYBS|bnBKfFWNwvQ5>H@Ay5k8ux3UGNvX0tn7LjkE9z2{#FaZ5aj{U20mG +V`&3T#tNEU4QmAglsO753%858t(g2@beb9NxvNiaeYTzm)aC*wguL?GA}?^Y+?2_6&XpSLDVQ{d%{L{ +Z$)_^T7a7|7oaq=zSue7*PB>Us}`Un7CKrW6>22j|y7~7!-g=Z!Ylj2yQtg4q6X_wMCwF%4l?9BpfQ- +*?1kF63R;t>S+}eQdz8}Uc0s%L3g`=6qfWtENTM{PrI>iTq9cT5cG6mrKj9k>@K}hJJoY2H5ZDAH>WA +%PGgSgowlnDAzb6uryNYpLW-7gM+ay^7$Jry5yX=J$VM% +>ir0wGVO!+(A2RrZnJR>=FjaMrGr3un;jr6v@hs|!oB@N$z6@{YdY|RggOUpg5P7WE1+838KW{uWyFQ +!?zMp&`0Q-5nTk51k-#sntSGKNy$YIAasR202H$!N~^VK9V8b5Lc1n;YE_bFL9!<@kFNHOoNMOTM(rqvqpS$XSN1VF{Qd +Olg?#%;x@gL=HoAU1$M6@J`{sp+k)0QQCnO4svW@|>FuSnAVN%qZ=$ki?5;)U43ribXXGeBUgw_@G+RAm{6CUE%fZR@y?&I_sUcyp;!}TrV`9Jm>9BlXq +RAii?=)Mley1mTn)Nb-434#l|bI=JAGI6lW7}m!f9}j1}Lm>LWocMma{-XUqs8<6C6zYhX_J5*9<|xE +TL)TdBHv-g-+_$CcbM^aAS3b}X8bc`R0N)P;#)HuZp&hOmR8%zA@xB)X{6f~lOv}FN%)$q +19LAG-Z=@{svC}A2ev&pJ6u~=+r+F$R3Gl++9C-eHV^T!*&HI|LJ0Tsvl+HFI^ZL7$~SAf>t$k{Un%U +ECN{b}sm|$k;XI~_iso|k*5Et0)`NIxw(C7&mi_4l&|Nect*b>6Yps4CgvrnL25x?O11sWx7>4~PulE +&*y~CTNKX%@ +7PQ-BT~qL$B5U$buhF%2T1U5ahNlGYC9-Ie@el=;;`xe9vo&3M)8ir`VVLK$VAnF4KnEuSVa1(Xe9C; +j&x+ykcy|_y@w-5Lwesf6k+#GH1bWK>Tg1_e-(8^{z*voOVknEmG%~OynT%Kt};~^!8b5v2H#?7x_x|k +)qH|`&_BM3+9E30(9fivyuMv(YmSgnr0grZPV3Ema*^|of9;(NCcTpdC +s@M2Zrh|RBVOu!QXXtfvc(6?K75dfnA6o4Sjf40d>G_iewN#F!E2ZjWPv$_X(Tjiob?pDW3t|2M}|Ld<=Z8WB~v@W;vMdS}x^kVCjNIt`T^pQ +~yOT9?D6*Hiv{Q7~k~c;R8Q?)rp52!GZcU^i32T^msk+!wfVn7u+dWU|R63N{EaRI3Z?QqiVdCV`|r{Wtk28oMSWMoT2w3-uSn=N{9B27f8EB?_5r>kDM~ip)elXtzV2AY;X6={dh ++`L*aA1+N!B&FumAO;f7AVcoD97=fspGvTCuT;Ai}3N&S +oPZ+V)ZBSGqagVEF_D~PFpHedTCT9oGzV`3;6#A;UZh=9a6cS85x{#%{I3j$(J*$FKf)6@iev_2=-li +O#^!K%Pk91U%hBIP$z%f(eV*^=%yM1Pf~q+$Z +3#d2{#B*Mj&nVu;!sgaNCRevA)%;o{yYJ?Oxkor@2x=b^I8$=IXA`c2<;v;)M2XBGwZwUI<&!2^`4j( +qb7em;Pe64Ha+0ACfJ@RdAgJq-r{8z*@pro^K!>^XOsH%jhgPBH~c0{_YIkiQz=KN%kKSL6F9!$Urf? +>DOc0$rfFRlKJWg3XL}pW$1+Z&@bXUd7?A*;rzm?D23QPw9@z@|(Tx>8Mv}rT}KQtg%N3%-`)0h&yB* +;)=r6i4-3D^vE~<)~-60Ti0rxlZNrk8~)Y@697M*ee9)8(*$_1c02&DdfaC$M0$dmNTs=huOfEqQ0M4 +zQJp(W8%s1AQ8eG`T40Y`7GKGevMBb~+U;Z_qUbZ4T{IH8%Br!`Ej!O1THB1ov3snI=@IUnY_lMm#j% +_&374!r`gyLOmm9~kvZ!4<{+Wc~&W;d$zcx*A9J#tk<(hEHBkAJZe%Ic$(=qjEDaNkk_5$9GjIoaWNXVy5W+2S!;v+%pxNW*Wn3^)KRYddAJB8Wrf$h{eI&!_@Kkf&Mjmm +hkxvPiQg(@UHGZx9^M2EaI0ww<(Tlef>gR5LFc)p^9D==h>vD`%1VIjpW_eID&zG +%U`umI;A7@pUJM?zh<_YyM!iz)Qn7!IcgJ|2-LEPS)bQ2+(&6)L~PRWG5T%KaAYK7Tp?b&h^QmRKwU+ +?3Cs_gE!exVAFIBNKv7EdisM})Q8k4Q<^z#m;iO3!mqc)4H2@s@_!2cKG)QVh8wwCZT8$fB}#dMnl-=PGj9ZL%&g4{6p5MlnkQ#GoBB2oOkO5W1GOu3PBZ_wN7x`)Xd?J<=o6Nlar5h9ge;$GG}j$V>Vm0t2{eb-`FGA?*B1?Es&mRw_9%KJ*>xM7f(pH?{4fgv7Ge>9$23#D^wCspSKdp~Ly5Kw0SlfjiJAxp+ +Ht|lL=rXBm^6YoQ`-Gts$+w(Wo_9Y=kHl4o{o5I_Sz7Ll>@=hh&jWeE~uO$~PUoN)G{cB25=Uyd!o`n +u>5Cl^(qN8rW0<&f7W9f22@Mz`JB%c@?+sX-TY*OtJvec5R&CE@sWT})Xad?swG$n2-1=~m!Qt~hA=wvKSaHSS0W+1&;nF0_x=KIn&& +l;eEiZqOrGpt35vcDZJyl`lbklf53g~#TTWr~u-hI}5}jY8UmtPtcZ-0}@7yw1tM>#w_0hG@J1JG?y` ++w%Ox8_|Li@xFDRH(9`3MSn0>Xr(z@s71Ym$wyr|I(tgIbDYrKyp-=fH|SdPg_r!(Q4E3~GRR5;^E#L +DBdTs*o%ZIm8D)PPjc59=8(;O|JuA~X`OQh=;@Z}2UZ#&f5c7}U|1A*yuRQH1Y5E_J`85<{tL7cPO2@ +~mGB3%j8uIB%pAG@y0pYy0Wq^L&=?D|RoJQi`Q5uNoE_j({0B?Z^Jq8eQ0bXEAf&pT8ih=xhLC1*rxj +rwTybxdj9$3L*V8(38*C`Tg2}#hD2^k=D(yd!c+; +(rOn0;t}O>93%;{o=_|FRAc1rPCP5(1Q{3v-hkN$*Kdi7$WpJp3%CF=Wo~s^h!Ult%JTh=-qWh5tP50 +5>JqMQHUicek~A;zNN+2hP#KffQ+#YW>ZtR$&Lxv|yVuRIZJJaz~8u`e-HgY@`=7i1)y_aI- +wx;^|nQhaSr|$@y8`&Z=dd$T^Z}j6Nd{H(kihWR>^rJ$-akl4iHumRrUl%J2k3KGO?Tpr8w6(~qbm@) +3>q7yLL2ow9OPF`s|QyJqC+-@U@Gwe_jYdi8Ktj8^1^uNZj>yl`t2;>B}S{;rs-?6d`@<@|kr=*t60>Cx@lDHQ%36sit;`Nm3 +;On5<3b-8KW$C>9&OM2Tz4fBZ51PI+f06`*{@lR}{hob?rgg=fEpuZZ={tTX>pN);Ptd|_{GJ)eNbi> +^v%nmOvxkYRchYpf^wM`&_L1)jq}^C4&giJVWb0?_1bgK(6=q$nq34W{U +3jBU__@d2w3^2}KOXy*J~&jO6Q1vP1d~-sks5s+QAm6SV##pUZz!snt>hrE;3<1ny>QUT+PuTkXRD~$U7cXU>r +qP7xZi$43B|U?UI5n0Jxw!vAo6sNKz5t0xWwXUlT{M6i_m=H}QN7q|i%(onh;IHVH=06B=mj6A4iHMO +P*SPJ!GO{uyyJrhsJLg4IB24+UEKFtzIZlR#1jLsqP2*1Vhse1r%E<#>h$k;C$?3x)$2&p=v_AYcT3i +2^VZRMcVS_cZ(!jLS2at%`Pk!1$Nt??26qtBxRgOGbVCfN^uhwW}pWD4aX8RV}!8H~8uU_saKD@RCJ* +G&Lunp!XT`PWcIpbT;*Heu>??d0ycYH&o>1CA&>hqwVD>^ +$k|+12?MW|I3`oNmqoGbfF}bqazKJpS6IibGKN5t*P3y1(6aQ|Rhetorxm<2Sl=3n^X3eLr_iZ-? +9RQ69vCHJ=xCyE|-Y=5RNoPHxSr*+9Fh=t^4i9ILe-P32F=+YuQ%LaEB_aP7N|EXbQ{i=k$2!q@Y`-E +NNkW^chgHckzXLFd;!+1_q3ZQ6Q>ti0jnzRvo3Gme58vj1~^X!|@nWv$6Y753~|PdQ7^;-deugseedPUBKi%tY6mv30{r +b-zNB9=c{=MY-H^vtdslvkZU1(ElT%C3FE(Tu%dAO@m=I+dF_ItnhU`sI323I(Yc-#4FiJ^YTyyiivMhOW~WvL=Q+QfRUgOECQ +K3PllL5*I4#%9CUh;yk4}MLSqxv3113ji$wY!`{L38zy&HJ;MoWg +-mG0J___X^KVKi)Myf2dPW3p5O$c1?BiAnB58ex0GgBO%$`Z$^$p=#GMKb|Y+b<%FYnTfmM`arbnuRr +Fmn&9mt5F}v*igZhHf$-$*fd4FWa;P0#)0h% ++~>;WlcxvG6(wWF0$w~{{d4c-?FJQxv9;U1!Jox8tmP)D?#Ez&bh4g`1@{DOR?nHYKO)EdjX~>NXimX +`=kxizJc$gOu^1(#;5cgr?0ObpzDS6pFp9wxOvBXj +gFF8LaF`%S0;OP*q^Ykfi4+iXz;RHp164(0WgEkwTDK$-3;{UKK&$}=fjs`T(^rOr6lIC^qipp +CTkDVv4ti+InW$C%5?`B#0k(c|&>*I0C&tey_N|>4{^QFlpyZteKKe;b)GW +a)zDL$XB7RsQ&A_c4A(fDD^cHaDv!rk#8uuKR9#(iH!UZOI0EUiT*ljxbTIu+6PF+b(j +0@?+xB?VaFy0gHKcc?2cg;Ar?G4vy-QI#rKX19uqbvU?g?*E>AhKOkw_UuQ$>A2G`IY8EF;ge0Z)4I!N(6| +;TO`;?I#NF&1GTX~^kaZ2ns9d#Ay&$keTE}pgNZSHn;2Ci=zmfa=0A*7LgieM;)w!#Sn;$%`m`ux`gzhQtM~osvJ&2ilYemD@8WyB|{1Pr8O+wTV +Ntz-P(5LA>~`^C{P=2S*_Xd)hFQQ<#w7ZbaFO%%{hDy`+X*(Clmf7EEW6uI>FSj26)wH9ei$;)6F7f= +c_l4i@xQNp+0ZersqRU+t-#-Ctg$(P)P|e{%OP)_Auf`NM`psCG--bmJyggbarTJfI~BX2EkoS}wZ47 +A<&K$XxDTwcKD?kTw(Jq!fp3ZRaS=%;_ZPl;PYo=;WP#B7?a+okX6s$F`YcA~j6pP%MuZ@8As&+<2v$ +MJ8N)hMb|c`{B;rm!!eRXNIe|5ZPDFF{K8CO6jmsg=BL|PQJ>1WXb@JePXd)cba +dSTfI_Qe)M5T)u3KU`FfYW!n%m1lPILNkRRrzx@%J=_txR!=-HIMGIqs`GNUKv!W?8V^-_ +24Y}XoOf%TQ9s_d1IJ+SeN%fHR}yBTSH5SK0Uu-yrk`LUy>G+0#yuYzlFsGsRYmpLZqE_R!$zU%R0{3 +~Ju6H%Yi!zd-Lcu5kKusnovrx#FjvmyiQ{f`eL;`MacXRH?`NvgT8e>j+L1qVr|M|X*2Z^d&(C|fXDB +gSvb)FTex{De62OxbV%=jQg>*v@!jT#=cDQb;C=1LX?&|uO*k%_K`+1X1JPc<|9OFlJz^@m@+1|yIDI +&9A3~UW`LGZ{9NBb{VikBd0iGh+Z`7KHRh>v0rA4x#3v%9xh`dI!5sVv93)rKrrXows1LQanV0r=uzE&a?up7K<_wQrOcO*kO+TAu~q$(2Fu3R;kD%>EQe%Y>dLA&;~`9+=Le+;JWPR6K+2of#$6D?tlA}FxQb9?~wxV` +5XHRAJl;n?yS(=D7W%wNh{v)zp23jHvTZG-!u3uOMHDhF!OIj_bT5dF!5 +=>tK~>fY{N+UK63)$$Crxp~G+;0%LWv@Ja}$}Mx1zAPL}m(XT$E{v(55$c6yy7Cm;e7>gTKy~7OqQ>J +4W*Y-q*{%wqJeC5d*|`IQQJN6Ku~3=45R{6olI!=$P3a%bsvAh)j6HJ?(u#q(Z0Pl7<=OOmz}=BWouC +bRUUF2e+d%V@}MR99dz`opXH1?oqU2q#ZPYWl8@~oK(5Ci|Do4u+g4B)_BVuIP3)#Pj*tPfTb@b{h71W|_UK#~L=&Hz!XYcdpJbnJAM(I78f#CyP*EWTzNrGnoA!p{S7_Z=`$H{%p&}1D3%O53xXGl +Yg^t6WL>B@EW@syT0H4(6@WN6%Rll!vHzca;@AM)xD&{sF6AwT!>4Si5) +&>5m8X^14#c&Nuel@VvffLgE}XrOfxZjjt+f_w!4=Fm-YkV;ovF<}iPor%bSOj +ZJ}9Fiyh#v5y}OW8A}7>~3wU63}hfU5#zT*u@q_J@#)jgs1ZHh}-4^Qh!50clKlB{`9|p*^zx8Zu+tB +`=315xAyLz&hs76qbP>c6hlxLOv5zB&@_dSB#y!`ic=`XFf>Ww=vU!DMgvJrDh5Rgng)$gFiAwNLOm( +y|1O|PtZe3p{yqCzDxAnbGd7FCuoN&p#ld(w4YVsk-(w%}D3XuJQK?^xV0E;@M){gQjX}&Bqiop!m5)niM@M>A!m7>8Q)e%W6k9f3U4Ah?>$rHge5@kVzu%5gRSy#ZTEAj+9cKDQ +^WvXIY<bJ)i4+EEP_DNgrD1rqKW%SeBt`wf@GO@;m^b3AR(yN5pX4QSvxK($Qj=ZDzui4=+v;jk7LYVn@sp +>T+U~9|lkK9*ESW-4*pbLynShL4#*AVj8^UW<`poS#-nC|{$G5CWnp3=moU+b(Ei`?9!6Qo)*e!KMnc +=d1E?4r*rmRIH51C%>er|kT2?|aLGQFiYK}yDMhe?q58m2C}_C_(oev|61`Fs@{-;uCqbCT5r;ksZ-t +_M`9_=rr@UN|SP=A_&_qe&FEP?d!KSYD8Zqi)_DEq4d+$INZ0?C2gEGO@RO?+ib*=(N>elu#Y7JL801 +uhbw%a>xyk986*Ia$~8$@24jXmyGn-9@Hy`-I05WdChGo9;dN*2}!o~x26-4xJ*2Sjok(A$&{c`jm(& +(=s7i;p(4#aF6)wKQN!73eaEy5UmP5qEV)9m=JcSq9{%KaM`P+0nsK5QLKt?R@WufrcLfqGfr1iN(H$E;Y} +}(DcRG(d$QqqFU$EwAdDNDp7_@_W&NWONnxXOh|_U#SR8M-q{?|CG;)9Aphxyt0^$4f%4qIzp^iHyaO +H5nDSAH=Xih!rkKx4CI$Sz9X5q5ivv{kzlOl%(!oVqnb +c{C(W}B^fKbwO^5c+95s(n4)9~M+Uw$Zc9iG6o^mt;k~3l-HbQV)i%R(GVd4GV|Bl29#A2ji}5P@ThQ0sQo927yX{5GcRB2Is^!Mv$t +$V5R!02%+|CD7vXKhalGlSdZ(eW!y~?|8S|0Cb%t@*H=V=_UIV19B;<)pHziGpa9;?H?^g?b{hHUR11 +vN1|GayA++LDmL-I1nw!9sl?_VsAVe`mxVL~9^Y`;A?;-P7bZMfetx?f>}grvdk5*%mL`zL=u_PoL}~ +IQ%Ck`YuYO5CW$ViotLMg$bIXNfaR|ioqEKhbaU{37Gz}W<*n~Li#G)h=zcAk29+SE&?cg6awh}*cym +2*zXkjwYx3>MgyXCKmbla{V1V8-1as#5Jn)FTcXS*R0N^h8ni_#B@xGdCMuZ%P9oTkSk>FpwIW3Wh0A +4aOC*?vpb~_9#EF2xAA$lEwpNj72JDj|;4Mi8*at7WVF{=oVN1*#|0+ln`c-}JTg~Vw?6aJ(vcMY21K +|nuZp%*lula)Yk3k|J&$|ZqjrMP>QPpWBRJ=`tTh%0eGl=Cd2*_lt3dY_W>jDIThJBor{KFWo7eg=U) +e*4KA3O(prp7ws;jVo2?57Nf9bed +q+87+5Mo`e?@k%jgZrg#mZDx5sHF9>H1z+B1Pc*}Wv#Hn~vL!q&M@BI-TPGqyYut!Jeu(thuk2}+jv_?$Gc+t)3XuGhcYxWEU +007Z=Jl5`@NMWjnmC-8j+oOb)}bt+*_AXZuk~rPvMR!3u4ygkdR{kDdVwl=i%yh_8t^E*BkWKZF%e&= +G)qej$3l)kyDZF~OlQg!`dwOrq@dDVjzQy7u3XH)50{+@iY{nT$uBm(9XDM* +>GayWZ$>Cb^)EEh^TWf7P?|E(RVqaYIz{#L&s_1$j;%YhNql3OQ<%;=Ry2QIwls9!v;aQH+($$X4grp +Qz8y*eimz&I??=%%Rkm(^=dEBA4J7nz9i*7Htp5htJX#E-C(QeaNEs2YLz3=&cdo$!7Dd~tfo~h(9W` +`#vqYuN(V=sFp^v&)2bQEo?;RR%l#jzUqHMJo3+_hq|VToyao$s_GSk^#ebQV0>6xy_Kq}CMdW_fpDZ4!ZrcVbn0rdM|rdi`y*GWM6HF3V +m3J4(QA$vRw5Wndo+2cEXeIb#YyFp2yUH18{Dew&Ls^1_(A9miYuU6FWq)jP|w{dHxf`0oNuc9OrLPx +2XkzGp+He0umtaRh8%GcLRgM&z-~i-!uv3wZvV4e +cljlu4j@~!4b|`nxQCKo$26j*168>-b{`<~f?fdhoG-HTO5|EG;ZPO#-Rb=eP!O8Bq +gQR|?EV*y66(4tK0sMYQe0e)MoQz!bVTZ=))wwqO0*sM=i8a1>oo1yu?~TeA%G*T8W4G_N=)on}B!^& +fzrDH-l}@}pjvU}ib08077WKO*3!2D-J%YPr%7SGbW_O!qFXisV9II^LUQ<*FI$Y~hRffS5@+mhV8)@ +@Q1YDHf_xb+ikq?Ul6rgK}pH3U?UZE$NCQodH>BB{I;ramuwiqBsyHADbv2VG1w;4vsaynGGa)VPm@J +@P^BU252T)QuU-Ocs|PhK4cCv+bjD+n0lQ9R1<6eEoYPu#M@yTP0(FbpZ-EnhTPJ3DApKP>@+=V3O69011KRSG-! +Nqr}f>q4-MSB!17KY4xKzERXE#e6NB!`6?b3xW|7NkUl2u_#s%Peug$>dEF|a^olWe1~T73sz +q|kPcZeyDMeQhea|@GwP2nKIVP}@iQjYL+}#M1{Z&{EROFMIqObu!y#`XZQn-M* +r!o`cMZVnZ`tUZGA3lX!5_VgRT$=HgjDg3ka}$2bYYChApAoEZ5W#(Y`8aWQAPyfc8=lNj?Pc*ad2zF +y0%MV_mG&btN7^u8(%#UZG +7n~mW=&{t{WQ&jV+Xh2WC;M{D~y|!|*tK6CqW5#*KjF%QaNj+v*gZZH2$~xb!_Z`eiQY-dU>yU`3H49 +`wN=4K`ka9!xQ_+A@T9#1{Bv%PKn#}SqvNR^3cc3G={FPSvlu{;?8oU +oHAT%(%bmV=cHnfF1^!e?0yzKZ*OL|bSrwuwXY51G~iWQ2)aVPpwyru95IPFiE8D182Og>CPqYf_K9w7GUm@owc +}H06dyisZ{Yb!2%%BQDlOaoA-gG2-HP2rU-eD8Rk*l84<;q1H`PwAt&qJ~MP*zw?V!!R8bs2>NRH9|G +Rl6)oE+|D0~{$=1O$-Q)x(di{9o<+&Aj9>0*p9};s{RC6ba+>l3r2-L%?h8 +^Uvj28Z_zYH&xNKv5m!GLL#F;H5JA{;WJEuq8N@YDDx#CQg8DRI2eYYP=KXN2Faj+WVa-)3$iVVAK=- ++ARz?m^($=7C(vUF!LJA!RCA +NnW_-cv&?*oiadYS)MSQKkRaW;-HJL9KGn^Q-;@?Si>o(N5EXjm(BD@Rxr%CJG>GC~mU +`0}ydn7*+0ID~Q6bOiT~)OY*@VH`nksAPbwe!!wsv`{bp( +jphCn%YYNoMzOf7jxp92Vok;~Pz_-ak*oHjaA0Pz*#psEnc;|;865PX9!uDjI9kf +hD`;rWB%Vf}+o#{rvb$4;URko&B*99=a(cr#@2-_T92|mps7)B<^?BUy`eZv^Ui;JCuplWG4-yRv12N +T7bSsngN^_$az^bVW*O~80A7<+9hC1=hHCRADy2f&Q^3bx1iqc@AIU3ZgA=#3{M@c^ls+P~uv=6O$nn +oZH4=a4kjklv&lHAdpIMVjETSPIYdx2>l2UTisV*c`(DBbjp;#Oy6&9s>4`?)e+A3LPF9(K<8sLZ%Rb +hzZ4;sCLt?vaG3XnGV>Q=9T~w@!aOW3-)bX`GL}XL5jA2E;LoFE}MPL}iEI%+}$@fr_WJrRBF>1;8h%f!?fO<9tfNjaW7DQPfjer4EAggE>P~l7gu8BYJq2m=X~<+z_pii(uK-t)C3C#zn-OxbXh= +YDlFSzfQ(fNzNSG~Kru!0+_0KT*bA|q#NjiQQuS|q^LXMxPVq9Rn{yM%b +kEG2=o|7Z5n0{|O%X1bU^Wh~g@#ftyx`;BbLKY|NWaX!FBeVu~R<*&{DyPP|i})V8zX)YU{b6ewg@F3 +D)>rcdf7J|@PU3Yy>X=tsvLUJE37Y29&S>{#*0v|ZfUR~f-k`l+6Z}PHPCCk-lMQzA_QJf^lpyW&Adn +xYW+2)@)puo?+1fr8%vQZza9=N|L@}8NdX_isHj_-OVG{pr>q@rfr{CXhFUK>K>z43xCq<6>Y=#3R-Q +udinX|q(p8aM!pQH(*xbuwI(PJ;2h$AD=TdRnVhn-I{UfAGpGW2ad#8H6JqRU=xceJ6Nhmt~kwu}#EC +_rI)JT}kj)|a)9Z%#}@Y$vwjXkYM3j@3Hq+!c?^D#v9_;|(4ur%Cee+gSF*o-a&BG()$var +exIP{vMc9Enz;C8QG>P%u>E}_JYS4HO-)|gT!J(8*)o-l;E)VdRzsd}+r6l0al*Ap*5x4a|D8`?g8Y*uO+VsCp7-5R +fYDr1qBc-i4F#1UYil#PesCB~j}Vs1I*cE~+?0c6Q$B8wZ{*o(Gfu{B*JC_KboS+DEi|wq6QzO}#L`n +aMOR*Z3h`@+{J#K%+X8H=Wb*Zy^uMi}s2G4g75*g>;cN9TS@8;qfyy+#CS6O +)lde7!OS%OtA0m)+Eol*ffn`6Leia!`r~S;hDVGg@%TGv9|vk6j)p3kvyxi+)XdiM}d3<_nN~;DY}PT= +;AO_He-R7F6PnuDkzB~qES$ +;OKurFo|~S>k~_g296s!LrIxTmD-XJJ=WmSn$_vEqbOdo3{MET*lJw!E`r+m*Lm7Kf^7}pQ@R(^m6gQ +-Ze@q(Z&lrMt?X=@d{M;XO_Iw`6wv*f>%C8x7)t)imRd@)6g{Wuugd&KGcahKIT-jHv+H1T9F}DlRE|4n#*}7kiv1S!>NWCe=kjR>EHY- +zj=3FtvT^c_$-@mwQT!M^yr&8lW&aij(LQhN$Bu;C-zY25!KnxhfucqNccY6GO9&dkGPPX1$*;tPJc*bRDlxrL@Uuu2btEcVG*&AbScr`$4AihL5P|2)$$VPq)8 +Ot|i-&o-6&rx9m&dEl%~CW)gn;GMhWul#jpOIduNV|6ys4by^@%tkbH$x7V@)cnIc;s_-|td^Kt +Rn;rh+-|KMx$A85C_>adw{$qjM|0Vuke?wuI`0djfxU$a6-~RD`0ps)k`R`@(+n9oFZ?AX%h;ogpAlHT9)TjZBh)k_MvWRXA_lLomb!1N3>1V +Np1)xM4>K(rxNyU+0Jv~>vqz%VuTJ4}P@5l>b_&NZ=&QP49)2v7|LblVK%z)J*>U|?K3`I&SLjsq(yp +qIV+ej+OoDPHTeGz^SIm(U=K!E2NTAwx`qJR1RtHRzQtIWo0s=`8s-L4(hNt#j590VuTLFM|bP15&hM +|I4ZB{v~b=0e)+}O%v)G`xrV^{pqwo?*fogv~%yvlXHxk`o19Uhdj+ausJ34yB=5#pHNx6qR%3Y?Poy +SPbgk~e2zE-Rz00A;sIn6Yn^wRcE=N;A6=C*++cFwtT44Db8UmU${{fDX)c&P5l`DjEZcPfj;md?OFG +4{r`3i%_Oj4}^JEEAjzE^}{m&M?r=g^AhiG?QmQ{fkA{lwW*3O+no8$C{m+F^qGg`>|q%~$Z$y-$7ur +Dx*`fa13?3Vx2)8ReN5rp#(D+9iXJsda85PFYyL#cIytS=O?=+XuO&Vx=6+gY@eh^H=Hmj7N){X3qL! +Pb^-99LU`HQtd0_RKj|&z&mq>0Y?ghjfo)7Z=TDfqpllNRDuoRNa-9unt6D%e4TW@6c1{R=@V=ndu^6 +-)M7u=siFFEKk%EJ$uA*;p{B@_Sb1G$EckmiUagKR}D +b&Fthc%GGHBHT7ADx5JX0-Olzj5IcX~)pTKaaOFK8B47fCXayB%>1KC>T{1kLvo1)i!e~iSI>8NGM(m +Xh+PMRUO4WlTJ#`xy50CLvy0lA%<1j*nf@r^^M6x-0q&TvN2je{AncMQz?J|&ss$DGSKu`DlBwPtz@N +v;?dScdZHr<}Mp5US3uAS)_Ih7o{BL^`&T#&209rqh-=1ERU?8lCf_T35f!YET}hEuz8PHX$1k}<{T2 +&4{9Ls$h}qEr?cPuzo<`SIxE13pQYL^3WKYCks;o}uo;KAw-diqBJ@XwR#sc_#vaA~;E>59|5olILH( +P@4I9v(tqb*Wa2%$a?m!+G?Wf@B)fR+mM|d`bDrI!;4xo;N-)*kJPrv;nRekt5ZUw0iUoI1yvWm#qtg +nHXAp(V@tFbghDv0wlo^~E8>~cdC9z0uQ&aTLOFrUJ;fVsUkS_EA4I8uGV##7;^p=W9@Pdp)<_Yyb^g +3^=;n12vy03hTg<)%-A>-1o7Og|iQ8S4(|g2$Afy@MU|W*wi{^?>!jLmD<5dy&!(rN0T|M6}_aeX4&n +Ks~J*_~<(D +;u1E|!__AkSP@$&yhm;hw*{uCy7#2vW)8ZJC}@9bScvR3?s{*}<+b7TO085)%A8id#=0BEUK1RzRrdY +{%g0irPm$j0XDgh6jjN0^YdDp4=a#cCKGl#mShlzso158*i!33n{8D!ACE3aG6oJYnnkSqSW}KPf)WIPF%v2caJ|z +_I?4R$qtjMf8v8b^YKY`5BJRuIa&_fsG9QJ`1Mdq8)%p}Rr>3qFn265Yv8-#U)*eYIQIm|A_ytel +z8wePLyf)?JKDdTj5L|%W~?$yNH`T)69N8?;|td6SZN~RK% +v?eRpuasNN1Wb;j*VdX*x*qP^+1A!F5r@eHX}y2~W999-2DvNlXuQ{G@mNW74Cz1%vy +~d#RdjXl}UcJ&|5eKB4ulKnAf>H^ok2B?_fgtMKVQ?INU6M#0AP*2S;qD3%Q4QPx^iw@>?gL3dKy%g` +W+>SfdJJ3LhGy){WWgnn<6M$GlC +HJ7xyZ@$xxHDNlCiEsMV#)@l@pb}sjC9&`M>R2U@^u1_P_nMLqGIT)?cu@uk=&?!ZF|Jr2J|B?{FEz8 +5DG%NrZ+;hCxvJOEFp$2k@3KE9@blIKL#(S-1+uu8gQG`#qyUroSY`4EA*+ng*FPMgtxbaBY6;WJm7- +0JTz%aRP(^*xDjsR_-xMfkB$Dp&E?MCV)AdG610$(1k;gvtudX6))>aSB^AHfYkz%$q=xn(-5=*fRz= +!x@zH|hX7t9z*Hk%h1(V&XMU-ZCJmqwO@3=ctE}F$vUouJYBPNm{u|=yTW$%h#q`QlewcxIQx-u$9Ua +e)r}!zq&pfQ-E${j!z#{^RN=}Z@)fb9W_yrhV${*vaf`S-A{xSpudAGCpe%pnUer!Mpw(vdg`CXP|Z9 +e=z%)Qr=quSanc+XR;d!2KHH#?#)@J1Nn1$TG}0YVNCPv1s#okmpNHz8%-SHxcG-t2X0Lbcl7Esef!?)CZX54eUhZe%s6DR%`;g8yb?&w7bvx!qP2?(R%-+XW`av +UqgP@BrRkMZ6oRjL7D0W}JnpX|il}#b#JhZa+=fXUvhGysk7`34D=a+quT9>c&e|?`9XA<7rUt#Ehna +P(ZFt{u54*3197WpD@t!+AyrbKb))h`|aVL@8l_tA6Be6RBIk~CRs|Xb>ODB(Kx!cSIR*Bp6j5WTR>W +|&_;fR9tYOV(QP;cd~eh$~P;jb5~&uPiO<-zpQa>!_}hh||qDBY!n7gI;C-%Y_z+qhoW9g1Z*OrY$7D +RBpfJ$bMDEA5bQ%tAUYXAPdnYj(BsAm`d;bL1FLzIR6(9Y=%5M!go5!?Wn} +TCK4QjJ_b_K1ULBGaoe3cDctKh7Hrqc%K*frbo5t_VVH0SCoA^n!a%n*pXJl<0iCuU`#aaWBixct@>RopV=G34es +`vJ`QYN)d>215*>0fY`_=nGyTtypGNy20Gf;DN8vj7zR=H;jIW9=y*3lOJw=yQM^H=*qU}vZL)+j=t$ +Gyi=T-B`ND4{K`&8hX8y>nFsdPXdKAmdpl`si2y>6q4JGBYO!XL;t&&+P5{KZEc8TO8%B)Mn7|#YtxL@TE*0>m%)?~ZTgR{*rdJ_U0_r|a^2ie#tEuK}wje)RIHe#xalhZlJky7 +1#Kfw2!*NR_PCKRUu!^d7ag(FNI-TcJXe0>%S%|S6U#=H4kN*6er7^wZthK*OWQ$`)PP3 +6!8s~!aPb#c<8p#JqSMol3^$;Ds^E{M}S4zB}6!(=m8wY<(gaJ5FskILmb;%v=c(S9y!8I+mLr%8xlY +HvsL(Qjh^W3}!NZ$KbzhsG{Rs^Yxr{il7bD1Nwl-+5}wmdvkVupi-d<^CNH5OAA=dZ>mFWS_%mu&)3) +Nb5s8ztq`TYO-H#h6GmgBc9hv=w~X*RQ>hi&Cvf;YBjx4K7LcycJVJimdZ(nZhwY39r}k?d4Hi%LD&% +t7P(ux;^h!W0WB7(Y!97)00P%ATS22eLSv@UGhRe^BjLV{qP;q}=|VrBB5pb<{E~@1gG(W)U+dvy4YvUq*bU2DGly=Dj| +XIDGu21O>wwjll$lA +QZtc1o>rRd;x>{E|C7ffO_k!1TTOtT@DJw2om)11QpmcsAfjK=4?#5YRwXWj4ekL1<(!2Qc&a!)Jh7# +)))+gcM=MuB;qjOhDZ)l)W7Cz%Q0jI!a2#>O>LoVAb7)o%nQ)gU~NvikTHw`>H0XiR+GVi!hv-9a;+d +Qfky^j14%^=2C>k`g;Os4E&n}d8$iki8NPEi)td%iM_fvW?_VavJD(K$A&?Aj!_|-FRnm7(2HJ2rpSm +HllM#JpQ4mOwNR_zBPM?_4N3j?CrbRcau-UA|UO#UeA?K$C0{?b2&<~{UtI_<1w?UsZ=cc`^l#GcRWr +n}XT4;TXp0)*TZgMM2d%Y%uSqY|RyTgTm#Bmcg21uIW@?{Vg(U9=l@ht2nfz*{&V4f!;(VKv-9I>A}V +#~U^GRP;-Es5yxBp;jbBvR=Oiag3rO{Lvz`+{;%xVy4QNXqVO%Pp%ODe;xRAs%NPKW`{Z^Rew>$Q!kP +f*qRlPK5+@DH}9`o0AyG0cZg$EXcTc!JS5$!G5E1}wyo_7vA +ayYFjeVb)PW1zbO=1gjto08LA(s{h9waq?e6n?e@X2`W6S7au|H!&q4;JBe;61MSBi{F1iLmzr!knU{m6P@y35ug34Jwjn$(3a$x&>UQ$~Sp%k3 +AG>N_KWc%xKR-)8eJO<)-b^?6NCA4aiF;_SYCv?}hkup5|gvY$^9p&1gt5p(s)eT-=+UQ=99tL*P3p4O*I +<4M90wBO?y$QAz~)L_>+wEKeY_X~u9n73Z@bP(I>6JSsoeVI2u^vgcS5;f%d0%Xnzt&=5gV3%2E{uv90ujmiTR42)g3&OEV9+`0s|(NlYo*j>lGFj$oxugXL&m()? +-NE3q;VhI5PzVl*Cs_Is_yE(-|nQTt>bSzGb(P20D8M1IDpXQJ`3m0&0jbU_g1XD)Yb#t^92YP6=Xb? +MH0QmUk~C8Ib;Q^vMW)4d`$aFJI^DMqlOY{?Pr^L4)DFX5(8k_sQTtsMiJhyu;_(#NRaT`;gdyj5_;4 +W5=vP*eiM&vrm{_lNeI<_gq~k8l`W!JdijdN*prp#VtT%=LuBp^zmJ&;Q0A{dl|taI%vdu6D;UgEfN1 +TB?SUGDZ{M_itW}f6{NdG=DDDcy#K;V=3=X=tb_|WyLO`O+%^oljf2hHisKVo7|yt3AT~^Q)G;(uQXD +%SJsxAyw+1sjvFtQ6^)u-s9xY&@-anAED6db+4>>1E7>g_JQO!cJ8f21>suNX^xN_)kw$F4~p}7`M?T +kvmJ>H8Y!X2e%RO{eyQg2gZUj>93r)(5qh$BdW_f@ +D%4s`wCP{sV@`(gvAM&8ZF3zrneQnnusYhpFSO=Z{97OTUkLUCVxybO(-3FDY0K};R!ZIBaYN%yGYIt +`;!09KmajQ~%+8*PV(0268<#p=>4RuuvZ7q93#@cKCX6-$k$kaFHGX?`qO(&IJMWI)q=&EjM~qg`;>4 +c)$)l-xQ(0XRBVO|8l4!o+m05aiAvX}7QhsodBh$NX&YSD==I>r-d0TCH$uvV_KKWhP!qjeBOcCA|F! +WvyZMchbDhbqv+(DP!06&#e^s1}4&6-!&)uv0n207to@r2RiSthGkNu=g7J+>{JMXc*;%_~Ft*r%l$@ +|Q=fr#siOwQ=+0C%cXMYyWU4kMq@|Q=-W|9}Cx~_cgNHme*Hzl#$!X*(Q;>n=U@YdL&DWyQ;DCBF!+v +B^{|w?k=hCi|`p%rB&_KBa)E8`Oo7@k7F`EiVu+aE@kuf#{XJj2^5a}2tOZ59KvZhfhIcJZ@H%AUq2l +9zyFdhx4)7%u$qhfujjq^>(Vu^p8)g!!(qGw?$<;346h_ZpbWCWD1*Wn_#sFV1=4mHMN<@lGC0h@U&8 +BxP+788Wv(6IvjPO4(gKJF0HFZ{M6QrENhGHinETqdf~<9rt5*dpfCnR6^AUVKRj0A2MW>v~dQE*0PjhQiPSD^()$rKEJxoU~8aWWi4> +gaT>!}+ZWkEjB89Zw(dYKl}4yo7)%CXL~@mdV_2=`Ye*pzBYf1AmjTQJhP3$l=%>-{JLQ@X>o+NeO+? +6aBm5{)-cnL)?R&C}}O?hVXIVu#=4*q1kU5K=bP#}X`tR-u^z%*mxAz44`KJ8adjkD@Q~uwq@_LoM~7|kG3BBuwtb*&u%-#+~Kb{L)lxQA-q#^cf +oKp*RO5ulx`jgggLUg)B5bFv360ROfE-5QlBdP5%`XE&pCotp6&KYmWai_I%I!Y7-cDEivgCEm-Y;iJ +0;3O-@G6aMcrmsZCUdfJade?(SC5(Z^Y?Ex>V0u$J3F)Z!a^qMt?dh4{U!#P9)@>x4VSRKzYn=dibFC +0-YVyY|6NfoOR|EYguDnrBQoseGI!9Re{*jeZb1d}BtdhS~_=xh4DJ%{Z!iPO{qba=@;OTtquaCi$NhDW&;n#|^g`==8WjT +*w9?7uuAt5BBp*dX6jBc^>_JN+lQ3*<2seAMy&Uar)FR`K;{jQsy>JTEA#fYEv#$Ha8GwlpT8g`SJgO +i>e@tQ;&B?TwtP~ZoZP~F2TvyjZW?U32T@u84jb|RK>Bn$19%^3B>9-wKTg=FSM+0dyOHkZB +&Pzs6p!TDS0z%IX3So5kv<-ugHI@GK|XbaQoAh*ZLbqs6yaTzX{MeYM1C1WlQNF7>NRF1+@cpBKZ|Z- +j4owo%WWSTaoJW>8NtI$w1spf^&(=5v1rrcHd*Os1=IULnW>pEwtJLErA^t3x5_VhZ5E#W#N{T=WR^R +exjjcgb&wdzztMCL7HC|<4{v%s*kAi+y4dZ%wR`{fUox?v`}^VF@%`h3Z^o}#JjToI{2kVRI^s|H#s8 +nj`A$Ion=$_21;Aj8B5@ocDT1V7f@UZfA%PArzHFdK1V(V;%e0*=1v#k2D$WP`4;8><2O15<+B}e2gopJ8Q{@ac3Zetx$5jEYyJ+yW5bql7lQXgr@c~QHKu-Vx<5sargR{cQR9;RDXO{V}pk^J@ApLcV;JrO}#O +wa><&f5#K;gIr9!TU6B)ga24N=Up28|rFARdpZO9tn55FmNU9>EG(l|9t)Hqedl-3i|YoY?NN+8uDk?j70z62NZ +A-Tkp|?@V$>gEv}p}~u?1#Ufw;=Q36;UimF?G?gC}2-dmRzCk>0S$!%<~^qGT5zH7BY++C8GvauWIpT +E#C9(wc#{)=%qLJf||#r7xmO!k;unl&u#hC65&^iWXRnh7Dp&eY_mBmPs+?68@iIOJl8AO&=IAkCA@sDg#5foL!1^uDuRe +Aacu5HY>b5hGY{_iDrBcAJ6k?YDD-fkzCm9pipG0S4Z+mb?2`q|6r +wuwA>V8>|TS@4VAHm{`|0y{F5IJ`Ke(J!%!5y&<_M9P>P~x8Y5APSjY&Dk|a%{ +F!p6v#XJKNPz!P=6mUGCEAz?UgFgfrvp!v6sh&l2l3!&Gdo$M{7vDW-xtGracx-%FQydW6BaHt& +ck9?KmFU$WRzjBr=1R_J$ZaHg$OR}bvEJOsxfHosYl_7yJ70@+70kz37Ky6au+xS7s3JwyCkyY8a%s_ +ymq(B6O$p1rOzl}vafwSbwf7cG#^VWf_!ahOxax2`l=@`Rb8B7AF{#HB0M}s;)Xw7#GDdv?esPhelei +Ghj%qGHuR~)?QCj6v83?Q5UQX$r=K&%pmx2*lEK8U~~K+?(;{?3WMtMXqw3HjRv1}N*eA#2|v9zQ9Tc +yYM)x%m*``bxbK`lWp1?s=|?Fqq2&DybCj(KjFOPC=+m9B!kr&D#en7H24awi`UMhNyXIa5}JG-_Pd4S58upT|_ +-#jWEEm4Ddl>Yu6L+3T*PfjrhX>z|q0qZo^F;cq*~q(u^1TNJkui3K2`0nEpeaUd7jCr +C*LObWxKB4LOxw=fjBqvrZydMjXqPB!hnXf?2JgmgMRk*vSblpUnYBY{x`}(5f9Tn$Rc`Uwuj4Y3%e +XUqDQAZ+e(ha|-@jBcA@y=2j*O6RwpsK-PiWyRR6ezE1$(IQ*3`H5KGqpImbu1l=~~@IuV_q&!GSRKp +*){5frPq!xe9PR2KX*Cl63UKjS(9c;yRg>YZC5JS7Q7=-j0{Sf_bVI|3%TvicaqhYW_76{^5Z?V&V6L +e$aHJK-(J?Rt7?#6Wn}_sWOyy0!NGouNxtCQ0)uG^qWu +e`qVRv1Vio0rK_&qxaRoZWYY*ZKB$)yrB|-3hnc4!aK#pU@;$)fK?&qIuQqOd27!5?%YQ~d3*oTlcK>!n(9c8qlM($Ju +lZoQRCJT4AhF|#aLmiHDC|*VJUZKYiiDE}o$P%-6n)_|hK5Nq5?-$}0MyX$%1GnSFcW-W0dq#I|(ARF((nP0kn$*S*UNtFpPO&VuDP +aPG6eHVnC1u8wS(IE6nV7^+;Kz@mbDClaXXNWUy=NSc!;$-HyFc-cuLH&%2Z=}p3)0+=%?>!$7OK`)+h>Ie`2{*bgSf$@n5p +i{@*mD*mNwn@4hOUF`j6+1d1orQlc*>4$^VEscj+WQXdU;3#%J&OEi9smEy2|mRA|MB1-8^_@ovA`ro +;xvjg3sf@rVouToOfUb@7><)TL48@qKx7~mzJO%8mIP3%DnCI24>7r_J!BcsV^}Og8vYOUwU`u10uT6 +tsSAdcYd;!h^=dCxUQU3%GjO)*D6b_A3&?>~w;bs9Q@_;r&w$iqP6D_t-#XTmK&^^l0HhbIWs4xdpAB +rq6y&f`s{^}Sd-EVPkhNHjqB8*5FagX?WDT_gm-g>fA{1Z|jUQzUws#SiyRS7kdtWFOjq)+2_B5>AxESE3|F4qJeHNES?)n+@cw(cU-9W +4{IeJR-^e+^BCnq?y*@hw2Kkwo2CN&wWV;=UWOwkM%7%KXbA{FVOv}x{pLPKs-yV1B5)@-DNz+^){Mk +pi?R5c6RKChN>{4Nv9DIp{5q=sSW1E;nz$e}~PKrGH1AFumC3@Bkt!QMeY1pfplIVJjX~-t-K}Z!(Q& +TpGthTb4B>T<4ZA#e=HqU!ep*o7GW74JpE+%zmP8YPKMOSSw>~`p(4VpjfqNS}Aexaet)2V#fhd9<*> +VQA2lXe;8rxXY$ORV?TgR2S6)gkXJvXkeld)PpNx9ODh<}LR^@6GGovY5c&lKrLonSJ;i!pqm +c3db;9A+v+bcw|qEP5GXLESD;Z~DDuJ~S?6Yk7$DAA{Pq9$KM3oyWi=9ro(+y_yn=+4Ldwvq$)!3kW# +vEh&!{L73eT$O_u;Sn^mOFYgkT0FKwR{g64QsCoP*VYxnaj>!D&y8?Yq#9VfMrT-9S-}k4Y-9{;yXT$ +?LJ(YtRL2hm-glH{XZ>wF0@bV~_pyVYtF1tV|q&p*!#u>95z0yUm%BPg(_m(WGSB~WPJ3Bxs&u}L~$y +_m{=`1atU3@d>iq#kN_bjaIvW?p8>3NjWi>5~H)2wjIq^}7ByR(sPA!o{s%UzY5steIAzTJy4havSTs +A$@v#q2yEVoTcHse66bYtCwf5Y{+GFXS$vD;0-kEpX3UZsFQ(rpl#A4Xqxa3ViNjW{(hR3Z|!Y#t!cGct=0hgZ54V_8(b04`Ej5fKVo=)Ors5!}SD5cPeDDqB +sYq8p)*!~w`_HW_kzuZgn1gLrcK~d>5{{DSW{r~9yhyOW2{r`~@zT^5Ip6myJN65wKWst=ZMj6l*cKN +qpK1C2DMw2vx;xx5v_|iSR#-JAvUQFN&29f9mHIaPvup+=Q%#fg7aIr=gK>bB)SPBOSyWnqz0oX36Rr +G1iGsjaP=?rqyGmv3U;;Z;G3=HR0mGTz=j}QQ=7gDg;#mjjYGZsiutuN?R2pgt=5HrVC)ZZGyJ_Z~upa^?KpWUkrihp_N +sGOrf%M_8CU{XAmm-wyfb5kvoW$Y8|(!lV|?gF?E7jLE2q-*{>vP*1jN9#pX@FD^WfGn7$=s8iEaTVe +S)Y1O`A^114^RW+t +&&`cJMreD4d>4;a@RWv;;Nf?7Y~RXAkUK@PJD8CMzM+GdB=KFb}a0vKbS;e?r{F$rdQu&wzBNsU +!_*#$ytH6-83oaeb(el!Ihb`u>GsJz}cZy^xLWS%KHwEd$B#t<5QEiddO~XJL@%waXMqlV}Qn8q0)_s +-BGT%UGWQA`}cHqB>0scvFDU}uly!;FUDD@Q+2bn!pZE+L&(c9wisJ6pe&>{Z_GY0mTLX5@JnFM*%i3Ms1n_dzUJKJD8-_Ru1S|TSk5f)c~7u5L{*QwIyr@u$ +f%@&r-#^ZX*n`xj-L3e2wRVmJsl`#?UI!OmF +n;YeTaasld;wG)mkSd#s58r!YyUQqEB+)Y@Jq$U;}_Z7(5E=5vDmy#x-9Lg7$37XA5`h>?{{~x;f$mF +hH<*UnTI%>?$Cm1a&*wT^u_UuF?&-*f-}76Emj7Uk$Gg@F+)Dw$aWrT_arpd4nhzJu>KP$zQK65z_mE +9jr(RFeuHrpY=a?y>+8n)>pA{ziqP-o_`4}WznkOlrU?Cc0+#ShDVHgV-Ja*=!eSjxD>gSMoF?ylogU +o-<0qbw8rDEgi*X%n_GPV~y8N>6U$Pd_S5phUbTKd2Lw)I|ggq;SRr`=|-r~sVVf0)|P_Px%lvVf-=5 +hAgy`>}A2{vnzD!i@0844?VkK=whp;!*D!!Z}KJEUBlVlUUYOVQ@j!Jp>y)DycB7w9LSA4WuX^>Dn=I +!$?Wss%@-DG!_~zA8i`h>KZ6Ggayles}O2Qjpukq~hSU)7`t+>b+a<+iKoDxkDHXksF||K5KFODd;C| +2P>^5B_-s>k9$5`cZV|Lib$fz$Yi;an6~z~okgPJZK81|c3?AB+T&aN4l6@=);3|Wb(?W&pby}$L>PE +Ij9=BT3FmjOH;~&N^(%Y7@C#+z$v=6$iS#E@Y%Ia%dY1+Fl8;0 +PC5JNx_JDz?ve4(<4mZx`j=Ss=&F^if5(%tTiW==Ea+MJQX+P5&GRmT`9auLC +zD%uox5iNx@l}4wVgXSnQ&?#i{>rT1V_AMDFcusfw>%zQ~_Q2@-$aHo`Y^URqap`bdcL!hUeVrpOPf6 +3X$Ez72REDRrJkS@1RgN@1g!#A$&41DP;+u0`7W5A5QR@bl?a<(I}14Bn8tX3EEQ8pz +s|<)}(ie!DyKIGSeMMIIb#`6b^_5wswyq3Xo$4dP1z(>kBtP3J?WAe<60X9*q}(EG(uyo&)p0SUWFbY +iB6}Ud!J}5Lu^-)itqt9DbQ&hO8O(3sa&J;EF(SP*KNFYm2HJR1Jb!y>iV|TMOsYwK5M}F9D4z7ABL@ +U>xYmlaRGz)iS1q4}rs}-!T*Z1ei&+`EVjAa4}q4mCYp1_gJ}TQ7hin?2fCdg{{=q9t8d7w^a%HZz2S +5YDxct2m#3I`DnGMevc4HHf&U1RI`1-RI1Sc?S$W=1n-IH%SKPcKPRI9yz+iEMd){P{M{6x-_7xNQ-p +q=V_vg1S7qNmE|ml6!CAA3?&WPF?Q^uPyA+6Q;tAiC2yqYH*#?i8ha+_PQl$ +39~x#BmOiCE0=@E#1Y~)%MGB!7Vi>IS$hAfos@WWU0|ii|Y$3*#7mv>vBs4vc#Tu +o2$@5rCrO5<;uvr<2<Rn~R>49m=dr$4b3hK0vZiu>O|HRf|R +1I(4Q|CWyzJ(_1>%g-aMPt!w4cpRdlU%x^&!(%#s*vS6;A{CL+@e_DV4VYl}ccHQOkB8uV!0;4pAQ`D +E~xNrt+qC5xTPLPU}01>u~2IVyAn&`8bVaaNb5!rt*>g#|i3}T1qyw3Z1oxd0D+O1o%j))l +-_UDsGE?2gH6stM*^%!Z9HB3bgsjwIZ4P4_bf)kX+^Dk`yePKq({#8-egh27Ir}@}92hcEnp!ZUL%;K +q~+gSf-!=dhG{@p}#faSm1Acel$#%EJu<=&Hhpou8RC0bT%ON9Dg*4S@@MIj&VoY74OR)ge+xT5*?ghHj8uP+~>hsG$)|}oEczi+czqgIe2-%Sx(=lC +yzsrTd7fn{AX=7HtZM1}6mjGy);gTec$ycG#=d`!renK47(z9)QOCGgvZWl0{|EwN{`V_DRh8od+=Eu($W-;%?2W<+>%KvGDe(+sKbOG4{8UHWsPA=XySY4fOu +7hJg5BN9Zhca4QyA-i%1>srKRW?tUpi_^0c6x@k%*C#JSKVn4Jv4eZ2wy}eGI$X`Z*x)>+$kg!c7t0r +J(1+MwcP(5}uN;wWOU|MF!nGgoLL^u==H9P_NbcX9wQr7Er+&*whZL6;!4qY$7n$d;Tv15`$o2lw9&> +BXrK3m^_>+ChcQ0wb#R=;wEK@LRwp_318lo()Vf7C?n_txVLGQs*E+1QT-(!;RT(&&ZTAf!N3cKHqks +{*G?n*O{3&%Lk{;0h$8@C$A25Ii?b38 +}a?ML*PRkTM-oL)3c`J%bufRWpDM`Stnu+;|W4X8IDM<$7Zo`wwKG0SC@Ta(rSmK&jlTAIe10)3gT~l +vehp4y^aYFy2%UPm-a~Hx8s~_=3d?Qd4ITH?BkGIO=YWI@fwE)%PgGOk0qKcH_=Tz$=OJwsWx^6imHd +BecT*;OziT3y4}eaoLYE=j`{s&5_EnX+XFR+jsr7 +%k;$lO5tIBm>_eas*|KhFx^S^XYSPOSo=O!>j_)FV9yLbCS3|2=c&mx~8_5YdE{g5F1Py2p`<*#-1S0 +^e+Ktezj%mSI97I(D;$TiCe$AAbHXe~qjC;!@PDGOjFWH>0Y0clbU*ca5;7Qi8jtwk*i4D5_D2hC_ei +ZHRt-v6qtZnBOFBt)$RzRX(HLaqi6wxTVC0;C6LPu7y(wFn0&@V^}euZ1&fytZ7XK&`s^tKMvx0!Hy$ +nJ!?qw4WTRU&lGCpMr)vUl1F};6D`XGan8F4~9Qlsry(15`7*Z4(Pq``|^N`dM#cJzIvC;I6~h%D}Zf +-RN+T@2%euT4k^ftv_r8kQ)6|CgV2jq6C~9+^qw!0Ry_?@7T^2I&fj0_>H?b=INMwc#5&a520LK-#=Rz^D?*NOZSnSGZG*s$s?9mGDT|w{hkXg`o +A(M+d5_|&SU7V%`n=fgAym3S6|a1PkEdZXmcphLvjUrh +r;E$n-U#YAhvQ4(hj(JR2ON45Y@Md|&RxTHQK6lcOp-b3SYr-8$EjuULE!GwklBvq?G{Rb%)k01KJKn +(L4u6QX>wK|&N(@-a4p%AmkGFQC%hn?`!v&^KJO$q_JDYJTJ+kCAa|GC4((kF4@QJQ!CAW+(w4t&)6? +GD%r8gY8~%Lg;PVe%;(rKl3c-%?(P7UNJY?-&w=DDzdGyMIc;9{%-~45GlZ9pI7tzMcans#5BG(iTN?bf*{J~cC& +S*#nIqv)3En?_OAgAL#c1CyB)aelI^x~#D7UDc*nH}i1HeB_5M8fT{>FDNgu6E|F+dVKmkS4(uQb^Qp +>2Qb%4lCl_4owb^>*T@q-HgblxtC0}<)W$U!d7`*>XMZARTiF~5=Bhd-N51vWS@xLv22}FcoLWU*R;f +SgU_WD>>i;tEl*@(8yiti+eE0cc0(NsG4v2)7w;R3(HRR0bOcY;`Z^G!ry1IqB-&P>EBa>F+Fd)cm)E +U3sryI1*wTM&|5@t7dH)Jkx7Zc0_Y#veGAFZd^(pV~0gbFn|GJ&3=B-%_u?kPppxx|(Zi`X8*sIIG6b3~$%PC=?I{vG=nN?jKU6Xo1 +_AtK6f{{Ro0?1;liNQ1iqKOL}0@ZSAwPVS(bY^V|2V9o)+8h^KK@?lBvN+X$*Af?nH-8MkBM!;61q}80aQ@^OyL;l<95SVOK}ncja-RLJu;7U&gJ< +8NH1^=e3q&7?MImYHd?4uZddNDnfnwpiT-9RsmG1`x%kS8KG{vWqmv3PS#dbkG=(i5`CP@GFL_p(bQ* +ho?G3SqMgy~5jCHUup9MJ0KdnWV36qJuEdY^KIC&OI`z*sC~AV!a{%75?hx-46x%D%OPU0}J{yMgIDE ++;RR=rfkzvzWna=9Qtr*>I~-d(TgrnD_k;(DI^j(O?1Z{GOuPG3DRr#qu||R^tA~qJ@5F_X=+ooBht1 +4~&5Q=9)~LrflYDN9poL*l|1G3OsE={+AdyIaR;7$$^64`8;nbZ2NlL$lSXQr(1rN#2bR9LKI9Dd#{n +X(At*EnUj%e~0{D*m@SpQ`TiN$c|CJ^hid#^uL8{LcwN|HWzEVfdG)_`x|$p$Li+3=S$* +X&5DN3`A%VhCt{Ah;af#7u^54t2?{`6bXV>*{b546CmM-Ua}yn2hma41N}J7DvQfOwt#WVvF_n;*4CjpN3UhgZeF0qkVX-?u?vqoJrj`HGK$;fQZRoVAwb$mgMR%s`!u +@S|!r^ga|Y5>Ig!OHlL;PJKsU{qyL6$-Q7<^&UNweWZsXOdCLXqbmCkAL|#WCWc?BOMaEx1AR*FdAwL +5s1Ac^v79oSPjPgmURPXO;FZ|N%g6p~iaxoyZB#zpD<>0C(I@n@ww{>3IO0xI&1DYL=^*DAdDJ&tdA> +y*f+dOK8#MXo?)nBNXteKK{K?NR9gl;<2GWiDQ2Ix5e>f1=E89IWkW;ceIvvq2CZ&0~=H@cOZFPM~(^ +K4^#UgIle#&~|`btt38tN(Z6wB4N((O?mn61D{k*3Qe5pUR7;geJ>l*7Yw(mJ!9t#-ncFyOrUggE$~q +F^YhA1RaU??|k{cxR8)sHAxA-rD$nO|~bdKfYuY)=En3iuSVXt1LKS1ls-@Zt814K_ohpjB`6D145NS +z*5NZNj$n>;N9C;Y_RXSJvIj7Eym1spE_EAj9x%3=IR_U&WV+asc +*Or2rN$Ee$%58TP>_e5SS$Fk@0AkE(%r04Q+4DU`6P%@JX>>m2kj9$o9Hhyc)vAj+|m?(^vhe|qe)%Z +>NLcYlC+B6qDZITV#Nj!g-0n_G|bwN5#AJskiGM2whVfi-u$YofmoLYSnlB!hj`1;E7bc*ak33!&xS? +F1nYCc>H_BQfn^qhFfgMPjd$Eem#x{3nWf=S>S?kPZqtLT*_4fDMelz&}wqL}iBiBK!EV3~x9 +NFa-;x>0-WtuH2wgTH#cDXCc1?;#Skb(E_;6e+tg4w;Xz7PF!hh>P_$o1fg{S7m`P|u;2a$ +Q(LEytvmQ^RxJlCbIn;Wg8R3jj^IiS_?>_gC@PqH&k7f?{Q`k2E@v9S27P1)R>|0W@UmlLoLFtuV +maRv??!1jdY5SFLG$P$Q^3^uIT!B7?Ty;`fv*s)6C<>y*eX|epczkI-;ub!|}O}M(9&e35#;0~7czdZ +-AY3)BRX_}{wpVq&|sNZY@uzgwD?jGVZKfN#5?zD%%Sw5d+U06?(vG>0NiY^+=0yx{~$GmknKEwm`UR +>tM&9Y=aPDw}{v+n%0{;Mj7Z}&-D@CP5O=*dB%+&tr!VSoJAh39q|TVf`bh08D}2LB&O5cmWmXTd_UJ*--5+SUw4^$uRrx$fe5nZ-FR7tP*>y5_x$f +ipo9sVHA0(;Xg%q5HVX52JbOrmqT*S1@85ek*Pv~_v@=lHS2#!9)9|?RB?i19-kzEb)k2Qn@2xE8?Xt +#S)XslWb@?>TwvdY-VDjbc07vgtk>NDcc=4M=!@|uWtM{d;~I}|-q4mGmN#7PTrej +|y?{Z{Omo$OX=AnMUIn(3$5M%u~bwVaSGUL2LHNEqzv(nt4#dI)C}M#u`)y1BCMN)X`sl&2|k3bqMEl +NH|0zRVl=sYxjlDPNnAA&7*T$ZHt1!%b|$X8R}~*4=3lgAsPhgJ(rtp76U;I?&ON_5QfS^5VFA1@Rpr +cDJq!G|SZX{>BW>oRYR$D!Zk+VKh3$_l1h_!Ri0z?oE~*RkN(YIZtut`ZGn}#Ec#!0is7(Oz1=pl8}V +pS$?audVn&kv@)wv&LZ-?ijU*Rn{$ufCL*(btGagGP0pd!0ruK^uf105I;Vu9w~%(!G<~Mru`Jny61h +8pL``9GHd$Mp-CPfMF3l6+IFy|58jraS6Dfaxg(~m<3BDho*X3QbBn(1Pwo`vEhmUN&&sX`%)%)_}AI +1P^FtQJ$427dGgOMn*j@bVyIf&Ll_lN|u?trn60@XBN&_aOr6R3ZYp!Y_(wG7>@`&bWqwcL-kB`en{X<{MYSfolu_pA+LFQenk9>rPG3% +1d-`;8LxV*;SqQ~-n|25KveuGA@Mn`3b+@o1n+%_+$;eMd5fg!e(B`K#&F3((uLng1(ryUVZ^09awWW +RpWr`WG6+`g9#gOz%@u{f$x=aCw+_%sl+bx7EJ0pXJ(zq$#^&E#n8*bsgxo8sn7u!m>LCDwC!HjG(z? +$3P=?^{po(54+;w@J19vNA5jqp +#S0JIT|DP_S;43YAs9T#2kmf>uiL7kUGY@sLYKIA2X%S%jO{GS8(Nm7Wcs@2y~n=7Pp4PX9A`pQxfq3 +ZL*CqSZ+|z^>TonPsnIvVaj@jP;;eRmR&Uj7?2!w0>`9-E&);NB#|5s`f2=emKd_DIwC0_+!e_2b?%k +7^rYA5?9HEf?Vr3`6qmQ${v9eqkdlUWsHvYzs`Uh^~Jg?d9eXbT{z1`WzpUKaQGVk-Uy(9}85!_sBXN ++CYt^NZ)>iaqP!ql?5Q&97|EqYYW$nB98w)+OruO4xaHj!{*&Mkg+)Y}s_=>m#9vT@s^AwH|;{(gCqG +muI)AsxgGPFqgts;pmP!t0^ex8W0WMCkm1R3n#bXu*4|iA?hSj^ +6;d~kBWEM83ymm^V2&r|nusQU8XgZw@eA%kUIJ1wt{kJv%-vlO#KU4ScZiieati(BtRIAsoe>OibnFq +Iki1qK^w^9xIYM{XY)3w3Z-_f~)zj0)FEoy#Avu_;or2O0e)%_xrd3j%c@-M&M!H3ZI-+QF@2)Z8SuP+|^>x&iMkM-r>$kz>i&~~R8m +%zkBOJ4{AsvN;?*2@ +^;e5wz&9sWCP~bI=!>ABMt5FiRF?pnF)M)`1`DyD*}Fw=u5KAP6EGwgtxQe~XyK$NkZ4a}@Hf!TiNLO +x-BBxzWWfqB_7|D}#MBG{ow(&}G74PO@&U(ye;x6=GxG}s<#|s0Ix~OdFv6~}XD(%WK+CN*ZAR_Wu&W +F&=*KibKWc6=TIQGcl|VQ#s$W9iD#9fnIr&JFw9=r;ORW6C8_m}*Bc(r75xl?}7&NX9UoGB_LhmC*(u +%n|5!{lKRLk4$J(5O{>4J<$5pF^M&I7MTQUX%qg(_(e)5gD(pBC{soLl9TvA6i>PXS#{8VTHe+_jQ>7d~9~2bu_i*wij%d1A~i7nxl%oCx8 +Q1{@{A>^_a~MO>ofxF3Z5u{lX=ZR{=XzaBHJ8r}QN}UJMgD5$E|rCialmB{v_#I)ROjqYYI%KOVE8SM +u$vfK +qHs&AaeRflpg|F}+}6ShTm(w>T? +R^UVF-l2l@%gqY!d&h$>mtm$|wu$}J^yA7zFZy`dFgu;ntr8Xt9TA&YJt)QVmw$~+{QTaX5j7Z<6n& +>}X8ocXa#!1YP~B4gg~kGGv^DZ{^D1$KCVGkd1&Nb+Y>zgxe_qc!= +<;H-4Z)bvS^FxROH@3E&p&tO`<~qcedf#uo1ICfXCn(NcjNTqu(j@oC2x??e9WV@z@MtD&9$Jx-#E*& +oS#HcyaXNp(qV5OT!hbGm21Y-%HV6bWZhgj_cs=?Ild8{=M&4y(oacT%c^8@G14SdagFtw&FF*$22*( +onMHW#mdphc6`po4ijqCR-A&#>#}h}7)S@LDn=?p_Z|OjgM4u20e(xggzvcTh)W{K~N>Y(b(O`VnRkvV<|$sQWSg=+4Wsmx+hPYElXUq3=;6vg1XT+i${*AB9FQF~FeQ^^)L2p=97xen!$8sAhph^7Gtv(> +*|N6bZqv7A$^AB3eI09fW3UDw^U^GcmG>R;r7c|VEIR2?DWRd~i6o!GeF2R7$po5!%8KZ2SXaZh`F!+ +FGKO6X5kS76y=5>|=>h&34d&CK#N|UQOBOr#YGo-|-bb+H_2|_H#`B}k<1PB_4J(7T7O|Re@rU1rWpe +?=1AtU5pD0r1_{W}6S4sFk}Cd(^KY +OD5W1;X%YCp!J;%43P{OA*-Uy+kb{mhetXUXb4d$R(;`dOy|q*N!X%O4YLW*^2sb3iMeO)U}2Cjr6QJ +iu7%L=qDTGw)<603e0g%nq$s}V9swc6z&%_DHVaf$Vs6ekni$UiHXMb?+pUS6SXg-a7zf6Km}$zEfgs +sTlkT}_SuRi`YIAk%e8XtOf>I|bM~br(C=4G`;J5{xYc}`9A@Yra&gg& +aGm$ugacDUAPb%yR*<(r#MOuc5iHN@og^BbmWwQXQ<{DQxrpi(pST9=ml7{d}D= +N;2*&+{RVx)&}yo;@C0Wp)#-pfQ7px~PF|JEwb?_Zt`AG<%57(%ry072_WcNU&!VsX>o=sZcz*>-O)HR?99NIh)b3?CbYfe2%tPRIj|pWABoZe6OX(xYb^LwnXyxTFG69~DRU9hWT+kqL^ +Eru4{Em&D=7fD0?)B(E!`}WxotbRB7eQRypTjZnvCgJ +Wansl6Cg?00iXO0UaLm?MrAU4ZQ^}(fJvUgsXR>=MA^UWwoKv-T`RY)l2S?oR!uW1D9?Ow^9eGfZ`^n +X6PlO{)0xOgu)37*i&KXJ%4{y4KAw1la_^O8;(opqrXUs}kihURn0m)`6l)4wc*Hy{5I&Bs1)x!ec@I +;YM>79EeS1 +Snfl6pErSfx$2eQ_QDU(F6(n7oup@h+Zd?m*9RT0lf^!I*_13N3K#>%bN7(@|Me{fC;x+M=Tg;fe*km +5ntV&S93%fUp*b+Rhc3Jz=4cF)9d^*4@Lk*;B~WgVvI@tlC2t+=qgvq#Gow(6RUa!4Jv=&r +OGNc@~>~2CX9m8Wk9M$H8^7I40aXo3PRC?-si@P**@ +d$PW+{e+}KfOBLPYwzpy(xr!Ub9M()93QG&G%EZ9m>rdw9;L^FIl`z9D5{sxZ%UYV&jEJ8|Ju`EK^0< +<_bM(Kb4dwKSvB(=IJ~Th7V&VTsb|qPl<#&29HCf@Txv-XqVZl$RYGMyBZCrD>s%1WW|^T3kr8d?DI7 +}2&a}6=y)LP%Wi)(uSA#l`L;^_OM!~pKd19RA5Sc!2T;IfHO$-HcvM+L`0oQM^M5l?nf|{3RP|cl(W +4>f9$cHp?vV^KwSN*r{4A|jjOod`2ma=!%GIzPB>8k?&(T4uIkdlvq#?oEDD5%NCZQaThe?c(&3+S%! +mv}+t&v<#jE02ca~ChaRgY13SD|~|6635$$yKx1Elin>dO=Z1<(jFJ$4#^m}#z<0ayncaprW2irlCBEP6x3S89%>jM_SAN|2_jrYb5g5g39EEWdp&1w>P=+ +88hM;i@!zq;f46fh=i0{!lPnQrt2nJhA8Te`dbzYs8iIqVEsQ;f^Mgte;Rn;m=!8F^ldYrBDT*K)A;7o*i2)W5y7nrU{VotCS(}kW2 +6~MEUq#^m1?OZaI4yFu#m;_zA{_&PaQHfrZYYtu!WHU}=DAYp_x$uJT*-bVr1dA@%1&U*Z*b+a6(#Qx +1!0qPI%wO07~g8V`5xob_Ye<#ALBirxB%bS1eJz2WvcHW%d9St#YJ@C-Q4O8vOoZ{e1R;)KLS~x^_44 +#wZ?yC_Q#*C`0?yC`!w#p%-IRz3%t`m1_I8D+XfAT-TcKFEB_3({Dxhmg{ed+-UtEKqQqqQNa>Cmj+# +t{4Gc#L^8MA>7PQ-ixRSSdOI$s>z9FY>sYgjTmaZZQ_9=0ml +9C}rZu<|K%xA;qI{#32qa7*tG0HbcONE#Z7h#tk{m7ZGqw!$n2@Md4N}^!5#T&Xgx535Nj;)nT-er4OV* +M+Y@~!J4^Om2UV;oY*bu*x9ao4k(9=x36_0&OhB;L`YuexMTDPg>KWdaB0me;$Mp4>}$$dKD|AkM@l^ +g7(`r&z@D!rjSz?`wKBKvNnjNmm?1@#IzwZQM4qav%p2q2gEknB-wN^g_6svHbxS=Ii!kYi1d~R8uBK +_HcBdN0o{`Cy{J>RcRrCX|B86^yOjNhL=jVU88HIea!m%apI3-l)SdExhL@B;Sgo`%ilt%b4nhi8@Ux +6QM{@t24D9THj+Yj%oC2HJop^bfyp!3=?{lxA$#11q{x18vL>th_Ui~73J9wof5^&f$ov=ZZ#zrANV> +cQ#Sh{5zjVj%Vfg1e{gL1Esaoag4uMB&RsSu6UZW~tr&2(5`V0esHe^+?gz3*~0tBGPf=ywNz9XyoF| +o$OWlu|BTz0dB#3cq|Fo?W#0w&`y>M!y6XA*2A*b5SYrbr3{VM~Tu6|`4xW+n!Ej8=0-fZAqzAs;dR1q9k!=dmt_j@hJH85cJuO9?z6A5FS}0%*SXhc0SNj&0$H+$q>5fevYUIdH-!HE +8QUCZ&Eok>E(8LQ@9~Hm`mY8kzI+p1c@He#({o;0^pl<1?-YAT71TA58csdxGfS*8Yt9z|%J*ff0Ohi +*`t@Z%9|P&1y^K}4=AXF?XvG79`nw}@-#JU(cv3@fb+||e(S?eLrbWXf;@L~>E0vP1tT%24$EaP&E!S +T54XgG}i0p$V+i6C`%J+whB*s8FkA1;IroKJ))Rp)Bt1Xjb(%yS@Ke^q;uPbY-qk!n&1Xcb#v62#ga{dqSxz|nD?5c+j;pp5#?kW`;a+iK-R7LsA}yIGu4>Tx^;SA}4b4dM+(#v1L +%KeY6tWy+*8#AI~L$eVy| +%=Xlbc8L8;!$ofq3Ddw;1n_fw+Z3o +(-}5v0zSpxJt)CT<=bdeQ9ZVf5^=IzIRdqVFj9X7qTc(zlS>=2BO;un#lUW1O8jY=uJuk)>4BhWS!YI +6Rz_r|w=QQNML%l@!mWsqo`oDh0_wB-1Sdj$n9PPNx((yf%3G>^9IVzMb@kEl@_<+$pB=pSpa*Wmjh` +uF_8xQcy?6&tpqAO8>TGt6p0W0V}m5UU@|8LVSyohOhO-tbJ{S)L0Ov*;$LUWC-AjhJ1T}Q^0j5{YVjK +gJ0?t+j=NhFl3VdEtx%Bh-@G}E~%(4YASByXx9mQ8U(KFB{U83Uhe-wkEjwMe8opuV;y@9-Q^pl{r#4 +^yiUne~9)%yvs0&ozLXc9!IB|QX^&p;#;jIaPXR06m}EPuzV#WB4aH7-X*)&cV6oR$z9(O_@s@9K&QR +}j=L#&`4KNpFqq{E%N##bM;`=%UV}{(L_CD11{RVc*n9?k?JNamhJfEY9mSOZri3Q;1Q-S%>I8#F(8U +d>QK&*jcO0B|d4GR=ry(F3X(L3ygg0P8eyz_=3LazG$oNOYG^F5XJL%`T6iI?ffc;4760fp5@0{z3q; +FBD5@dmtUMAB{aQ}G*!>Ws$NP-YSX~`+k-eu=}s=B%$Zt65Gy}=WJg3Hg59B(%M6TtTnC)#3n*8#f`2 +eXE01UXxG7u(n_BL<^JIE+v8zEf&7&0$$}v*dO?f>jE-u&GCsGQJTR;y!^xVXAS6>y%>aOF35s0JAT> +{#4X3DbL{oQ>%5BZi>!pOG|esuAvB4RicRzqnoVUG;bo`k;>+R0NbfmsqJ^zheuNB~Mx%;9(T^$v +Y^{ynUcp@$_zq&6xzupIp-axC(fNu%r2g`+Tb!u7u;`f!Rqj}P}h?O+yKm|O?%mfXw!oXH^vJq>}uX5g$ +qUM0+k0uuue)9mfBYALtV~HX)sRM*kch_RyzT2YnN=0BgOk0@~&w}KxBL<$FBixk9QtQ2bq7IsB8lV# +OZY}jk%VmE+wzRxSP=tJ(~31a_<+ZxJYM56T)+2Cn39}6Y7e*Vsk`V3-feC-)Ma<= +R*ZrKS2{_`?+n|DDcJ`ETX;tTx$d08dg60>fQoa#9c3lonjSY?cH8lV=J1}dLz%nD+NtgI3JDDpmD~N +f%<0V*MGV;s4Rt3C-E7W~QCWd2T%Ngy%de-qIg6yRr-_Cui4-m`PAXAOTxMDIr-IxRXSe&BW__<7W_< +U9|M833B_9LcAK&b2@cVR=A1nxHjG$l)rD&XBNE)Rn3a4?5{M>b5ooc|>nq;=lV1VxD+DHW?v;-_X<3 +QTv3}mT47bQD`keCr5w#4U^J4S03vCt{ +w5f`U_iro$u5_5mh2IzoJ1gTTcYz4VnKJA0$Cfr>Z6@wFk6B%ApBtrkXea-KacA{`K|vdN_JS@G~ho@ +!2RpN%|8uw#w;$6{OPM8*U`k95^#~%S|2~=wog==^~D)|tp$cc=I_8n!IymJO+E{H*U$PQ&543EYzb- +j>Od&16OgYD%f23cwJrE(jt&mK4qg8l9qNs?yi6_242$EI)^!4+_~Uec-IS^iUSemoa@3nBF)e3gMd? +gfXD>!E-dLVZcw<#vwFt?cI_Ov(G!j**bH=a(rn!m~p7aznBdeuW9Okx +`>rB6wh+Gs7@QPWa)8#SG?zuX6JB8ItboMS$CjedOos +EgfD{YvLChw2JMn-RDx9_pi5P+Xui1-y){g$6#P+E;hNPi5c* +X-Je<^QM96tR=8hWrT0N7>;(XR8|#UaTzQAj& +lC~kR5mPNs2a#Rzd!CN%hW0My&<|He(T;LoFF?gNWIZ(1Q7J4MKHe;7;A=7Zm4rJGwl{DOJ9ZiBH@Y6 +c`QB;oJhQ(1ITm_voItELukbdlv~*YcAMkn&JX247g%CSh>R924*(%bF%=e0qvo_O>XYp$HFs9II@w~ +LF>3V<6KOUBWP|faKew9kqPatLvbc>CVB$`_rH|udNyk~3Oy!a*Hn@mU5=Ha1e?vA&;H7*{wtRe +f##JQ^moX1>X$RjMc)HXtKRqQT7r>Pd`3J<;teqhyd4V4^tM-HVzK>KxBfLK;L$s=XKnxA8q-5@W}a5!up@z*?Tzr-F1IR4QYlTVVYioB83qM&5$5ZgqJiCCYA*#MZ!2meQF!HPT +w!lXbEK~3Gzc=$D4xoAfQ*DS4uU#3VJTN-RE5GB~C42Yf0A52r#IiGw?SNgVDhy=0^C+-d^2)f%zW_c +E5zh-ATb0Ak1PJZKsz8>lLI=w_ +p!IkL`R(t7NofF0D5CtT-6F!f2K`#54*ty>Pt<1;gV`QQQ61QoeqT-h_A22T +Egm}USATa`kKk7(ps_&ULTz_hp_oihjA*sBC?6!e3hs~h3G*X;^@aG$?DSeaQ{IE=u@E;{s8Y=(-Fp& +B_T*+O8Nbw#aT3{!eTT7YXwFuO#59RnS3ieH;dmM|<;|`Ght@`>lG5($E_4l6W-wzmmAB&;S1`KiAJy +Jaumx7LjGh+g(upjQ5~K}v52bkwUAf^vZpZSU42kP;yUTB!1&yyqUTY4m}g>}Ue!v*4qPzdN +1To7tmfv$V&V>9O4xY`{L76l|?84=J1wHxV +J%4Ig01095Xvonzof{HKQ+y!$nHhO`E)cyD%IDR1;cme11CAG5TfsyJhKq)3Yz+xpN+>-YvD%5~YV0!YQ%?|i=u4yZs>%6}?NAQa7%J@OhivciMj9oTH~_Ea`dWT5TuH +^zl%RM1m|>p8aOxG7HD4M}j|X$r-`@eBDIwQ*Id@r&O=Qkb7L2o?dd`vt?Vvz>6Vg<3$Aw)$$kLI!6! +S^^Ot^o2=tP!}4Z%ff?s)NbkF(4{k7t9byn*ac4o2i_s7u7aO2@FN^`DOsgK%O`cce?DpKzEOQs?BeV6s%bcqwo;t-@^cR9ZQk97cB91B5bn4wV>lw@GYNL9RRfF6D8?q$(_BA(NMyuQxN)QPi!kj +Btn8fD5I9~`LmZp(x-<8}WcIiJ$^HHRblCkbuDEB#U-p +0dziWV{0L-eRUzBogv->Z0^!I;jqUrDdp8Wmahrj>(FaPq3{kQ+P{p~;6UogNETRzw2l>Ne$P1z1v^U +D+To9nJ``l_sdVQzpc+m%eS!XX89N+e|?eI`{&{P1Ndsb?1;a;e^|bz9|jUWMcY{l+8qlvrB}zwga9QYCix46foX# +*13LOy3_RN+Aj|bB+FlSlzE*rlWL55>05T_Wz*kss@`BaL6sT#zD5zbbKnn{DE+Xk)n4cA;fcggo%2p +T*wu}hSV1XIXFG|-67)GrXskL!Lt~T7jTbuzLhBO94n#=h|FhKN725M!X2)1^0zy(IXi?$`uhuMC$!s +NuyO}cs39zMcV8`7+Nl-~L)ioh~T=?gGVfb5BrjP +?fMzC98>0;u*`#HS&iAs_u$c$iT0IG{wG{+n6^kkqQAK8=ht)=3tMICrSs+%}49q>Q`XASn*cMo3#Mu +2(zXbB`(p#p`pzk7MMP!GBd>J<+4Ec2|6YIIo0e}(jo=WrB5*Hl4=H>&<4F8$@LDV>wc%+F=%pqFXF% +j&7KK*<38Vu1Y1S?^(8^Lg~8>bx&3Ir`wEMaI}$Jcb>Ljn9o~1E+q8i~%c(iAN2BvP}HC4Aj>4^9LVtNqs@U4D5@vvL?W3bL +uV)xON+5s*~>xk@KTIiU+=*_I}BHH#gg6fFd86!{r-K+m$?Vi`%zvc)2t#X%(r%oaOX)_a%)vq`?jWU +*2I!Y2LpRX!%lJw!q2n-|!LfhBR2&n^L^&a4r9|&27C;#QT!IaBz&io>5z`_X+g*7<6p2Gx*Iwf3z%Gw#Z@o;#FffqUVd#lO< +Otd%S@17$>uNj%f?A&qzno(@tw5-h7IMAx2N?PWgJ)YkkFsGAfdusis9o`&oRF6%U>EkU?23IlS1dVO +-P)v^(-acm0P7@~Ql&Jm!kL38(I>HH|j)HP7xx=+&^8DUz`@;dx*eD- +#HaArPTFauaI-0_d0wd2;sZ6IWdSUy+_3@Op7qRN1`@XEyA9{As*Wr>clPJF$MERLoD2LFSx;;X=(PF +!c>bJQE6Y$fFon{!9m)LyEUr)_BKlvN36XFSD9W~t5H(5qm7U_1kXK{iB>JE*QagLlxHn=IHn7+$&S= +2Fkzq~$(86za_e!8Q}uV_ga{9AHxCgxz8XRX!iYuxyw22qc|GN-g1PZgHkv^+Mh%hU2yR3l%m%Hp`ND +~}uNw%IRfPm+nRV(ZzsXb;7yIB>>tCmwd0AofmI3a3-e-)iGh+vR2uOwrC~mB*{2*0bvN6 +Y1|obv{401BRZ(pH#_8tYUx#TM#3ug=rfEpQQ=EfDf~&=iP7a*Z4Q}g^XJmkx--h@8?Ct-FzQ^~0h+? +eL?6?|tfu=tSN}LX<(7@Woa1+@49Eh(-WRj>zc4h0kQjziACTUk+wvVWeYVvPSmsmH9~zY37ASCrfk4 +<2@_`>ux>67m(6pk~2}EkOv-_FI!>X?U3}jbY;yD4c3sejyB@q=?j}M9-iyNv(uQ1O_Lx9Qdu*Mr41%=-=(Hx +d6&kk8k#PpBD)aA8Le#Gm9ytal?CjbIr~p5-^>$gfDl3m)lc&>6JEXRq|3CHhzx>lDI>%fLlicp&!Kz +*w?o{8w*@zN3C*4V^tazKQ0^X`2!=wsp;>I)cS@0;2Uq%50&f?Rc8Q0;<4{8y +==W+-AK>t?lqq28XR96$0n{M$tG8(kzEO|owY^`(DO3GWFvyao$F?$bFW +hMgZ(-4^lqTMwhTA1~f{M+KbLw%Ba^@coz8)HBm+L!|LLV#+hwywX0=S+J602X4y?-){EU +bHRw|ZD30a_B&5RC>Z0t2Xn*KkrJ{WUG6?I`k~KcNRK!g`KKqHVUMIIX?zg6d#x@TUr` +R7iwLd)1|M}lbWi#=xVIZf*cT>cAC%j2ucpuEohk?=JjU1#Ly|qqNH6bI2G=O6Lm6{l$phOXc^8JY5h +Go6*gqgHx$6W%pFKSG)ZN%`P}(t$0V;+E^c*&sGS2-KHtT(`V~exH2O#jzWML(Jl?|9OZ|b-g@n$-DK3z;e>ZNq2_&>c;~J7kPQm975aJJ +%7uLJ3!bp^Q^`&phoOkE**a>`|ARpW`-g+f?``>ckimWxWIpvnU(!!(&5j8Mc(r8|$a{&^w++Vsf+t@ +TFcZ+4S^~%C-6;fc2Z4MKvJx+{wHdTB6PeW;eTgc|D?VL^(9)HOxa?~pKiy9}odbHCZ!Z54e0Q$R1Lcb0&pOf+byMxU1Ly$oQL1u3o2 +IL9rvfo*<9da1GTX@mIRA6*3>JcJ5*=OoAhVun>YRzlsTgge?G_k31*j!QV~A{L +?{(3rRzpY?l#HJ(b$+&^!1p*oof0yoEV09U(5AsLQFniL-X?suHVYnoruJl3+>3n-OVD1$7b6yOTetJ +TK5??(Y?9B45K{Go#c1iL?F+C*rcX)=MTFvtrZeJYw>7Z&T>&@XRr8%(TMU+_&=UxlKx*Rz|T+wI!1ekh%I +-{1XmT?iNH-ls;27-6X|2Pfm&=?Fj_vEV6cV2~N0Q)cjdnM?f*}W0#kJsI$EB}A_C%LKsp3mS&V90x| +Y=e|B26N$Oe4SQDzvNqV1`@L6kV~LMnJ?$GTw1hj{=0O3i2z}d{#r&>ojo&~#bl)HuR_7fYs^pV3y{L +T%yDbl0rq%n`cUorgC#Wx)YLR58TEJS1W!n2ovg*lDDlsc5C2e?Tn;it_F55McM64pHH5+LqKe|<72= +PNG!nP^G9OT}I5?0ds4q=u-pZ`YGDvgGWudk%)Kr<(oP5;3*qRDFv!2a|dh`!PU+6chzK)13(fl1cJS +=yofbw}PcT$HocThQpzLm~jP14qDE%tqVpG+U{Z_@`Vm_AqnxA5pytAK^eH +7wW(6-4|@W*u=x3kW|yf|M#=%_Dc3IuaZzo&s#=$Az9>OxePlr!;%XIYo7AJJAeE)!XZ}MhL7knUt-e +d#PN>$#A!2yWQZeCCGNfx&3Ws=LhYeao)DIb1b8Hlay$|lL2v{Wj@(o_ZM+f;sbO)-sLvWg&f=8O2fJ +)L)U~B^VsK`blBt+!M+~Z{Ss``^DR5wGnI{ZEo4u7tutV0>5a;@UrpT~02A +$n*+WfVT>8N!C+HE06kf#&T6v-pGhP%#w7!87V)ADuq(RI*$^uEeaRd7-XI-nbnhzP7W=WZTl53lp=;gt>XCil}M@Gm>bJ`J +b!3`MoY{i#CcPDc%V$acF1iBv==#pK1=-eY}VG(t}+}-{mcjk +I{5dbqr2w<)+o>MOGp5q>os*K-Bm;W3Mne-l=>#KAo*UUN)R3_j2COJKetZDpwQ2KBX_Zoo!41USFS% +U_j1c&)qA*@ZD|XTgWxLTGF7ZZGH+-=Iom6p?VBsw*b3@=SaK`j@Q|=Wu<=q;P47_vWFzsl|1Ih=s*pOx!VR$KHp!Rm~T&z8kLmvG%jMp!1q&jqAzZX&CauI46B +sjsM%}VGk?Glyd*FE0>}E}OYT7S1!zDUmNn +$RiD>T>518r_X{@hr&2?=@lk_%4TcHUPZ}4-T}_A3o-E9T0u+kbw{r?XW@FiLsc`spX?051!cA`Q>bii2y%ytGQ(8zg2-B* +6BK(y@Y=YvNqO4ZO9nW|Hg!KCsS@0&+B`Ak&c4}K%nB>UCpV|Pf}wqi}d)a32b1e!pp+EyG5If@LlRna2j%6T{7FZMm{2xY`a%$_Q6GQj^M4-AjIT{wUu!S)i +J&$~xdAeEn=0hVwxy=y%tAhk_q}^n=C#fi5@>rBHl<&G@GT+|}Jafk88U0Y6yuMfNX-0Z#x<0FDA>Y- +F{({~XJmBLMmUY$HLvd;x|)(I*D2|9I8qIg?<11;zk}HlqQM!&e<3CjJ>EAOgAq0GQ!GUvR--WDH=~0 +v0nIaDovA@C+8n2L@qM;2cb+t2ysFLV8}ce6qEkvg`riNCp(%fYFL=^CHK(6Eku-#8k6 +VF+jC3w*INTC6?_x+%J#XLo@91bl-rp#A$PLP5{-9PwY=SsYsDJv=26EFAJeG=m+`qrl!v{@hq1xD?1 +4QG4$aPbAY@p%8Hg0J(i1*AJ~|AF*{Rb0`miU~8`BEegs+2qNAbKM30BQ}Vb=D#KwNnK*0}xh{)rK?H +X(zhHWmDeTR6U&XMf}sM}XCQzIStw>f5ByB|+$1qPIPEZ(Q(c#D_!Grj>esNX7VscD-ui54~yFUK}L~ +3%n;T8VB>yT@D)t$5@t){Hdzo%WFPXd!^kgJJ;R@*max-nEuM#{Iq=Wu6pw;(VOI(=nb^eJPlr3Fn?p +m$Jben{h{6~Jj303y{mttda;3vX$KvufZixUN_0$99<9mI>H(Q|2F<`>=4MP)-Q#*>Oxre{=w-^ugWk +cUT;MP-PFZq-w9ce$89#RL(`8Vkc(bK6QTi8idt0Ph +%#Zsy@BJ6whr64ZgkVc1?YZV!bInyY8*FX0qL_3+L~NZfizhP)^}}wZwGHZ}S^cDTw2o{N +tk}GaxN~GpkU~^_h}>PXCJ>KygW!}B8TM@0t|pq_%-g+=rcx9fQoD;+LtO1g*>*}sEwsq{u$j$zu)}0-|OPrwtjf~;rl +kn&kp!#X#BYIn_?=CvnT`D{im}UacnWU$6-;F3O=1?sSG4pO0y0f6_0q*x=5uDh?9^loZDFvbGa +n!TheIGqLReU37iSnOTBbCT3%N((73iP2&!jjMd2s~nKZLy@ENt-)X{Z9ra99RLmu^TnmXTasW|(Ds6 +#);x;{}_d#le +XWn{mpBF1=4ReL_kd6*!elcB(VG{+8z;9p@`^|Oj?Z%JW${(-z{RNTVx#C~--Xq^N-#hy(UdKe*(MmT +f?9Pf-m^-M-sBcq( +oty28y6xV3@8emRzMox)d^NlPUJ>*-e*M6aTZ!B; +99m@+ceQNB6;5f{_=8eX;@&RG!$URK*&-FWUi!tq7HO*Rzo_Kb3y4?|LQv!=0cMxDBhr^aqhgC||poJA2g)TrCYya1(#I_@If^WYZcY_%eZ#c{G +Q+;c%FD&7)%LS5&3rDiFZH&w +PDP2}8^>hy)8T-UR*>0Zx%Ii`LSC-?O+O#*Z0@4oHb0z|>uH0N4?xYRx}N0UlW%a-yf21}k`YX{+ewpflsH4X!-o9vs%8373cpf?Qp6QBWvgejuB$DQQFeu)vA%YN(Cw +{zBNp>r8y?wou}zunZkg9xaxw4oFb%|!*^9^MEJjs)u8){XQHb8u&KNiQ(T%!`+MMrFRR~Jl-UpAhP~ +~_o&C4}9Wm^wR?P0%<8%l65qP9Lnw%V2}8WS-933 +)pYN%*O_C#YteVyA&N_dUBcEN~u@9ip8EiU^h=ZO?;vWRyW`6Z?F3{qF8C`i07?_|>AE^dPw+j`rUz*_9K;UX@Bsf>6uhDSh8h +)F;7qzcEiE7pQq$h?M3vU{PI#6~_~57c#yP~DZzIcUIga$+z#ao03SYaNv|o7#MHL< +YPH2gD+j~tD9WN#%qnP(^!qy-mbrcUnwH(<>oxaD{`jSqu8#*U|3zY!K&Nn=e2k^K9 +eM(V1^DhGAPWs;VC3z2?;&c(9f;fPy#mMq{(tf1Z7hp3WZcOw~Q|1Aftq{h;fLL1 +P+sq +I-hYwP!QqK7yPJa;Vo`2w!1N?Q$K)RlhTR=%MCiHy(b@ih?rRuCe*o$&l0w0)^x^*9S-3mA*=w8mN!v +W&M9j!QTHhkK4e7;xNzqtAP%!l0@*5AtPqNB&Gty3SY7zXi~*1s?b2+b +s&4s5bh=5q10$8qECNe^ogGuXGTF9}b3nBv#G6boIl8fDSw}2d~dnSGhjYDp;OIk$2|1`});ZgjWdXF +5jy6p~dw_3~~{KwV)2N{knu2zvZV*EUNAecR;*t*nEAek)jQ+mrSBD($3>8cT^woTBscNm3A*#BPzo#8BNv +dEuY9SrC-7@mM-cm@!7)0ANdWT#=?jt8hu$iVe(Sx>>Ou)(%P^S9I{jCeJ!5yU03+{6e$FgnHw{Gj)b +V&#dtZcJ!Df)tgP1{|hd??k3=EC8dOU*?IMM+%Q7mM+}bbmDi2RB!v_>a +EX2x;j>saGG&{WA5>da!Cu=~=d#$>pac0}&Tez-sU*{!3}sPjjOn{y@HIf +j2Dbb*Bp_Hxg|>HTbMVSBYF38ryxJ4H3sL*$@y8b(3{Gx_5y|Zx`-HlWm=51KzDp=luG3tdc&|UmS?+ +w5Lg*<)+xOp5q)6_PXCY0y3Xyf#q3w676}viPXpQJ`#9Q#9T&|cW=XtRC=|G?e>x$Wu5FZJpv&v6G~c +gl`3X;3P^g5qmEx^I;=d(NoVGL+^XlioWs1m|^1y`Qb;wq +HF#+_OANK5=ZVI`9|?(!nGD}I0MUxJ_d70x!fbV0SYq&z|=Fw;M2h`nhIk?l4|f@r%nu`9iFqdteOpX +ibY8>I4jif2hlpn;4;hEcM=Dl5+7+w=1oinxljkLp6kax+mg$zrQ}UhEpxlDppy3%Vj4yYvGX-yOCA5 +JKnfw|oD$?=hJ97+0 +VjNv~4_mG6`x^NZ;3NyzT3v;_5>R_k_+@%myueL6|48qe`)sVw`&xF`irbXfxu%)3TLL1P=K$Qx!_hP)eins7`c6%}0K3CGAHc3zcmJHAf& +FF^w<~3Un*KZc9=59SSiHdvDb4|S6$xQocYg!e;24k(U{i_rs|g^Kzjpq4L+Q%m8Merh7yK$e==}u6( +Ga_lFZ_N!NFX+F@|Q86sJ*j@xa99L4en`{T|+S56AcDjHS+bczfyheXDaD_c^Qc~O`AoR{yN7w5O$y=97>>e=d +2glj}dqwGFzj*^+FyrP2baAWW6ZDp1>d3|3$U$MHvWMX|Io+;TVZ2iPVe*MExkpgV{VZV_; +uyJ{^hyLFggoOehhMb;`aneDv9RNSuM5)j`PLsbw2G?vSM95Ads!`gij~!QlD&(!Zp^XHGg%)VZHY64 +in5HIEi7yF;?-3+r_tY?rGC$*0H@!V)qF-2gJ5%P-lBG_ZzIgQ}`v8hr~a=s26`t%aWE)yZmpsfBt+! +BtF@Aza>Xtw;V2U+WsM3hD!@>S$`0*|6~yOuUX5lLE>8j2%G_NB2@5FG|gf-$FV3yL2#gP25>)s8zjS +gN&&&nibZf<1lV8M@LwDWnG*?JMPXBAwir8*5zLgrhM3Q-OEV1a)Ng~T!O37+mw?{f&{l2fbOGm}-a1 +$)$Oz*QrdR0*oc<>$0YxZ_Wh(VHHamfQ6f6duJ&R$P4-V4CmOjn|ibP;dF@~0F;Qu!_HgI|NO>#^@V1 +hu#z=IR;bmCu*rQAXaIDL$zG<{w@cW8K{8yl^=V7FVR=IUn@u=!qb`fH@P8{!92WXLD%1d3;I@bfi(3 +37N29x)DX{{&(n!hlUa|HlyXu2B9xh?(CY2A~OQEZFvzEk+gxIG93)E^vQB%=bd$Pay`b8u@@2J0Cai +5HoQOEzY4}Wk=obQh4&Un`CYZQ;WovbC)e$66&FkfOuzg#UvQkAvb72G +-E?}{hx^nEqb+4gMBWH?;5iOd&!G(Hpt=IGiLtizxs>q?XQCXyckdV^<=9rBuK +g0r$(6#BPd0Ef51IgM2P5N?^RelCX6autE?opl_AhcnJkk*k=oa4h-5ta2(WsVvD0x^fRAVxTFYLv;q +oCEQYZmx`>0AFYXWU!6{TiF&xwoWs3m>w#>Z(cX1I^%3_NfI~-j}FVn9u$alfLH2q8F*}#~h{FohSf_ +)mb`8!VzOtXra{I-$*ILj56{irA+*jlrqdHBma?zmxJC5_i3biA}ljLzLp69c +Rm;ElhBHd=!MdB-?IZV2QI%}gBO9N-zbZgHSX-@w|n)S!Qi{^KO7X>%lyNTsy?X`WPQkabb;M6PGJ-Y +^fR}oQsd+y-D5|78cp_-zh+MX9icQK)N{qP7cdO2#8=2*}2WmlutZ9H+o7 +P$;h`g7>+U%6+49sT_gf0D+JbG+@&`?MSHP4y>N{O%FI3pM|XE$tnJ{^qj2!68`2q!>7>7-dO{#W;XM +G{I0fO_C^qF*wbB?l%r0Ct3UjF-QQ(Wbt(%p*#qtD={eh!N_GK74{f@ZKV$wW|s3iF#k)g2KKuK<2vOA-~1SYF0uB`I83x_AK5ONunfpr8n#6fB1>&JBR!GK= +dFKrir@Lt(2$v}kGpfI+LqUvt|Y3S4RR1BXnZkpoc$WKEW&W~k(%QM4blNME?^;C#YuXWsq5qAOJWT$ +ia+9~AD-ff+kQo&pbco_-l$^}ZJ$g0n?{t+Fwk`*?Vl3eED@v~77D^7g5u6uzu~$5DF;SABf%3c6X!-2_WSO +FO*X0h(;OPVmr}z1wjm&s^T1MrDy)H%N(LtIG=ki8|i|X^#yXzRB-c+a(<-KC7JB}XP +bY6JpujQZfPhQ|%IlQZ*kRRkxKTPA2RYOHpQEXMHM-)cc5WpMxOe@Jd!j-3k2$op89Wc_&9a+;l{ojdk-&A9m*8pN9V*;e*t?3X>1B+~N7dZ#7~wXq1FoqFeZ<) +oa5U%LwH!TZ8r->X&ql1e#E4)}4dhbwM8JgYsYY_oZ;kTx|ZJr0Gd8-!A$iP%o9y>OmF+O7c>M$eZOWSOu+hc9HwKbTLoCy1v-gDMaaZFfbe&xfjkJB{^xmxB +Si*a|qzu6@r%=x*Gvj+G5q)-a#VoqtV8itPzYiT`Vo}Qz_AOyM^XIrw~90-IlaM90XlB!ncT6~11`8P +8EAHl)9U(>OVu9x_C7%TY?0vP5$99#V_xXvE}t$(n_ucI!Sz(@j4JR@0*A}ExmX^Oxwj-@CR15p@FqA +2yLStAj`Q7Gx+pq0I`|8SX#mMvNT3`RfLLZ)&2U*zW%1#nNY3{n9h5Su~gDguK68=Jt+A})b3R=g;}@ +dSE4#@xS%42rynpUwZIxy34E8OR31rU)hw;$>JiM!@<9h_0ZPjD`gUaBXr?v(bw+3BkcM1{}>zE{bvr +W*+cmh7DK*oQ(ZzwRZvQ&g1hV>e`XgN+-vIo^yII>G#S{+x8Ro|N4G-=HHFDV8Dg^lZXqj<&Q`W`CAd +!=`@<-mxybgz7E?2DOxPR_!&@V%&(`1|N5%B@E5@Z0;7o~ewja7rr=m@>@5QOGG2SmN5hfHxAEF1$}8 +VqK=}G0|B)B)>!HAu`csJTL!cbKxcUwEDFob)%>^oVSuE#(G!QU-6RCR8ysPG_$6 +v=j5SQRgLJ?!y2$Dn%MITjYwl{yV_$`c#vGOp_~kMuDQ*`GRjeX940OkdxQK5T8(cyp9}N679jo_n(p +7)m_4mcN1K-9><(h9!y+M)Z%GsXCk5lw?AJpsS@K6@%%KZ?hvgZ>T5HQ2jy@^4eGKWQq +kMLT)p5f48j4=G&ygq+@I*g?KcZeZcO`=rDUVSMfv?$%Uwy^wWfjfX&F+68L?)d59?1CI}zQfVuTcbM +>}9Yy0VS%hcDSND0j%h9ggzC~ZIQ-GjTR+Yaqz{%=4!fU?~^UPd+CUVr?zH!xD~*W|zdq5Qx9M;G4y{ +r_qI{r~EQfB!#kFbDB|_%`bnV06AYpt^*~zyIGAIL)Vp_W%AJO#fG3`yG1!&UL>{v{NLB!||dRjeRQR +iYb^o2bh;-Fl7#bY_U6l%55BKr~pg?U?O6e?_k-_b=ovkX91L?7OcdUQ=;UO1n1!3G-$f8RPGZL<{7} +%I0jB;;C^OJ3E&nwB!{s1He80HWhlgH3WeuNQK%|U@C8y+=z@%KP+kBv*cdDbz!~2x)RxmUToZ@GHZT +CPBn^}N+%Nr)Wd$ZOh7T#1YMx39T4U_Kk&b!6)c6_SN<)Xke)`Dfu86Xw?id%)=d-I +k}p$J^Y-19Vr)1oB}}HIBWjD*ebj=8?wGq&*bT?b?K%QjN^M(Z%A^qBZhfwcak?m2V|*ejHn;c2P&=% +C}(xN}t;N{oM!C!nrmOtK4cm3rT*sYV`#f^XY94!f8B6`t;UI3~z((%wKK;$cQ|?8;)Qrr|G?k6wXEv +AdC +2knD@(-ew#tgNKEJwO$PI;w-9xV +k$E9XAot`#Xf!Nz+ZU-x6F8(PUpje}ejHq4Z+8)o5Hh#7vHxXoaMf%uSK(%M~{q)GUgx=Ww#xYi#2?9 +&kw@6|}R#&gol2p{m}S|-QmnJG5-@y2*2d*78C13#{mhqP{YC5O=ZmT&ebLy5jI`3Itd9cIoj@V#crvm^YmlC;*Yj@i+B| +_mTfP)I|>4unYX{L!HW_PVl#m5d@jqsqlcT1k6X1C@qRB}M}e77YurFi+)BbI|L2AHZMSBM(R&6Xdos +m*6l7fp(}1d3;i6at5)CS)Zn15X(Sj)+PP=u7Wg>gGalOiYeaCs)q^UINJ7tq+kIUWZLccqlg4ijj8W +)k3$X?@}UTj+Bb+T5*&N#@Gu@6h8Ida?N`bc{p&03|c0!*>@&xmwOLzhM@AhWGCi%0|(>$$k;&HY_+q +~kzf>v>RTet^%o*kG{Av?DLHKv*H +cAG>)AGL#3L)Zvu%hBO!x372M%m>;2-s8x*RLSkorQA)+EHO-{gTJpLvrht#KY5Rxu?${p*u_qp?HbAM8`>XlPbR!2&?WLZK +U+S(Gf6Md;#ENy46Dz<@~{;w1Zd!5ctexcECW5OSe-EoPv;8BXhFppQkom?{C*3IQ^L(48zi82j0%C0 +MSA7c&hKt_R>S5y9#O89{)BEzcwj831BK7fgC-zDAcJODXJqj)+Cfw-|8%y38zQ(qLr~4GR`@_Dhe<7 +c6))A0j%L-(0-%he?32uporr+eaggB&UWjzI#BrC&DWHvzZ5~`-16j_!Us09(?T$yB)XYyZPkC0l-*5 +m2efD^&G${__}F*kE#NX{9dN@`m@8yc96T0fmFO?O9U0+s- +4K4Y{L^x8U{cl9D-5vc5Yvn3f+_GH9=!=V&Mm#~lVl{$;9A(;6l- +LDh3x!T9#kdB5X9G{}^Cp{|-GV(AolRKNM2Vk+{aT{%t9p3O}eY~D%|8lvej6OE&oESTm#>$f84&26& +(qMB@bZA6{P*!v!HiAox>-)jLgZ)c6p0m>>!W%^{f?UDQufPlI$1K7IWm5Bfx!B#q&ACW#;Tk}TDtR) +Q*o_$_aq<(RDYDvpl-kZ$iajTy*DY%U&Z=3>AM%B3liZRiXW)#Fn~RS*k=Vs2>%r|8{rWij{HaV +iaubTAh0&`H~%WO~@$4R?sh9Gn-iGv<+tK8{1?bI6lRfYJI$>b%uE$9E()2P +Qz3t%hKg7lJ2SPeD&5^at=By8dxn_i$skz48c6T+Oi(WJr_(|i}vgORr~wrDPP?;xnCYCW*^dsKqvha +v!@4m_EqWld3I(s7k{1w2EU^y(;s8%-4G=Y;xP}*Z>T@=rv^cI3mo{ESs0*GLTY2Mi{kJ_2lyAFhmC +SK?y;-+w@a6)?f#OZrP;Cmy=>m;2=ZNX890e}H&2h-_OTW6tI(54=C^aju%qsZu3#}QoZD!}u$iX#^-xY$t;{;ZS#*M4E$}7`xr4$ek4+2xfs$xC;WsKE6@_xP?RAyg)@8pxR5cRGdHSp`wveh~j6 +EZQPa;vpI1oMT_2kAXqWB!Eb9P+Ce0$ZZambbaT!p3N%(v@MA$zQA?2c_+^1*v$NE2rlM8Sy|gWn{fk +i~s_*p3@94)+g}s!pawTyO_$ov+v+h?OEDJ|h4|cIr~{84u(68MvpJn=5m&^QV5kN0-*DRu1dFHg{J) +x~~6-x+vJ2!@+*0TOvSSoyE@u{Bb((?aB}r(s36>3qZKlu^4ayNo7>I#2frrPxjKX9Ib}uckz8zl*>edzKvp`cf^i& +SY%O+Xiy=8H6af@5s*kePUs3EfrR3WhWORffy1+ERR_IGPhLqEB|A7Mq0J@1}OWn-tH_YgKM +!WIwG6yRtcwkY(;2}+Db8;Hxw;K4{QI@%b+rfR+_5&P&^fr1oT}i-0dw99=9`6m(%GoSJH7@D{~ +t)IiZVBft%PDK_+Gy`PF=1wG2h!_pGa1EN_}iIfZs+f={sQOUOBvx-epCz}|9NXM+B8x))>FcE;Tu?z +^Nr*}GkctCCt=BH#7c=XmnxMn!|V-D`!1*z5{#oRx9uVwpdHkxg?jL|l;ZeGw4?h|m=@A~t;R_MYftyjPX_Ly!O>hqy=nyt5sATpokBD`bM +gj%SDO?qZ*BegF1R9(W5ls--mWqGlv~aitI5LUBF9X|dV+34H=KSikb^lfM_2;GSsKc(}0eBK_AFMZg +UMJa`9|ea0==19aQf`&T6K;d@L3egEKFU9x*Yd#DbT-+Ax{CcQ@Fr(SLfiUQJPH1puEDX#M*KR%khAX +$226(YY*V|K#{H1gWkcy=>KgEnZeyP>0YrOd~^TQl-Q(YKB6kAt$V)|<;3^Wtd8`H-lq>cJS)Dt4wPB +Fh@jb%(IMO<@(xe4`Ay<1z&49@i$3vA3$bMf+^dIW;FW_DV1pU!?A@gF24)<8h6M0>C;<*rqdG9xvj9 +5IHaBo6dB_@s&9MdW_oQ`9nmJ>L6~t6ZrK`3ct1LzS_M~0g*4UbDqQ^X=!kh>^aWYf~P$H&?oIhJn3u +gdYAl!^M?z1UJnWmMPs{hZDPYo%auKHR1YhCwK8V+VfJcqTA9zlm}H&|7}2_=BIj0WDJn)W-u6_O|2| +l5`o8%$dkb)ox8H|+bZrVCufDWZ+E#u09d!QQBi@1Z%h6xsD93RaixDXM8J>pW;(wOF7V(T-+Pg#8kQ +Xtq4v#NlNP004C8&Qp>2(J_G~hlu?b%l*tBG=}wtl +!O0+v%~ZV0d@PZpTZ(;`gpKWbyx5Yi)YzHzT|iz5Nr0$#o`MFkp1_qRuEoSrhQ4y0v +DBrjyl;bep&5sRHIF9oWgT4*uM32#Nc#3qNu=<*!}Vp1kzw%dYc>s#2$i+LUfs9-h0$o?erCO*?T&8kdIz+z4x{R)!D_{WY`pg<)Ud;$EJe`rR7G2n+JHah%MeN3akpBN=qXM&*K9ml=zJa4gXa*TlgRGg$ezb3&{Il +|bJ;i|$0%2hojPA*!hhv!(ZsW;qmH?L*ZW~`?_2#qjZXJSUsC8irjCr7eMvmpmai@t+3pa0nqBV_L{c +n0DNizQYZ4=7_KVfZLFB^`ghuN9XGUr;Eb`t#2YkO@3MsH6XP#8?0_B3HFc<6sJbC7idBT4sBh*FkVb +Ub+uJJrLXJ86fUgY_B1Yb3sPhjJm>hqx~G`uSFzA2#a{%90>_%+F;3gOj}4|Ad5H3L2Xd^P#R6e@TCx +VXcMC_KRoe?I+qVibW7T&@i605^2JTEP{7E1urIYVa$c!xcpE0xHVy;ECmyht{mfa$pXY1|AsX@XRe- +>avm$t_0i<4s784Q4W?4z9wHz1Xs44ARL7mj_LmD#SxUk{Rjg<6hZ86Z=XPb{A2uL$L(8qlp%s>j(W- +GcY)3|-4DMDKIZU6T?3nYE_(tFLIsiiCUJo%Jm7>?T2gvFs4crSx3Pc3*8_dVSBCKRyVpk(>fK%mRNHr6#+Z_c{sGxOc$yK-Nu4M!o`FvVJ8B +-PaKBn4N7pc;)L-&F4Ik!@9ajoWtJ&#Qe(8#|g|bvPPTb_X`X(Zdw-Y0=ge +s=WOC%9WD-2%p@=eYErL(uM0l?hmi~^VJ@z!g$b6~Ku{rcw7~%*{=B*Z^%5a869?>{U1E#`hpJUOLIx0ufR +F+3>FW +9y&tmVy#O6m2zw8^byzi90i{u+}oUe|UKAW&F(6-%N&pN%%j6GQxc&ZFDwyW5Dn_seIeN?p84o|h8+6 +q(3e0bC!Wq|}f8J+EYePAwESUd9l)YoqKF5YvJJs7< +Z+FGJmF&wOH`0$4|1Sl93Hb~*roVs82L~2>qOZmm(-Oz8QUZn7c!U*BcA-$YsHsjz +vy}o_)QA(*7oVjf;wAW76Ofz=&-01|uJTCVu_}4Sz9jlejshMW< +~_9=99x?r#_@z6!|wVhD*;xR-H7?dtTR^Cp2m#vMAv1*xyjsbdX=oQvQy8&Rbt-za6|bRjL|qqt2rEg +~0A<@wj)yDV^ +`t;tP-|>8)VZv8v~>?=2D@CHm<+QMS4h&8@O*MJX}*BIhUkLu^$>V}2R7_9?wfQGn!~+ZOvE +m2z(y_V4TX|NJx`Rs0`M@ykpxoLafa%~Bld&cL?IqADS@4LFL)dB^^Jy-|6nxzl}cbMzcz1X<(EJE{ +gBTrW&RX|e>j~>GC;Jz+hcLjfCauyZ!;j9jq$$qJoYB}5j1WwvgK +m9i$XX76W@l@n#htRe;rN|;XxvNtT+_GRs-il +ZH#X%gMWIvDw-YW!ulD%bzAmpqaSkqGB!H}}cfJ3pRexTsiNJW~bbqQsz7Iyq(uC|x7a#ER}hrR*7W6@tg*K)_ +71bX7M)3>gHqN{aV2KKx#P$sje`8p0QWb%#NQGWTd_C@LA`q>p7v5>VYnwuR9z+~uW^|=GTZ$+O(<0l +RV^V|P24HmOUiS^V7!ry! +~gj5)8X_#j$8dZ9QxIK1Df|ZP?2ynb +HB21;S&1@5Az%S^fiFxYqoMYUW?@PdD$NLJngTEhW8ow{YEfac3s|r}>qv(d-iv$@qZu3x6pT>mcw@A3|>3_X({iTOrR+pHr +Hz23sKfIPT5UUa{n>SJKj8dEQ1mAl@oKbp~C(k@!P!FT~CfrYFlfX +800Jj=d|c0pEv1aeU@fZONpoBNxSEP=qi~h5>J2hM}Lj&mAofXA~jaFhoK%G$QSB}s7+bZxotNkYW1! +n9{qGQd~ZnIXT0u{!}+l}n(J3{c;Z+264ZUF8yHm{Fy(T+p7<@&p>`q@W-~s|jb3=Zyua)w)6O)X%PG +^3YIa4XAlkY|$DjeNQ%Hspy9)g>B;-3Xr2&r%pfj^5H@07FSOxw-$9 +Ly7vrSYp5RxFk&hrwgde0e)d4_7?2F@Nl<+Ml$i$SK?PbV=GSVRmy9T!-PVJ+{4!opl7aGn|m~s1+Td +NcY4ocvkEkW>({-S +T6VXvwFkDicsi+Cp&*!nK#s~LW#k|d|PI8zc0Y9GFF^Q&lGe<{RJIkj^k-R=%D^JJ2(yQj^@4RT--!p +8B8Sm+4;aQ5pW9E;@r}k{$=OMS@OxkT@N6|T^)#vqi5-4JSb+(iFDWNRBlaN1}W3hd8o32add-yzYrg +n>Q*Ju=eL@a(ukLH2|g3XzygxrEjZr+gOaW{U|V3x~YcdZv7T&zH3J0Ot_wVc;7!m(Rib66}=;CplkR +IdEV5Jos?{IKIY`{e00l9}TzC)WzsJ@ZiOj@6ZUJ~ZPcyL-8-mJ0%Zvvvwnf@t97-j$<{Oc7M%JF7})c#__lnS&t?!yZrG)F9-!W_KF3fm8%iqDb4=pL7<)5N +vy1WZc^ldJ1;wnnq`iUPzVbfcS!9(KEkM&{@1nn{~& +fJ!j{j*>`XS;wPst$6%n-GKmG#{zsa9$adeR!`HEO%i!&F!#qvCR_2&QPh&=Wy(C99>COV&z%YuC{Zoxj~UWe!C~|v-bDD*P{OI9JBv~vw +ht%-~RoU`R`izP=EdM`8oJz) +C9skXqFCtcM=W*rW#Af!G{KeP7-k?s0(#1WM}Z%+CD_eE*h~P;mIydV=2u>MN0{6WPaxWUSw`Gu9N>D +=<4K~jy_OsD)2Q(LeQNo)8oiwu1a0pwvDDICjr`O0>bJ%2PX`RGl!H+xCIR?0;9hrRNYp*l0eH +JnzgiXs&9GOwH(+79{dD(N=^QGKtz*GtSHXkixy15ft-UbKVjY-08DdKeamln}6ZrnOy_41=z8 +{G33cDNR4%ndg@Twg53;3iy2(c}H5RE~P;bFWYyU((L-X(2!2tSaz=@H#y!MG>l(C~M>7wcA-EkGgf+ +Q)(8U=_;by<{nc3#PChggV(#LVwY`YmyaqtDI;;Z-mGG0;twm?R@J5P>YI0tO3qoIyucUm`xc$4^E2K +cxON&bZgce|?1oi^n|Rf_%3NJUlZRf{;GUO<>!9fWAV)ilG8hA(|8 +Czeya`sR&29{WLIedekdt2d>5|*h%MEdPV9?Yu;9<=YjzjW?E9?Q+O)+n@9ZwHjkIVh^X1^T@9$6E9` +H}^?@!(y@K5jWPu?C7+5f^z>Re;_LC@RhB_XFIHOBD*6cJG=*1RO-G9g>8fzv{W7MHfI +4Vhgs(GA@EbYIjzkoY(Q5Eb1h>(GCyn-O|jFp;f6I9-4Y@fXF(-%vvGWb_bMEmR%$iQQ@ziAyhfy-f{4 +-@n(Jxy5DgTLM?%)t4nQOS`Ss0^so)qzDwq6eHKdA56=Ud=K}<6|R{9IC%A!*ei>Skjhe7RTMd@ySg- +oVA+7qAr#SAc}?*D-EX$p5e(i?sRq{o|)lbs{k(of9OF*jLL*PiuD4jhk~@OkDF{yNsT2PN#a1i21)l^f+EM#YO%)`5=xyWT+R@8kM1!$>dE<;ET@AgW}rj2`tf+hEZQf?5I`;!B5lNpTOnj|)J5wf;vN +SUvZ9yeR4Wy|2CiV=g7q;bXl_3V$d9(!PPRwoGu{J7O^3}F2D5&E+;}J>%V1jW@Y?u=aSsQ|LgcztGNHm^3&2^9^u9}_AK+)GucO(KK^-QzQw3;%xn?@Ebbn8HYkCJ7v;DH?_#oQ6phf}o8Kp#+M(nb1%BcA}j{?1UlMw@!V3-z6pAMkISi +8G0K-C;Ja?ACaHe_q;uvceN3ENAumNIez;^k-MrFh3(8`J4nVmlM3LS#cb5(T_pUgI%8tzGtgUuoWOU +16!=|!1ch&FlW?~hfx|t?y_-`Jd)9onfqqkWmFjsq~ +A+@Cu29QRCu7KXm=icW7bY2Xu6tZ!JbLEiv7>^igvO5WMjhmh;`Y_P1|gbo0t!;}IL+6{%t2wweo+#y +>w7?5>^#f1LDS)d1;V(KBA$zP8wNMBAPmle%@>{_K35WHh|_%iZDUDGUCA*Nf(mbrsV1IC7gHAy9XTf?rLhB#8aJI`7 +q4qo)g0W{B!Ve>>d^PMBgEGOadPJz%%dNs3kx`YA;CpWMUEqrk~K`u}1QG1llgSqloVk&JwJ>-0TAlA +bLiJpU=BmvoTAe$0M-Dx0t&y&uw?i#b)hg;6~>nT62!WiRrvXMF$Jpy=tukH;ceQ|!O&)8CC@{}6pw0hCghnbM{?o-8q(wWKukK!dGQ3=>)`RKrh|MUhX&%M3nI)W7UwoW( +AR3#Ms?kuN>kA10(x2t420m3y9~L!*ha~T>q`2;u~fkRA!sEG3i$m(bmwdFy+`CX_znDS8~6J@-os$3 +X9rGRroE8f)q4uSweR{_AIe|kZnyE-!;LI$7t!d*R%@^`A*t&n6!My*s9u0qap3&(ct}sBN$~I^!U~$ +J9h`FUNW`MiXSP69TD@Cz@Vl~B86 +H;PHu*zX;tS^B(f$c>f(TjASvzCh-wC+Lf5*vfor=xJelh^IfJwD23;Fs?@p!0YCaK8Q5S9K2){n4c3 +zZu|*%f`>o_!b~B3dKnXMK<<}(Z)E0MQ37vb-qyUl +PTyxTzAaQn9KyO?!@;f-u>F#4fyvU@oD{~_PBoJ8IoKlFZZn-d!R787rKn@I7cmsMq%_kXN>&1~-Uw^ +evo|CwxlqiZbokrw1;?PenLc(26n+X5q5(AixZ(aE)W@1Xk(E?g0H0itAqsPCAFeev%gWL%s-9+Uk>K%h6K!X{NigB9RrDe+}-(`f}$_lAC~s1?-lsc-1_ZX$iFteZV3IuYu}?2@Q<`p +o64wRakfq$;&@|H(ifJ;BR&{cL&$3e +Zq$%n~8!6%>=PSF;y0aj=KL6Z;E9H?Je7;osL8v4jMrxsk8b)<36 +0ZgYN%al~lOuq|WdWn}e_rM3H +?`B9KBt;h5cSkH&`}8rKxU)Ff12qtUnlRVXKMO6IEZ=(%j_4(rlh4eV0fwuP0_Z&pBN>I0_k^2i%k!I +p9KOs`5?GSah(!w%49ia0MfD=YZ(d0C`bD>HSr2(s_50SyXd>L_*qJ&~h&h7iT@OtLMSnAf6e?Zf5>x +ICTwc{S3|Kify-M}I}}*BzyB-%%1DZRI!ZGl_S%NWc7xlf}On0@*kdL{L9gD*a!K^QDUEza8T{foKRL +5fVda64^~AQHuJh2M3A1eTK1JBOwm=oh={Tx3YX<-ye$KCAcB=E+B$7MEm*v)?1HiqgiOOpSuyg;B7= +4Ub+R= +1F;cXu1dp8S(_Mi6-Qf$|O-fc9Y|HQu)Wst;u-90Q{DxMs0BFS-BEb*shg_H9Q2?BN&WL~w|$XVud*7 +EG^h7R=NyJqI?%2(gJG36gd7G4upa0Y}&W%R1++b3~%zA&It+87d|<@Z(R8RX1=NyftOOee2xfOdVGT +Uc8){uecoj#(0KI3JkBvxZ-1si!SOEyO +*rNIQVY20f(_7=|yRCsZIzShKx#X`C?pGk5E#7Fji`!MKZ!MjV9X4&5HEW`e|Nnv?iF6^=y^{XoA +UqLN>)=r-KzM-4wu{-u7jxeo|IcT>G85*AaUsoMilz;i;ymq>#BZpaqeUk8QddUb=N!-Du`Egr{0O@` +?h(8q%foMdWtucN&fr>Ym#Q_v)&K{>KgfhSrW>3Vs*_~|(pmz +Y-=kwa$FJb>vz8lBV`*HVWSob8{WdvwokL08u;yqbLlL)m;_9?mrb&er89K~^rtP6#UUG<6N`>OK8qVl1Hy|=5bZ1|lhSI!#80%IKJqjT3Y*b&%UbUo&y2l(A-ySMPB?8r# +i-cUO*62(O6$8nuu&`+;td*|+bV#{|g@Vhx!5|~{IYzuE0jbUbn4}Vdoy)C?KL_aSTgod~6*GRysqPi +LL8l&c(ow}61T1$V+`LWa@6r6c=#^Jsw^ZO#5mr|>f8wOd(#0sxeEoi{6aH^uu{Xx69PtYq)x7Eb#G) +^DmK|$ORobT6}!{_Ym!iU4FFiE)3+7VIi))jgY>a||%i^x*XwFX!+sfiWa5CjwF4L=3kQ-X$%M%HLsXy_h?^O+sl{{Fe8ZMSx ++49KMumIFQ@OFwNN{Q*Hde%wZWka2`wl9ZBA@iAbW@U@k%>yl~inCj~NWxs4#+0!y&=D^HE4CMuP`l1 +qnNzm0c~vZ*okdYz4!vsTcqc6k$$Jefn1?2IW-~G(-`zO|dbC+HhyWUm5%E%x^r+LcHwm-g>Nr`151f +3#=*+_qGYNr#%FREJPQFuCj0EP0~8Qik^tFRyi#edtV`U}xE$BZ$>vYoS +vx$!6)+$!71y;T@?i>Jem*#jddobSR!`I-FV^fKNqdx$k+&FK8kz^LG6S3Rh${vaei3TybWxD&ABUXs8rMzyzr$zs*ZKd*o}gcZzpVew{J5|152t+&7{8wKea4@}2^1o5jD}E +(MlcwsaU3NGilAv2gSNQvr$z8v=odhHcAvuc5G?ZdZTh`X9ou6=l-}bhB-!IEg8UEp^N?_Rouu}ybOh +g9xnOGFWykzIQ@?i!!|y!BTQ`di_iP7@?{!Qu{l(_(@3w6C9?gZ}u6aVgL%;1B2ze*$-$hVchzh?Iy5 +Qg~i~i2UAnzZbxAGYF?%}21Jy_^lY-9^*BkZG|{(%U4sQrvAVv1E|de)R^~FQK|vg~7L3c-kS>q#a-z!XOrtRv;r1H +7jLy^_anW?n`E{%ng*kDhe+K3#t;+M!v(7?)>7S>tNAk+N`Kf<8(#L*K>R544s7p-CV%(ZFsL&v;GnO +zOvQQI8K&|fP9hn_)U81n#D0Mt=Jq_v6pb_vPhJ2NH(D9iKI#CK>M8^bFx{9tM<=V`(;td%5^QqD<-F +dae(h-}azHt|h7w)07Quy9vuy79sJU?}R`(%&R0ty6V0Ilj2wEZxjk*6Y~L_$4&>=TJf6VLNEAaKA+7sLLv5ano|oxlhWS@ud!kn~D +MVbK9L*Zt@7Ru;UQ-pk3gM?Qa!PhM(`E)4X$x&Z=5cRmk}v20ROG~M}5tH&x?nZcn{AbaE>)YdPIew7 +mxHNwCL8%TH$5GF%CbMdGN&gU-|_`{cLPZsi)bKm&YF8i};=*H+K^{Q+ro718u&N?_*36Q9wfeQ1fd)Hg_)0vA$E;EvN>u8-IUFuaOcaUw;%wl$jB#dMaNkb +Uy3Sr~V2j%Ap^(Q{oy8I!uWLMJIG$-l5;C|q<<3xW&l!nLF)pM6P_uKOGk6t4RqH8`X-h)y=es@;{B2?*={24&!NRDo}?fWR*1!K9g@Z +sF}VuzV9NRE!2_Vvti(OWJNXNr=Ak!aq8+lIydMpUougW<#6WA*HC +j$btuTl0<-Ii7>g|!J&DDuiS#KY3-rltrkUU ++kGfn?|L~5=##&zk$}Nhtmp8IzEo>);QZ}F@oywnGrtPrw)^Xu{KY-1DsIF0V-MUkl+(Ja+oqY7)s;z$TDNnb>gxm2g+}ongEuh@1n10_^ZSrvEObBG?TZF{1)s*$$ +uhr4;S|e`FA373u`fCk2Nu3pKV0#b@{uTK)h!Yv3TDW+oIL&;C9PhfgsuwqT4@1=yy@#(Ox-@wd1d)p +r^~WN)biplm5^4r#FZh{uZNMZIRc6FFLA(?TW>oo|Cz3^;{>tqt_*@u0zDJnJ1ZxciX}}NrV9T_*Rw5 +?=D=1)kik*lR4*?6Hm5a?H1?n!A(su>^)jERxM9aKr_2Z`rLy*E3C1w{I`RBjuKBcQ-9uOlLh^`o%7g +zdI4FYtL?xTyf4zr&s$~cC)eAr&6{s0xJAng_^Y}6M$f)ExZy4KW9ss%Iof1=%E=-emG)#fZIhpu>>d#A8hBPk(Qv_wH-sLNMSh%^+aNyX_TFH3 +v7_2Unb^t;xSp6ry4K(k8*dkvlQPR3vF!;&E0&hIlli13BR6L7F0oLQ7ng525xl-rg(hQW5pm(w{wpQX`%w2ARfc!+&bE&oVS>cat+<#0;&b&EZ!|UT +Mz)oh_{EZpURzh7%&`wNXL14_Fb{cijqsF5#!~9L0|pA&V%01acgI?k1I97U% +dsnA$}Rz?G$X}GPU3^Z+Sp{t`Y9ipa!d)|WLmb<%j*kAQMep}QyTd<%CmSPMyAf~EZ-zL0ECfd_VT6| +`+MAC^s_LCJ6t>5a*HJhq;W%v*GO()kGe@lGmg_@KvS6@@%f~OGY+@~w=>=-z@dY|+UtX&$8tw|52WplBi%+mOHia>TBgcHc=*tODhVfF@VbDKPpygGzg_+x6LjY2kHfMs&IkT}L6xO}RiuINM+*$_;|lX{7Z~8j73SYAFu;#1%)eb=f +R7dC!EpwcBZUGssx%<^&pjG1#^?6h`=s;CvL~B?cea^(PABI3{@SDTrN8#Wqya6q_bm1s7F6&3qE9J{ +Unm=I7^yH;yU6hL(r}6+VNoTg1riHYbnOUdK{7X^e|#E<XX$_P@G{t*zLGN +BQ@FQ+-0w(UzDHd@|Vu<2{!nXW^%xH4z34HGaW3HsP6eF`@`FP>lXt!{M$Xe^clP5i{VGTS^d_^!kj? +_!{BM?CMz*A0>%>s9ieT;X3t@TBE>plPw9Lh+p^G#;48U~YA4q4bKC1}hvBpAj#-sj8JoM~}Pvo`dsE_@ifT28g>tnllq3CxLP5Zr*=E5#?Z|&w1%gZl~0el+CEJB!FNV +T=UBR1?H7<2eL>qK-7R`88jvttn0_)!^P(!9m~f>`$9#0QOSP-FFKxuluTiR7-f-7PS;2e^B-!KMI}S +XtQhq3&)Fmu9tKm_G~-uU%VclOuk0Q^h+*`LS$|J?}R*S-Df>hD{?a +16#_m?Tkn`Z0#_`)o65p%LP<#*i +DSGdE4d3ctKD;N0@nBEkCd6K#?QbmOS8+d#?p12rDA>Epc28B4d$rs)RhZZXT{aGYV7rbBiR`rmTa*v +IjjG9DzZvp&oTid}T6--7wO_T(FNk;k5&l*p)kL&CkhDo0|DBj9v@oOO4Sv|s`?9^)-6SH^3z +nD8?-I8ui^MS<>@3j(ZjcDbu^4rw8|R-#(n4;-(vOxNTg?`P*HS)AI6OIzn^-N~jJ-8=;Y%zw!ec`QT +>h@uO7NZD&AM-IWohHk=|Mj*F?5)PGY9aOE#M_RgXU&8)=$WN7=-9^0aP2+q^@>AA*m{3_VQ3S7`2&Tev~rS%M-?Cy4kBm|Hn)S3A0_k~l50rSd0&RyKZcd|pY<6 +#ILpHM>;s%!Mf_{2;XQt*Ufh~NYMIz7=Vuqa40xu^lDw27ZD*tDid+wbm${+J1RRN%7ar%8OCk-Oac- +DKZ_C&82l^aMv48UsOGblzjOGMyER4h!+vS&z|lbYLrgJ!P`W!x7by)H~M|8X&_#vc#jk)Qb_s*@bQa +LhAgB<~}+|B_C4(-loi&5mkVh>pW6sfnOe33Z|gY49{b4Aht!%^b>m0&vPTtN(M}xL|WUrl|zzdL2KZ +f>cLU0P?mKs1Yzo#sPiF0Q7h7UcZ)~v)RVr%4ty=^hVPy!uyVaxEXC!EZ%8V>c4<8?|E1Qb_HA7Rz_J +$3g|G0~k9NQ}Z9BjYbscOrcZOTevDinLnzQoJ)8wO@{%}6<-32d+?Oqn!ZseflzwcKuug*KA{>fC=J{ +NGdMe7aVam+JBuB9yLa9As4P#fvS1-6yvx`qpzZHvv@c;qMX?zo=^e4JR!!rRP!AKkGzN5Hf^gtS%0^ +i>En_KPf|WjK2{|8+3nZn3sn2!m#YlVW@pH^e{HB2VAM{_g_k9})@=4&V%4S))q>-=KW`7xDh*a3A<@ +Yw +(+)14J&lR}ApsPv`b#mfMrF8UkUR64Bx#DTSP=Fz4(Oa}@e^m +YFt&wz-n4WBVJ9Lq^g@NW_29o(S53yM!NaD&%3k`f3Rp&HoK#9IMvL7kU)FN5uh_JFA4kTZql`15+)N +VXRy{>?dXephGBF7hJ`pAODk@YV$+ZwMDx>)JRR4^Pij*>fBK6m&0il6LTeq-~bIMK@z0rzZ0+S?j6x +e)j5@t8cF3VfNbemkP+$FW%B#e2{+nJmpwhl{3k&P4l|Tr`#f{ApuOsZxXMnkop5IWEW>8Ni73u2ysJoL=)OC$n7y0@M*J=^$cB5k ++Rrm8HU+3zSh!QIw@V0vb8l*O+(NIBhl49#1rddgI_mb*L6M3A-cuFoB=8}OH`F7h>DYpv>Gph6GI +gmf4#hN1M-jnOV;4p8Gejf^W5yS|sR;6V-Ik+N7gVD;uzw!zKmX$WC|W)>nS2qZiNDIye0IN;p6@gFq +K%(Q@BUv7^@RZZ;V|D)fuE|pZ;>?W@1hR~vWNRIu^0SOZ)w5Zw&h*ju@_~$?RBA_OFv-b9#Q+j-c*8o +$TCp-&cPOM@6{r2yS6>^{w~)DkzE5KiS}DjzY@aPOGmJM+hM!)HhLWFG$N$l{HXK&(C{R$P4+Z$@^3PT#ikDq9y|f{Kt~KU1_tBxcI +kb3@YK98jR59N<9xy6ABSC3nXWja_0UyNdyQ^G@9=;RPm9^{vt#3mO}dgj3qk;3oGo96kA`~Y2L~+z$ +fXMQWo~|;BV-JMI#d`{9AcOCH0qV1e7 +hP{^jx75_ndv8>FzNh&NmIXx5qavLyXeyLLq#6Pb08j9E70UeO_g@GaQh +G$br5z7Zolhd0R20tJh*r<_H|NSS`9UxN{pz&~}kXAe#Ix+qil^yo@sszE0pHyS@?{Qz!E7iOlUpbmu +3l7^GQG3&1BD<2|;p+bw(jIhm50*j+ZKJ)aZIb3H>eEU`3px(t1kXc+~POzRMqb+1ZOF|HXP6&9OwOJ +m^o93>_q^`7Tb=!CDhjE=1z*Ew@KhvfW_dD4PWO&b>RUTCGxD6TR|CeZW!bjsUpEmeBch`C6ed0=Q9pTuO!GQ@NhxOE{X?$?vq% +cdRsUWC$pDsU>gpnS!xTFsnbjStl_rNaj?a8y6Z6KR@UH}^K#Es)CRwo2u`H+cwA_#=DN8S* +BV&r_9<3eo!P$-7eiMaZ8@qr$?$xL(|hBsi_6%L5KUvqCf4c-o_AIkRl4zozKqh0crTH5XwVY|f%lx&d +ut0K#{?|c}%WfR^WEW0GrTk4Lc_g0z>z7cpAzuV>dNux4yT>_TR6@Cr{Gkvnfwc!9z`9x?@Y$Mb{@w%o~u8DitYj=YP_4)$wE2Y7i`{>H=mO|r|Z{iHp +=)tzW!Ty1%AZWukcF!5xfFF;_Khw)p90z`V6nL9ZBN8Sycv-kzS>14)_v2Zv3*|-p^NYeS71R%;#{T{ +O+P3;THHE-u@15fe*Yz`^mUa^z%UN9+WOl%ZLZ#*z1Hci0Dci?dkjEbg`Y`;at$CTLtLz=^soj1!~n) +qE&9LBZ8Ci8p&g`pj?!dAc?q7y9=@ke^_gniQ_f8^zDsumBwVPhvQvoHG_fU**oB(HCTu28kQj^CFw1 +^*6s0;9-|GaEfw$ji&b^Ikdey@SGgA2d#CH8M-8 +kCTUXGggH|t~k8%!1>yF&U8w^ygHx&mPZGOqySYPoLAZ&j0{3a&n`W&u;gQiL8}a&Wf3mx3*pP)yiiy&$171E$xG56XLdohsONA38ue +h5)Acl-pZ61UGRCWkah5nkv`8PL!tG9Fc8Qo1!>QDajwVE!_Q|8~^VB{HJ687KveU-#6Ne(2{*Oh=AY9|G^tJ>D`b#e +(StqZ+Su=`6&`_D7#TfDtQ~PhP&q(gzYke8;Ik{F0DZL`?!481OC@c1ykRg6?IA*#?0*OFu3ofvSU~&DU~~^GHY7&q9q>0qNBo^g@3nXvi~l_mle?5dAO9A +KEB^mWB>vF<{-hUFevic8SlRr0R0jTu^?pHRFa0Gd1OLQ&{{)qRZ(;f8sN7BG&spJB`5u*#>jFgE``j +MZzh=aLrbeMV+PO1cphG_B0P{*1JU_(qd|VIeic_h8Kn-y2(o15msE^*UJ6$06(<8W*6O*d)=-v)Ub| +^{%3u@o&t*YU(FuvSX13m|bK(?X^0jRlg+sA-Jtlh4MuEORQarEwkpZE7tE|1rdDxZozIoQR|j)pTKa +m-37fnqr0X7CBHJDM--vA*_qCe(V1tb4l6+j``WxS0gpU88K*klR$-?O#D0ZP+p})QhS}RWl?pkeQj1 +NZ$FmHvKEO4LU~g#yO;zhr)z!(!&uqqJMNS +sO{oKe5}QyZpExe1A!{w;j%WOz_7O~6a1+Tzs8iL4}dozg7;6708JWn9%o_YjMJyMPrwQi78HZsq?<{hZIqDNo8tgKa +XI?!1U;?LD6lD(S4ZilY_T(G?X*k0`M^@SgWC;se`FB%g+J^ee)bONGK9H&W=CNOx{kN9aFIQ3!C=I^ +B%@mpb+@^@tO-%7gp+Z&C-K9z6;Kd%GdPT9C@@b=`y@EtPg@a-8M?mlX}wlDObDBMf7iFn7?kldN)?l +nsO+A`-;LHS!rIQ*Cf^oDb6zjy<6=)>tJewTT_u^)e{QlP|+&;A?x>35EM*EWXUN=V5*8=w3weA@d`n +Ok23BqB7Fw%EVvZqrXykWBsu0g1QV_$On=T^5&v#OhrKcr};krbC+fNqc6Oa9};w`>058!uq-b`)VH` +@V+gV`>xo1pqem!=$;FZw(s@5Epv9k-W}Aw9DC0M_?z(gznls1c`ARK$-i;`q_h6wO=0^qZ!r5%)#D^ +B7^;hGVJfQHD~f5mYj;Lp%Y2!OjhTuGA-tl1A5ItGI1`fO$FJT(@Y{r(rWYvcw_;I)F1+W-(p~%0C2a +NZdT5N6a0o4rK}(T6Eht~qy#)dv5~)jjJ`{xJhU7G4#kyVlQUf*#kH;Bvn*W%{dOnVNmcX%dNe`uN!{*IINz3%uwY<0HaOy(H +qJ|jhYqW3La$QW9Zj`yj@dM6l^fytV&6*k9Pd4h5~)e!h(mciDBPdkCzv90O}dL;9hkdIU6Zu>R)AN_m4U7!{_|%zs87&(^#J&Gpw`cK1-Wzds5?DHuX3BP+o&#gBV)r +}eZ}k0a)coUhgCyk!)z1VUNmYv#eZz3r@fp5@dw%p_7@7`u!G0uLp!FDgz@x15;+&V8)LkFOiMo&TnQ +EQ&)hZ)2y&lf_f}Fv0Ff}#s@<*e=o=mw=pka`n^K=U6IBG8y4DSA*HL4(wc}T($wsc1nndUwo)sr7WM +bZLIt>XCv0zqp@(rU-r9Iq|Gxaa**S-M&J?^Jx +TWkyHA4AMPT=FxB`Fi?y5JTf6N+A?NB72)UN#Z}%DEcs63;i7uwndwMO9^4`jXEmaMPhdmzUbY}y%D+ +O=MCxfzOEzhR3;Vd1%G>X75Pts?<8%Px7)ZGykpdMd?QvLdyuGEMR{Vl}2kNwX>%=a_-HxSdywx-SD;NxcJBck;@5BZ8#j(v8WRH@agYYN_-u +Dxxw#^4FHlKWU;mT-Ka3vgGU$?g^*i{);eiTIHFt%ioMsi$z6J!yT&2)@s+CLzB3`{*6ij%e%BhZEZk +gTV(1PH(F=mLoaTjwOiK50rSpT8pYZa%uE!9errWmz*DU^VM1>qB4XbaBu4PFsrL&s(>L_vqUG^^t>@ +>#vCp&f^FgREW?*@MBH0I*SK+%^dvy8uttDS5vygIq??|p_>^e?Vx1+5htqMT4XB?g<0{1>zdh2EK3$ +14$UvwE>v71LHh;OkB85E*MzEk)#|u_R(uPqeLMta$AJIU+h)XhRn%E+c_zw`n&Ib#}SAVLA2Vkhy6q +k(Q9BpAyq5mt0`C{?O$mOleJmRIPG~8D~wc1>*8jC0(b)z4;@fCxha0v=KIRiZ}502>gx`QJIDx@T?q +jq+k)Mvs^CfuXi04uby1q`C)tc?KG7kOqo(YrQ}qFD#PxI;4nh7eH}8El9Ij98e**ZLA8Bk6R!b&Au< +kQh{QbNz*vu9IETVwAl^ydC4K2dL@u5a_u{$BxoV^G3zmRCJJI$VR}ZIAzy{hO9XX*n;rdD}C_9F>NJ~Q!arhB=a**j;4oEz>LPDcY4 +_9!D~`XNvUGvEN9qfL`yufcce(?5PbRlNO%7o#9Z3AdJNSchn@}F +5PV0aJ)8ONct!W>oZm{Fn0q2<`66vD2lvS_TdCrPzd1W;JF*x*s^9&7J^$*~%(MF6ki`hAYwzE#{ohc +zz8%#FN)vs0^ +hpf%O3x+lcK=ewAPHQp&SyU$ZC102GOiPO{3DaB{b}!tMtNEF3h+jM^ykM`&8wj36Z0UW@}r&6rR0H5oQyu%0TMbN^bIAEOSv}7xa&n_-Jw1t{vZKY@JztZD;ALrPZZgK?jN9xK=DWmNFZh*6%&PYHGJB*SkVwSfY;HJYC$P4FC(6ekavrFKPbuC)9!M$j^ohJ8lxnns5rGo9-amiNl^Om#EK!SnzR6XfG}d1*k +eA+*P_^d0Taq7gv@vBin(+}+?1onV+L+?{NgnnBdub2#Isp$lLV7}fP-tnwH34@=hVO6@k3xp@v^!eA +9$ma_Zdrrjdi-5+Ki*+6AFuGBNnh;8WA>t>>F^NM5rv(lsU_T54Iv%pSpoOfW+(d1oai^>gv>2-|OFg +Usj`_+i&)+$$e4Lj@vd{;2~^Lkm=9)pV+f}Bk%rw#*t?}J8N?56@rX=ff4v=eGTj~YLAQDL8b3_GXk7 +s7=M+KB+@t78GY0|r?RP1_e_`7R6|8!gqW*w%`)g1_Ldc2H2c0>`l)`>7kT6;<z$L7l#aXIC9MCfgOb>$7S1M=p0WVHo@`@;m(&+b5#US_s&k>K8ZO{4Pd}3 +sQ@3rVo*ebzOZM)V&>RV`f?~APkTiVn1J}=^T|;KmR47`cdyGJ6y?xUbfbyD0KzL_p=M;)H+-=JM8Fd +R17nCa@DaXFmQucDBgx`*XYl)UL>P(8y8Q4IQ+aNV!2Ri#D_cOR1gqO$H^xfVcl4#7~2w-8SuQ7K!8g=HeD+?2ah(PF*(w +4x@Wob&Ghmz$xBnc=YqqBx*M$-y)YcgWj{Sdkpn2{3m(<9!zop=ivM{m8k-TM;SLoSlu#qSg9EjbtOw0c)K_V?uShv^JO?co!=8>s&-C}IzLP;_ +^{W^|RXe01R-LlIfH^2Yk^r<*mNnYFx_^} +XFAH}`%zXb+V3e!9=cG{JdqQ3BuZQ5qkO_iuyq{`nmn0_-{@1q&zdQ{*LHB#rOl!05qfyIgjq +)pMgyCvKLqx^g^WR^{xHZ}eq=H6?|QEc5Byyq$Eo<3W6v&Z-^@F1KJR=UF*AtYf0;*I(_`o)^1$f(N9 +iriIoPXFCKMvlk`%wmDi`sU~6bU3ZFYL0U(QzjDmjEE4T%cPa0)M3A;UX`D&p|N(tIptTp4Gxb69cGt +$I(`J#wh|9d0~wbZ#aQnGC#H%&RJ)jT+NhUq|9Tw)* +SZ03PO_)WO`if3?)iOQ_|Zk0vLI@ss4xm<|sjclc7{nj^jq@SSco-*7r#mf!Auvvaf6aUy@=8ZHtFTd +ie2?wRcY^{g80f&q$eNx29aLW-4#&cRMuy=JN5^;KRNi^L<6t`w%gDx#A%Q@lS{$ieqBm_p{uD;y{dD +%zCoWLAiGzG@`VT;3047{b%}a6gf!Atx{!9#5*3%(|I7|AeL}@5gP$c&{IM_8G4OIvMu=^1FJ?$J-B; +8Sh5px2*5SiGM>B_3JZr&Wqf~9bC0yp0;#z0jF9)peXM@=U6Z}wMZnSg(j0drtJGHN7n^N9DNMic +KkQVi5;ChveHiU3y@tch<$OCkoVB!h#?WN!vfAW%YsLe0(l-ENb~|1#7#fntz{{kisuyyS6Tb~UR%@o +BWY37M`oYrj|Yw?T4ksdIFEZhmHa!m263mggC3L7B$S-EM}okRk-?7P1g2zb7T%{s*Mw-`6lKn~PR{7 +K14MyVe7&Qs4YJCAer3*=B0?Os@mb?)XNeS#Ard_5wAI)@tJ41VP?S%Aebyu;JmKnvxw)lxkDpKD+nM +K}g>7Yk(xLKb5PL&^P9e&J@0p11{UQ6Woppmh``n0R~M9+GqLY(u$wY<6}iWw&(8xpg<_)s{knURRk0 +SK#ASR-f*3opWIwTB59u_nS!bcv~MZZ3<#@C4RdCxHWJ^dPzP8U^?f8nrDQ<+g^s( +*gEk33%jAL99E|U9W5JhgWoY1c8DxGnVhGsOBQlQ*>3?*=&K0mmjO^czV)t +Qa~^iR?bsTT>a0e|7c{7qM6h$(&mF5F4fS+;X$pL4JPJ+Y7P&y|8^oq_QOrmu80w)HVkdZAQ(N>AwJ; +!!1*UKb4OqU54t{?0OjQQrnSX@09qHqU-or$HK(8(;S6bgXWfx_f_GF3fbj_~}v}ccMliaLhwczXGUR +2|HF;h3yRY$ZA%&NF?OF1Yqu2i&i$!$-@&3VMD{<-Hv=5d08o3*C4t0<$kILYn#tPwBl&QEWu?9w52; +cV77UWdoymUeN^z7UYR?$*hnrfmMxxO!+Y +5ae~d5KN%r-fRA6Mz!v4*LwKvzkd5r^%(!J|MRzFoYq~wnY{1zZ#E7=5bQSs$61zPk)PGC{)a<-ZytX ++%nx)RUy6kkAUH}hAnk_WK&yF!?kNjmr68}x0*By3Arg@P#a}1lasarqx7rByR=q0TCv6rDXWogucZc +BS5MUHY>1|_YIIv%z;v;{ujzDU<02A2YJh06aX!OJ0J&EMIhy$e8-mHYcX+VMfqk*vnHWC5cgn%&w96 +$n^LF64n1wLpDc*tZ}1iRl!gMbQQr*QW)abQx=NAB|86bpcO7EQA +?9k5wpWs-XfFGPyL_@vnCgecyKi=9^At=_(f6tAfy@->ivubnWcvpL-{v{2fSbB0K{eyHQTu)4w{7$3 +r#_2gtNo7M5Or}7AozHJ$_P3yV26e}Rc0G97<&`tZ +U$$OwaGM&92i86lX$$)+!%GhIaM$|ga@7PD`W?ChNIn*D>`{PVfQRBC8?{=;i;O!&DLRhu%mo;NDYTlh%W +a87s=It9Tz_(jisP`IEfG7vFvtNnWd5Df&gq-Bj=I}b(jzprD$DTZs*kh$aT`aFPi&>2+V%(8@-aW~+ +RV24giTR`s@Z3+YkV_=>m4=2_ +(9YQrQP89~mlqqp@bk_BFKPI6^@?GLrr-t9|qVb!{K7`lYU~ASXD5!Nkq3w;^?R5|$=fKSDp)Jf7)z| +`IlQk!;omCp}u~xB8q8)OoU(_>``}JVAx{XRu*P-qWgF~ZgVfA1o%M#lY#vxXLAlxdvr +q1&hfV~+7D6FTJJ>v_JcQJ4V4xNi$HpuYXSr!>K}Y5qm8p`%k?S65ioG9OZe20eohGl#{XB)?j?Xa6X +%QA8OI|BmqGT6Ez=!_S!6*FqI^`7J;HT8$&vGd^MHds6O2B!;`b~|or>^+q$$-L@KmSwN>+cYR1vSRG +!Y(d>9FOcwlWcTp=5@F~29b+CWUo01)MuOAtO)gk&r3PnRxR!=SMqf}b^B5Y4t(Oyu$nW}VSGONoNz#QoS$jqCad# +ILf1=MOWUI{06r)}Dvb=GFL9)sL%1gkBh!ic=1r1;6#3=R$46B7^bK6hwNqSJuokPw9{(vZyl>>2zdh +K~xuKs}@1v3gyCYD+6g70k&OQo5xvxxB +e#30C7=2oadM6l-G^0$^4kjC)Y)M#z_mVgj|RHoCT^X0R_e<&LpWkS+;h`1UgN`F(1#whgp&9ZdiM?+ +D3K3IAP-^^9E%}oo_hm*LfxW@3+4&ptE#K;oGab*8ew>{(#zSTYGTh0Yml%vA_}yloX~4#X%mv~?Zkx%aPf);Z+CDgKlRAV8;n_0((W+bRtV_@tKRV#KA?LhWnF+al;B +;h%Bw31Nx~wKuDfTH;d8OQPW8>@;@jZI`oXC3hDBC* +geY;lUo9};N+C;^ZM!s9g$`%3&)8sDH8&{;*^Qr;v0d1( +43Y5NHFQXo0LLCfv*?H3?RD4^00elOOSTJpPrb +?6+0feBzRUXbE3F=;_lP4WO#N->CQ#OZd4;|4n{}Z>*A8Myk)+X2Bbqbez2B^&B^EPlWZFs0kt{<@r= +q<**au~>XnT_);c=6u0n4bT!t@-oRKW7g8cc=b2bLhV__02#1T}1@?iRYOA;5n86&oMA@ivAcQ$xENw +t=Bo+$zBsO-pYwF(LJ}nY!>M$V4z_+^dksM?%!QLTfMV|#~ZY#fV-y^k8 +D?4w$5Ah%5B{f>{OqPcs`9v2#xKOYYLIVZ7Q>pqGjQufb7l$n|y?R-s_HEorH3@LXToKsq8qLg($dsb +j`ugp`9%2j{iT~x0KyvNRpBO+2V%6C1Z(XNCAk3^|Xv~wQW9o=5GUl7M+(*8M;WI7-xnRD{xnZ#_SK2 +Vm4&HL2(k|^0^e~rd`A2-4S_BaN8r36jeroUVuwWYY*GZc$*4PUn* +36M64|&U#%OA{KCjAcbZ77W9lil7WT$!idwa1rn^JPJ#z7}X969yIY1}q|;)DN(54kd41%D^y$3WW!w(S +=%V8y8p*dK!9pafhI2%>?Jw++c#5RKqOhtoM}-cH=EBsoA)tpR#y+d!}HX9B&aqJRUylsGOe#fnqRZ& +NqH3G08lHR#KGQ{NBieZt2xNB?y_dX7KA +MoAB@=re%=*Ov>e@wO94p9ByuatgMn|uHLohlu41|x1Ge>`P#8(CbzEo~nY4hA~CA94w7c +uTpAv?r=IAO@L4B0AN8dy_}5lWc#R$@|kyl=0ZKeEmJ?h5V>OP2L=i_}9S++!KH#Up|otmhzketRS;Z ++}))8s)tbV)qnoX^g(_u_!tmN&9k}mGm`wlyIthXK7!3onk1Q8x2uw?O|~B<5_y5zD0-_9LZ2NrQW#< +;BztX9cioe9w(1&#(1IdysDRrXO_w>9w=pG{njsj7_*XVrS7LX(u +KcOSYDR_dl3tT-*Ns&1)L${bfkW}WPKS~|M86{h(Q>J$F!oiF>Z&Y9x&zYrW08GLNoVCV3!-->_z=GJ +MI_f=kx!|)o${F?t(Uw_Nn{4)0c`b~_-ynE*TC9nG5lxv~_DEsrMKNmRszje{yD}1V*%Z9@ +xD&{I}ZPIh3Gr3nY?=xNcP_e`{qf*LF-+DfdFTLf&?G+rcP!VkkE|Zao6-++p*zvprb;Ah-plNv(We( +?F?v%`0L(-6(j`v-@C&_E}Z{Fvh2w@M2mB#%%Q%7X!-k$) +T{{(R8y$9%*~QIIIKR_*m2PmA=!#xM +!-h=G*>rh_;&2j+-UeR_GB)x8si6BD<~D7)Xlt=dgNhgN&z3xhUR8c!%c(Q<9|dTe-%Vv@&`M=Mlt<| +2W1ppvp>3Eg6!xcL90cE?N#w(cY5tErAZ*S^;jRC$%($^nz?;PlKJWLyV1^^oo9>(PG$-P((PH|luTb_k8I3a2JL_k3=S#GY%1T(kS +SkfLramGJgF?z~)6O5dOHQ9ozcP_dQ(I1My#A9CoDCOnKeL(qQ0B5(NRQJ(&iXG99br|4bUZSOJv@z>l4)z!+}TCA)tJlkqccYnaj2gApmYrb +)ssGMLn>8w+yAF(6|l0%Bj{Mn=U^TB1m66FeJk%Oe1Z3QQ}YO}%C7^Vp4w|G5;xh~9rrw@vD#}H?4Iv +;3{3As@g9wGH|^WiZEwEf3cwqm1ymKjf_|D#xY~#PB+OGh)!sRty-igB9S1tS{>1p^ +9AP$2IRTsJ4y=WCPX=1+m!Ard`-zgr7#g{ +tBMtS-?vZRqT848Mv}DJ-CyC&Uh{DG91p7_Jc5&lBn6D2WLW5u*6NeUtaKqhJ18FR>M6A-*s`~m2PQP +ltE|=u7evf$;=bb6P7(aIpsjv~%9e0TyVt2g>T-QWOK~|vr#c_bt`Q;Ys*oq@V8AdE`i1>_mXL~KTZ{BXH2P|}%Ez=D8AJPdSsXZgR0uU$a00KIoi3T)tJWI&B3{w`5xKv{bFraD32y +wfQTk}ROTj|CnYP5i1R6n*n3?(e(ibm!FJkcIqx5s_B;;c +O5Mq0CSG^_AqG0;YIJ~WjgGk@8Z2B+z?Zt5`D0YEFPy2b}9Q{{T$~nZGrX4-jY=~j>vN}*@ +%TWED0a@AGiOQY+&ba8a|r1km{7n)xHTQ+5+D3?mZYMDAMuVbAL~<+6M_mJ=QzR7cmL5+Q`+?L{hs+F +HwxDQmCK6*RTlqvH8+J5GnG`y$Xj89!g8Y4d->T~!M4OnMRJ|1<3-5@IyoJCswx8g604m&hBkC-x}r6 +zS$&nedbe=V)fNw$`B3g{zp~^xZk|lCB$2v9b;%y>vN}<{kedEZ8By1rp?J2O*+m$6L?uf|<7{)>e$@ +;oa}W6uWi5ZM7)MhHkxU23K1ez(uD^1+e$hwV7o#}ax0G(%K`V;9LwjJ-aCNSirTJEl9xZMq}xUyM6_!pk_w8vV9LH|bXB8M}uEuD>Dp-*&{*ylwN%O#H +@e??Zmweu=y6w_`r!ai3PdY27f^;{)o6-50e0$hv{@s +-#RW(tI}6#Y5(>SIW@mo5S;9}<2R=6+%1@TbOgo1QNEh8tuWdyH!log5hqgbeV)Fo4Wf9B$8P0~+TIp@82{A$i$uZ5sd!s`P5z05$1`2{vT1J;acmKG{b%G +y+uLmiI^fg_(!GwDWrFake?#pRo;J#glRNVOW?Sfka!==~%ULb!b-1Af>|!Wv8p<=bmV>x?W2tsrIRh +`xfEe9xgd%8tT9oyKW^bDOL7bWVI}2|G!{)zI`DQJYnC*yb)vGf`an{i3Ou{a_VEKMnF`UlM +v^Ui{H%A0kAPHWeSE<#fl2t9KP{Nro7=r@uHOZR|u%7;kLuJmSmpYISwLUVJ;gv$9p4T=EgQ2S}Dg6} +PCt36I0bUlZJs20$=^oHRXnHX8m`Q{sWiI{Vof;qgA=JoeR2ih +sdn-c;PTPu0J0?xNLHMJN5A37?TSH?nQQK!^vf7PUpy<`R$D{uE8bqIHfF|2}R^mAv)1EkxRn?n1wxeVwWbz +k6|c>4_n7I;w_GcD^3v78;OEN&uSY+ZxW?Z}y9uS+{o1o+ajvPVWFYUsdtIVYojtYPUJAzxCJ@{#yLv +mY=}NpvbUz+A;a;FK2V=Sxhm%B{_w#D4&kgB7nKnd6_iV~{MciF8cJ`oJ$IAz^!n-?b +FLd{P)mo|_1;>8xDswDBxegNZ2x)OvpMni^Q!3>xApKguz5Fr?|6RnJboVF{_FlP?q54(!{`i&AuL7z +oGkqxjr4m4^goXBz3rwj8f6HArZEEBej+5oeCZmqpiKhFfayfuFC+|-0g8Fy-wTea +Yc6c{;7!X{)>ku*K-JBi2on`#p!I;0hCllbsg0y8060Y&D#9%iMoyCB+%e*_jSqd~-Qg7Q0_(MN=v-?*|(-be4rX2DI@oV9Oqq#}RkPdMPtZdV{fnhGRu)XWT-tBKm1XKRWV%v%5Oo4I+;H_L^9T8+&pz +2m1q$NXov8G1)!KdrNPd6__Nso4zjCu8W3+kTk-yW9PLGJP<6=zlVOFnj2qF!tP;M7q1zi(&6t#SCX( +x1NyiO@+|*`}tB5!l0!$zS>=qP@Q~khab_KI@cn)`60C~5)B$3lJiBl+_?}97%kDd2qNMaqnY|bXx6d +50->bM6@Klwqe?a6O +}yYr(S;T5wUOi!oA}i#`>ld{68i-``)_4l0Fo4QC3k%O&I2RC{5on_trUC`R&X&QmiY4?4-%bBPwGK& +pe|vpG(O=8$pd>E0($zj#_msb+nAZl7wx-1b9J#+jOW8(p@j52>6iFHpN|!(uK|=84hA%wfW0D9M>tD)dOX>?;;| +M3goy5?4^?lk(a;{{y?OJLT|HnBZZAxhC}LREDI0s!L#4HQa4e +|EIkhH{XiTAwKn~r@+HE-Y!fY{`8-;L3_U4R>6jW_bEiO;R1u>`kjcIk^ZkYq#`?TRM`9nAGwGq|L=XovhBq-ab<`Y}i$8>d?AwGOYY^r>5+e68lzya-&AIKN6ItMfNCRlc0%8|V9Dt +=U6ebe-QE24GNaC^r5B`bGztcM}Yig1h +-;tGYgv`SCB^@2I#y23O(akH1g3WE8La%_(6tS>sg7h?TYK7BIAs(KfbHIE#y_}LNxh0H0xVQ9>23xq6^;X&+Tfq1KGISp^l*WH@8NHY4+Sy=abIxsFB+3r| +#B$C#Cs_?~e6~~G4tGz+ZZn6tRIY0UQ^~gGE7cX&1(UH2_?|sO44afb<$8%{p#=W?%a+S#k`Qh@>ZZ3 +0dI3b6oU7TZYvd>vLdG!7qNGWWo+qHt&gN*L*IM)@i9ufaZ2?ygv5yp*v$y#qxNx;C^D--poYRkW$@^ +~jGHc(~M*BVex*#7UE8O*ZHVR8dk;)`nnUI}r4w-taP +itFye%qO-qDZkz#vyZoNqaFhie$66%!mWjo?LS;^`GW&-?i8#LqWPmsZ^rt|E88|sf&{ifEi?&+L{W;zk4!agdfqJBHs +hNlSBRf~j)j9eW3~}~D$=#dy^bq`dYOf<4>cK7cI;ApV&NVNjDI6NnwbomGI$hGrC)tJ#pZOYLMO~>- +?Ww8QwHKA_+>q|!0uy$9{_GB7d5`N|dvV5K2QSai^2b+3n&(bAh*m0LWpP!jrh%UBMR*);DG^L$Nmaa +S%yD|cyVK;4!}Kf)bC*2OUN;Nb)Sjj+?Q#K*EK)S+$X!+rLXJLjLF5aP$FR1fHK(Ry*sYX9-?r?Q+S{|}{uOfB^#h4fUc2ToOZi)+02KKW0%H4}P?0A;0$R`x=wmJMjp9 +_7*pIdwulY`H{mPRRgMcq?=RwQsLtyj0S*X6IHu=)*+*9+K%`bXos2Y}UT2Onv@rd3S ++`1_b~^-xHaM6n5}Xgh#5A|r-@RTXcFB?%hIu1qWU4!A;m(A;vQU#WTrUh$TfqxE;C>g)*AQA`5q@4c +GvfCFytjo{-QA<@gARy+u%4N$T;|()Ci%%mLr-%rj#(3f?)P!TN%3$XAe7f$utSSOHoq##84_kxMEHJ +n9QMEjb$c%nOT^UtekQXb466fQbPqYOX-ZV-^ejOI>Y+DSI56rGXgB6Q-js$2QQP1r?hL<1ZO@pes~T +)3O{86%$6DmB-~3&#L{n8VGSr;;0*9%BHFlF)Oea!>9i2E55=RbhaCpkW*d8zUtfzb0?zC(zPHoLo(J +CmZ?noAN&d2SgwxYHlwe=+Z{faW6mNg2uU-Bk>)7^R>VvN}zS@rxku`cT|ZhsKga_h3&R_QO~zW%pd< +a^Dp|8#-x4Ix2(N%Q+=z6G6%1jyGH={wm?f#d;(gF-cue#=)P?;QNsVTu?BMb(>m!{1yJ1P02l(*pED +W+>=l-0Ta^g6%8=XqBjsoIKDN`Gt|oQIP&;-x4GU3xX%bhw9in0l|JS+sB|o6NrV#8vk=awL9_hLk59X!m|#fhsmF +`aNWCdsJ}pT7Em_}c((!)Yz8f1JREAq89?4Qb_6lz_x(S(|$_ +)4!vID4mUm}9<9EzVp_{Z^hY(A|95*0UtY`YqhwLEi>6sG<)O)KX=n(c7nDW2S+KKN1ka> +nENlz!utZUoxlx?4YDI=@owoGAUDLcu+UTEZYJWsQ*XP8_B=;Q^KcC`c4`hGz9D#F9d(!73DCaYQRDH +HrcHpqnk6HLzS`f0*y_$HmyL)lL@=F%WzFrf+`NtIoJS@njcM0W$MNJr`lBZAk4bcoc*{(?jN}ws;U0 +$*YKB#)-^J=etwwOY5Bomjii-}**r7j;*x@V@kyS(L`jnmz-V5qr@SP5SJf8X!PuS%AT)S-A9m1Fq<@ +nK)mDYN91E;c+Z(WEiZWHQanh^Jd&lFq@Uc@Jx+nM6=JzI5#H}lz~Sly!RN1DUuiG5{Pk-uvwMhe8b% +QcUr2?w1a7_%P_WsU>mnC_!~yZx&nKVsTYi6|-qD^v(qb<|0!IBRM4JLRxr*h6n6clBmnt}vurs(a1o +p?AEw!}Su)&ci{UcT&65yQv%Ruqvu>cf&EOw2hefuNf&2(m9F9|uVEg-C~MliPIJ2p4gAzb;{#y_is_dm!?>r=qV*J4mGe +lSNn;XACisJg)03I;mg~-%2)((ow%1vDbGgj_SO^^YJpdvR2E9Bkjy$z8c2!ODhQ!jrabo&q@*nXJZF +V+D9&_Ix3;pR}P2_=1J$D*>P* +gTyub~JGQnJ8_OyW|X=mD6l-KMtTPe=z{oPMZhuO2Xg*#UYUPBWEyBnKFtX3<~f|_*oN7O%=8kDAYc* +6_IbnNNswx?qKE8x9t$v0qUuAmp3!TnauYSmg4e!{@qv6q-8r{e+M0exw~EG8dPV2N8)X{18LCaV+rF +Po)UCm8JLO7f06-xC=`O+>5mGHypv$tmGMh?iq2IWF4gI}v>IqT{O% +b+fAy5XvynF3deY7scS;Cn!>b=*EKW7WQh|g}P+U$?U`gA&9H*D-_WNln+x@oNL-f3#G!;K*4E>Qq{= +%TXBhV7p+;$zlKa#~kkqeUDC)iVuipkuSo(#>QaV&gYf66xAa@N%p;f0(ZoiFggK4P)Fax7|gY{x#qm +{#}vD;FP8c(w3@y7QkdT-qaaMGLOMHf4T*m&n7b}9#ry+i*j +tH9k)%1c!`k|Gq3Pis>g0%;c&*DEve{%3>}bG3|J%ETmEp{VaLYJQ8FKV{(d*}mqObQWCnR(%#?dWWz +Ug}9fydk19;M7q|zbOVeYhf=4JubJf-Aiyg>GRdw3RoHPl??vPg^xE&J%3Jh0~~IPrt}^yimuI%Hy8A +-!^znefMEUoTaAKh(ixoYDeU%~~%QA>;l2>Rj0Rh9UPm56chs*_LTN>J4f}!6ZTZPL-;FT(+m*D%g5D +WoAssUb6O&yV?6S+gZF2V1$e!wn$zb^isshe4|cv>7NPX3^AF&h3BVXW_2PG3-0y7t$ywYwsveIT;?S +@9P!F?((OG$@IhcFn?SjCib)c!#O?|eudrn<8${F{9&7%AywqQM1;4BQ{_Yt3Q@`TN5&o{z@RKqy$$n +X^#DG}UhRWF-WC$7T8yj81fC?t+ot*@kLkysJiugJ>h62B#$bdtzA$1CWYft5%DtGfqHfMtU;L(mj5R +1hBO{d@=DBk^*JP1%fj6r~odV4MGo7xqWKW!e&2QMuPqIvY2>2C8IHpk>+*LGz3ri{?qI}Q9SfTmlUchSaobYs7T0JIA@P;EeJIEi5eM6%?v_H4{lJTK)${o* +@%RBF?HiNT6Lm}tcdeFIaa2erPMZ8Q%dXCqZ2IVB{#`EN44I=a`?7P9L3c>A+?soHqzGm6>Tr+9#8XK +*}5@UUaku18)gq}BdLK`^e=n4tKmHX`kNZk2(@hb4vknlrNsF$LsxqM|?t*cgr_N?)wE75gAS64U}Ea +UVOhC9>M(plqlAa{_1T$Gwv#7RzGSj22AW%0Npb-+adO4U>AkkLavxtX9L*Q5=T2fMmbw>hAG6HN;Ige4L-$=a0_jmpBqA>Z|R*-ZCo?druq29BdOnVLNsLE2`l*NXt(vASg;HD +(dJ*Sgu1@wVTOX1r2)Nx`-vj0cvy#{v2}Xcmi0g?_{OeHlx=T0-7bFZM19lbtl9^Pd@Sz +oJq9zDgSUs;0_iLc~#~Q8nyVRf6f*#QSRYO|kzI;jIDvPEn^?(c!fQt+$6Qb_y@kaE?0CBN26wlCw(F +QBFt4bSV_u%|#};U%d4U>ku{|lrWZ5SYCF~>N&=IaL*MIKhH16VoI|qH%Ctj6n%=}e0)@o_;{D@`doO +4f7FTy@(byHV$bM$OfGxklEJ3-au0ZN&4fdQ9+6dFHajiXm^14ZQ5}B+DBaxe70AZsGlDq^DMQyN13kQC=NvUQe;HT8SiecDtQc5KZJBb%@QZQN%Qf4{`y!Za(QNAl(<~E2 +pPvh{#N3lCp!#*RiKi6F=h*PR`mv<kz)SZf}Vl@)m7M8S1b)8g)_-cZbwx62|qLvX6?O*~^)={m{hi?%IkRTgBKp&rGW-~0-@9TfXYN8<*lgTU +0i={kB>;#NGb=H*pZ(p~FkPH5!ZaCTfXwLLW4n28^o<0UN=>3KAF9v97w8r$--dF1`|mfT4iKb*$aii +{$0h%D3oHlE_A*F7GF--H(Y#J;Qi`rO00|HU#mO5r&6bM@FiKKTDs;y!!#0dId2^t-l<0SKy~K&ck><_g}>6q0~0EMgm*{RMDh +V^E2<9f6S`(7VAbG66+lWcF{C01)UyusVHH+kwJz23#+p0OuU&_ew$j5;Xh1Tft%kG)ooln(^%h3Fa? +>QwRbGi1J63_n#`1-oVNJ37Od5DrFmR8a^9peWwe^RFPLu2j#yI(iY9dYRuJa(q&tN^G}io8QG(G#8) +Y9f`IGt{>7|+&L&C#FukmXBh0m&P4rV=?T2kM9V>c%D7tFk)8h!9(NRo6J&8Zp5h|<%=~<8Cs%74 +^h=p$$m|%PN6qCHRJm@qXw(I++smj?KCKpor`(1DBN&2iQ08u82Tye6K>Au;t)UvVPnN~=-4yWpAMbJ +oG~}k`ir`chma8OW8o|nWgT~B2H!&1_VL1R896XX4ORpeg-{(++;j?h)KL>ZmKqTN@4I*xqH~xkkgpv=<(V`_ +!7Ym#nxAgt9hQq0P^SoTw=MfQo#Q)$oio_xYi6Tp$zZtz`Fex0Kp?ly7LdEtLL%OUK(T9gD*$z|EXGJ +0x%HJiKZ0Q9cau@l_Xtdm#C7?hCz!izhB$kJtFj?)})PA^BK!{N=tw!x!o$=1M4PA0_nt$}ul=L5+hz +#$2Eug~BMP8-C(1eDkQ(%Wg37t~$EVVdvHBVP9R?&GE;ck^i7}u|9GR#Ya|P5sZ8wPQIp|%_K_5(X=_ +V=@tEH-KIL7Zx+P5K%wt$QJp5b*;9=cv_3Hfi=WlOglRNMj+3c0`O7+82Q|oZ+EKNAU1g00!nAun{l90&>H|8%NnS-MaiL?=KF9NcjCm(y%ZqK? +Ah;OnG;7&mMU^M*Nj2B-NLDy{^(eds0K7T`q>i?8aX2yxZ$`ITtjfr)N46F!F`P*hp2 +0)GG4mwD75`=G~)xoQzW@b{BJ(_K&^Bzh*MsFRjt12BNY! +#*mY8csl+8=%?iGqgv8SGF&o)o0eIfn;sf?@n6p4%DHO_|6Hh8R=#%M4fH1~L{I1+6y8SALTrNOluHQ +)E_W4%$Y;VL4xm*GGfJo#aFzvB+PbL4!8(bmCY`%Hv1+&D71f0+S(*RyTq84LWPx?utU>0ofTw%XM_Fa@$xRQ60?SWIjqnLMdQ%cp2UJ*9$DfDqmVz@oEHjpzr0S +?=52(*gZulzrypSp{yzarf8*q@!4m$r!P160@B~N=u{r4H{y<7O0~+8M=3S+pzjbJ7(8isoUsH_5po6 +ZU!B2|%R``xkAohb2pfx>t7tU`304gvNB#&eEeW_nXneq$_w?Qj#C0VTy8RAL^dDsuiMO~xCB{vdh?F;k?ePY|3nuf;$V_Vq4fdtKE;77WeJ+ZidmUvpcV?3?% +MpC@Brp>h4cnR}CEN3m^Nu+LXSGt*@6i9%GzEF08FqOMVo8bm1}%5O=_`wMyd*?Z^xSAw>04|fmu6A| +~myq4zX?%J?`1skn7W;I5`vKcSd&fAe=4^@)mX&sL_FJ7wNs;{q@Zy%E~&t7AD$Kv9{BR*bfAQm5Ok^-b&oEqtz&cAs?0ypq|SedTl(lUFnXjtFH@>M)a*f|=yaI +Z&=*!u3Rka;sF6J@fo(xxGYKx(Lq^3XxNrz$4TgMd}3uGu#ij0?%?8<@kF +CGp#u1Qs^q938;{*8_HAEptoG90~xjH(GE`**<-# +ZY%Zw`{JIFO*-ivaDSxON*vu*M=-;G<=0{VfUNyb%4m!7qZVJ;yFJK +7q#!Rl=0AGxXQ)#@kAftfxmF_G(#r_ABel(W@zag9t9a)JK69|;4D1*BXg#&@qqEk9e=1^ +=u4cxF+(Ob~#0mM*$~T6YUql5V&AGKXQilQYB2B37Bgi$Z%gZ)RU8Z^6*5>L~p4$ypQp%GsX`bKbRQGriH`Ta8C~r|gmK6dPd7!z0D~49oc? +3WN2~7U@d|enq3d)GVrU(iy?XJuLjmvyr4!C*e6tnds>~My!W(dKrJ4ZB5z9QHF#IfejwPWm`!c*o!z_d1WUEKvYil!XdM7mXzkcDDBec7zS&hQND!-ymeY|e=&V^ +#NfdD)TLG)2kp%{vtPaN`N9Xk@rHaeN?>FMdHVpZJ9vIQfYU +L<2Xa;**jnrmuOE+BfLY=|Kj(Fvm4fMx;&6-p2JPH`vyv(?ljt|0YQv!VfGuAzjJoaqsUg>M8{J*%$pYqm4!8?`%?vbifvggW3_|1Xy6-@ +m%OPhz~EDhTy$rDJt-Tk_(x4+2D;4>Hy< +=DOIV$MT$c0`i9k7fX-A4|#Qz28;41a?b6jxbV*u4yy@%P(5SqnL57Ez*~yAqBtLBVd~ZkKcK)Zp?XK +oGZ6MY?I6kytE{Dd#=3^Y<9l6*XaK8M3|cMj$5L8)f}B%~iQYl9N*Bj^u=t|j3!B*pW&Or=#OX!$1H1XV7 +^tW1PE8uWwlWO)NiZABf^k(DnQM%Ut+Se!yk)LG +Xo68h8uR;RHYuiNh55rOBpA8Ju{%k@mY?cq0f^~q+X>Y^``z8v}=?C5{)OrLi0PtNk4sf1tzJ` +pg1;TQ~pFbNSjM8en!fe3;)k=q}Xz<#PbbVA-*>%`8TgU34~-RW(O(swaFoa{y@3HNsVZ2$I +S$`#YMXH-!2Oha4hVS{%;0;j2}bwR1aA#_{H^^MZ5HrX!42ds{~iW!(V=(s4uQVagz$I5>CM+pe#kYG +dnPD))7fr-VAo(q-?ja315Bd(Ww!Hd5Mgg}3-=HBpE3k+)NW9RuLf0j&MexB+Dn^gd1)K}gow5IGsb3 +?hJLJD=MC!{CE{$l>5iP)pY;OINhL(AH_ +IBZr8j}#+~84In~r_7D{D8fg(8&x1|UKMdK=IMG~aQM0eDxKQ|2UqE_ucQ`!c2m@?XASihaIQ)4==DB +!ojqLlGjsb50WLq1YjCgIbe_gDW=7=Tb;y)I?+8uWg%~mk*(?s2IqpOv9;^jM8IU&(B~a?AA7em%sYH +=qtXi%whnb2k4_DHhbXk+1^3>0=`3Mg=!QBrXQm`I(JalU7zZ4CYLqk?L0Ad_?c_s=pqt{z)DW2>`*+ +FEOa}nSib|!d2E6oDu*lze_M>-!IPiBW#J@%dXlZfp_`}JUBe3d0Po!M6YU$z(@n&ic +{|AL^i2h|%zUFm#8O|>Ux0U=_9TBhko$HZ^KCu%RQ{o54*0!iZiG>pQXY9FzCg%pkJxL#`NwAM68K=; +XCKRLKCr51cG|xG#qBv;ydXHhNV4L!^HB`}+kU30v-{+pIBmxBJ+EH5>m^#ORHwLuXuFl|2YP+T)w$C +e%R9yoT>v;#*w%lLGFZ|9PiI1SIpN6PqPU!#K~ORyRG__=!H{H7f3x9!fGYJG($Z`O@oglg`ZDM((imv?AU{tV +7r@gg(c!H#YoAKRQ3bkvLn|Xf&2*L@w0b7Y*V#0)oR_e0l9I7h9Y9J|=1sF6C5?Bf*_-;NS3u|HuDnT +rI;kt>3t}&Pdx7<)<+%gWtqrt&`VpX7JB{tAgd9{~rDG-}`_5`|iE|ejr^`S@GLH|L-b!760?!iu$)P +*|&Xs7XHWoGbT+{{PW+6FDI)uEBhPu-~Z?T_1}N{-=hEhH|iNw|NQszx6RQ0n40+i-Q>Rd-1g_`ziZ| +D^xd^*I~H;B{J<9bv484_Z;t8at-|2WBSc_(>1_b+Ig*I@5L(%5Jz(NJX7g)*u2;AjX#CC97h=2j8%M +iM-#|lv?5EjwZ7%)hPH)4AHy`|tQpla-2lPvVzWX5TO-}SdJs<7>BnWmi0D}A84LxkgW^?fIH| +hQ6n(rke*jtzIJ$S=F>6?#e_vW!LGS!=#_h-04+k^d!`zHkQ3_Y&gQD(tU3lBT88Uc3svhB*T9A@)O- +|{J!adYLKAC9Tf-L}uZNuL9+d)+*J!w@3Zz;m8N=Ij&Z3`E;MKXSd>_uth4>1h&l7k&EPC6}GkjKf?2$Q4ZW`V&z}uKCF0r{LZR7aQf7cDY~H8qfZ;BcV$!t +KyNOg#t-q9+zKdGP<{T_L!61cv>6AzIPI<-RPTP_*10O=y+Hb9RA +|ike(UtTm^`+Y`6jKf^X1B0CU;rthNW4&lhrYz8kK0HLmxzzdy9#0}g+l*>}bC7jmSM9|D+Pe2Y(He) +@vqW@rDEee)Y*0(Wi#ljVS3n5$T5_y(?CXYp2jJj^dYb16G++roP8wwZKiF7J{W+Q!dSRBzA7#Cf18P +T5tEx1HNn-F2I4zcUj~%KFy`h=C7g!U55;hrC=JpHG4-zC@(?wAxFoDKc@+5V{!(mQ?(ajX5OI{Gfci +Vrv;J-UqH$KWgwJ3K0dqBq#8EW(Vw)g1u@wIaKMf2c)qX +eU^DXaWf{8Ve&{J^!;}!@d&V41q=X$c;?h3X8#M(D_z2RL6Z&&8CITS7mf)J(0{PG;Qe{P6F^rTrfG` +Y?2I_k?63_58o*Pq_$xc7!7H3-cbFkX$X|OO2IInTCUayZhjr?$Gtmh-PudIci5(@W4I2)V#lJ`X_rR +CKm480vvGBH9i$$Eb!P#M4x#HHbbPXvc~@}6F1xu-{-fG7E15D+sBUtas_Ig2IWhll&|l;>sQtH*Ak| +1JSB@FQ{H7v4a9Gteh>m|AfAvSv@tlz1M~O&hi@$6lKcT;n>ncgrSbi%bA#OLb*?3a +!kkV9>BW695~D2?adD$ZT+?giXa#C`7 +g-!Ldksbx^rGk96o;K86kJsUU0x@qfCRlN%Io`&nd3cNsuGf*71ngm%_dulbbdAL@*;^3~2*GNhEq8m +yd0G?5l`18cMXyZf<>D*kSfP!mC^R=)D7X(EX#&BDb$B%vE+4A$DjP6SwYc>Q4&AtJTnU9xic)wQpL( +dv^yq)XY{j7L;?!?+bt`+LqwZ;RqD)KLb5ca=)7}M_p}<6fD!)gv7aXVUmy29H +z0z6KP8jd>F3|ol^FRCBHoK9gSP}QLGFSoo0q*8D7-~fka%;he;z$2_S%Oa+;z&3H+u~7Zj2}1M{gcB +6z;KWnB0TmX}VtrO?SJS{;JRZ^bQ;Zr*~)kX70f~c8|gDiqf~mMo(`deDuu`i0#!9$-4`mO!h;Pw=Qv +v?G_#(_8UarjKwIv6aPnlf!udrSLd(JKFj#p`ZK;Pnfp;Z%-{jpuqST%Vn?Z&`;;jAj3EC`H80EJ&S~ +<+V14@RK=>|wpw_osBYS?Y^r}TA`~>bT@tbdMPbw=zij@c3w&lldz|W@jcV-3rY+65`)!$*pRn*1oNz +6EqP`zlFS{z-Qb1#bZ6asQQz!Tj*REp({?Nzm@BDL(Utyp)pNx}B9D03di#P;s}^^UA2m+M;gOpVHwE +-=D!9H^Aeg@w;)=GiA0c$wnWTPup@$uRAg`&*9DaORAtSK%(MwSNt}wG$ZPdCn$5cO)bT(pM_oqD*oYAN~hPOcVLfwxa|aT~s@FAQs3aG0{@;zR2{|XcaRgYu%y!4SYk(i*=qpUNU=;za&ETZSrC-+ +pDb5?;nbtU-G;&S@zZneSLlReFh8_CNr~|ZSWfW6&c?*P*DNfG~f{a5+U0#R)px2j?r|>9t6$(zES(e +K;TCX2OTyzJ^IL{2P9a3#UF%9X|zw1C-3j?0z|Cdc4BY6r0?&7iQc37k948mL<|i^e#2T>+m$w=UNKo9iFTk3eEme@azi5;hHzJ^MH_AhO`84%Cfu33=TQIfCX%gSrS2QF1`!E1~Pg4RQO +IREu%!LN-b=lrK^^)C34Y~W=s$Mp)i@ +zRi4mzqh|H9&RGE@V!tm3dife={s5($ML2iL?=os+C-Qma`vZAHFZS>v~IY;jfrItKr9XN +Ut+!*O^4^XX7R;v%5j(Fd&hlc*dXivjmGaXeuWAzR$1wItAyUFV8U#V*aqx%OXia~3)t|*hyy}~2Mc% +oIXkUFWSOFsr;q1pFz&|e>cOc{pc6vm$PF|>MS?2>=y0^|+7`P$5m9)GIj=DXHHXm^8s=ccz~1(=cI* +=sVaF29$-Ah!MDLBc$Gom)NC0A{AH*x`v&75H;0uAbFRQvSor6gaU-$fjjc}J^H#`$$b9zN2z`n8Era +tX{diIyfk)%PqENf!qGlc|-O$fu8`iAjX?eE +jL#IL*#-=^{4sMhp=`)2~vb=*^w#@9@&e9Hvuqri2$A@7UeFls6~7W_zW)n@AVD18*XY43(E*)3es#7Pqs!G6F;ki2O7e|h +u|z(F$^?b$}#=>Nzx_HcZX#O?FDk?}SK%~1De^$pJW{Yu{#1pEw4B-k#9zL{zW-V^#kvK!#|T{cIcJF +1A1w?x2OjP4hW3^=%R?r%;#e%g@){MIf9gSST>@0|-cx)bqlrzg`roWDm2;vJ~`QYa6JcEZ2yU+A>c@ +ulzXh`ntSf0x}wJNk*U;RvRq|-%ZZiGBQOD4-ZV1)7uYX-E5ZN|p+DV*3mV;&XD^14BhCfQye3MqUlkA +IX9)2@h;JfK^yOg;CZm!Q;u1~h*N&lFc#I2nbdvq1mZ$hhKyQRU0s~k8B#y7=t)fg?mcosjN+_b0j0Zg`}DsUk^L$sJr-&AalG7s-;hSN{tm%GKr-))p`0`=PSm_oe)R34d( +jbrJHa+A_uq568((9d2_(NlFu%CfyGzr6mEJc9c(iNu&)o5eaz!z&C&{U)=(VBrek2a?7>4H2*p);A% +p-FiM>G$i5f^*s-1(Lo=-0ciPo}gbK_BT%ypf~oMYgd?KUkqR)fzVp2zS^7eIYQ0+&dlkJqlr6R96xJ +fUfi5pwaP4T?5tolkvoNoTEAIh7C|`t@==$a2`F8G<6=Ic7mX%knN%?l#JXrwk7kr9DLW+9G@dAKSX| +ROq#U*TX}D=DNhD>$w(S@WI>`-n6`+fB`UsVx~fo>Uw@n=c_u(EqlG2Lv$4Fm%fl=orI1$=7$Fz;B0= +-dQoosn3Fy4p&e`y03Snsxoxk_U}l~b`KrrNG6V?_#d0sXC5Yg9*G3sT!sR5DY)p2C=+f7&f+39>T#o +=&H=$!*9ea7$ulVrd?*$#Z;eB4Futb-~{iOxPTVpnTUoozJv*=iaq2U%u +wht`E1%RCOE1FW;*(_f4Gay{PQ6rhJ#|tCKrrhPUgs7~`4WQc)Q~4!*66F}r7yx7 +BEsjdJ2YJl8Wf)7*~Qft_M+vvu1bdb3b`FI#W+#J79PEs(Vjy17t(=Foh%8)41&-_92JcDj3lcU!KPJ +-_S2+^nxO{kh<()%Kg(GtPUVxr=VMgl_92mjSmo!RxlxZ713m%=K5#;>VMJRC0f#WBoQ7HGhxxhgQ<- +=3KnJmYaz-A$%UanIR}ZKWofQ=)Ln%dGu+VdyF|k`mbI(KnLmRXgY-qBOfCuS;G)}a4u_`L5Vv&;0b +C7AqPaKiSn~JSbAERQjnPFW{^TL#}xD+O?DEf*l|GVO6~6h_T+qJo{JJQGdY>(@FLbgC)O7?HyfU(c< +ZWD&Pw%D=;YOFI*6?~skTHGNSTeOp2-HE&K) +JRm`Q@fKsXsy19@VKFfo?x`pSm~xbpF$3JFu~=)61Vy!;C5hK^G7dn`eA<7iWQpo2VyC%N-xXPXDtZ1 +l6Ae@{6j_!AP>`F90IjbTqis;JwDW&Y$h>P((rHwjpI0gbF7|A(mg`#Dh)o`wUQe}&*VkASU}xhb+nQ +|+ew?}R>TMWQFeD!E0^ryyOVgy*ke_ZZT>7yYu`Di>o9BH!G~5^b?=Cu$P(u>M-lKxIxpi5iD*IM#4j +qNY*QvqaoLSV5NgNqD40ymK^lo1^3fztbT{|#wf@V_Hj@`k@Y{KB+G>*5Z%Xo-+Gn|KNZV)qdm(!A+y +mL)RFi$k%x>=PUp~PPKJ$O+g+JZr|J+5tbGc!NKyVVr@t?WgyC{A9)FrSOb!_j1`>wVJ?W_YZwmZJtt`8x;y>1TNGw11B)n&UZl>EZ=hN8F59=0db<8W{M-(2a< +8HeF_9sm0po9m6hZ?(X5kNEEl{lS}8AKCZf;qLkGk^S_|9F^`#`ORnF+t~0w?OP-FIR5J^!#!tS2jo{VSd7Q0?sr+)dILqTPhIz&;r=~P-Y}P;f2mDp(aq +W0`~q{=-!(R8cTZu`>diBd?cnEr@>@+Vq08@{^Vg#FYIF2>r})08{pNk40bt*WfxTbtwAt%PS$AyI1dvvB>vk7KPnx5LZN4uVdHH!q{!0FL=?t-I{`%goyDH-^b2ShlIxx9y&x?>Ytc7Byp~`On;jR +w^y8x58h8}7bx{)THI1RPF?8#ql+j81X)bR+gam{hz^#n$*5TS82VEOWN8?jh@wS&nxB;jj!JL%mljQwC +NaHUB31&)^c1XYkT1FNm_y&buvIa`?+YT!hdqs`nl$I*ugGlg;`)qPbu=&)E;J{Z!i&djOf=8NZ^bpp +ugcJMA780J-)&T%)p-WV*R067#k!U9VB$QZ6V*4KpX) +~)d3$-SmhsnQhd$AEm;AC!%k~7d*BQP+Y2;aFH%38E<6pXpxYtQ`n4{q2vL?r^0HCmqi!K4fL>3=Xn4dC&9tBQ!pR7Cl6jh +{G<4H8N_va3JZ7vQPyQ35~Utf9`BWH2CLpoI(_XL(5-jR5 +k`4=`G+^E|B$4{kTzSNKZNDTd-Jl9u>=s%q2J0%$qBMA_FtKX6!LY_#N +AP@+JArMAj@C3pbO#U>dj)uGJEk^D!kh{T>d +cdjxvhh@Ey*`O&@>68iuW-EAfj?1C}LuS9XvH|gSDH6QIQ;?TRoEqHH?-#PN_V%u3ZGasXSb6t4ar?= +DiycrRR_aWfB@Gg2+O8#Xh>5R!KDyYQT8z6dXmVszu1(xLZ(cv=_$hyEdAkQJXM +D+Q?orLNjl^AqDEANsziE^1E%A#o3-EJkmJiQ;Go!PxQn$~*J69=4;3?}a9Ppu9uW!cuL%#jP&RP^K- +}Svj?j&1A@HVsWZT4nnKeow&{#|qfplYR+jV}USdxT=jtr)J>Xpa?d*OVFgQ&}c5gsOSR+P_g40Nxhg +d{>^s+bvYl%7rprenw@?Z=S*L9eXCVd}`qWe?<(pvM*|WfeiE|Uoi0!oZ%)+L`LOD?g`u{kX<`XmNM# +`VEua6tWH;b&$+srNr*&4^rN2uU?iH +GO%8^6cLn@0#mz#WqJHM7952arw>YYT2hEf0?{KMvLA%UNvt<7f_mzOH5YW;kfnaRCOY{2jgcYMBv{2 +0!oC@{jSQf)IVpGNO!0L2W)HXJ4Gz>3a1dzf1tG&|9K4t0~lHmV5M&N&Es8 +3M3i$D?W9iA;s$B);OP%#Kuo>bjmmXM}n_i~zg~7>|X%v94llFMfzDP+(>k>bSimz-uUHA4 +OZV0;Kh139Giq$D7SmZ`cHO@5RtvtlC;xlVjzCkw9oe)pKVwSLsQpMQqy@ZvkCL%19?f%WSJcakaxN= +zonkoO9Zxc8T_s)Tk#PHS2@T<2do>6#dk;}pn4TW)yaC>DjSAh>9`nsw|E)B%UO@{86~(`nSuiTEsgp +!1!i;b$#?{?``3oTmK=;MqM=8)vzv)Ao)vzWFTE=Wk0U&NAiiC)yxo^tEgP_@EgA>oaq`n55=()FTf` +yx>}qC#-4sqteXxV}b7m|5`nFVV>7gAYSCyUc4f#9_eudkmkt%(lEPeO^rOR`J%uv^MJnEb8WYr$HuNzbUvYlx8!fiXZU +*{icOj!bf>H-vF7p}f(s{S)s_Y}-E8j7AZeP6apW18^LHK*%Khp!Sn{zTj9G- +&`Sko(#vl@TMsHRcSu;$voeErydPM;6SkAxQ$lm$#J^EjLHtm?RahgKRS1@+uq1dE2dYl@Uiu`T7sH5zP10=0Y$j#I4_l!Hq +=!EAbH@Oo?+)CFFcQrQWJKW6i2@f?fshbw&>hoZ(J94FgDe-D_0!Ync6@t19V9hk9PqTDe9=(g#V1BIC{4 +m{>IL*kRXG})H%OE4Qe}Urir$>P3AnA_2XK5io4GIU<}P;2@V~>lFQow=bqDjz1#a8{dk*Ql?2Tu9N7 +^GBr%C+CFR|S0{EpttkI)40C2+BqMt+eZ;U?w2>++W1X2VV&yh877kj!Qu+wOGpiEe@aD7^hdx4^I9t +$3%RPk75ae}uPtA?J>80r~!OHp!nR?PUuQP13`vxF-=h_HlX!?5xTRCRY#mgUYc@$esp!yC%z0D~%yyw(A*>Hl +@gOojWVvx_}gVsc#WjI(sI`3*0jr1hv%Z*))v(njDt2`O6Lb&Od_NcL=dIZO04LKCi8aun#bxJ8qX#n +Clnp}|Zf@q*9ci?&TWh#g3Y{Yk&wUy&D*UVt)j~yWu4*`N*P)*0D8TU&ds55y4&{S$~Mdn^&TB_EfL1 +p3sS|Q8ec%XuYe-H7w$*QL|%G(_d;ylbrqXptE0M~1zk3bRE=t7iilfL?j7d(z01ZHkS?dUUUGupGmm +)8pdf!M-k{@sctYFLfo`&>|AReEc-6c(17haBhitEAhQ~UG3KGUNiK +c5jfRsMLAzmgif#0Kb?`z;~FmndltA6K8f#Dx`@*dIAr}G{@)$6ujSgB>XA!<)82_32 +)w|cfZP6*LP8%iOYP^KRY1hY+&-+&-Y(u{MjFq^!({Wk`pmoe+dcHGhnty~hH-82n4B% +8Kn)x+6_BnVr0PXuTxy5mr=!>lssp`>T13f30)z$wVY#u2JnmDo;>PyzAiWbN)!AI))dTLH8GI;*Zu|C#)b?U#ce +K&?{L&TH3whN5e&G|u;f^pOYfs(qnHc1#Z8_0i3XEXBF18ej$#8j7xOGM)@l>MRX=*N3e~I(yWCG2T& +=%d+k>+vlt##2b_i;h$m+XP*F`aHfi`#@v{w718+e-8e8|D$}|pN;*Rq5EOncR +9Bch{Es*#kQ3e2Qg^-|ECeZ@ZF07L3=)o4BkmMa_6N8-?%A)_J|pV?`^PA^ba`rDVihRTom}}A1Sd@M +ZoVu)CAqbdg^P2$cJd57*lDcxzM6Pv8c*My +xgfR+Vh7+GzL7g`bBR62RHQ6?-HQj?7MFJ_Nt)nw$QoM$OG_A$&cW&Ub+;>#XS>T3fIn9Dad0 +*p=J7na(?EeDDwu|lk8$XwQ{)t}PV?yo-aw+Z|)Fts;EQoHD01Inmjrx~N@wP?JD;g%S)uFgWrzJ+nG +|i66$pYCtC9e%QcvlY98a%oo-WovF_1FUH84v4&Lkz^CV2HDxOiMu@(MvFKA8NZNul8p@d-}-sWUNTO +r#!gx;c26p-qNDk-I#+pxD0OFhb1;Tjv%7x)m8E0s8RVZcx4YsQI)K-9xyJ=YL3KXDIwqUt3 +9&RNGVCw;bp^#GH+IE+!fT!DyL +yW;GMzl6PjJ}5_^gUN8S7+h?CPPOu6N)WmF_FTW3Q`DY2KpgQ=;g=qOym3H&9H*ss$c}G(?L|0W&LVF +_b6qMQZ4!fnGKXAk~sha-U#!gwm1$76wi;jBEluXk^E8R`50 +M-9$4~^xo`;Xneh6s~C!_y!l1!(m5Km95~XdvlmQDG4L3r+Pb|iXk@o-_?X;2$X@zi*NX#wl^ERff`$ +G7)r%aUk8!9`&Of9!q1`vQdBORk_8OSP$1WSdnD3hoU%e50sZE1ANko0n +AS3-%6N)UtUxaRC5YZqJgdnSA{TiTRKv7qr*Ki@AG2ee0rd#!xJ(jgvHR@s{#rzQ;(1}H?(Gwmga>6P +mOqbwM;yKmla;=fnHdV4zWsx$X3pLurK0pbjct#UYg~#fcUs*z7mPobXi)=jKkbDoxGBnC)=gU`DWP{ +0hbVxtl|*4<%f<#^w#DNcX-Yc`sgMGIv!@>Cm+Cb#t%|Gr+E~-)R>!a-$=A&QIBS`< +h60TGr~JLmpSBn1aVOh+Yo7`XptYui~?GSN-n6BQlL8z~i;h+>5!QX8*3z&g1^NhquSYm-6!3NrG}T4 +mzkJ(P0lZ9z2#zmt<~8;gx7h`rv^8dBjay!(CC_%2Q5}E3VjqcEtt~H5LIn-lbwD6eGkjD%O~CTAzz` +s8VDuuf&G`03Dm=PSP6eIQdW}bj0$|lnj5qB!PH=>m|SsIYBlco=DT_0F})h9INW0WxOi=N1+n@H=xo +V#{L2-eHROZKoo}&6x^^jLLvx4z(4O1g0Vdol!ou7;5Tz8gzuQ?gzhvP2=QhJMfNdB_zw{IDO3v49S< +ep9;pi6;&91nPgCw8G;%+|E{2Ql1RbZhCLc@4H#S1|Sk?*N5g +AVIns(t^UN=tv5r%v0D|}?PPLOQ&3QLLV>GW!K<{Oi@D?9@S)r +0OUB#7RWJ^dn5J7n_@n_KoJ4WHABoTg1MhU4SyW^wg;&K^Btoh?!w{Wk)6DjAbSopAH18E(}j{nO%#8 +hQ=v!Bzzi?-GnVHLUt2WcYv?866mHPBsMMd?iT8aUO +xBz89vi8D5t$QhJ9UTcZE9f +J<~0R90geN&O{3tq!EH%mKbHGXU82osR5?lTci*jMKj$Hx)G(W|Wb*P54s7o(fShF!O%4rwIsiawX*a +zbSxD!S2oQqbzFq3E3P)- +$B&<#)b`5|-Qkhcw%DBf!kS^`wGaVI#9_X)ybzxmyaF>9}Bb~DIa5t3K0U4jN!bVnbUkOOn +mwke%qV$b~_AfUoUK;bg(_M5$Th)i0tHLkb^{>wT_8k$WM8%Ewd{gkS+Q=J=x1n_yt;YtmR-JxD#?-N +KSqRI&0g3}?scIk@Lpz=%>6V!?D4CWnw2gof7{0kSo>RMy8gY}p;$UIn$D!#EOwV4F_P+gJSmt?as%9 +YvPyJHMj1fp-&e9tw{z0wnAk-UtaKfiPcxLA!fT&)lAK&VAV+R93rym06ih@r}+vntRPe60W*`5y+=YYcsetJQxacU` +_(VBi}rC>FKs2^)fOuq!Y_aeB$p795R}p7q7~+qWU +7b^SxK^Pzmt7=KwX@T}1o&Cq-IQ_tU=trGH=YCrtV-^%n{j24 +hHM!$ky5FceEM2=Y64lp#Bk*!AD?J;Zv$76`kCk74M(*GFd`)emgn@nf(*kl)juviM$={%rf9k65w0kyvzh<&a+ls-JB;65riD=s(e=Z}^PLcPAE#{gI;|Y2OdTN%9?Aq3kXSw?VB9_w4R2WRLYm +Kb$Wc&f5SG`Wf~^`vd)t@JK;cp68NpJ{C22o$&r@!u<*SF7R`*8}Yn796$I20@HM +~T~qMdBX{zPVMq18BOy97PiT`FtaeiETP0+7g>+bp;0)~G0RxSo^tl3uxn6Sa4Rs6nYi0U +jhz=nQCMDwmB*qg;}yKQXzl7r1plj4fQ*C-p&G{Codow#3vyua&?c)PO4e~ow&=n;=_=stqyatNZnM* +>!e+Ba?yqjRHYrf^n^cQmWG4MZ_)7Q7V9z3E8rao0b;bs?k-wS_q`BZ?&!SX}cWxj5i$9HlIOnc8_QL +@w>lQ;`j3Y2XZk!N-I7z=TdeJE7k}GFEq1-XM;=uwAO_fTj$qGC*ar+Sw2qwS0EeCBMt!GV?alcy~s; +WY?hL>UJ@E0JVzsTuU;rz==Ech}L!*pVbpm0W)d +R*((mhxR(9xo=HIWiTX(*@npLZa)SZW!$eLSy!{^Rhl32)iD@28!U?1fLx`q&tY;ikXN4W-B$9QMA5O +fgfF~n8<1U?If{{-mcnGpTZrHuaxDr@d)j6$5sK<4_>Q +6h?o7S~1AoPaj`J$P{z-E}BAwm;d4ym6@*dp*$Tcr+z_7<%4IP0;FWwl|v*9ET}t%qR0WaTipgLdv?C=L2+JZvv% +*)X>U+K~;B;;LR339eR~Zq9yxlEW;iGW+?+{Rpc?cBUq~Maw?Ud#i;;_Z8USFb~f=ieKTB&`+<^yjdT +rquCf0sRrm%`w60-h-X{Q%bv#ZN~gjORp^^b-4@04!o3ag7n1fB{D#CuYC=35qriAaxAp}^zI09ecGM +AR39+irZtSZ6O7ym;)i3NP$1wEGCTqk!7ZKSby8g`eTLD*9=66pCX09o}=b4(Ae)HD9Zv9=(6@6*&HN +9Wa0E4{o!I785XgC6X|5HHx-{Z$jO&LyBVJ`Uv@`}i(I;AyVi=i|Jc29apznJt&Zaa_nU3@>>Gkt5Wb +oKIAlhaLWE-e}y8_wWkHUV0(vm|y1xl_5vH?PS +Lz>%XX5vP`1K^fh#S;SZ5|n!bk-Zp5KUYQWCDcK-k|tvkM4d9_l9K#B!GJ +ZIRy}HZ#`^1<)0Rft%q&M+t6d1yX_;{DpdQ(Vp~}EhPQ^KeFV`y(yiP!g|9E-&(KAngRh3pHYb0kU;_ +jQAus@#fgl3Y1{e@spxNLv#eE7kkc_?M_D2uh-f{-G2?!m~C-4SJ3bKjA0Z;t+jSP^LTLYgTaow|vzL +QnA|3G++6$kl{9&SrFTmD>7IyScv)~<>C#mx|4o8i6{9t`PAut1rd({?XR=Le^DVk|rIU+D-xOSvZ7Z +E4@)Js;V31}OH4w;ddtSZ=WdH@=7)e#DSO@^)W*F=c#4VR-B{3V!6}{)4R%d@W^B+=(nod;V0k&-C9v=+foj1)@lOq}NX-Ddi%hXfiC9rkv>Xt&4ucl3P +RA~Z7?<7lDVygC@frej?+srMLzo$Hz^@dICk{257TrgWj>!uOGQf%PFmAGg^Ix5apNO*dqp^{V$b(q+ +ZGeMfO8K5f&354N~jk*i9(wNnU(8w3nk)BAmPFxYd56|NfecwfrOG(RJyVe`<6F6SZhxypP?wJjavwXxgyDIMO?F9{YY +Ph5Jq?Q(^+@&l0z7l*NhPbV|Pu|kGYRY>BGlh(}+j%`;m5;x8E7Pdvg4MnP(Rt-LBBpMz;7}cV;%TKP +?|MC6f5L`CKSWmd9GKu@?HAqjU+@zCo4#$*1kWV4Kd_h|Dn~Rdp}Rv>huR>7SBsA$H_= +|K{cJ8mJnX95}ntD7UbU9mFd?CpbDJ<_F6m(4N5c3iAtxCAVsNik`}rvZo!O=Lm0@%0lrPqvscQaa$g +?1z+bW+W(mshLwF>+B{)Bu>O@O7IefP@*zTf6II{V4DCnq2ar;g%x+GQ3eL3jUS`PSFTWE(VP;Ys@J; +#x5ov+^0Mn+l0m-HBx+*r1h!uTQHi$&rH$l#e`_^64H{_kZad>;JJBm70C=>k+AnE$h%yZ`!e`R|es| +DTHAat!~s(qH2isox4w7wqo;r1L%fGN<1i2eb%!m4M-;YmruQBrR4pX06Nd5>EDym8QSsxw`0?DHUlK%E;Y +JKDg6omXG8f#VktGa?q^cR_Nte%-5>iy;BWdxi|L0U((HLB=^j%^7_0fKAu^j6mxMkNOOp6Estsp*Ua +6D#lPzOv-OVToY?l~pMEr$@=yicO^vln>f1wB<{`SS9PO!%eI@tUUcWMpkyWC%l6X-u!Cli;wRf<@}r +0Xi0AkDiXY6^OsXdmP6$3lWoWIj3WUAILI6&vRzr$?k0q@uF5fZpk~TkCvRm(xI3B(}W0_^q9y*Jacu +QMnH16+(bsxK`vnvGBAUI3?tnr_o$dx9PePu4w5MhNG!+1{@Z^*ta+LHVFF&+^x}9|Dq`6%c-LJ)qIib8?jOupzJLHpiv0A}*3sT=Z1Hw$LkL1R +d1HbK|~dhKi%R0yN}E`2+No{63>eoc5C|-SIu{GIkf6HOf!L^lqS#zmzXJEf)wg)nWqWXEW%*CT)w#{D_ir>~Y@Cozs_)OkCCRaa +&7mArJHcPD`m$DR(5OoByJU1q?}`I>qfZMQ}9ceO;@x$he~*KJZ&jTzu&M(x2sA7xD9z9A&Vk#`@ae_ +8OQiS>%V!RHlzAV_fOVKff-Rb6H~f?MLg8vmU)hHqaEKYy}KPRBBnq@6Bvk3wLzOXMN&l-JpQ1!DJI& +2`{JSnX0A&II0384T0B~t=FJE?LZe(wAFLGsZb!B +sOb1!3Ma&&VpaCvQzKX2SH48?bT3ifWeyWq~Z76CF8MTP*Kg6x9MqHMM{4oaR>$ +)O`}bC>Yv51jPuxweV$mc?~c0X%seLq@AbWa~e+DVOn?{$`3Po{_4iI-?JY7JsqicXS++@+~J0f^)yO +VjFT$e6R-TNz!>* +8%@4#~09*$LPPe)@scVx`zjECAzr>lYb!wG;r8Z*rpgAWgQFs8RG#vB$0gR-RKYU%`^P)h>@6aWAK2m +tey7DrUx#oRCg006xO0015U003}la4%nWWo~3|axZdaadl;LbaO9bZ*6d4bS`jtom9b&+At8k`zuCpS +hfmL1(ym5_0aaPhiWUKo~kM`juXrp+iQVqVOJ(X6M6Bi?+6rTn +$%MHEch(4da2!*CRo)&TcU(O2S_V)DXFY=0abHSgtj|Le7@NYpdno#rh{9Qo!cAk4A0fn=`&tUn-v3khGFT{av!LX2WU?wk3u +?x*+W8n@!tBZA2%iU9l`Xxx3shmV~H=i#CsZMk%2h^j(hs1{xw6MXrdY8y;UX!!O_R2sFaoG^~-@516ArRc8IRfD&YBMgtbpf5_oL>lu85OtEFB& +-fqy7?;jqA`yn3@C$Hz-7|XF>$@5;8MX3Z11dmmPFquFP-)ANTuxi)wO_u{KL2lN1_QjwHP`jby?l=JRX1e)7n8N%OX>IAw?E +=5K4`IdR}Z(`pzLiQ2&=UeNPkP=japw7!_m-m0sx>xxRP)h>@6aWAK2mtey7DvoU5zOBb00 +1XL0018V003}la4%nWWo~3|axZdaadl;LbaO9bZ*Oa9WpgfYdEHyvB-2e=)&=?BQ;&X)t#zUf5c8w^sTs)qPVN+>tLkVmTmi}WUcP}Ht9v7My4{NhspU!-qFfeQ?uMGj+g>>>=7N90GPsBXoSHpgP-1zRIFwxkHi?S|^frXckZ&<#I_U;1+VaY^5Y(MIvG +olb%zX7)A7WZ$j_Nv5IkON5OSH2N;3<=ymNZxkUoY-gise}0pOF=cg)Vrdj{;jU0#!1RnYv@xSiR8X$ +ihF5yLv(GeN+r!os9feNQAwb%SB(^h2ib#Sz~XGzvS?62jOa#|;frlQ| +GKH{j=>RvTP?R&D&1aN?&y>6TOm^1ISl8tRJ9cY$9#ox8sYn#;yoTrfoP~`%+HsYfKq29}W0}nU$;bO +U^HIbA$Epado+>4^?blYiF^b%+OsU3(YJiG%-JBmXAiy(5$i>0_ld4althTX}!J>+iFnN?^Ln+$T09h0ll7>> +^z559lJ^U%JpKU;Y}(%KP;Pet7r4l9WEQPr%moW0qWy|iaTJxRXnNJ7HuPG_k6^8AEMTRu?p_ZiFOO{ +-w2KYQQ$z8ju-XbccZLJqVhr(EsvR2s?dpRA1PtlK##0=hR)D)TM$a +Kb&kiRH~y1)6ZZDyvNQ#BqpnJH?sG?$TBimFOyf0W0S_*m4@oZzQ?L_wK=vWr^YL+spxA0%jjj+O$;9 +%4aT{RZixvfdTtBbvvt9U$_8<^nf4`aRE2p<#~R1DEj{tUlm4`MO}j?gI{Vv!O& +S*FNbu!QW5;bM)3I{O&<|FR5%pJ2v0>Qs)Zp$cmH%Sx3i@t^%_7auoDY~%qX4>Wt#0qz!5~oAM~h(Gz<41eoevmd;;K;IXBB+Txy6Pt@u11DJnBvTKy#3Y{M75Bbdbty`gZf7& +d)o9wkE8sN6kB9R4n>7wuT!cka>Y~#T6#>1W^f{76_;ii1rd$Q*?$wFyPdxN) +^;H{NmD+1&0!1iKY9kIa?9fSgk7pF-M2;12@0Cylli^?LEr*IHyIN_vjKuCfC7+dy0c5SCIej4kK&Ty +XZ%{|W#>X47L5eJeQI&GbR|3p!Pdj6o>YJda`lBFoC5J}V%fVIeSTTZATxgb7WjtF@LnEH2dP}S$;hw +H~^n6A$%sPn>U`2?21YNkr`jRN%Uw>%5&+Z|n1Fp20Sg92x<&d-+2*iMXWaZ4;ZXY +g+2)+g1f|^U(k{kO)HDx_i(rt^=B$)NyB*l>C8%l;r5=TL%Y +(S78oObVOFM$04E7?5IyH2->F3?!o{yE~Pq2me~@FEap7A!Dk#7P>~APoh#!QwgU9~ZLVTZ5<%#MeVg +|6wr19NT;%Wpbk6$Z3G99bx$_7hl$OkOo!MY~pcf^&^qO=wl05ckQQ?761Woa!2sCPWKh&_FkzP>t#mWg^I#oV`VS>JSYz$CVH&{DfljK +0eg+4~|W;;XUYg)Z0R=!{Sa!I=iwlH<0HrSoaTA%R!meg-yE!V^r(puV8)W+)th_9p7)~9UNlk>I<>e +tpEB`ylXCz_#Rl_mf<7<`I8Huww*GM>^Nm{5?Ax`-1Y@I;bcd@j0%zq~22gkN|+5}7kEd|-&-Tn@NC +uo89OV6_2lv*3735=jC+J#q1PEao}%lb8Z4KZ}{sPvc!wz0g)EfMovd@cyL4JRVB^djK{l+GBjB=jHkP*c%Etb!fGb&* +@Od+Le#{0>oo__Jh+!~oJH0D$nJmwUvuu>z$C5POYRik~B;H4%Oa3_i)+EMo$Upr7N(^Wuqlp2qx4c( +Kw)(p<_7a$Tl7Vo5!T}Ov@C0*yXC{1|*_xE6=WUFef3!6`{;8d@vpi`o* +X+!C2r-|#F>ZZ7hqL|T;x)KtpBg`Zw?mF +>K>=bR_+v>EKo8K;hcZ3lzSXuu +n59(bH(k2P&#J;qS62s{Nh{PzI)q-b&UK^gfkQxnCB9icF^qfzS_1&WXD{%OTxHo26k3Gd;(0)nDp2_ +T^K(1%)coUgzezIzHEJ!Kwa`x|hiRkza|!RZ>BTxc}>*G@ZGnU +MNZrlZyn;-rdEt3YKo^&5dQ3o$w;Ad(GCj&V2%PS1uzfn(;QCuXj;I!ZW=jCXKWsjEc{9Km*V(`y-yw +xkeJX;@(Ru#Yr_HDMH*nXoy9lgpab!#Fnu<1$*1XSrZY%)#Tz;!#iIVMur1(S3aT9@)Ks9s<+9vb(WZ +8q{mL5mGq7!cs9vh#!@viQk|a7j)dz6{Y;|8+FOmsZpToSrg{&E($z#gWU?|2h0%g8tIf*T%*i+rm`k +YQ#48a{CF`fuPS&!QQ9+$=U=>y;xKh5Iy&|^Ff?T%S`3x7J&Iqxb&x4mq1;QnY+|EBBvBa!$wiKc04h +EfM#U{EE86?5FH@Llgij|mf9$FXKI=L8B@yUbt~r4KzhdLNCr5QK@)xLmr^0;h!B&x +~ns~Jf)kE*{OM8mK1vJ{|74r(scdFNX7+pTJbU=UygP8GnN;6*AUC*Jbix5kKN9@s6rZFe@x#>dwiS+ +O}hibOpvmwR&0olyq+6-uzAB!JX&zdB!)JT_@Ts?M?Arm)O+Up#CC5^k%nYa>j#oe*$jw0pfD)Lt?o) +T{fd2Bdh__GCg1m8=}gz!f6&=A5|^RY=IQQx!95tEx@NZDU3rc`*d;fNkz7iMtCm#UjUO1$~DEg$3SOP*%lwcR4~H@#};H-o +XT=O}H6d0lajpPA)^RR_&zo_NzoYj-7}Wb_E%P*Xe#1nXZN$w^l66?c;Isge)5)b7aniki8nknn_;e9 +8|n-Sj%ca?~l0!02Q{xQo3Pw7~_qguvd@vr7f}AWWScs97@POI=5Y`{^oChBRZK{zCjHGw=kJENX-xd +>Od0XYQ1*O?VnlN4Hmk%FdGnsMmngDkB8#K=Or?4)Sy(0;v7quKw9ZcO8kIr76bOjM#@^OdXU->H|D_cTUbh@y`sVuml`L^sp`4u30HQbldvW$rFJrg{ +CZP3%|qkqL`(c7ylc((*E2^qpFu%bd-QZm4cz8qag(9+;-mK#cM7G9`88xNUpei14lNch|P{B5u##r(<|G&yBJt +_VeTD^}(XvRBcZq$AgkGM4pY-3u<$Ay?7zuy=OnlK0-Rac=^)p6T5)Png2e%9YB}O@TGyC?wwa_#bG@zfFfQ`8uLzhsM-!_y! +W2u4X8bT@?WSs_Uz}>#Lu{)i>*_*Xyf4i$A=+%}%Xg|43^{qA@j?UU$?qnSYheyF_#G-29J|gWImeI3 +~vJh}+*leAd!QD<*xHQx`JwH`Z0TkxnV64$1x<`9~g?2satY`@gg`LvSja1I;pWcP +2|AO5;3p~x62-Rau)>LaQhpq4uX@749KpLI<0I;~k{~<~HQSgRO-uH(&=Y%AsHU +f)kE#x{$tj5Y4z2zYRyoU)akCV6K2e(3Ht^1HPLQp?4S-F11~XFT-;rgKuiZuSoQ5Lc?>H(0H}uQ?nI +^dPKRlHafZc;cDrjYHrgtc|gx%(kQN?4VVJO&@_)(QxY4#AsQvFiHaNEV5SzI2%WkNo}P31>(S9pjq` +jjJk&FSWG*2{7cg^JoVk}8YzlA_8J)MCnRESl?T?3_ +Qu2QQP)h>@6aWAK2mtey7Dv(^96)3P007kq001HY003}la4%nWWo~3|axZdaadl;LbaO9dcw=R7bZKv +Hb1rasl~zr2+At8k`&aCwhd_q-(o2V#9@;dWW+rJfg!T%;T4NPka`h2H5Bcp~$(F%Dq2+=RyYIdIl;6 +Ph)iq>_3%MMFv-$Nqf085@7Z-`fUk;5mDZXS_TcM;$UJpM>GA)FGN^w^rVM)t`G++w^gBDZ{lNRU_wn +%Bik!w{!TC;4$mS|F^%Tg@f?l6L=YNaiFnNA;XwN@IKfsf2!caS7WRx)EE&297@+V_KS|f*bAt<7PNnTQZV56K4NNr+LA3!+Zn8R!)q_DHuz+jn=;EL&`p|7je ++CQ}#S{>c<9k~crir;vk9@fGZFmJi$q?r3(rlzFe9Ms|`W>lM_u+a?OLqng|svca%Hdur}{Er?c9d@4aQ!vA<)g8(RI$9%&4luTz_CW?Sz|gX>qneIsVQ!R^R6=q)3$|l>3h_~^mrVn<2fm9{d#h70Pfz#fK%_T1g) +tQsDrZjwMY9+O2`pK2Ap5kLryFLo!jGKwo28*yi?W2w{{ahSi(ogV$sNyMk1VRR)!youcMW#JWrB=%_ +JOn=uOn59@$IE(6azmKXS-Ug-h?QXUz;AsKic3>DeL#Aen#CUC2rAXNl_KK%Lr{JMU0l4VL5sfjRbxu +e<#MlQK=0ja1n=;rj^MJaAp|@8Pu_|RMrwVtCW*r#rw#54e)((?*$8LjFX-HOxurpYri9O>)`{a*ov6 +?yEZnLQV*nQf}D(L37+aQ<&j9gj>bKt2Vo3V;3+GxVn@6aWAK2mtey +7DpF${k)3-001-t0012T003}la4%nWWo~3|axZdaadl;LbaO9gZ*OaJE^v8mkx^^HFc8Pz^C=E}Xcg` +A5PTT;Fc?hOd=sg$y|%%cbV=%vv3>Skl2+}uK%4e1|KI)ZGKTqd4w=e@EEmw)V*cPFjEzPkrt!T+V@* +;ibu{dIuo&A^!oW%8ZH>@qbrv}quoXha8-5VAuz~`G(mwdw!N9}7T#Ut2!r0@Pi<%#Z;S&qS_Ir({QP +SXkzhFRXL;5}jB}&xXVh)8?C*VCf38oo)TCbnqUA +S8HJICed{_1T@Pu=5#>w$(Bu85_f9y;?7BhDDf)lJ$jN*jo{%;Wn$hm-vX6SpbAB&AH_>m`;x$T$iSE +O8u=m8BLb^lLX4FP?Bp$r(h|_9y9_os!4SSl=#8i_ZoKU)T!f1NQwf;hikjLib31GDk;%Azn!QPR@`u +Fb=>t3rD?|NI!&X=4Rep$`j6d>;l}R!`CHzt^g5N!NBrNI1`=|0r=nYs%EAlXz>wU#>ftvH`+d71`U6 +l)0|XQR000O8^OY7y^(yW7<{$t7_;COL9smFUaA|NaUv_0~WN&gWa%FLKWpi|MFKusRWo&aUaCyx={d +3zkmcRS2z}eFymCB6cbh|mV%5IvEt#{iblQ`Fz%Vi{5glyInsU=7`-cIjtzxM%v07%Nt&duFvCb5N&2 +jJo1eFHuc#}AIhs><^6awghlef$JV4h{|v4-abj_g1P#C7UXfg*x~z|8sC~ew8Z$m2DvbM%ko!sYG)n +#kS5jX?-iIi(loc!Lqaw+v-Nv;++9XLmcFrZB;kWyC|S#UX{ueWoaXud?ODI)^)WJc_nnk54Vj}XK$w +BL#f&=7Rl_*R@NzY=f=rZRb4C7A(QL0Et&-t>ISN*+f~!n(zbe@DtT5aS*pCrck)HPYV^=a+BR3F*^l +SvZ+}QtzIq0Qx_$+K^9~Y!{WYx@SiQ&q(o|f^X2BJUE171po(lNBy)}i~@D=ZxEQOIqj8q-IXu*Gt*0W9R(v~Cvbs@?#C(=h;TlNY8lbWm~uHDitC=at;j-kC1(fq>5oi +KD)(>k1b84il6S3pd>B}_+9R9-6vlsE8Q75Pf4sh-KNswx ++7u%`kJ3$~Ue0W4Fb@&ybHOP^Rm-fYvxUl7wLZ1hyX?AwyYrr*`J$Q$~N>1&D$nTiWMpM*Am4Cj<*rW +V`V)2UcprFABu7tRaXwmFbwx!{g)0{!`@CT&`^K;X{lf-eULM>BB_oJPq;RBIvy!L7Lgvz)wy!v}msq +@{pOs5Y?ZRaz9c*nL}9fG3q+0Qah8me;WB$-%pqFV5b*e15)ofBx+JOw27704OlRoy?}f`y7eKCy$&q +>#8k>+MGIVDqxcJK%2)-n?~Y#fr~E8d<~`ODYmi|0Rnc>TA<`?LRe3FVJY!~^*6^qYgT^Ox`Zx<5QRJvbmz%G%9VK?#0I=*z*u!Kz4=GMv +erw4d|Oc^R_^n9OL_e+HbxoSR$v27DPP8IA@}P^@IJ)~)aZ!r=#?jf}+!G!k%_fo?^sWI~d|w1mzuos +XZok}Z5UwgV^nQ +#2W?qn^$nwFJ>siYQ8ctpLZ}^8SoxAYW}{b5&&)$qUW@;pnCt6(i&KQB7Nhc!qijJOmCK92l|9l{QVSAwF>V^33^OmR9-Wo>?2t!%+^ +J8!TAbew=eASBU12gi+;1H7bydpYRvik=AsKCkpZGdq8jT~;a-&JG=xdT*6W9VJ0e^deiQOH*b}q2pW +HPkzR&2(+jH$>fCI3D@uUk2BC_>3`y1B=hM@>Y<^#4@!PkzT_FRJX8HYXKUPke}a;xQdSZ4BIp3(#Qy +{~3VC0i3Qe5+1D~JaK6b+xhQl(XxITAHJfMZd#bt1zJ7TF3)6^98UZb-D4@v>AGu(7r1yD0jC9{q=I| +mD7J4YZx-52@EC$E8)5{w8NdBLaT?=l`fa&fH||gU^tm +2$m9!Y-Z}(s+N8&|QMxbG)NZ2qPm|w|^pQfv3IKbQ6$Dn5mY;##5o!1p?#uz8V5q-wMf@GYj?O=U4_| +Cz#`{}m&PR18gyM*nEFs8aa?*KgB2Vlx883GbA|9;0QFWB!q+;Lq( +L*G8d>7l;RZ_CTtgF_rXb`3uKk=Av3JA}?PF`PNTz0X8#;{-LQI5-LQ8tPm(NQ_IFU$cChQ|~(jxFx7 +LVv-GMHD6x^l6swN(rd?W60g{0uxM_#(6#ZK_fKZMcBYO3b}C#5u#8d9Ox!{1EB<{@p%L~Y`nm=zFjN +g{c?m=h92Om7WFSq2+yNxO1eEv+!dtS~K)9P;Ab_w{66(zaf%#o2$m$}0+a2;Pa-4V?gxbng4l4(ybd +!VWr2)fciNmkdVI;m1F_pQD#ivaidFnb9ljp#%(b5k{vzzBf0{O}893f&@FK6JRQmPM9er^aPv9v2h4 +_1d$9+|IRBkmi}=$Gu=3+ZgxwwAlRYL&B*fNq?yXk*a7zARf-&)#oCAk)r2N) +A0M?uKT3dNhq`h64)x^xb4X@T8>WecXCUsK1&tt>@H2EI)W<8}FGzVa>Ns2K9^!lb%hRRyVQY2q18TE +Ph3MR(UYXjSZ@DD15Q2iIOCaZ~e07C-h(d}6Fb#RI>Yc1L{2A%3f_3>ByS4a>@qM_>z=W6?zX*WLyh_ +c~W~A)`O_4u-ZHfoGusjYr{AO6?jOrO3ziVX?pjg%=K%iEs4-q-ptTQj5IUJ!Bkf0ZDtO{|q)_S=f7? +5Pt>8T(qL~6GZFa=P(8sN)fTcj%=Bj}Zy(f@SV?i^Uej(vf=%QByd2bVo3A!-oyj-i2r5ce>HK)nYA{ +lGJUfdgPBWmdq+M12S;aZ0ArM37eEb<)8Ff9zU3r{ce+HBQ6?AcAF*9i`1SmokVi2Wvs4_aa?gb1mT< +I2Ej`1dY2@>7}$s0Dhm%%!z;c^r`X8ns|{@14SU@Y#_-T%;+yK&m-WWS532>J$#5iF7h&|>dS|hvax< +J4I$B|EjH!h*%BWC-lwMr=5TjL@FFksX0c#aX&DEfs5vT$T_GH%pv0&Jekl=tP)2%(U&Is>6e0lxMSA +PPp>Y#}GNfuMn#?+O3pNW!w}jkmn_JpcMVm+FHqRpQCQ25fYgZ#o*3~^{lraanF@N(~Q&EU5=UH5VA2Zz`9Ov_fpeUbh--#dSWjoM3x+x^)dquxfDmBCdR{<5t*J)bdZ193pHpD0Wb<;6k@S%ZIj+?GMV +6SI0GcC3HD!*`KZj;Vl}?oNo3v~(V)=h0eYyXaNnq}(+@aq~I%=^CTP2EYWDE114t$G`rza<_I3Jeh4 +mUW`sxsjG!f3YPR+zRvKlU6&28^Rpd&*){1z?zShcJA_iXiH<9CYtEybppR+e@qAEm85O^{}}@bK+VJ +xTC?QBD)T(I|p34Mk7$~;lgICC{p@lAdMCsR}U9v@L*KxJJC!H??TXhG*2IGBhq|OW=uV8uha5;?QT% +3GoMbo^RzlgoAb4}LG8_aTrJL&k(-64%;{6WNb;&RZ@tO9=-7zU!8RCnr-T +$<)krIir&#|SX{8Ym>z^a7kREghL`S3$9V3kqy)nrfK>_ZLo?lmV2r#G2X=~#!z*UJ6gVl;`AL|gKoL +(dp<_I|&6MCG%U`myELzWqIys7GIbp5AVfap=Ofgl*3RX9jLe|Uc`F00_A;m8TudwTq;#`Ki7$V8fD+ +L1Pbb)sqdfAR%dRgW#-p8bGm(hkr8mcmQO7l!;2y>VZSIGr*q*R0vI@yrA`%fI;V +;q9wZ6#a#ge$3(78jXVSsY*t>|FY#Znfr+s@1h$_Y7NteKd+Y3yQdw4C&60ll>CijnrM# +p)$1zz#+^z`u)ch?*bFQIoR`e*GwH&XW`+Lr{NyD(BH|Az;|Bs)GX7((>Zo=kW%12$FOvh#{ImigkEV +zK2hr_wQ#1XK7LG?7i37frRCI-r)w#g{@hE6Xs`8Z+O7ldVbW?hHz8%&9Jubzv?|Muit +*auW~9RxR3BKRe1yPp?}v>qmfP+X-;dyOB+B&{!%A0Z(JCrx +jtx0gd3A8KGkC%>KiOa1!{_zibYZ9YXJ4n0UipToDZzDl=B+*U2{wG`H@Esx($e*e>9g5KS<*`K~+u^ +l9?@}bh_Wzt_QqW=y|c?;$*c_ehLKC6w1Qk%Gy+UZG +Mv;ems`jU+yL>$t(VwFb(ASI$7X}`hQ3${lz9t@rt-QtjfN>c`U%sbhuKTiE%*n^ +xhkj6-Yf&oGFJTJB9=N>hF}QXo_?It$%lv2zXsA721b^R{7-CNq|PegRO!DaYVCoYefG|05d|-stxyt*fa84>sfX85@L2 +IbmOT7->pGGRTS|@Uj~mQTKis`AcapSg?CwuoI^GhI-v}mTMlV`a;DSM0xX*B-5k!)4rP9P4*1a5k)F +Yn^NY4I--m9&O-6?4?S@6rYzVPkjbR5C-bxz?gNdWE8T(>CPb#< +do$f>YpWCwf%9guOYO?wS1<>Dyh$KT*%<6RgL%Z4@)W`!Hc2>^Vk`*0Me}kqCkut@xH%w1=e}iJvi5; ++S$JaQ!-ALM8V^aokV)nuJoUpYDB+6`EKuZj3pf<7u+46J_XT$zZ2DvY=6eyvLmh_p^`v+`Z%xC?3Q4 +e0+0rb4-G0b4?$qG}Re$?2%G$wTV!ri@z_M=rp~&%x` +7Xm94d(}IkKDB4dh^g3w*AO~7c1O_-@VMv&mxs1nbHj{Luq`ZzMw3?u%kwp=b0ahj0B|e#o(@B3r?#l +!S5RMQBcQm{aPJ%>0TK^~~Dm-@1G!X3IK!*C4@vdM(u5;JyzK!zz`108cu#K5gJkRT;Y~paJi8=d&S& +e(<7o9|XVjvejlYn*P&!gymS`b;5Ls}5&G@M2SlN~rRpk{w=Y7En2>Nq-~bT$@n)><{54VY>${f$Jwl +}>%=UE+1F6}nw?bK4W)m$$L`K5;zR;T-lEmW(^nFL)o3vKZiSa{3YHv8BcF3V19s+I-a^wbxuv+q>Ex +KcE46?5ilM8}5L)f0%`rHwv%ymUt!H_eW^=00$UCNFTO%!=DHXLDh1N$*;6i1bz@C3mv*rzgQ$Kfrx8 +c(i`NR#4F99ED4`v@6E$4!yC}{P0Wi4+=LtMMcdpsyjMw~B;(!Y#9mg7w33e+lUVA&@N#K_zlOps93I +F7NLuvjb=SBP@uDU7x-E$mEKB8=crpCSgp@5Xa;WRON431PxeP3~(gNl5EvE>pDf#y}Q^HwFXELNEd3 +X^P$DZNqO4?jaU}kjR)LqOMXKf_nS$PXA_(EYt$@h7>SOKhjxeT@ta7oLgNCof~U>$&XA=hiVQr(uIP +VpWdGV(jGr``ifwWRCeur^qZM9+55)^*Ob$&_(6#s>U{c<-X0Y-Q?4tk+%-??s9(QtKFW&hr$S>v?5< +U~MY+Ts!OYA?%M*Il=@xX{E#IKj3|!ps4meP-yh7!^T;BUW`iT3?eDwojrR&ks^)Se{0gawMb1(nnUh +}jdfs6oKreDT~c5R9O)k@q1Nsem2c2L+$ws8fYUV5Vst>cnT(Xme%ys7O<C?IqFRG$ay5fE!Onq7J(f0TI856bL$qFBy+b67#w;YoDzKiypBb>1w!)s(ZY1mr@OP5NNbD@QuXmlZ +0j(m)ZhXz#Md7NYw;&NTwgdzM@Nj>4rQj%cbQR#^AC0^~tbs9jtdH2*6<%V6`UsY1LP2!b4|Enmop +6rq&)$pqVom-^Ua<)meOg%)3J~3>MRc>uiT2A>(AHiHCp>il)6>*69t+^6zb4o6N)IlASknXB=uT^m{ +0!celdfGw0??0Kg!Zd4@Mwkx6q5ivpi`!$+rI6_n=HJ=x^p1ZFg}-LG=Y+d^gA1dZHX9#5ciVVI4<(K +#H(Nl)znqy~`eoq3_3=~iY!{DMGVxy_>A6^MM0IW!(>5DG8n2dHm57W_ +@Ja89PRrJAuQf#i~Hu`Gr4CgjmI&hXq{L!1gMV_^zXF`Kk*X~edRsKWP)&J6H99bI}iu_5O8pIb|odY +a%=86exjtxb?^@hfePM?^!uzHV;={wWT42EwjQ!EQ_;xBl~aW5cepB~(E8#ySXTg@XA%awh=Z2(8zee +Aq5(U{lW$fBSKg%Rdf1tA5IbB*ydSa`&Dbm$iiU-wl!5rdeRpKhxtHdR&Zq@AByI?`}pN8-q+e +Nh;MAZgaK7@(2==HBS`VFpg`!Ml6o3(b2i%NPn~Zvj_Vl&VN-5kveRT2$;j8Q9Icpa9XD7QnaMtw%N6Q!*xIe#? +OI=p$%a!%*NpZ!^*9h~Gi@e~wtk_zz)>i&+s!}sWowc{*;#Qc+x{Uc6oA$bt}0n1bStJ}q@>l<)&=;}PRqe3OL%_u6Rb;Js`+kgaPz +oHH@>Ky57hVRQ}Lc~$pr&;u{r?g1UX(R&~G?pwJbXbslSSQ*^y2Dm729m;%geJB0x2E`w!5cgDfJ(-ZJ0QnT@`zW`YMO~;Q*6n%YS$QReC1A6?CmMC7_98||l^vTjc@a>M{k<$Qx+266`P5R_BWb8vJNaO}g-!ZX;00U>&)@a%SJz +Yy&S&kkuxf+tPRv>(O4&{TtRidXYNgr@62nAk5{?b``GP^Nq@Sm~YrJNJwG>1JaJxU1auUZG(3neRfJ;!H^)>;-}S;Ejp+g}H(#i(M +uhBti^oJ)=x=pA3K3mdGSnM2w2Q=-g4AIb5GR@w^)})paU>b*T(IU}` +vPePx#I3K7;5#iaw#dMBU9_%so|`!4(_~*7lSG)9OfMbZ@Ve{0KlT3yE5>CJwEDeMc65q#cWVua1m9t +vGwKA6fPdK4o#0w)nCe!Qx~T)68|Sm?@5(4vfNl;nC0x);CsckjNStIx%Z1{MWz0V4-&`jlp7pESK7P +T`s-68pm!4ef`csM2olH(6hsA-KeUNV3k!IsZL0E^x=L*JG)(J0o +}q?git|JYu;ye_L7*tSb)ldDpU9pIgES})4m##zjifCuI#%Jb#2wn$tq(JugdR_CBNQ1T5$2V6I{6VV +uvx<^2ix8xf@_!Opcvrc=OL2z1~sGJw2>)%gw+zo@yHB5kv{QGOK%nK5jR?s%pF}p5MIn=`>Jq8?-m_ +JrH-JS!+e}Rkmn6a@5H=KUbAHK)8JA5haZBDEb-EFf(_M+xdEy>33-wKR>s;cXDtM3HZ>jINdtUMD=L +&{o0A&{Bp9=l_fvb?0fW?{2BTry*L-Cx)c_?*&K0<*zGR-=WHgBpm%Ncq0_I_gc!PT6GUbQ24=YA>Ys +6>>H}GhZJ!uaf8C8_j$1-otiJ=XV(*vOr9m*XsU*2iG@r_jcH)4p_#<$2y<9i@&WM*Y{MXjygD +B5B^ibpNThg&pIt^B+ljq&|l}E%LQ=y5&df9Si7gr;@PB_dagh5Gb%qw$h2J4#C80(2lw?o`(5!!Ko# +q8HYcy~Tn^@A?P;f2r0Y-A8Y0s!;y#ch89AeCdC&?JI@c-tHkHAptcFB6&lo)kyX-e#N+8fQ>A~u6e9 +J(BH|LB{=j)Q4<#nt37v?YG=UU#fDS6Fv2K6^0y}T>JyuLnF7ayVPC*8Nl!JW&ky>Q>aMqm?Vp4T!N3pNV4B+ +OHUX|-zWS_Y}V_};;Sq{?EWkWWPZ-STfvPQ>@~zG?Km_`^wH8}&hbrNr|hM-jqjR_GhYA+)KRzvEts# +w#R$7@fhl_nN_bK5hTp43L;SphF%_i|p8MJGJCLcl>i?v=@~cdN}eO8&E2+psZ}5(^geQBHo~()Hr@B +ley8UyPU<2T|iO7htiRwn{+*$uj2jrj+KeLUZ#2J$oB{Ms?|)qXZc8hA-bmv%+y$ZUDkYe=_PsKE^W| +!V=p+Z87(<{h3~%sP)h>@6aWAK2mtey7Ds(S{wRtX006pP001BW003}la4%nWWo~3|axZdaadl;LbaO +9rWpi_BZ*FrgaCz-K?Q+{VlK=G-*h!@%CasmV +1_avg;231VBo0c4q6UZdX5Si3A!ze|MvS2jbw-fk?_UE3T)ash0;&@X28C)mL8)D*00*Rjnc=mCDLu@ +L$1aFt}P}O03JY$)(s-O9YneKQ6{yhORY45_tIHX*n1~CFm{WTGM|`xF)wMJY$9g27gUszfy4OU!tt8AxruM<}v+qydy}X)ToIO9kI6J+Xy* +z()ex-q|0H%eJ%4OW-^^6`)M4Bl;M6#max_wh;?U*p*8@Zj`#`!GIa3~8v#(*jS0WFHS&Tb{**U~7G9 +}~IpXvlcFD$7@KvAvLKRsoR#zmy8k?C2%JbYGFC7|cDENWTQ&!zL!U}+O4H^7Q2 +0y+T|zlml&9CRTQ=$~)jDVZX$I4h)K2bg%1)J@gW^fXrTyil@G87>X^!E#p`Z)#Y%Y5L;o>g@?X8}wn +2myM!O)^gTV*+g8+dM1n8tSXC{76pD-$hu-?od~rmn>?K@wwqWf+l+u=Q{rf1HCXjvJg`fN>qY?r(sn +WQV=#CimSqKOmT!@Wu>4f4fY~Q7H~Dc>D*YQS)qT@^doV;6fuFa +4N#BbV&HXLZ70}#EAFy97YoT)0f;3K7swzQg?;Aj;^%g~^d(z{n8E>GmxW}+Fw+53+Xb6;wtw(^Xa8U +v?*Bl1N1Ta(in8{WCPp&4j>N63vgLMchQn4P3!5Io8i8SpM22r$H-{`uqdnLT8*3)1H +Ny&1jP@?ZZPBbHy`$(Vx&j)ClIVzk8g)XTI0}qksAMgCr=%aJ+e5`*2$pT8moIKg0~?1q~i##5{nX?0 +qcmM&}yiHphi4F@_KOIU?r477GB6CZj=;vt5#+3M8xs2_+<#jVgu$y4yWS%hffo$IA~b0sALQ+FWsR8 +*dMTY`8M(<>k&bY(<4%i0-p%y7NqOS;ZYx@-nZdE`Mx4m^LH+Fb?>8z3+S8&ZJYkW+E-{i%5T_N|5G-DXi5iK;F*fNkFgF}NRMUqFaXxY&L_9}|K0BDdLQj*|z;OaHYF^%f5fB5>F$58-{y~N=m1Q@Hsx;#X+ +-c*Sk3iR**7OIiqs;)QF!^5;(L&z4@dD?A14gjA*(2{2{h&ECS$N%P^pZtCz?j)uvFb)J;jN(NMintE +xjsA5x_~A@`cicO}?pkRO17eoo)ZS|#A4ETpkPS6U)Sy{Zl*xJ-mDTm(s$S=Z)i +Oa=d!Sg94}Kqg8+{utiK*p;%IN1%lpKLVn3WWOg>i@ZXvG8T9lkg_dETc7tZo|qaCS8eXaBqeI~`M~3 +4UUEr!bk2mY7;mn+$_ih;C8{zEvp3Ab?p#kt_OI-yD6dSk1yHs-JGXYg|I4n-cNDwS4JPKw*|eI>F&$ +@%GK-6?&HJKBg4RvH->~*T;I+z;zsO(dp<2Cn0pJJ2%3VF)hu}X9IxsqY7iEf09lG3pYY +ntdSLj!t_y2IV&g3xZ8u%C5!TVRaC4a5Y*eey%`i%3vz-3!uvcw9_P07h26IluE8`-3B07vJNz@atqS +tPzQ0jV5<)m=Aeg~39Cc!2Ak!B>Ng0G3TyHQG}v!CS!Kk8%xQ5<$vjF|5UwQVtF1<1`9T(U-*@b+A9P +S$+z^j6XZxFFvN1$(xXUuzB#kUG)P4VfT!BJl92&0Ul_pfVMCo!rKDgF-1z=OyEFq04R=)`J(P7E87{ +k-Qn<{czto`o{k(31=D>4foYX#f2FLl>#T@#%Nl`m{Zo%*41zXlW0s;Y2XK%{Efeaet>-7`b~50<7=gdY3&X9Xz{S?<;ZfPsif1_h_5RJf-#nC$ +r%&2PZZ9hd?dj=N;_#f5(i~LShEbAOy4n2>LqSiaYd*LHnSyxFPn(tQ0%&g3|jYk%b?VB0zh6TV|<%c +#m@C2|&hIoLJ&?7Zb#MbZxz_+bz)U}27h)zC-{j(;0$-I#vpXB8G3GG{1uNl0`k(&}P@)I)CEUpWtQ*x +C&WM~vjRVowj`xm`u;VHRqeZx!B8Is0cgGw~w@C>exS;rZ8AR^iV6YK1HRg+~B>k_zv^fYFm8-= +zMt)9VciyX}VP{ZS3GmVzUiB=Hax@r{dzfmy84u-R03&lxe@6VuFJ49od{thlVIog$SV?K5Xx-laCa_ +)*PY_ycW0U=;>$^}#jV9Mc-oukK(Zf){b_T8SK8H6)TgU<987?xQ|sb|kx8uuBfR +J5AI82R=wXH3=D<^QeLWp@*9lF)MXykSPAIy#E2~r^&D-rCIjd@?Y_YyCaOoX@cQyP#3v-^jE&Ip1xe +sptLIHG8elzNh-%*n;&BA@5QQ!Vhy8(D&3v28)JVSqL3Ypk(GX+bsNN}IWX08t~S4|tqxMW{lF`(~oI +pUp)ujO=VX8!EiGgAyBs4aw@> +w#XY*FalWuI4dr%hTrp^K2bABsMeD|(yHaTs=wpDdNQ&<6fyWb*$`DpLQ7iAp3#oU@pBv4`2Wm4uQ6@ +hjYu-aN{%Feq$ejyeePQ`FpmeC@vrr$jN`pNLqSd*YZfAWh+5X`={6RsTs2xqsLJ6hp(4o+Qf-20T^o +q4~$Eu@0SKQM=C%QHOx1oPAN}HkVIlZ +Q@BbN)h>cANetWclG)kR*a)Do&;k^Sl6^pzFU6lw3m6vdhro&gAmC1U2LLJ!h9GzJ#}<8j`YQgIt(&z +dn)O0f-Y&A)P$H+4b7@QoNjsRTBgA>O&ah0&k}ll*oC{l{NNH=_Ax(pcdI}6?yra<4!vKeQ;L?&xq`5 +lo^}qN7wBA(@GEamp5G9hvpe})7023l(bO(HEeV(u<*k+Z+?L!%w&Q$miw#jJl12>KMlbKUuiAF>%O_Xdtx<~fz0qw((6y^WoTzA1o;Si>NxO48qy!$<}tnacq)@JI^WB3jEe7Jhg``g>}y +nBJ1tQBQs5*fq(}MOLj%HbdCbpM2@H{%8&OL_7+rVVG#{Mn85k(X!?xTf0NQ{8$&uGN?9JIdU9SKZ~c +q12FBbx~;3YP!w4r2T%fvYjLugRre0KbFqq*Eorylbe*P2mF;sdOr4@G6$LbC3u}P|j>g=HPN$^n4O% +)v=|E>L!Kw3Zn527*3pSJNM=w&G<%PxAy^6wl&_@5&OiP8Dxj4b{Tb`{z!frp=f3$bAqr?w9dyKL +3GuMHP3nbW_@=n*~IhwXnTvdq4f{zv}3>(Rku1qp?{ORk5|Rx|Fr6_5t}63WZ5ejVn`bjG90?YEL_Kh +93Cy9s#=D)u3qIIEFr+`x9ke-muNXK*K;f9PPL<`L7U5fSXoi+^u%YZ1p{A)Th(@e#vBu_og$6g#)iN%(3-fb2@Z=O>q<=a6H_RK888FYq5* +1XTah;cJ2RV@TooUBkK#Pr-tNKS?w|D4nsi{_=)+F_S$Mu?G39E#FnNC +WL<~nRLBcp>J`>^yI@f4G~hjDs~u3j2p8Quf^PCc8?#*7kYN%eLk+ZEBUI4U*kAlX;Z9s(};j0|dR-1 +h0D8hD@%ghg5A9WBGUeitY0Pn!8yF$uH|4cSU~L)@+SuoqTeuGcWdxR!W4ue>Xe<-D4qz{XR8Co)kki +R^q%37vUYOxPBALuV))h`RZl4zJkEjXjY@owBeP=tP{J%)Wc~`uWQ%9R8Bj +@r0ouv#MMqd4?*S=7G{GM$tyD$Nm(~m*NU}Wgr?boZcfEcnyfR*9*9(T1JN#eFeBwU})VlsJyzY9wHkqiu^z_w10{NSJqqIKv5|= +{GWRL%dPK&8P3iAQ*-;F)OeatWzwTI5lK?rhcozTm;%|V=p!*a#8J%Xz%o3yy_2_R?kUUXNaZWhwbC> +5!$F2X#mH{?(&JupSRMN-2+S3$erN!$KY--vAu9k1AR*n^TUTs|IUa(Z{S;{4(y+J7bYp3wH_QQz^WO +L9M{y0@)e+~tApb~}HS&-j-|f6;TBiZ@#22>96`JLp4}^SPege2xc!rP`r4G-932;|`T3WP&=ukxt4n +Q&S;vh`1KDtQgh((fj7@)%ly(m;XSqgJO-7J!nSNdVd^aN&Mdrg7pcry%?rL0=v<>DV3)o+StC0azBT +3Iz{k*h4eiU--P2m@{esC5e6~cFzvSw{5}uyw`84OHlR}zE{!Sc#xy2BqnA0FUA*xbhIse)#Sedb>b> +hDULVEqW|+T@W+zvtFaANb-;`>IQbV`T5H6Lu)F&zKW$2!ty*#@*`+s5TdU40=+he%MBlh+o_o2+*Bo +pk3MDAu9?*OGXJU1u)I5fhb8E*;7e%ARR)l|BiHO}wit)kjz2N<6gs_58dTONXav6iGvn?&l=16RIw1 +Ct&nz*cWLWg+8z9ZZ3kTLrSWgAUJa(Z}A#ZE>1g4&=pM=eUv99uYvKHgtZH3&!Il$?&WIcsE;?<=8~( +9p-x=erWK9qxd?;eM$zVHZsA|6|s!797#f_scoO`&ZcFTfER*YO+J4ACoJ-zs?5>w&t*egP!?vY0R$B +douwx$ncT<}%Rf2Nb$8&*wGZvN;LM7ETN4oMv^pT8I8FV{Ker`TWOCY~2Pjo9?(C`y>h+x5A-l!8bZL +r@Ht(pj1{ChHHk-C&9oo=s21~lxB)BDnwnxm3XLP62lEu*i47_3(Q?u!&+Uod_#hV*m6&8)U6vjoEd(3 +7FsdC)1fP2ybmL=fdk(qX6N&*4^hQePO9fbLQ9SKcIjsVQN39kLF9E9htam_d?BY~d;lXuXSJ(=uy-? +;oVb4V)jQ_!Qaufxfo_Oz_WV&26%Ox2pz7n&dQ}-E>wvu4R^f;b%=_L{{1n^qLT49Md0JO)l##Sb@f5 +9y7b~oc>1Y~psSPCzQFe(T9HCw|DB9Z!=4k!o)7%IfzWSMglPv>GHZ8-H7NYGDjW^}WUt%J5Fsq1*Td +lR|A_BvXkur^cQ4uIuEnZ7$jm1}#&p9&njA7a|PNvPb{7KDK(N2Ep$c3^vC_Um>+YIjSA%n=r^AvC$i +(HfmDcRTtwxjA6E*T|Vq&lws55NfWMAn96Q^g#?4z5a1DMD{{DMV|pI!hZrmMdy+SU4EP?-ur{$+9%! +Pdib#g%cD|7dP;1cFV6n$-Pz^U<;-qt4H0J@2<<0?a0*j&d-oKlVZ|=;hIR~kHaGkNpO%q5N7!_;j)v +dMaDA^gZ!zHaF%r`2(Cad7zXzSrc0Kw~Y=1Ff!qm#2b?v9Ej2h2qDs~+x=jdTd)A;0VLs&1z3V(P98w +aqV8-<(NK{2q6SUIFac5|hiWCc&ZWFIG{%hUG&y`^?8B`3e|Z-0-0qekC3{w@e|9xo9^i0Y=(IgAs#5p-C^S2*ypY5J&*9A^?KW=S8mBQq8mTK!C+;1(?Jcg4vaIp8H=a%MKg@!VNgejcUE{%eO&tUf_5 +K_`(%lLmK4rFPO3P?YuCpXB7jV4`tBJzI$P)h>@6aWAK2mtey7DpAz +004jt001Na003}la4%nWWo~3|axZdaadl;LbaO9rbYXOLb6;a`WMy+MaCvoC&2A$%48Hp*1nj|fkz^D +9WRn1UYI`WqQ`=(zL7t&)Av4mfq)FlyeTp7>>C^Q|N|72#PSRX5qCSxne?HNl#N~IFqOq+uhX*l+{pD +Sh%w~IMdvWE18=EjX@Iv>4bwT`W?bA5?pqnt8Nj!%;U&SA@nZUnK;wQ7Wu2(@@qq-{+-dtZlh{e3ICT +KIl{9<{LMUl@xSUi$rAo5(u1{a{C<42pX2|3|M{zEqB}JXRDd@7wBmcHrh(yHPPZ`DNHvC|bvj_^ +o?hTM@1 +GJA^Lk?kFf72CF?u2eG{B;H=0m-OJG@aVoN3pw$kV7y~Y`H779JX^vK7#bi}$PD^i}p_Kz*{0v^Pql} +U;rSo#04^YDPb~J6Jg|g)Vqzy-KR4w$80Vxqd_SjH+4fSD41zsiA`Rl3LxGin)ZjT}!Ahw=zF-Uy#Xu +3%A6|$&!L@~}+t`yKd|HXP3`&e6z?J<4Uv7c_nk%);z#GK< +GgG*FFV!B)PGSiE+_vsoS4z1BLBUL*d{fZl~K8Or;_xB&AZ!FH4p;oRc2V +b}J(a+uOddje42!x05<;=pO9Ixlf-Nc%LYC-|43 +G|K^6`f3T)<^M*p+fjNX@)#UwN>2C79h_msVb?s%mMmRCYDtD+2Z)#j7;x`~}6XVB$`9S +tqvPy>2Kvnr}hkCd`vYy+@7-F3=2cR5#jIrNq&YgG*A<>7}teMgbuLHJ`I*U(6+$G{dpFj;Zwd?eyrK ++~3L+RNv>9LC@Q!M$~mAssx$al7Rs?Dz`&g_(IVE}_Y(U6*ImC-5S*0q3zfc)Qe%&lxU$qSwWI}Qh@S +~x50BrC|fca?PB2OreZiV8W_1rpY2Vhws!CSk^|sgRHOdVrHiwq5J%iW2j8vgzbzdN7gW25UT|x3)su +bNK|MS7hcRS4t?%y4f4_ufha2a +8irsK$paGrLCW+3$5j!S(?k+KRZgOu;*4+85m-vv#`I$cC>CK+7KFy=8sZfRBNS{v%FXE2_ +SZ0jg3v`(G@aF-Jh;ei|E^vODFN>=GQ+I_q0k>FAYX1XJO9KQH000080P~d=M{JV`qiqBL0HF&203rY +Y0B~t=FJE?LZe(wAFLGsZb!BsOb1!pra&=>Lb#i5ME^v93R@-jlHV}Q+R}cvnk^@^s--@6q5M;OL0=t +W%NYRIEVA0ap=7ts(l8S3A+Hdd7P#4OMx2+%ISUht(b7rVZvA9}@(p0M6T#MGP7eCOGB)Pb_NGv?J;J +nM7w{7WL3oiNl^phlSrI%s^3BQ$IG-eN0{MP#jE)%tDjP)2%Ybd=kwM&wu)Y3U|Cmp=69n?;F^#X5I> +9Yuze{8*6Y4|9c2D6=ACjvj@l)i68iRKG6+KZy7&_z)!w0Z(zR$tH&ra|cUyGFwfYVU;9TI|4YO@;s0 +l`suh$pM8~Gq@+7*e|V0?(BD8oT<|(RNmda`}LlnuVIC_6!*4;!A2{G;#Ad)@KK;1$H1SB#b!#<8WFh#S +z*5(QmPrXw}3hfUiyeKVgfB-Z|k9>FH*PMQiLH$y9&wgy!RA~>JpgN?M61{WAb+pXENBmzRz +atC6MVl`H6RE_dKpsI|8s-KOZAWSld%~(o4Z<|VbAPG=a&#lzT9}u-`q*cgK2saK7DS3l^se`b2C2S? +Cfo;hn4+06u&4-FtfEa}lPy%gT!CKWrV*RM&Q?XpCTKVNNbD-CAfvL%xPo_qmudbf<(r#S0ALv7ve91 ++k5~`_C)S9g+AUPPVI24`Sh_8Q5eFZKuI*kG*QFb_RG#^8P$iY0cGs^2y{EnUDaV089@)Zy58VS(GJh +cr{vub^45F;f{ztoWn!b@#%L*Ra42#3jEtNsDOJ?%6US(H|s{pK|LDD6(9=lni={}}tKK!3v*o}P6Sd +!dEXxj4-vW9E9|`X6(#!#Rd343U~7obyB6UX!vl)MsPhSr$2n?4o^sY>SHhKzC2HE<-=}%5VAR85$p! +WH0f!xQQS$HsI>;4_1L}&n5_>-~=^=9C6WQHb5qv!1K^KgW|GLbvQZ7^*2ezr*kp6DknE}|6$;n{T)I +KaM12(AUje%89!X%P({;l$NOkc%Y)+(YJ69sN7x%_58Z<4-;4O=Yz#ixu5@Mac0Jyye3#tt`FPOc9gvL)%o +#e%2cQ4F$n?i9$Is~-_c{G36>mf~1pXfz>r(syG;VkkuJLQ(x7M_qEnbNhZwzO`3UuU4w%XH66P25su ++BYO5~a&!jxoamWopK3=y|mDJEzA4e%obdG)w*gP)h>@6aWAK2mtey7DwZ>xD{O+0034~0012T003}l +a4%nWWo~3|axZdaadl;LbaO9tbZKmJE^v9(JpFguHj=;VufWQiC6!9FEvLCuiPCi)r*$`tvx(jAo$F; +N5|U_Bq?RCUt9|X?e)9p4phP+Dws-HXUsFjSFc=Kx3o`@mh{5B52(u_oXCqM-)4?-r>2$i?ZYP)jDy1 +rvR~B)iI=?plI-Rq5ti&RV%0!A~p54TeR06xk#Y#-eG%VsQRic;&g$QyfN+lz48yE9974J3ZPW3cMRE +AxqWg@0oF63Py^E5~Rxm1;lB?9vpuTH#JW_cmPSzLY1A{nasSCUAc-ZaIT`Ic2}%OogZs)hNTOY=>ws +!l2kuVqpFD)KU{e%%In3WQUg&NR;!!V|jP_itpbV0zzQdlJeV7R_y8wphaA4KhKlq(3i;rJuwKXrhGA +ZTQol%OH|@>qz%sWmd?(DD#8{^u=UVNYzJV`{Fc*aWZ-phXr&=b>CR|%hj;o5p92yGERy(^=bS}7O=T +@F#^OdD}SRoz$Kg>uR4r~96yH$f6d=kMQiI{v&=b6Ed039bR!Sh$;r^g5ll$7k=4{MRRMjz3@@$4h0Ahf +ZHOK7WHguZ~|Ip1(Qsj}HB>&fmUzbL_u6Jo^T^(?)x@bD+Ho{W_7H3S5j|WWK`L(onilZ$y*>rhYGBX +@G8!ia6DrZ~Djs}Z=5#SPe)QoswQ%+NfNMohSrOf?A +rf#OkSuitPEk5*p8>$AugEkPsLGY+$K;}VvYyW8sPcnN*k*`J#zTz&hp3LK~upsk{HyotgI|psC#4VT +6DJ(2N!ZqO__tpawC7X{8s>++HA}Cy*s|Wn&tN16`iaiJkuvaN<{C9-(W}f&8W%1+`IQs*M!pW&;zO< +6lGqBvA;TvdSj`M@En7bf%n|xEuWhG9cD3_pNMJcOY8N +56;Uowwzo-^#tuT4jSiDs2G<>nwGSuA88XO|70yzio&%z#4%pXJdR0$&W&sDPB7d~WTMayq0SRNvh}r +FlQFfMs`LbM0z|2-0Ya>3-z=Vzgmd6h~wFI}sbw*C_V(+rEUCFSZ!BF~iYvg+#%9BisI1Gv`S1wM`TP +HUUZ(}?bRPuj-#50hIUD8CiS-#0#)WJtWxO+8Nz?}4z*zaxGe&On#8o*`W3>{u>C`)%uqWj|Hl)kKS$ +c{KMJA4aXNkFa&C@>+hvmgZnnsx!)$rcy66c7r~sU*dODzv`_^Hw@ZBCbl5%5+B>Zz}5!4>?>e +k5gC|$XO6x!>3ZrX=Xtuq_Fg24naA`ld_QOYhsYBSwWnXPZ~a0NH?2Y)tdDzM^B~5xKp(b>?krKh*qm +G3Y<++r#O^4j8Q$Xd6-;*fxt%a9FY5a#(=og6O;>3EKb4Jpi6*lecN-Q4%mvj|EIBVUN{>Hi5?I3`T5 +H>yQ{ST!ljks|BQJdN9$Uyd@wuYY`SEBEJ}czgpLU>ln?@&Rv>K@C_Pw8T#y!>;I=QpLjy5Ey$Q@hFl +ztB6X$7y1pvmc3f?&bCr&l{vhxf;+` ++bj8W5Wa73@ce=ATn^kNyWY(k|M>>We%@D0sLpeWyHAr@>>u#TnL-OQ*P*7P1f2_FI{H$vQ>j8x^!r;{CBa>c9L-~*FjSwHvb~6gFc;F3ib;Y7giWpB;MZ7>{K-+|1P=$#=VB8DDfYeM +5C~7p$=F)IXB`SeHR*Zr?5~DByhh+2-N&QhP6cpf1&Txth&INtZ)f6OXT`kcU{1ml;{n*jY?pY>6aLE +c#mx95u-;A5wz(52u*t9-|;;L=X1dGbWvZ9p<@aaX4kgFCv=ZKa^yGu;3btsQy^)X_CjGA*dGz(A>=n +VpR!HNyflDI9%ADfY}hS(U1hu#+>aEr!c{yx|r(GREVG+kVRJ2v4l4btahIE~yNfqT`nbQ|L4Az!2s_ +2}7(fgk@)oj}o|PwND*OrYocnzfceoIgZQR4yb4>5a^h>xr^pIKi2xlPlRqiytwPw27HB&9ZTqIC>hZ +c^7@xeB1>LZe@}f<|Ko(T4KZtxu2qX#Fcp|s}72SHf|NI(tPbY01??*!*qIJHE>#Nt0qSC$3kD9MnT( +XvTzgx=!6#jHim--I0PTjG;K;;V|8dkag(yL@O6ZTy8qnrWJI>^mxs$6&h&pHZwUE*d84`8^!zr+Ak2HOX +Cpyf#SX$5sK5BL+AK)0B3(q@f>#TJkq>A+3JM_G=s~Tlim+{T`AkIEZSgG8&hozOHTHLNdv^eOtXT4kmR0m= +8PoWV0~63sWo++_7j?bTPASO%NwWi9n6(Xf(bYtD#L&Q>LiPHtjb` +kPL6f9D_Eds5i1J>c(54Y1wu;g>4<3biJIGiOxDC?BRL?+p-$Wm(-jJ +UI-I-TNakIrP2fNL-S7)Bj>in4M7G*zJS=Ek<++*O-iacYeRal7+lS;vHWBpMjlL=O_wRG!1+37i)x; +=A+Y^JmR)Cn~^NYB4;fwbPK}Ge5$g)0%Q%@ztboxnmy(I6b?yi;c#z+C%L$6U7v&WSSdZwWONRAnx)e +Ss5lWQ-P>bVNEFxuSWGFbM6Mp%DV!2MVJg9LaF6hyBhe2>?>QD%FOT+lrI2ZQO4?j!QVZjg7r_mYKso +m7)^~JihPrJv+2>d`?e9MUZti;8@28u4p0S7oHDP8f;{Lo2Gl5w1V%r!JIC`V3k0#RwI@x=UJWavG*Y +Loy++;D;}jy0VAx=x@XAUz(b*bLc!rTc+ocGOJ~zo#^=D#nU{v?kzR4P?_}Pe${_MP1Y}AC;Gz=!|?% +@~Lt@y<`K~t<#U231?E3r{P-n20jOp>T5xOzSKNB +J-ZX}za*|Z+Cq8Sa&uS^3>d44#^y;-RK648@D$3QL59IrA&d%P6Z`j8{p>A@%hBdNvZVTtPYfwVi$D< +UGSVO{$vFqq(1AJyhz0e%l!|sXC+1)5+6fCefBAmsZE>2<3-|kmWu88jk&n_qUw5yMIG_d?K +(epyB4Sdh(U1f#oRgha5{MQ?DH=M`;Mt)D8S(Z)h97B2wSa|8K_UcOk-@ogL;n1yS~Wlt^7b^1dl<*Z ++bO~EOM{fn2kuMeNr-mn+ARrOOSi)v$hC^&vWOb!?BJDcQj7n{D|?mAkmNA8i$@sxi>X-v|pgT0WzlZ +GQDm`CBMOH5QgUQr%T-%hpGIg4f*`0vkk<=K}8U!K{CbzeU;#{0aZYFqYyV=C2=T~%i6y$=qJ{i%!+x +vJtwpZ@T1^F!(AxmVNSeN+HIL3v+l8ln8#R?1}!hBs6waG*0JH{3+Ok(zMnNPsH5rhY}|NgDGbe9tS= +15xp{kqhBi-d6f|~d5`?r_8cb7F66!zE4i`w^+OOaUB|X^z;;%kI@k))1@3A+zXDm*ofK11G3Z%4N1hxhMdg6XHa +3lYJ&KuHFDzmmi6X&cU>D9hAtTXCtAap-6ebKJKG-_u+tu?$%ti`~ha0`ak%hbf%#rgXa`_Ss*IsV{_ +XHR>b^SAGhKODdR{`i&u;rI+_59Izy0s|Jzw%x<8j$R$V{`#AfZ~yk@ySJzB{{H^M+4=WB{Num>Czym +F>$7=$b)78IZ27NT73IzC-RdWng3m;EZ-033q%8|`2=R;1VN=lUrNSP#R|0mG;p@7$+{|-N{Y_=dMjc1-9PR8`O#k-xA*w7{_g1c_{+ +auT>iS&9fSGJ5$yvSEV(0eB$f?I(bP$n@vH}&VYtj1V`S4-UQtHQJNK%@*bWb-wQ!@+eB|`jwIvO9x9 +Fiht$VydtA-}7#lv3k50dk?7#7peo15In$Z7&EzCv1=fG}(%gn0M(q`DzVB+Tv9lf=mk#EgE@Ieu}^d?C}63f!ip#Gl|UVHuy~~LRg^}fgy#~tcK?f^xBv8+x9{z +|U=iDUtSp5H*f8Ui`)2(}-DU0#pylyt!tcy4gf(n>f;=Cf +6KsdR7TqI(d}4cXxu_VPufIyF1VN*W?e_N*V{8H+)hvpV{x>=bwA#-(F){y$gGHQ~f9YDcpVW;)OUEi +hN*m8+Za>!xk85Y +oFB$fZh-53tGDEP3A#+hl&N8v)rFuq%4|xERgFGfl@T{V9tV>|S~;yIZ185wl$jh^W&a-UUNb*3@*0d +%=1LbYI)`IxnCgSaz*}9=kzvlt_%_l&8mC4r^oSHW)=+h +kD!B9{J?^c?_BM%jNDAEcnOw$X&^BwcSSR}z>5(VOVgtfRby@~TIrNA8s5*AUfHF_l+xpKM!f{@^-6~ +nPZGo3-EVl&L&@?8Z}#Tcu;?rhSV06Y%7qM>gUx|P2+k&u47tj<;<5h8io71_ +}&Ue@}MTc03D8jiQ8*TT~rJbfj)0+UtF*0Jw(_>v>G1sLLX;dX7u?NT=F7`QGyrfu_}fymRXi%%i +0$pqV^a3}a41<6kf{nom*Bgt_9;BT&CV6MTmJ6<)N*$9za3Vah~l+X>*VhccYy_QSu%~vv>a@rhb@>< +6=^b7;yawNP^iUDHgF2$0E9&UuUNu&`{hFxhGsg;az`*$?n%$O$Pq!BdtGHWxB34RPBM=_QmOv>48g- +ba7ApU_g;mbSvqN>u+Kyco1_1DmQO4K4xm2tyDN~8>4c=E(49$Z4AHLY+d!+08p8jy7Z6V%NO#p_b66 +TqY2$byH!^e%Cc#BH!rRE3?(8yO@T9-NQjB3>Y|u(BeN3tfoZFglt9;|4`sW~_#z;8qc)%F&wzv0S?; +Qh~D!9dIx=Z`hl9+neUGPA!pwZ?`t@O}Tlbv%tDHW&jKWdbS(!2?J)Kq3gL?ZDf7Bx4xw+r$Lz%KHiP +0(Ql{sX4H{KSrZ`v>p@Dxsqchk*+E8n1-iKj#Su?;pX7Tj#Z<` +5y9~r`KtAn>sC5eV4vAOV;$`kK;qFWuxeLq(@+rwj{zjYb>XH6*oe>WZ#r4G^SVEk#@vYQ12g +w}s!WF>BQ6ZzI@f>(p +UH)UeE&g`dniN65|?3Z+Un?rHLvN&o +_qDnN0dZ3$ZeJ+UxfzmxrNXfh7uc#TqP`(jQX0tKGhM{GzMNmG66r0a$3OwgS2v0MEOPqUKK=-Z#MD* +`z*?5UJ}LJJWR0g>l_WKBk%4ix)42ReoU>$O-7Gl%vM-A;}r*Lc*8^a^jFsIO5>H>doa4 +0>VmK1&Y3n2e9RMOQJk^0BFb4(Dd@C$Hruda{^AHWb7iI1`#5ulCfUP2DZc2UT+9AOC07F?2GR{z#gmsVHe97vN8w#6!q388eX<6X#eTjf^_57MeRS` +x+vT?+8GRm)1*2sNsLwDV|5#gy)7$sT6D4{plqQCemqvyuSf +@M+{SXlZSYMVW0;Z6{dOk;xSuv`5^GpFM?UsJ9ypoj;>KQIYMA?Fq0L{~!LNJ ++!`W&$hC$WK@yyfW8Us`@3PFmyMqbExUF8S5@=XD)@l@@I8+L-H<@xr0a#SXSTHvT +gA#Oasq`d31Taz7yHa+jonOu}t+8YrBI~UmWcVmPR|j(o-BdH2O)oP2NH#kNtQn_%b(rh^CR#UYb@62 +(TsH;qn&A|~T=>c(4*b?HZ$VpxrOChuX@M8|b>*#n1(M&Oq%T6F7f$C6^S&0(Dv?3Yw)K5A4bO<)#WW +Ts74Pyu&p_@~uVyn(%v8N**sA$blYU(&)!UrQ;ed66@brF_>eUKqfF}{3qc&9?W>unXypv{1#E@3Udb +lnT-fH!%@6aWAK2mtey7DtaM>g6*4002G!001cf003}la4%nWWo~3|axZdaadl +;LbaO9oVPk7yXJvCQUtei%X>?y-E^v8EE6UGRh>uSzEh#NZjgMEz%q_?-Dp5#GD$dU-ElG`s@VU6sK< +e~h(xpW?IhjeuTmVo@0|XQR000O8^OY7yacoNbjRF7w4+Q`KF#rGnaA|NaUv_0~WN&gWa%FLKWpi|MF +K}UFYhh<)b1!3PVRB?;bT40DX>MtBUtcb8d6iSaZks?5z4H~L_z)veYA5QYZYp61C#a5X8M~2B)&fJ> +cD-xuE_V6*4j7VDNu+j8Ff;G*=FQOSy&W(P@1i-(qDeT9Lm1B%lW*`&Z_nw$y5I%`Pc+jN&||Iw8dzJCLs#B%RP=hTHEb6@hl{YVU^9{_<7^>Z&M9l;&%S7;$z%! +nrGziSVq0X5CGf1iiH?4)ltq_O6%jkj9&}X*RuR$GZpi81F5RBAyNZ +)zOg6Byy;Ig4D)Pcq-h>!+7aUmc!K~%V4#RCYxEXg5_qlT*RRd5F>UL*Ji$D@{`3mQSKEv +nW1G|nDgjcTCX92B7=e*k=C3dKaxBKsXA2uwL_ugk7iziJR3R!o`Y1@gOlcTJ665kF0nlC*Mmr=z6YO +%)Wqa3K`V#}KIJ)4PlZz2gRwHUZhZ&{JGdGS2OoylgCW2srp$W*;r#X=|BRmF>~`&y>~?Si7gzqZKe% +vmt@dClQ!i3!+g;L*%Un5*lVM&vjH&IjahbcH9iSi!`u&%k@CEwU9t`T6q$4w28p~vg4alQkiKi+<*Q +G;f2)g*2`p!g&q1Hvl(%US(X$O`3q=eTnvQA8!y>y+1s`0_^T +%ev>858H(Th%4`_NwAAUA{U!y_$^p+!LXA|2*DwM&ttkITQo-w7c&L2=q0|XQR000O8^OY7y +ah$&~caZ=9qCx=xF#rGnaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT49QXEkPWWpOT +Wd6d0fuVuH9VEKN3#Q}`LxPY{L_9ht-yKAZe*=1J?yVu`7e*XTOH;=d9KmPgs|9JcDx3BxZ|NQ44-o5?$^~d)g9$$a^_RYJGkFWbPpS^r)`o+7qAK!M%e +|+=rZ@zv1-J1`O_kVnR{2P7t=YRd?ZpFTc*{PVwi9M@Id#ozq+XOGXn{r2%CpZ)&v<(u!{eE9b_-|RQ}`TKVtKfL| +J5B-`y{{HX&Q~&1i_~+Lj{@dfXZ@>Mw4{!hc_{pP3`0?@a{o}WP{rIQ%@9y{SsrvTqA3nVP@KrHy#0Q6-xKli@%r62KYjn9+yD9fH*f#=SAO-wyKnk+81=_DAO +8IPr#bwmU;qB`t2f{GNFV?7=G~hQ{Wib-;Sb-w{kj|f>h0HW-hKb(@%sD6cl_@AKmEr{{gQ$F?jFeFm ++!lKXZP;Zw`c{^k_?$D4lh +c>B(7|I~BeKXixvqJL?zdi>$dWi=bh0*`=i?4qDi{Jh3@yp+Q`S| +?t+t0uJ>WiQM{#T!W`S|Vczx?fQe)o&d9*^I>dGl$Cnasa6$^Xw3|FOIL^ZTC3Z{B=-{r21M_pAR)FY +os~z;C~K{OR?-zv*TE`pw&xsK@KxBH#V>|JNFR`~Ka(`M%xcKPL3=A8-Hoc=!I}tH)nHylvTO>HD8nw +|n`I^?lVs|Mh3D9_#22y?*!KzU?LWT{r*b+dp>Kzx?+7`wy=kKYRcEM?U(`pLg5mc^uE59OHRB9>4!x +|K@-7zsE0r{g3}2mCBD^y5pa{{kO%2`0qcwdG~coBAJ5O`dB) +MdI#+!9)yi7@Y8~gNU*+7tI-cjee^uA0NyF!?`&U=48b08QZ{DCjK1np=`;uvX{KKcte){9%C-;wk_x +OkNGj-3GJ;wKc{u}Myb;BOcPk+4T^Y}^s^mqU8{OowHy^;RBV0e?z49px(dhZTkI3H +q)Pf`1((eKebX*fwa2$@*lr^dHLBF|Fr(~tAF|J7eD{}SO5BtU;OT?FTeQN@4x!uH^2VZFF)`9+pn;C +p??0S*B=n97OMaLn-6Lsmuh$L`Okj!i+}yy7ys8U82ZTQj(c5c^VR$RXz>q^AHTH1JYF63?0?oXUiEO +-t7DGiRjcHB)qlPEpE~&|UajY|e|Kc|=bq=Q5!KCl@m`&E(&Bi&dZ2=jco}ufZZyWLac2M23*G;j{e; +JyuUdNf>(MQ*+5a4sua1Mi#=2gOEBWvluf|-*t25Tv{f_hHU|9Wue)?F?SCer(WP8VgqS+&_{>Y=ZHZ#|Yah!wUoILBEhkCyBYxK-K7q9zd +J@|=d^{0B!$2_|?X5=`T{iidXtjJ`%J+*sAn4sV%`n}?%oA+QA@^JM!_dl#SLUHkaF&F>zU*m~99IjD +6dJH;G7GwW`|Ew(!{R%HVz5O5OC?32JwhN)?7rI6-#q&B@=N?D)*pAur(7&5>-XED0DU6=4tLLlN_t^ +cOy>3VLub)?oj5-3qn@2K;gSlBf`{zhr?o!y8o0c2D@VA`x#(6nFAdIp3h#lWNgzBF@)%0^=$FZy^P1 +v^V=(vG~y%E4aUq>_ffsRy=hS#z1%I~vHLyeOTRe%o;|C1_B)^b`2(5mWoOXz7VfCt$NkrX0k-V*k3D +D>YVewMxaqf?o%8w9@6w{nPVLVR=B*d%=r!sAD(Zt3=XX7|Jyf}eY||}lgG?~rs$uFp&o1<=dfDNC$eY1+52s>ArtL%v8G2Lm%TjwEQI*t{aR24l +id3UIq%=~Clvc)@%lwp_uFfJ_gnSSAHYhukI+C@x&741-BGVQf^yIjCBbeSY^w+s6pa!{yu0Q+_dJYe +uUqs0`wduF-ftexG@pu-CtS<}lRS9wr+py0Pc%h86%&mp@HTn(dp=vAoott$yc7E}Sgn4c9+ryPE^8t +q{g@VZ*Rpz-^|G`8`d-Cyquh_Z-^PfS9+skuSwK6@e!pH=4TSriokwq&wtjvw(->6sn|eW8VE;d$QsxZjugb;WxDDtpRSKcPjT2Ys~8Xw +|zIIsGE02ljRKjI=_+X!Q#Ae-8ffS$DtfgE7nfIEGcH$_ItVgJ+=&0?UjMPt-*g&tk8%C^I7$W?XgE1 +Iya|&gZlBy84!uH65&Au^_2Fzo?EX^{F3Nl^$Y3XplgxjOh4~G +y>3?z|0q`QbZL>eep&vC7S&N;E%Vy@Vzyt>T`~_?@^;GEsfb6iWXX~RQpkc1RStH(4Mx96zhRI3KtJg +)VNK8|^ow6IdR7NEr+4LnS3pT!EQDd@NTl9pwR7i$`Y7C|S5YJe +5T_Tm>IUFdb>aiSkkIVUsM4@80X=lZ969@;Ny0cC86&SJF~R!_l&#$xv}gl&pT)u7=)E1(nSKx)e_7k +}9Mc(z~C#um}RmSwTQP};-kX2}-L0lL2Z3`Cp_v(O$%=SQG*dl0RVH1=E07JkWz2e!~%2P>Xo=lyEYc +BpkNny?qId&64yLJcM3>UC>35TTfuHjVe#{@H53WH5w@#%QZI*a*1FJ?P1f?#Ezk^&fB+v!`k@-tG;j +s|EI84to&p{Cm6;J?UB}PRR<~-awSP5*eW}iX#l3|{w{tGYs+;(%}m*6@)F4YDWtRIhShC6}jelCngF`>A8Ji1>5|2v +%#Uz4G-VOth=zwMWt_Qngf5b;7o)xg{LQ2Pmi8uG=vCAO^J5Odd4)owNN@bq`=n%l1q{E~hxTzf{jTw +PoOKCk0n1SKaT-b=%aqaRLZ4)vCrah$Z%`P%Z^KETUlxA#I352*nRUNmx;mdSWe)aGa*>H*>yKNU7~9 +7Yajs=Z;}aP4`B_Dfn;m@Qm~Tq@T^BUJ-#E}P?ERj)(qcd?0>+TkFG7y4Pf578rQ@8e$BwnNLY`B9|{ +{fl36FhC-ngS|BrQ(~&t5rrktYd}U>+JpC+yNU&6a1PE*vbB%EKkYi#_quPqhBja_x6 +GoH>m0Z8uvxwtheg5>G#IWaD)EsR?muhYl~!BIcY8(*wl%@%#(5$#5QcEsyh#WAll9yI26`*QjZw6Ll +eMJ;3QsRg0lY2~YavjEYgEC-cD0Gd_;F{fBJ7Dj!}Bs} +=}lJnw$-OV|Vbc_n`mjqz5-PX`Vx4&>mKh?#pq(J|U4+@ICWdbtPhfTkK-9#X#~_%)GN8w@_L9b%W^2 +t5cWil;_)KwoUc`Z0JkX&F|99wUt*5$+xbS4L87lVTBWU7Jr8OpHsrgMy7>$8XnBcJ;3` +NsuC2P;pdYlXgp6HGJ=f67bHy0iHkAzK5m23@o`JRp|_Y+F;$iHA2Gq=8LkQ1WA@x +Y&_WNqEZa4ynZvVtvB_S_L*l3#|xt%N{BcfMAv5U9KrAOD#hxxQ4gL_chf2j6Lx)J)JmHUYWZLNpN-0 +$o*Q7(z;2D=wwza}BpQ^6v{QY*27?HKKT+b_Y$p>T2NPZb`j0rxWY-trxiwTBEbEf>==CPK;H9@Fi|T +gTqV)qcsi$9u6_-BG!ZdAeE;EYqLsS$*mnPDjq#tE@}Vg<+IKxq+~hR(;D^hp?<$f;*(0s8 +mCFAOMDM8cFE^PNK{fZ~ltQH(d;M01+3m6nETm!AoZF(SeN`>@qbbn*#!R;2d<9$kfF~n9PWDKu1~`B +`m?3wTGcTV+XcB+2bAfZijju|F>1nMP!Xp7USTUMml_C6>B|*dR@w=P%rr+viRp%Z;JD0Fj^~Wv4$C^wlie?`iw;M<4KW8X&k-7d%}ZLuPR0u&y?nY4F8;yw#qe +y`7g)ff9}I8^oC`&cTlYZk^kkr<=C%86zodn(7Zx&p0At!EApU1>jp0la2k^QEMtx#SL%;O0a?7fIVL)Ws~2M?SYo +`vd#k1k;10q7irB?tQV#7`Y51Kf7LKh*Z^K`g8SD@kw&=LjbG=<_M(@(Iiht^?u8f%n#KocIR9GT8oW +?~4xX+s>c(iJ0!hv&}bDaF6ZI!B^{R9)Tn|jaS#Q +y=nlfa2O;Une=dT^9*(jH4mq_o_dK*;(vA2{Z?J{^ZtczPA%*gMiUV)}2vj{gUnjntP~gc^87M!HycPc&aR6UpPr{ +%pL@@iYtj$8b-PBg!3Ht{I*|mOn+_2!h;hmf+8Qp`0FsdCbIW;%Z0+k@4#w*1P>c_aGZC)?U$Ua+XUg +QV{bafp;^MEE-~451=!$dAUx(t>^{&BhtaE9yvV(7qy3UY!;aJ*_^`{M8Wq*LOPq$qM-7SK>q%ydzmi +d!AjEYj`+GQB|Mt{$9E$;juTL1`f`~6r^||wq2hkF)dV(vFt^s#FPCdW_jSZ|NGjJX|FVfw!ZmL=3SL +X604#1g#mz;)`q|y$v1&4bZoJPFc0b9_ezK6g$cfWyso4f%|+PbtQ3;_>?m08Sc50&&CDpDJ%jw2X3K +^iBa{1V{aJe3p<{i3Q*-7vyGq!vASTn>7<5%AOmt%4tv_2D*A(cwq!__+4I82BZS*q#TxGJGcB%`rBU +C3HK5wG4l`^KiXGuqMencq+?cI&SkFsBh~@JRsfe$E5~9BnhhV#m;n9%_$Q<0`wtypAAgrfn&Pd<>wA2>2j(f5yil+B-(tZlX=5+&jY+V~+;Xsw7^vKU(shN`&Sff>%ucZx87< +0r2T5WI6^m6YVT^^9-154bo3;k>Hwb%i2q<;4!7`A+X(g5C}T+MxBZe~hPK!jPjjj+R66Gb)kdDF{Ng +E@lVfTPkEW7=*%t|dsO`7dZwqTl>|<>Nsn{O9VI{+Nhu|>+E_5Xi^-*$bl#UpHa10Zq94ZZ;;2CN>grc3v$DW6P9E$|nAL?XW$$k-XH3W>$P=I +H`KY^J>q}4wq<4n9_tGmvmGSw9=oOHCn&1%!1aUu%YHSWaG)A~HvHgc=zvLjb+3^}CYbVQaL<-AMvPH +rIf=OJ-HjH>`u!G(Nd;|_pFfvRE-}WNS;~-eh17XKxM3a6WX!8SvH@5LgX2})wG3?pXEDv-7Wj)T@9w +&YYxw+#sh`UUQATXwU_5c?xlYdy+%RdkZy32)Pg;1DFjjhkpJdT8nr}L608uKK@FxUf=cb@l%@Xu0Ah +R<(thk{~#3HmH{-l^aI`O=%j>ICdJ0`!*cMO?^>gQX`GIs-mBtzAe~gl*a{hef*Xe%miuyz{bd<ZHh+&(5OY1fJM#_l*^Ff)fbUt-D&39M$1XjxSfroTgqpxY?-Jb7`vUR<*aP5j(-ApNO{y+BrBaBI +IQ@aR%^5q6>aO0;vS9r4A&q&vPVUhKpxOxJhUfwaORkFz6H3N(ZZr&*+8&`k1l?R_*colI6&9X}45LK +y|mvc=wSg&-B-WRlpcg?PR9B#K-t&81{jtSP0+*Gd~7J5LTT9D@gjg +|Jmcc$m0xa=^%x9IbQp<5BkMj0)w6m`oRW2Vwc!pf-uSxR{;IHKIw<6{gM;=(wjpYb;09(0^Z(~@M2_ +e0}-)7;&Z@j7Te?`&wCo9nM;VuGf?N+R^Y7^N1JNVUpM%7&p!9QmOxx-4_sqRYfnZ8mpYNbz*X7vg3Rztz0rP5iz +=E#E_E@sQx4+;hK(sdncE>x18kh>z!|d4QJyIl2-4JwcR`WD)_VW0Ea6m(C2v>(KTig=CbbrE-a*paU +>A2dA{8`xS;5FtOFh-H&Nn@M$FvYCg@}xqmF{^nobLr`r!_8D4VEdmivhT<5SpiZID6Av%1LFqv%d9t +T4`&|)aMUB8JtOgK5nE)0_g=RLpFy`IPRmt7w8j`auhtNZ@k;txMN^=Q}^Q$cZWqe@ZW!<@>lYok_?d +e355xLnLb5g}6Zcc3h%mCKBG2&kbM=S~<0mcTMQM}kwiHm5zQdmSZVkgb`?AU~tO?9MY~Nho$4N*6+G +=|#cq(M5~E{XDEdsJmb4UU6$4$*Wl%z)qc1`tLUqa=1f1V{HS8?ioT=IBxFl;||BTRTK<9U<>4$d +;>usrA7W`D06b+7X@Lu(-$P6X8KWYC8@m6+q85^NEQ^~jYLz!s%A5{{vQvFQGmGwNO^{@KB{BAi1Ip; +lx=Ql|&EoZRbyQX7DbWrBrhWl|`(PV33=nk3BhOWiAF95dvvLs3Tw;;x0|z`}ccQXuyPpRCge+(apGa +N@pO{(tj_le$;3aA+1b6W*+(2bb$`wM5WtE0WFp6^4Raqd~bY6*uY6;6+6ER?khv~u^`e#t?y=&%ytFxTc`5W?kIR#>=3-~f~`ym4CFxp#C)+O0> +2SnT-Xr0%uDN~>V-wiNYCs-oY=8eN`JVKWiBiM{Hu)`GGH00N%kW4YhvJrC`dOz{ED5BV9ga$1OqA9G +?xAAsS5`C6wj9pL-vmaux&LGTe=Nc(NSWKx^)m=@Uc;>k0Mtk9*7QBN{dk}jvwXj!Lb#=|-_643bT=k +t~a>Runi+^b0hY!pQvgJmCR$1#*-7X@N~3OT`K=OGh5t^M(@I0d&~GR@;)hkz`Tmd8G=vTKF#iLqrM_ +(@A#84M3w=kgzYFjb_`anCPxujlXx3WCUD_o9GkjpXoE*bQs!vO`arm{=wt*Q)7p?0PQi3GRNWd-d!9 +d~%JgB8`e!g<@+C|6uBZ^G>B-A|b>d7;a(6BkPNsWWVwfroaj)osOr;X(9q^@N3VT3ssB~T*%lQG$ON +xnM8z-(IIjg`2T08%CQulg>b$Hfh;Hf#6l&e +0d5u8>jn|QQZ9ATeik`JqlcBRQFZ^V7S<$=1_gMj$NMLdB*4}D{Zf4hi?!c(L{A(CgdhLxXo?t%gb-D +>IR_B>GcdKlwUOnOqPG14IvUcCs0g?cI@X?Yc&8_t(o0`JX|Z8z53`+~aH)A&u4`P}6+EIa!RZ);J9J +UtPzbU6X)hkf7;ne3H)5z~#4_jvJ3hHHBGrp66}|3t&8Tp1CyLMPU59F_ns9YW$aLrvl9<@4`;7krXs +w@S@qiejq$hMSMHMoRaJq*#xLA-F{VXq^eufJAxu1?-OG_t$yfLe%Z^~0Wk2xK_|M)EM2{K)7|6T9NLbV-|ac=#G1F5?oR!G|10s1>^FSXIi)KmSiv)o4I +gv&Q4pzd`dQH;?AWGV6`mze|{P-c^u +UDf-yeK-x|PA59px_hHNoVjNyV3)hzuITI^&8YfjiVZh4^Y^$}aSYIyLO2(MXyiQhHVu(eAvl@a!v9y +Xhf30<<5G}znx?4<5>jV;#5gP7rDk|$4KS9*4r!yrpFOZDoB4S8r^JvDmC>WnWo2M4#boyT8C(JWNiV +vVNmFf~?lc;t)pi>lOuGiqGdPIQU1m(z`i@4Wv>-Rl579CAF*VGq}N5$|EOFUu!%wan4t7<>GPnzWOW +*T;0KJp8cFQBic>_L%)?E&ipLdh|m1A=)N%8`c?;)}Ed=3)$YOz*^uBLiEt~?N?j(N|pUFEx0v7Xo&# ++4kr*6xMz9@?&*#~d$6=?$k!1gi&w_BHG3aZ_qv8#lVAsN8hFBw<-y7=Vz`n-a%qg@W@eY~QuJ~&D?I +Gbb@xksiDyx*B*(}cqQOHDM=h-920enp;fe#&bHZd#@|DM7JtPsIRUh~HmXo^ILoP>VX;9sGoT>{ek4 +XNQS0f=bjy-54g9!?!TZRtqVK~?G9`EJ4;R)($r1feN8E6qPD`^KnCM9?l6{r)fg;lLs$bpe{2~s(OC +$>IIHUfy&Os71^LY0l|5l*(`5+B1B7XihAS2oH+aQnju#m*NF>s~Fv;F#usl^qzFgDULfR*bBhXZ68I +R`5MSBY;y$6oh#8s(3E-x%9USi+sWvAoWMv}o^FgiTf&P +6ME0)=q(m>Vj7r%skvGCZ|KBa+EC*d_|h-x@J3}`NM+fw55u`|>Re>;`*vNR$Uz5obZ;&Tx@C#s3#c9phVrNUj$Yh9ty%x*A8KcO$-q3b))X}+?fY`P4mZ8lQGF_=m8QD?2zAc +tV6hQF~7JNBIXf( +N{tMN`TPTjHgTj+Ho^ejFJ^>75+Yv-658v`-7n{H%t42z;jJz5(CIYV#kaBmQV6i^CaE_=Sj^qisxvD +i$>1K_ZsK^qoQG*H*3Dfuy+Fom1vEiBQtsWm&($Fw9AjBj^bgV=Gqz+hzn}VTzvLA5&%@FZb~JgEsfs +-O$u2QQ9=T1QPe4AET6Y=wSX{X0=GDWxS5E*u_k}wS#+)uu69MD)3Xz{_slVsGsA=>-qcF(YU2NDK=i +M*oajt!A7A=AcQ(KYpgwxJ_Q%uld-qiA1*e%dxA5I0cOhtU3Cxb)7qcBg0%VQxV5d`@p(mD(J-Ys1MJ +yC>>D2&X+kbuX=Y%0F3KB*2$c4DkwM+- +Fo;>EKeSdl!NVo?{XB{0JWzSR93ZI(Tuun{nyPek{oLofhjp*R(=wL7E89?Y4)L6X7KiGa(%<0?N|Xo +>ue>R#Qd!~Vbp`lJ_dHnlYSCqx3PnuzickL&{~j9xvpk4^&!?thA1To+vIIJ?66SrM0{02Lj8nJ9i=d +{WPS|sKc@oCJLJFZO``DUm&-)X~A2{K|v%`2pYmR$<&EpWQSjc9HuKJgnleLqa(qvTA+T}6Ms(znR;I +!BQWp;ucVi=4?^vAfsi@(Z8j5wpQ +_{*5Rh~v4lqgtnZkQp94%f}Wz_*`vWK4xOfOVfb`ECT$e8iSZE_WJ*u?{%F9v!{*{V;>N*GbqsJl;y3!qR=FiuU2eUmJ! +{ZU+ye6!CHCL#v;xZSp7?7AbFkox0aGO|*L~<1m@xkxblYlj)cDDd6Z?u{AyTjafpESk&bWRm-Sm$H$ +Z%b{y-`LUs>;Vx&9OdLQelQV)exp<2}IL_&+?J3t+tR=B~#?ta7jOE{nPRJt%Sxls_3eEKX-?x7@>7S +|0%?$?AorKyA1dU`T)ZGMLBeL1W_U*0hw-ZZj4TsP-|ok#H%&|+@>fnW0Qq`QQ}girRuy4R2iP^uOREGLnto&=H9+|%gqoPB>{roA|Z +Xvu4zrm__GJdnr1L0;3k*V9AGo>Sl?+G%MjONME)B+08i9#koNOrNOyAiJ>kWW<&;>Ry+4oFl@Ee-4T +^j>Do>(vrd(uE03bECk{GcC)=;#S;Yp1YOy6$8XfVKD>6$TY@g(9EF%a2pwfaq!{O$*)`< +stEdS9Q-2GDbx;U8dFtjL(0)Y?&8NEijxvn!JmbUb#;4#?k!#LIwb1nYXlhnN~%Yw0yhbNy135S&sR- +p{ngXoTAQe_N%62HX4lGs)7^_lMTU=D{KRM-USVKyrqgE%AN6(|H +z(M2ub%%!b8g~Kd`uj0ramT4=+leF3}%OUd~0Eg$FST$M|kyo?z+rD-Rp^=THZBAGJ5AV_1R0qC- +H!`W9K2+bb>1hPD-_^y?Te#C;Lqw3_*SF1jv>L>RumKag`k +rSxxo@&+G;y7&$jfSo`K8d}4X^r+)EEKy4>!tD*X&HtzH=9v +;m+43zde;ALU2kb*PzMJ()h&mNimy!|NZUWaE1A<~25y)`WZz*n$J7&rSImJ#A1xS7o^59|BzAMhEM# +kcE@v#5K0l!d0J6D95@&`qm408oaXKohbzQ;d%kjKd2x%p8_oQYJLEUrpWXNlJK>JZN9yhc~jkt_9I0 +nL~`futU?kxXfDY5-~F0)DJD9+R$1o&(o9PQyE01pH8xh1|w%3lVBE4X;^jfv(Q?p;QEH5kOnkQc+zbb3d%U#(I6FiT>E|&ug){is{ml`_ +KO?OlMbZX;IOj6GXtA@Qls7Rkh3cI(2SAaWaq8r!C93RI?>w`mGclThad5kP)LWlu-yGpU&4b2$CnT5 +ye)!Q`<670V4HmM1{j!6sm0&~+_JSe6+1lBM7h+w>+q&^uTS&XM!OOY)Q|^S@G|CMu;o=Y9DO53Iyra +t5Yqv}*V1t`OZmL#mpsn$#5e4eg1(caz#-x~U7k}N&b0zhufgTfJICZuA%x}35x4ApF|B)5!+L9zM^+ +fjDZ27Lv1=a#@PMiHo}5lrh@rlkaSqg+I!t#R2+k#TQ_0h>W(qVn5;DN$PQ4Kk;CURLB4+jnQ#+}gTl +yZuU~kvMOzK`oI={?=wGkE`do;>2ol@_R*1@VRHuJEcC9HPc)8}<;_$9aeTK7ssH-~4jw7sXN(@5`Q= +e=}=619V>tT}Y%%!boZnDRp60n;-#KbzFOo|JR1rGlQy6#LT&^+s2A4b1X5_GA38lBx1xRlT;yJpQ&9 +le*W%&Om@|-(A&yA +QJXL(7$>Dau1mW=D=@Ua(%?}x&Nwvu06-oT*0ZY2gF=LoYP$KCJAJ-u4orGo>o^2)kY3J`2m^<#JG6a +YwE2lL{d7^YIzwDa2asoWXxa^RPcDdMA~q=!}ZnteJ_F{-;Lb@Fb^eR|a;pq}^Kmv>;OciheS$=2(8Z +1A(8lw)|TqVzc_8Tw4Lqkd(o3NTB3X>ZY1G9*)S0*5vF;Vk^1xaxPI*p +g4a9a5Odgk0s|JE7;!!P6LND(N@=9ZGV8Di5`A~E!+})Krd +SXQ@EF@@s4PtlIaE)Jd-IjYPg9+|?FDtOC)w+18UEOFPtbW;>}cl2CBvmAh|+!b0KCN5&>}pVkox-DZ +c_KUq(GDlodlTYX|RLF@=hmH*i$DI4X|&Ikqa_F)CH%4c{G-5*JV!YUO^f&ExI(+G&7psyzRx1{*}jY +Y{6T$$dwSI^=oQ}_Eo-I8FK3f>RuPqe(F|GWpo(e?fXEyQUdQ-9`F6Q;NwZYa(Sskdiy3`w;*!ud%q@ +iuji(c)_Fq*rV311#fiX>OcR=Ecn^dKGe4>jwZeW3xt(3NGO2q#DMNb1zLmufV27kH@K^CFM}bcG-P- +34PN$`%mS&GIHAIp#c7AhG_j-^Vo)*^d`9*R1Nu~9&bUeKm5Sv3>k>Rt!+b;AodxTod;SzQ)6TW?7gcHX~py +lq!P*M;krEjsdrL9Q!qd7$ofkXxDX$rfOK1WqN8@_lncQ*vPx5XXs3(bHk3Mzn1WuVbi_ +y)-&R)5Fl{MbnNHruWvb9p2xWq1y7lJ89h?t8Bh-8fJj&9_$$*Sd&4W`*@$=Am#MW5`qMnXOOViIzh3 +)6(q)jm9NwiQnFofS7NwkKxixLx8H0~2bNA-VyN;hT#4n4OYKag5hYQL#O$s2Z%ffQs-cuqN%G2X;@Z +6am<}$ItaE_fX^r?=Oxo$uzXLywnu$mmfa@ +?NU7e{!*TKf^gJC^CIM-6pt(q7u*75X(?+wflvanBv7ToIur+q~RdfcY0;Lr^*THPobvjjSygZPmlhu +7ryPI&vWZ_>Runh2u8H<)RrX`oUWOkskh8+X+gb)KtMvO5}#sl2g~sGq055UeV&YL`^&?^8r2qeKpi- +|%UW&;8JX|XDjbg}A9^ii;hk4#;UVqs+CZ7y{-kxUmmA$cygD>W>!0 +@XX93U=nVq-4L*45M$r{5NCr+7$ipI^cpMch1 +nrv6xn}f_A`I>lYc8<35RvP*(?!!|Z5ftq!>w$A5iRLu6W%C1B9@J5d%L~4-Lzl(3z*jc-@>>XCBJ@k +$>+mR~H=MD(r}u+T&5hsGaCmVn2-EZB9BUF)d)NE6Z!QoCg}csXQun%Wx5wO9!}8$NU+$+{KyVpei!j +q|f=(RX_ey@1*jA^@@`C&Rok`v6vF$AGiq}_q3GeWRKJt*bI)gHnd3d9sMfbv>aO8yH67FH=+g_Bs1n +2Tn@2JQvs+AoOav$Dvx-VbE8xcU6Avaw={qhpX)c!h-ZQrbWjs5oQ0TV*bR$58!l~5jxbIF+V^snqoL +ZJ|l6OkavEt$l3etIiW(*cU6Hi@tOBL@clT{Fs#_0r|N58 +9*U|yRV8fj;VBhF(R1T|Uq^aSQu!rDb2r}hg1Xmp7fkAF63LOIAD8x!d_bBM@RmcbL>WF14McLeRz|)*CE#Pu<(?pUb@e|vtMYUjNsrnUx0dR7rc^iZMNxsFWy6c_X{t1>b-bLt;hXb9uoi(TQf +RZ&|Q;@|6-8~&XmD`;D==MIc~j9-Rof99-1ug5pbi6O)dWkJt_}_Oy_~%UwL#3`~4=QJ;-LRxb*{duY +=^k;WrOh95g*rM{bf>Vwjb(0@lJiFI8YxSE?)tqcF15;4q)}c)3?iPoF?xc{APVeJlGrb5Qf)K4Pm2m +yuP$C8}xdi?GVJ{-b_a*1hJI?TcR{0AxrwAUC~VZr}0^IZ=r4L6%p;l(!s0MZK2(u!7}Nzwi3>0jl*H>=6&bL{-oJyC(2S;}KEk%A+$K{C%eKC`7Cw_`F4p#N_IVT%48hdZrKBjuD}vPjSXC2P)7~)DLTDA&xX0Um$r3)UJ#T +bnTxGx8G;NkUj7VBCpV6m7-NIhUGx%S&Jyb_Sua>3M=D9n5QF26qMy8Go`HID!q%#vJNxwFC055soPG +IAgQ6m{Yc9B{T}K`Kt#vS4U=so1A}y}!g+HD>i*GtX*zV2J#i>OugO`^(RG^zcp|{NKy3Um(cw?vZ_u +_uBWpx=FP|7HEJJmi!ff;CYSmq9#ctY5?@H(%DyxG;JQV*nSjO*7bN5PO5y;d-l=(>0*2C0QF*!?2YB +#`tI?>%a`-ikmrd_oot@UO=Ru&VGN*F6S+JM|Ae~+R^E?jnVHlMnHroQU3kpX+p{FQyApZxKCWrv9H3 +wL<9(k3PmBz~xc`CK?34YO}o%=RSJpMy@dknF-y5+h32aZd%ed9Me*L1$NDj~4)8Vww*r4NM5cY +1ioFB=R6TMg)z6q4@qn;fEfIZv;^v~rEG(lRV7k03I0?pbohO$%zWonOc6P@Yzx(0CckjP{!K&^7U&w{S2};3Z1LSmS4$%Jzrd;wYVZ`aoT>>E;ge=xck +MdP*=IET~vvivm_y~jEcApaB+>zqT*t4gW2M0o5jrx%j;WERjY2}OY!XDr0eqDE)H2O?Q2te`lo`$YvH^^1cm%X^nN>ajR|u)M3s8zQLQUKV77yq0A{6xA$t(Sp{lJNZg&QuoUS!MrXs?o!cM~wZd4?K}2IfNc9FM9S~ZGg$LVjUE +*4EKrZ*L`Spd1)+R^dj6{9wxM`!$8u=icn(_7c9MCU0l4|r9+8>xX^wJ&uv}%5Gd*H?iX1>_bru-_ZW +MtqFacn+64()6o)J>o>`RMFYg}qYF!J$tyH=8m$H$B?S7FJZZcb5zh(uksW6=Ag;iW!=de7}#wp6hdB +4Tsg+&?dqJ(={vUcqv!DaC*`K5)kyL8?#xl5uWHPJ8kdTFgaHfX7ZDePUijEf49C33s!UN@3KdWIS#z +HDM~55V#}6uiybuL$r~d=C6CPGc`hd;`!FTE8nw0=V2Z%TDj)HJIo*Tje>$~5RmM1MwTAs8#X?fD}q~%G=la_;L4O$FZ3|b6Y3|j0WD>!f +WJ7_s*IcPa)IcYg*IcYg*IcYh0)}+Ox#iYfe#iGUSJW@OxoQV(WzJsEy;LLb%5IZ=S6dXJV$}9sS8I( +8#a535U%bwXqmK3S|%-%mPyN`WzsTfnLI0LQM4#p6fKGtb+22oZbi$YWzn)|S+ +u-pdC~Hs#1i4Kk$xunmB9kkty3R{_HdAV%Q22VQ7^x&ss(AejK7#C_>J@l^MVtblFF6HVd#>z^4NI5=84kkRJs3LC_jEq$fz|evuV|yCC!mqMaZ<3B3Hkbq~DNz=I5YzQD-~JgmT +D2^@gHTE}rayA;m`XX1mbZ&2JBoc#@sWCX=tL5euYgakookO&Nt)j^SMP^ub~ss;oq?k`csAMJjT6-r +2gbbr8cf=D6oz5+BAV5oo;1>h!#;DZo62uFjkF>p5GxbAhkST|&a3vh#Ln1Xw2gIrQ@{xUdc9ONznG! +>M{2X18Gz6Ax5L77uf>=5^ty5h6E1QB6yfnIP*H8?vNToM{wml4#z2PI>HuO8f66PAhsZ-Z+b0#q54` +Nz4FO!zF_F9Ji^L6GhblIB4MDM;!D*G~j@Is}{{III~Q(+;q6a1=PG91RZG#JMj!!)NJ!5g4NCpae9? +;0KA}Ai)^m&Y)&HD2@*5FM~S5Ad4Fmn+4ThL0MLu`%)ZymhKmUAq5}g`+|f{kQfOv76G^qU~51vf>gst-veIPniJOp?@z?cCK2t4`VKAzyHVZet1)Dy6p82iu(KFdpRZ$WVIDyS?EDsF?i*`Pvg`W +2setU=~H$Y=)HoPbCMm?k*R9K>C-_GJ(FEZr}XM5;VEQ5c-Y3r^z&r`v+VFTpvMpd3Dc^g#(<5NZTyK +7i8!H;u6mP2sb2zX%cO)gZ$%%O@a7qzD3J8j!dE6a-Of5S;~~LQwD&lqv=F)-mQi-u6p^ymnBb7F1dV +bv;3{BB;L!=wpBsgLo>aTn&ozg3^?rbR(#k49W^)#67?5mjv~BK|x-Syb5Z{f&!@^fg6+*1?50N{ZCN +96I9j&WhDXA4(dpPN{Sf!GDLiq?iWd-)FLQ^2+AIUl7XN+AV}>8>D?e{AEf1joO_Te50cC8jg$w_2j`BvEV#daNH{>xC{y_g3`pGz%MMuDu<8Aa11Co1{C*~{Nl58zlaX`zJO&0)v7@S +U{Hns3CMfQowUJc>3$I%&b@@kS}wmH&GDxH&<8@~g;(A*vtJxB;t)w +t2_L|bIp@7@_$8bR2@ZG!3F?5b1y#{OU2ss>8I*qnl@~$cG(3G!t{@5t#udmJmz2NmliNqXYmU-~>U!E~xGe3L +S&`wV(hks4feNv4YHbtnKgMvvj|R6Djy0OC2P|f*e(l6BNOOUP%Xn#;G78HdArC>n;SinJpBCnuQCSuz++?AK0_A02V3d*R0GOD1ADyX +0eE2tnX0a^;Gq=FKt33v&rpMs=ZkWh;_?(yQ6P%0GE1_hNsLAgkPn!{5gxSkRAYez^I^*lipPf%VH7$4pzu}Gac#%Pp+d*1q$z_8Wsr +W1JBf!Q()}WXWEq3BVvqw2GJiojFGxoO$+jRz7Ual+d{~eV3ld*Jx+_R+#a&E|BhvjMek8BLOGvPNL8 +2?+_#vf}}!_R0vWDK`J3gAw=%Wt?)s*UxbK^ +L69N{)4>LZqzGa&e&3l5rUC=p2jD(n_5rRBAbsR@kC(&7#+G3C0J#UqJwWaOBo82Y0LcT89iZm`S_f= +8fY1Si4$yPdJ~V~<@ePE;$YGt?CBcQ$UgFWnrqi{SA$&}V!enSw|ML^>eS0g(=fbU>s7A{`LvCNG=^%3kI@Ui +=cUbbzG;EFEC!D8KA-|3n`M7Hm3T(*c_f*mS_81123X>8Q;K@GZJu1PeADu<3wJ2W&cE(*c_f*mS_A1 +2!G7>3~hgzKO~OMXG9F=8137{UTie>hO9T{YfZwK&b;t9Z>3kQU{bepwt1S4k&d%sRKG4cXAuwqWeXr +pwt1S4k&d%sRK$KQ0jnE2b4NY@d-RY)d8vwP<4Q+<9goX#V-L>2dFwg)d8vwP<4Q+15_QL>Ht*-s5(H +^0jdsAb%3e^R2|nYa>bA6evu?l^;90<)d8;#cy++51702Q>VQ`VygII({H3kUC=aV$lz_v~{UTEk?0{ +TPU3KtvfUg659pLM@teBjBn2z@6_)i21TN>BqlQ<0BFX9Bt4p?@;vIB-4FzkR~2Mjx4*a5>17%J_;$j#6Rw?}q(c`aa66wi^FJre?zoWR*#vSYkUN3g3FJ;7cRrnrMaxCYMa#tl7cCYo7A+Pn7A< +Z+isIP>awm{Gf!qn?P9S#zxf95pK<)%`CvZETo@*-pnlwwACC%=*kmA{dbSI=cA>9e-PDpopJfVEQqI +vlf&5NhnZ_%u1Ry4c)b&6*b+@0X=1a~L6JHg!v?oM!bg1Zyko#5^ScPE%T!Q2VvPB3@gUy6wle@Sq6g +1Zyko#5^ScPF?z!QBb&PH=aEyA#}tPC-gg^-wFLr=yyWD6Z)Od?}UCQ)H}~zw2uMqevumJcS64t +`km14gnlRVJE7kR{Z8n2LcbIGozU-uekasB&)cu2cs8Nm3H?s!cS64t`km14gnlRVJE7kR{Z8OfLcbI +GozU-udgpoj)fCSr^gE&73H?s!cS64t`km14gnlRBI|1Jb_)frg0=^UAodEAV_m}BmXS-iy1?HW8kw7 +_7C>p?b0=^UQoq+EId?(;L0pAJuPJnj;ymRdQJa+aa0pAJuPQZ79yA#}<;O+!>=g@~<{*~rP3z$2>+z +IARFn8XU7Gh_+U!(@yo#5^ScPF?z!QBb&PH=aEyA#}<;O+!-Czw0I+zH{%y9ge`+WjImknV(ZC!{+e- +3jSVJf(zmC!{+e-3j5&;qZ}`eTfCj2F!BTQPMCMXyc6b~Fz;5z} +|3HVOHcLKf>@ST9~1bipJI|1G~H=o3kz9ir~0pAJuPQZ71J_b~g(C>tPC-gg^-wFLrz;^<^6X2Zy@4O +F(U_`rLv<=`p0pAJuPQZ5pz7z1BfbRr+C*V6_-U;(gSa-s@6V{z`$MYD`?icxic_+*}VcrSzPMCMXyc +6b~Fz*EYCSh$7_a^~-5-TPVV$OY-8~fS)B0u=csbN+8VczMX_WLKwA)o%0K9C#0cLKf>;GF>Pyf3%He +s;ge58yii-wF6mz;^<^6Y!mY?*x1&;5(-ikK6#hCvjmyy>o6piOKAKjlrA;Bnj}HfbRr+C%8Mo-3jha +aCbtu6T+Pk?u2kBggfVTj~BlL(w&g*gmfpQJ0aZ( +RNOwZI6VjcK?u2wFq&p$q3F%HqcS5)m!krNAgm5Q>n?o%2OYv-iyA#}<;O+!>C%8Mo-3jhaaCd^c6Wp +EP?gVoum^;DT3FgkVFZIVzcE3mxxI4k!3GPmCcY?bU+@0X=1b651?U5ia3-k_rqWA=O=i2@bhO+xbk^ +tWc_)frg0=^UGo#5^ScPF?z!QBb&PB3?Zxf9HtVD4OTj~BlL+@0cXeSUCvg1ZykosjN?bSI=cA>9e#P +6&5GxD&#i5bj*NXcR-){USs_?gVltkUK%!3EEE3c7n7Mq@5t`1ZgKoJ3-nB(oT?e-d~c6q3nJUBG7h% +wiC3SpzQ>0CuloC+6mH5kamK!6QrFW?F4BjG&^G-Zo*K$Bvd>7Haf^jLbcP2L(3;1Ng(Y6X(vcKLD~t +@PLOs&vlE(~vFj1Bk=-vs1l3Ncc0#o$SSCT+3EEC*b^@{!kez_+1Y{>5I|11V$j;bt7Ur@0MUueS3C2 +$Fb%L)Ge4XJt_!#5{UY+pjgjXlLI^op`ug;rSV;;L-)d{LjP<4W;6I7j`>N$M^a- +;qSOy_;+F-EcbMScL(37byXbi$?+ES+HK1WPAGIw8^tiB3p#LZTBAosj5^o%hEmcE89EL^>hT36V~Sb +V8)l<3Q?gh;%}v6B3<}=u8jEFfHKdyf2l;9=;@4I>FKjmQJvAf~6BIonYw%OXvPV-}EOsLX2S236oBk +bmr!Wn8NNCA%aaOY&v1n37byXbi$?+Hl48PgiR-GI@6m%94cxEFrB&cBACMN7a@X8Cu}-l(+QhS*mT0 +C6E>Z&>4Z%uY&yZw364&1bb_NZ_a!Kp!k1xK2b)f>&;%wXfI8E`=nd`vq$6YsN}W*Z^lCgqCQxI6_HfI0!x36oBkbmn!>FMbJZI$_fZn@-qt!ln~8ooMb$tBSUSPd36@Ty}}uNb=?FOnn{F>E)!&>hyZEYs>f8gbH=sZUjT3XjsVr)Aya#V-LyConpJ(Fu& +s@=H~H0`dcqPKb0uq!SXIkm!U&CnP!{(OG$q7rz7|oe=4SNGC)(A<_wvPKa~@qZ1gNK0KXkD3WLUMA1WTV-yo60BY&v1n37 +bx^bb_T5ES=surBex;PMCDUq!T8c_a!J;weI)O3H5J$9>D@oCxAKu)Cr)@OHYX4Z%uI6A@6364%kbY8c8qwX~!(g~4Hh;#y@6BwPq=mbV5 +Fgk(J34~6yqp}BtP9St%zQ}FgsC!LdbONIj7@ffA1V$$?I)Tv%j80&50-+NKoj~XWLMIS9fzWw>nKTx +x`$e39(Fu%BU~~eb6Bs=eXNYt{q!S{YqDe?}LZTBAosj6fZu>^vYeJ+GBApQFgh(eaIxoe^w?UFFMW! +XGfY1emE+BNlp9}t6&&?6BTQ3ENE;w|-p$iUOaOi?V7aY3a&;@@k_;bOZxp<79Xm-%-pxNe#n5^#ir1 +?p6uJmK$7DT!r(gl$&h;%`u3nE>R=mJ6)5W0ZS1%$5q%R#YL-S6;qHQ4kq=wr~wpbt)K%j8)}3+Fd!k+eu!)IGl!>sGWZS{5yfmPN~=Wzn)|S+u-()!}jxKO?fujo?UB^D;g$e3@5g +o8}L8Qy`)?QD8r775S!KMo~U9jnbO&4ssVA2JXE|_#3w|%4TwP4c)n=aUN!KMo~U9jnbO&4ssVAFMY? +??I(njt}e=>kmGaoacQUJHC&;NyZ-72Z~1g36t`SI`Nyx8i{)r0GZyBPex2r|Y=65p}Nxr7kFSL8%Ki +U9jnbO&4ssVABPgF4%OzrVBP*FzJFx7u2K9eQ5yp<)vWL1)DC|bit+zHeImkf=w4}x?s}4HrcY`S361)DC|bit+zHeImkf=L%lx?s|Ef2km*rTayGVABPgF4% +OzrVBP*u<3$L7i_v<(*>I@*mS|93npDK={k3Q9@EnOA~mq-f=w4}x?s}2D0M-p3rby3>Vi@il)9kQ1*NWC;%Jx14XC<6)di{^%h7FKjX~*t5h8eX!K({iUGVCHR +~Njx;ME1ME_ijps|#K|r-Q!yhi3ac83v{MMTmgb1+*@pb-}9(US06&f>#&3y5Q9XuP%6X!K({iUGVBz +agVqCk^){A(7J%u1+*@2H-oAarub%C!7d|lw{0$&&Sy1>^pHaEgbbiarb7`wpO1->rub%C!7a$S(?f?OBmx**pDxh}|cL9PpOU1M`23 +`F;fBtftXa$S(?f?OBmx**pDv@W1^0j&#YT|nze3{jBlf?U`Aze01Ui=a;c7d@Aj9uXC0$-naj0M9k7w;VtMJE}(S*tqW*f(^*1pfYt@HuKTiTj6wH{`~a;BXk +9?-0$LZ)x`5UNv@W1^0j&#YT|n!CR~Njx;MH~WYK*~4!K({iUGVCHR~Njx;ME1ME_ijps|#LT@alqB7 +reUQ)djDvb?Y7KUJF!Rpy~ou7pS^G)di|9P<4T-3sha8>H<|4sJcMa1*$Gkb*)_&gbC<=5g1T)fvO8s +U7+d$RTrqbK-C4RE>LxWs!Ic*Dg{gzV7k`MlcD&#Ujzm~T>$C=P#1u@0MrGbE&z1_sB3u-Li(RHLt3E +J1)Z+7^JM7!?iZ;6P}lPFT+~QpUr_3TQWuoEpwtDWE+}IZhx}ekrr7mLjf=*ZLJQ+&YV{US;5>Vj7nyt+Wu1*$Gkb +%Cl2R9&Fz6Ysd-)djCEcy+<6>*m#H^X?aMf>#&3y5Q9XuP%6X!K({iUGVCHR~Njx;MKM7Een4~vwdC! +ZQlKIg#|!o0(1&|UEu2iUsu=&H586A{0My@Sm5gdUl-)MVxN~rk$1ny6a>2<*A;e-OhK*-a$S(?3cYE +cfM9{I3w&MR>jGbw-^oS4_$6TM0%I2#yTI24zAo@}fv*dEUEu2iUl-)MAlC)CF35F3uIs*p3ibU`!0Q +597tp$Z)&;aKp!KQ82)QoEbwRERa$P{{0$LZ)x`5VoUy_gd?tT#`pmhPQ3us+H>jGLA(7J%u1+*@pbp +fplXk9?-f>)Qf03G{$7Mi>JMVx@v1+*@pbpfplXk9?-0$LZ)x`5UNv@W1^0j&#YT|n!~?N_6@yI&*;U +S06&0#z5NxVi@i +l)BR1kQ?Z9-IuJyuL^@)8TJn-uB(j&lS<*oxkb9cW;641JU)&;a +KpmhPQ3us+C-N^GH*QG*2#}wqcfYt@HuG)1VXzrH+UKh~1fYt@HE}(S*tqW*9Aa4b^F35F3t_yNqkn4 +h67v#F?yvK`Q0>Lf_b^)ymXk9?-0$LZ)x`5UNv@W1^0j&#YT|nysS{Kl|?z&9$b@z)T0j&#YT|nysS{ +Kl|fYt@HoðS{Kl|fYt@HE}(S*t*dVPM%`-xuM3)6%IgKwfs^5>H<&~fVu$G1)wefbpfagHeImkf=w4}x?s}4HrcY`S361)DC|bit+zHeI +mkf=!?D2f%azrt8}0hfuveUepnQx&YJ#pe_J)0jLW=T>$C=P?tv8Z33V!0CfST3ou>R&Xb{ayI1mr7kFSL8%KsU6&K&V^Bke8vyD8P#1u@0 +MrGTu4^lwEoaod7L>Z6)CHw3D0Km-3qV}}>I*=90jMtk^#!250Mr+N`T|T}fa&Xb>mBM|F97ugpuPaq +7l8T#P+tJ*3qXAVs4v*`1)IKL(-&;|f=N$c*9Dlqp10ni?)8FAU$E&5HhsaSFWB@2o4#Pv7i{{1O<%C +-3pRbhrZ1TE1&O{O(bx0VJJh{i5a|mTeF38{VDtryzJSpeF!};UU%==K2z>#eFCg>UtsAAEPa8cFR +=6lmcGEz*VCyjS`;mAd7$p~dOD7xWzn+!@0#u%*^wpM&9L92xDnTq#|30PpxMZf94VyG{2gultK{&U? +%vGe13Ov7$7J@J={3`9rq@ibnO-wJR(g%}8tF9}nU>I*Z{F$WUehuFHqjt!xFIR?uk$omS6j^_=0}Fj^zi>N%~R)9N|jmrZu&{2RB?X$75D&}jvoR?uk$o +mSB4i(*BkT0%$b^PMmM#_g2TGCD1z(=s{ +&F~UFe>J3pF>9mnfo9MKOPMheoiB6m7Xy=_yk$>YhKkO9MbA_~#P8;d8kxt)V9KNEp=MQN&oz~K69i7 +(E5syP-q+RFJDe`aJ#;LV*T1%(3blOOt!;dyot)brzLb+LZ>BkT +0*BKblN}1`}wm@jQ`ReI_;s;9y;xz(;hnQq0=5ZYzp5~v$TXxOX#$OPD|*te@^@7ct3C7iScjT#;HAY ++C!&3blO9wJ#^Ybr#*DqKd1e3+CQiLbJ{t(tMC0i4u9 +t*X%C(D&}k2y_RwJqu%6+jWpr9br)6|nLZ>BkT0*BKbXr2EC3O6L9m_pJL$BOPCMzGe +SPap_&08Y)owcNrgQkXM{ipT>a?3qyXmx>PP^%}n@+pwuvubHR?}iS-{-443I2`SbhV&PyXmx>PP^&T +hBqy!(}FrJsMCTvEvVCiIxVQvVmd9RbN0Nt^WWdNovd0=rv-J`1DdcM9uXdbMyxG$+ES-2b=p#=Ep-m +Jx0BTO`RY!6f8#b{?Ud5;CVejvrfTLLGTr=Sp91a!Yw&pnJEOF!POIvCpRev*_cw08nm#a?m(tLn6>POIv)s!prwuoW`DMD45d_0^r`{>E*@+E=H2b=p^_eRbMbr+sw}Ph)Rj`|7l>PW$S#uT +J~ww6D(BS9gZ{m-f|ZU!C^VXdtU~<2Ft$t<%yvE +v?hi`h;85OtraAo9nc>PMhnrxlWtww7E{3>s-5@tdrZ{xJ^PMhnrxlWtww7E{3>$JH} +o9nc>PMhnrxz4xgT_?A{aT}sG*lBZ}HrHu$oi^8LbDcKVX>*-6*J*Q|HrHusotD;VX`SnPee365)ABk +kt<%yvEv?hiI_;~|zB=uz)4n?GtJA(Z?W@ziI_;~|zB*rD-C69PU!KXAi(b9?X=$C7)@f;-mey%$otD +;VX`PnVX=$C7)@f;-Yd?S13G825UZ#I9Y{f*oFw69M4>hSsMa045nmey%$otD;VX +`PnVXdsF8PV0-bv`$Oww6so3>$J2^OY5|>PD|^wv`$Oww6so3>$J2^`|5msbtk63 ++uJ0yrA}Mww53j4>a?X!Tk5o>PFw1hM({oH6&rhH-md(pQAEs!prw+&c~R>JJwkqnV< +w4$oGDbu&=sqW0BkU!AY7?sW7wZZp-sI_;}Zc#0dWmey%$?LBJK)#f^Ft`#1%My&O9T3_c`7wJs&FRi +iD8au7A)A~BCuTMLow8Kt2?6kv9JM6T+&cnYpU9GRv`a0kDfpjMN8@It~jh)umX?>m6*J*v7*4Jr$oz +~ZBeVx|VX?>m6*J*v7*4O#I52W+Y-?*KaT4Sfpb=q8a*N*;Quijv_zE11ww7x#!1~y&ou+t7Z?XdHF= +TZIKYuaU}U3S`Kr(Jg1VTV`zcGzi$op#u1hn;rVX@?#5kqQq%Q}umGe&?URaht9d+G(MkcG+o%op#u1 +hn;rVX@{M5*lCBIcGzi$op#u1hn?qpee365(=I#hvePa*?XuGjJMFMf%e=J6PK)fc$WDvww8&12?6kv +9>+5{q2hu6$Z`{U-Z|4usVB^&KI<2qM`Z}$z)A~BCuhaTEZLZViI&H4QtoVH&NavV;X@i|M*lBZ}HrH +u$oi^8LbDcKVX>*;H)@f;-mey%$otD;VX`OdHwsXwixD8QD>$J2^OY5|>PD|^wv`$Oww6so3>$J2^OY +5|>PD|^ww9fZE4V_v3#%+FDTBoITT3V;2by`}drFB|br=@k;SEqe-+E=H2b=p^_eRaORx--k)xQ$Nx> +a?#;`|7l>PW$S#uTJ~ww69M4>a?#;`|7l>PW$Q;9-HsHx}SSZ%j>kXPD|^wv`$Oww6so3>$J2^OY5|> +PD|^wv`$Oww2)0}&3rv#Cy>8!o0>LMq0*pI;B7naWBVTT91hr*Hr{md&WN-Bp3=K12xqq6=c_wy{0pa +MoUU*p!s{C^W4t!;%E8pn+{rx2l*g>Z?>oQN;ni%NtkcHdxXlmI?PGM>T&F*f{lA7NTSN9(orYRur$u +(!VW%B-+F>W(>svqfns(V~mz{RmX_uYW*J*v7*4Jr$oz~ZBeVx|VX?>m6*J*v7*4N2?4^iidzj2!+zU +*UfTjSLFI<2qM`Z}$z)A~BCuhaTEY)eK<(+)fBu#@lgt)F`hZx7mKr(Jg1Wv3l>+F^$dyN^TKVW%B-! +oDXDKhoA`Rle7^e(p7GwbNER +ZMD-@J8iYoB0DXz(;_=9veP0vEwa-hdwy-QdpTT+%Y9AmXJ7lL!{1$8vj2JadHA*2?j>We0XW;u{n~2 +x(p+-g;kv_hhwBd4-8Ds>DS8|+M)MVRzHZNb*y8N>`z{$xj3!1CqlwYj)2?NAFS#Y`l=^L}(0QXrF=M +a^-Osz5J7btJ%ov9;4r3g~I2`|Q-NSVc*F9Xf`w@O$*xnhWhdB&%G0??87Xw`kbTJScOSTK|B?DdDh> +PpqT=(X>?61>GyqDi`x_jWSy?8Gf<7SMTF>c0q7~^4#hcVdlxSe<}x$eVt*&w&QcrUr`0&nM)9_M9@m +oZ+(co~C@(Atmpk|gh6Fwo0D>`ULKyq63R1_%RW=gWSswtr%vFwp)l0}<3As6$YPptd^iC0iX5&>^5~ +d;c2(It29lICrO+?m5%#q1g!bH>8!#X?`>NHw;8thqMl9ZJ*vf-?$OtMi5i>hW!oM{65{?38#l4qeDi +AjPAaRLq>;;&hF-G#vq$)7WmuU_l9f^*&MRjlHENY;4ptDNvBQo3BMFWWasP#!3;@c=j^{SBz0FOown +2cGlP@YA+PLN`J3;JWj~PHKk?ZIew6TjyP^`_A-r?#zcLWvWe>gVgFu3Z1kY|wNpjoE|Hpqa3H2x>cu +4S&;32_7g4x9MHzfFb@}AwAl_QYgA;Cj}ThRBC>+IyOkda{vMINn}l}=?-1UW_SQx&d +&vM{0Ft}kYQoIZ!w}vfylwE$d3IOq;Zj_(1$n=+>pc5&7ne7e50`r-{*`&QO+H6CodVc8>c_62KapUO +V3A;vV3A;vV3A;vV3A;vV3A-EB=Mx}cYibG^f)9~B$(a4e+!0ihzoMihzoMikEmMnI4CrvcLOJ%(5b*BBQ%~s>r +CAT}3uUHbpi?Hbpi?Hn;O<;$&v|*S!n-fb5SmB#{-76_M43VxN5?DF+ZK5nGc&n8Wr4Vtu?w3@ViEI(##QVRyCoQ9qTa(*EZV$OVmje__uU)L1`oMC?B73JG5{0nA++p2`8)ca8_otR5+}RyF$q4}|7Rc)%xLxKwvC#3Qaxx>@J7IDAB1 +95gR@2jUc7d#~Rkl;gt*%It`NbupTph|JFKS+WP3I6UXrv~r-G@~%jo@;++%$eXJ#)lXmV$2?nzr%cc +m~Ri^J%slV-ore5$n9aCJ>>O}*F#>>R~+e2>m#Bw^^np-N)Hq3A)tqVp6u(5IT<_z^&+SjLA?m-MNlt-deI +&71YV@|Vs^cL`!@{0o^d?-7g4?DyEk_;aFN!Fv|gl@UC9q~(=~g^XhilRvKNtM^R?f_JbRJSios=tV#;0(ucpwu1amexv`L^X^|UaqrJF8fm@uJ +`vQ5pkB4>P1wq +XV23PXMEKOnZ*t3K-M^d2-bD5$viEPdnP&{rdUHZ>lhT`%-lX(qPQ3 +{z8yo*8zq36KLA?p;O;B%wdK1)}pxy-aCaBewv%k(aDZO{Eds2Fn()E?Iv)bWo@Fuc1k-drRO=NE(dl +T842;M~YCbBn?y*VMcnNDv4dK1u_fZk{CO+SF$KQRVDy$R|~P}!#bcN5f`pt4>ddl;ruHWL4pUi3XTM +D-@B_jfLEaXNSt*_+6+SLu%pNB8~s&BS_>)|<4lY5VVHV!fGIZvuJ~(3^nX1oZyS1uo78Z-ROgRJJJ3 +J|3j?e)srGnuruLn(Zz6m1uslST{jYxyQ|v= +jt1~BO|Cf){eD{S@!H4iZg!du558-_XFMCq|N;cg!od0E<+5f+|WB?NUFvUJ3_tEC;;#BYqBTCLi>Dg)oxA(A9DMU+lSn;Y4`6TVtZQtklTmcKIHZx +x9rdQdzf7x^7@chHlF@H`R)y8gAcPTdl~;8BKs0qHZ=XcMD``JFSF~*?D`T=w%Gl#A@1)bpf3S^3F!N +s3*4L!zGU>W)Uo!fV(U;lvC7UnVWaIE38;}29viXwDmu&84rTj|uIK=ZMo-gryz59VP2Jw +8EQ(t2F63drZzQpn+mM^hB>5UvjvcoAPVZ16NmUWr7$B=RMZZ@zoO8R1JZUy}KfO!gK3y(IHxCVffdOCnzq84?*184?*184?*1 +ncsJBI3*0p49N`149N`146pkkks*;Gks*;Gks*<#rn4vCA(qk3I4>39(!i=fi04+HTQhF;6khkYbqTT +DckbbJ|JuJ`0J6Dn%<{dLdO0QBw@7;`zNelcqx*uquXFoavabg_QSY1gsc8d4fkns5GmIVTKh4QUN&4QUN&4QUN&4QUN&Wk>U0NNJcgLq +J17LqPMrmwGuT3_%S+4YOv*X!hychk=Y{?+Muq*$mkX*$mkX*$mmt_g?DdoDjGg;A()Y0j}D+a(TGCx +a__}_x|9+<;x`l41YfiFbpvJ?xUY}@1GcG7^p!V^ol*}d&wAL3^9fnL)-{)U2$D;U2$D;U2Q+qPruJ# +R)bmf-ET9x|I0vTATy8|$P8o#GB@Hdz~Nel8*#YqH-GlS@ck2G9LCtU`g>&tI{g2|K>ZLt(VX9R$!Hh +1M2!$2wHnlFP^&?$X6RM})rgJLNpTNDTE)|>y&h>rs0N`LglZ6~L8u0y8iZ;PszIm*p&Ep0wDV^J+~W{bNNOOd +fushK8f^*)DkL?K)Id@LNev`5kkmj@BVwtYKbzeihj>C#qm2ylgro+N8c1p&sez;hk{U>AAgO_*29g? ++NbmgF*#7IEF8=Q3^5OF3k}(J)BsGxKKvGkZGX2HiQiDqkE;Vd-yB}XCsyzzv1g8d^8gOdBsR5@3oEm +Uyz^MVJ2AmpjYQU)hrv{vw-Ts!S_Bg~7ml|AZaH+wi2A3LKYD_F4sez;hk{U>ASlY5@Ke*I$8eD2{sllbj#M8`>Xw;xlgGP;aRAOmj2|x`1HU8$$t|sW87=w5MQ3FH`5HǼs-(4G=XZmKfBS? +M|7o_lN}4&v$QLB0x~ls6nF!jT$s+(5OM928|jtYS5@bqXvx{6HowZ0I2ade~Pn03~FjnXTBe0Akqp% +4G=Xz)BsTfL=6x%K-3&k3P242HD@+!=A^I?bvV7BGkeKE%%4Ei08s-(4G=Xz)BsTfM9m?fhk#;FbH4f +0oD^bEgFy`jH5k+!f(kzk{50^>z)u4|%^{$$)4)yxI}PkK=bJyfGNFHB41$V04e~U|)8G?BIXE4cIhb(|}C_HVxP`=X((~Cx)QYfKCHC4d^syA4xI_It}PFhirmP12#>u>12P9fL5H&?h`;Bdlb?NKM +nje2R7Y-i7W;+7}Q`;gFy`jHOR&Q2SZss6q$3j%WnvK7=p^%$Jvv03~Df_Ik4&83(^Wi4G=Xz)BsU)2 +q*wG0MuN+y*G!mLLh2@r~#tpBB&VDU{HfW4F)wA(<%Hk7ukfJ26h_QX)dyP%|17W(?aBFkf%YO26-Cf +X^^Kuo(6dug{&nFeQ?I@4+WaQI-0r-7a3Ue|A~{`F5Uf5$-m_B$Go!Jr0%8VqVMs +KKBHgBlEKZla1k4fZtH)7<**4JU;d)L>A9K@A2qH<5*(27Vg&Y2c^1nNAU>L7WD08pLT3r@6h)&Ba+E +@-)cPAWwrl4e~U|(;!cSJPqFq6PJ=iN;xzZQNxL{JM4sj*t)SC@PIHr1ylL>Jxk)R|G&s} +XOmmaXdmnAG2{Fz6>}%V_Ss~OkP}4w7Q))WdD-cw?X>NkLZ%Xz&?IxfQ(?CoEF%85t_q(rcHz$Qq(?C +rFH4W4>_ojzQ^yVd;B|z`Sg>2$XgEP%dHX){gm}VCNk(ht|)9`oV(p(-cFD`E`A1+@m8G}g_Sel1KVo +HN44W=~D?5n}eSs}JGwI%Nq12D})Jb|SFmIhcFU}=D*0hR_>nul0oO7rkZlY392ZcYjTrU94+U>bmF9 +x@6n4X`x8(f~`tVj(^hG3e5uOM@;Ax-`3Dh`97H1Qlf(lxa|=L7Cc@Utcd5J8FKLCC24WhBX& +|P7n5M+!P7DUaX7?s03Oz~}aMNoK@-)cPAWwrl4e~U|(;!dt5?RD)5T`+$25}n1Y2L4kdN?ISo(6du< +Y|znL7oPA8suq^r$L_PWllw$25}n1X%MGDoaVj1=Z14a?>Fn9%OJqT(0i6bP8qjH8=2Wn0z@~ZkTBHg{&nFePXoN0F96VGsuLo)HE!J7te8oUX(8N +6wh61L3WZhq@@oN2cI#F=Kh#ocFu=eCC-p8KAAPrLVx(Z12y_a0#q-4m>R1&5esC+?lac2e5;V}BKQ- +wB@E9%pYc@r0TNY8t3%pr#3vD8w`n(?CoEF-?i-Y_*9q4bC+A`Wu#)4Bj++-`966G735k=rq|Ovj56J +&8EO6flUIN1U3n5((X#ZllrfJy7{|@%a=>W7{(aJ7{(aJ7{=)QDV#|-lW->COv0J;`{qy9mk4hX-Xy$ +9c$4rZ;Z4Gu#M&s~Ov0JO+9*Lxf|vv`31ZUE`#ahNCjAp*m@y7x9L6||aTwz;#$k-Z7>DB@u6wxd#dR +;PdvV=se@9tlB7jK%lK>_GOk!D-FePD1`cVZv{PoR1H#g#DfSUns2Dll3FEijt>|t&OdKl>8#ypJiFv +i0e4`V!x@i4|7?cusF*L}I}%XMF_%a8P?@Wk~XL>6ySy~*!BpX3&F((F^RcY@sFOv0IjGYMxBE1?82X|~H3i%bMH32GAjBl=H4O`@UD?5 +*CLy3aAWg_tBJQFKY@lF%h-yL_?8L@1M30wsV+0Fzh(C16Rwl7J-vOMI_oFS#z0D6k}8Nx+h{pT!f4O +eB_?@?fA$LYagziFHsymxL|}T@tz^bV=xv&?TWuLYJgH|Lk+|@9?rEs7X+hpe8|0f||rSC_zkum;^D2 +?>yrbPdJlsCgDuloj7z^2d++t9|poBq*Wl@5k1V +0IW63e1gaWdyzf}I3A33k%%LCpi)!;o9}N$`{4C&5pGp9DV%ev(eCGnJG7<75TvGMTrILxiclaMDNPePuAJgM?z+IGQDf} +g~yC&5mFodi1xcGCII1rBF~@RQ&t!B2vp1V0IW68xmI$03{WlUVB{*h#RHU?;&&I{UeNvCu^Dlgdwrw +MB6920U=M?Q89z*?U|rw*$x0I;PePuAJPCOc@+9O*$diyKAx +~nNlW->COv0IjGYMzXwOzhgYa+Z!c$4rZ;Z4Gugf|IqQoYIh{t|2w*d(w?V3UeX&K~!hKUr!bDotxSmI2=nS?V5XA;iD)}*tmXmo$`Cu>cFHwkYN-XvBy32GA5Bvv>HViLq8RyYY=61pUG +N$8T$CEee9DVCcEWfICHlu0O)P$sd$N$8T$C80|~mxL|}T@tz^bV=xv?zK>{-b5&qP$r>FLYagziFHj +vmxL|}T@tz^bV=xv&?Qxu&i*!+n0gr2n+R$W)Fh}$P?Ml0K}}+DlOQHROoEsMF$rQ4#3YDG5R>kEe@9 +twBB)7Flb|L+O@f*PHHpJqmP9N#5y~W#Nhp(0CZSAXA(PN0p-V!Sgf +0nP61pUGNi1Lzu%vrGOCpw>2w)Pxqyp2)cZCkbLMEY0LYIUt30)GpBy>sWlF%igOM3RRBx1#hP$r>FL +Yagz31t#1mxL~fl}iGa1S|_GOk&ZJFePD1!jyz52~!fLBuq(|k}xH) +SV?e_p8bvpvEoFql3*pVXi0FA;3UCGf|CR%@x`;f$CQLA2~!fLBuq(|k}xH{KH%(Y?X% +wzA(op6U=qM27A=WIOTv_dDG5^&rX);BELIYnBsfWMlHer4NqYA?BE*6d!AgRa#G)m^NrICECkdy~wj +f(pAW1@!gd_<`5|Sh&N$-A^Su8jaq9hhA2}u%?BqT{lk}6534TR~Zg((SB5~d_fNtlu_CB6Ga1Y*63S +iU5dFNx(#0+9qF2}BZzBoIj;l0YPZNCJ@rA_+tih@|&>|IUIFv3yA&l0YPZNCJ@rA_+tih$Ik6Ad)~N +6_L*NEJ%`&B)#AJcNUzm&s8rOXde>NiX;h15|Sh&Nl22ABq2#cl7u7)NfMHzch}O16(>TJ#PTH}Nn-h +uKqP@kDk7adA4HObBne3pk|ZQaNRp5wz2E%Ff)gQ1V)>GgBq2#cl7u7)NfMGIBuPk;kR%~VLXw0e2}x +4+J9fl^6NQzZ+yK@v2~HAgn1mz=NfMGIBuPk;kR%~VLXw0e2}x4E`I7}FLX^bvB_T;dl7u7)NfMGIBu +Pk;kR%~VLXw0e2}u%?qV6iIq!y$!RYcgLooIVvU(VB!Nf*kpvI?=w3+7s`6p~jE&1%p`=KT`eZ?3M$#9b4B*RIDlME*rPBNTiILUC5;UxdqS&m!T-;~WK7AJk})OEelJOHV}Ez{9~e#CEaHhN8B;Q +*M$#9a(NvF5{+7|&} +$-t7e7HZa;7+^BMWPr&4lUcrGOv#v%F(qS4t|^&UP6JB@mJBSpu;hFRV6}-^$Yg-Y0FwbGvyjP{k})M +?O2(9oDH&5TresXXn36Fi>;8_@b3$WF#+HmNnKevi4U>^1BT23#`RsxBelWYjNrsaQCmBw%_Om2rwTa +70*S@e~OJ+5bF(qS4#*~aH8B;Q*WK7AJl3C4UILUC5mG9oXB!I}mN@g{a;UvRJW;K(MBqK>il8hu7Np +dC0yzeobWH`zGefOrPgoc$2E14xthLa2@8BQ{sWba5s7EUspWH`xil3BoHB+1^-l9=TtMwHA#CL>8kl +8hu7NpdCWTzgYUE1YCF$*g8Fl4K;wNRqwl>dkT!BT8m9laVANNvq`^R&Qf7hO+!AfRHlUdSaB*{p +Ukt8EYMv{yq8A&pdWF*N*l943ucJlme?+zJdA(N3LBS}V*j3gOJGLmE@$w-osBqK>il8hu7N%C$l&(H +QaWRx{bMv{yq8A&pdWF*N*l942{hRGn3K_r7n29XRR`LInCKl`tLVhrL5A{j(7h-47SAd*2OgGdIE3? +dmsGKgdl$sm%?H-EC=#4KNO5$RleBZ()Ha=eswY5+X|bZGrnmY +x^x<-wEil8hu7NpdCW+Eacw$-6f_|J=inQCP{WW-^>)Rx=q%GLmE@$w-osBv+Eowa*aQ +gp&*>`8?mf;e-%YGOT3QFd0rVoMhH88A&pdWF*N*l941MNk)>4B$>5K{?<~O^(JNwlR+edNCuG%A{j( +7h-47S)Xt{ZGNplee`VfUdEYhd`QL60#NYkv<-^~-Trvh31(6IQ8ALLOWDv<9l0hVcNCuG%A{j*TZf( +!s^*Ce{L^6nE5Xm5tK_r7n29XRR8ALLOWDv<9l0hVcNZzgP`MVy6WP(TrkqjakL^6nE5Xm5tK_r7n29 +XRRnH5WHzcss@z@HzPH7CZ8j2{_4GJa(I$oP@*BjZQLkBlD~KQew~{K)u`@gskJWY(M*KQew~{K)u`@ +gw6$#*fVR;u$(JbY$qr(2-fEWY#GeE%NuhcxKIsQ6r;9MvaUb88tF$WYoy0kx?U~Mn;W{8W}Y*tCNft +`TJfxv*^UAkx?U~Mn;W{8W}Y*YGl;NsF6`4qee!Jj2f9WNk)tOeJ`F_bz;=WsF6`4qee!Jj2am=GHPV +h$f%J~Bcnz}jm(-PqeZ@VEwWj4V${f}kx?U~Mn;W{8W}Zm)#%!?0y;8uWa!8&Ofn0Tj28L+-oLZ##Hf ++0M%OkS(2=1dLq~>=3>_IdGIV6<$k36YBSS}Kb&~J_IdGIV6<$k36YBlcY!cB&h;2p +YcearpAM*>6kO1>~$h;5eKeLPv&<3>_IdGIV6<$k36YBSS}qjtm_cIx=)*=*X-|^1a_BX4ah;Ix=gMj +2am=GHPVh$f%J~Bcnz}jf@%@H8N^s)+8A%^0VJ1W)_|pH8N^s)X1ojQ6r;9MvaUb88tF$WYoy0kx?VF +9LZ>rpZ)y2S$SgA$f%J~Bcnz}jf@%@H8N^s)X1ojQ6r;9MvcrOB%?)szSnG)o)|SUYGl;NsF6`4qee! +Jj2am=GHPVh$f%J~BeVXXF86z@A7DOtjJiAu_ +Ckd$QTjZzYTlb%(taM|JxW~MY|wx*YxZsX7_`w-+Lyk$XJoFB4b6yip;7bV?@S?j1l?W&wQBGC&r456 +`55>Mu?0M86h%4WQ52Fky&+QWXQ;nks%{PMuzQ>!Au>W_gvbby5h5c*W|@(ZAtOUZ +hKvju8S?veMl3%uLS%%<2$2yYBSdDIk-;H@LuQ$gK_P=e289d?85A-oFF7EOxR7xn<3h%Tj0+hTGAoRX2N@4C9%MYoc#!cR<3Y}L?q> +aoaUtVE#)XUv85c4xWL(IsFfuEQ3AZN|eEI=_NWJt)6kRc&MLWYFQ;vz#qhJp+Q84 +5BKWGKi`kf9)FKXYtWpcoP|BxFd)kdPrELqcY8k)a?%L56}11sMu56l5sKP>{dxuQMx93<(($G9+Y3$ +dHg(SHx!E!;Y)7-^9ijdCV^3-_N%0=Q;OdnEUY`yq4o|lDGx&c3NnV(V)Le{TF`f@xOon`5*t|fBm=r +`QP9F`XB%M|NP(o_V51zP)h>@6aWAK2mtey7DxVo83Y>x005K*001)p003}la4%nWWo~3|axZdaadl; +LbaO9oVPk7yXJvCQV`yP=WMyAWpXZXd6iU6Z`(K!z57=T>Wc%o+PI4X+YNe<6+1Q7vJJ +^bk&{77Bbz8i8YGoK{q=qHSF()*?CN9==RMAQGoEhu`bWdj!(>L&Niv${BN|TU$v^Z?Znx8=<&J4?we!?VZfNl3%U__lnjTTC6lEdTQO1t#6PHINiP7H5O#_)dck?$Q +M5(YpXd%_s%9=hBD)i(HEn2@b`lKILDY>!2w!yW^GLtive@0<<)S8A0p~-S7-H{$fcoMq&!&u;JQ_89 +hp+=XG6RP%XYj^hWVYZ?vJ5)*!tl2`%qS+`}06diiYsVxU?L*A%UYr_-Lh@4~G&Z0=xO+z|aUb4(V(S +p0PtoA~+KI7G=ygx{P(Ql455OA~-I78#>=_wdwctf*Nm3tZckmuRKnS7F7%SQ^HIA!B^}&E#`aW5Ho3 +EA>&mQS}oMrKB`FMw1IE`EM@5m(UJw~u3sIo%)7KMW#9c9TkAmZUc^AiY?S9To@W%(BF>hRW +HpU5TCB3gJRe0wIrG`#VCFTGFBVsztPPwj*$b)MQTij=>rkL7X(yf-Z7x`1qDbH`vTy%a50%l|gI+*h +480>+kv6_h&sJh~Fnw>j3znDu_A&HD)Thq_BnkaPp#?eMV_AWEtcp8(~&VF&YJz=n2q~1D@QL9Cuv5i`XO?0Wwx%zc-o~GDUs?+HdN;r3j9gFK-uNj*HivnX&(RwYhZ` +SLcV^y8v;kyou{+)iw4yR~cpQNVr^@{4=t5V+}-{}1b-@m?VMejEPi>>GpyvW+JU!R(|)}rR$@6aWAK2mtey7DsuqS6MRz0077d001)p003}la4%nWWo~3|axZdaadl;LbaO9oVPk7y +XJvCQV`yP=WMyYgMkn%X@TSG=j +0v8jDb?2BDLF?Lg`ZEOy3vb^*UeWuZckrN=5kU7AYil}nO8f6BINFw2qz=<^oJwY1R@oM|y&@`E7^%W +uJNG-a?=x-wh0xVU_GNiTj4rO~yj=nRDO^xfWl50HU$rBY9vFVgcQ`B;NCV-l28XU&G})f|)`QdX3c( +p~SNwx$K=DU~z{1SMgmDC*w#7K;K@%N&4QI@9zXi}*e#SfxF=>C!8s=g@0Klwi>)k5)EB%(&C8I%yq_ +?{4SfAai{gCR+h3TrBz3$QT@3(Bexy1utxLJ2(vGbFrY7f5Z90?@8s$8%MgW(_2FZvG*+K{)gKL5ckKh +fgC~?Lmc^XQIYIiUI%kXsAb;21B8EHQ*fK#yu3}N&Y?LPsyClf~_V@Mx +ibmq6*7lTUsMlf#2xcr)6Ut4m&NnzVQUzr|~hYs(LWoh%t9@d%(1@6yo9hF@uMT$0v>daQP@w3aXWU% +Gu1Hft&B){?}&&I-DkMV=CAF}=J+jDf&bH-BzkeW*R(Pfb}448ns()K@#`x9RU{$5;f@LVdizRxi^U-Gf +_gOQR4(=_FP<@YK*P76xTC9M7LVqrsiTGn!Vkyb!Ys~`y|UFTYivjZ?S~ns*{M_IsGz&) +EIWxST!+)ichiSU*Y;X7`$zu;$WFRV$!)ONrSOHS?qCAHJ(J$#kL$0W7FXc6io{LEOCd~pykwS*)c0{ +}sGv@*v}}UU3vft{PaAipxAERjd8X+Vwo?1hJaZ2DINTSY77O@6aWAK2mtey7DxDy!T=5l000Uk0021v003}la4%nWWo +~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyS3ULC2M5_7sx_{f +ExK;j8?8=*YS*{*5A*=-LGFOMV?noCj%48YR9BuL8PbjVL;Ajh=gDLiNY^n+lj}IF##X8z#G{@nZ6Cmx?v#$!T`e3VJQ^%4$FwL%Gq33aqQ-{u^#WB+PhW +#YCV7dfzE5qY4XG_cp}z?)I!RpxM$5qr$IOR?GprEZIQk3SNq?l}gboQB8ZwIR7G|u1<@sSMUkLQ}dDfzUY3- +E81X7n`r8D}qpv6VjB|!tusZm#j!~ZMy5V?`}Jd5>ZEpm5J +GySw>!)cnFpg1xtFuIMNTJqu;~5Ar$mI8av+v-0TVoM3I9KnJ)J7p|66GJukLw4El!TkOF0jG}jW?0s +2zj1(%I~ivYb_D$=V8h@9Yy4;OT>{ZbCW`qEcQ7pbN~!=yJ=>@6QxD&@n<%W{RN*TKp|A8NENo|se)a +=D>a6Do-5@<{(Yl^=W^-vGroRK}@>US~5 +3TfZg1=sQ28OjNp1Wbq0gBe7WmSf~&W2R?ENAvl-G>JNrlG3B2saBtbYr-QL82_jjNG?f^&*u+?xex{ +~xk8Q2#E)^~G(MbZE`ZBSUP>8fF-2G6$GzO<%$jLSjTXY>3%RxXqlGQszj*P&uA_o7TsRh7U%0eVcJ&OE*;}2>)>`%+nhCa`>(6XCA3I@;*Fd0hP8=@7680rf$6yD078PZP;>B8cnO>c3TBf*)C0!I=VQfHbPMfV=TH~9H3(3#j<@w-Ag|Tf7Zo2`3o}P*16W6KtM|`@p8@jw^Zg +hOJ#2m!-MqpfmHOn<@71NFVo#t&$YkVKARMg8C_}?3usp&!I_#Kb(w_K@0}I(Gb#%PQE<{PwEoClCSnhFQ|2R*{+2RIFPr=xPU$>}HzLZd7p +YfL!3au&6`BxhXKXiLhw$_Lz>KdBd5@9#m-L5PNMw?$DFIV&aDeijGOIoO56 +5CW?eOVcGAe|_VN$4frZ_D;6qzW$ql<3yR13tu|{uu!rG(n*)?+Q0WEI8Fqs{8Kdv2DOG_KclU%25Ai(|3EEHqYTg#DQ^}wWR8;Vylpdf}0OA;ZC5+4H$j~#nV+rV>or>Blz +Q0&AuuAo9qkg^~KWzE_z5J;V&&DxIuF&7>Cz*--^aMFGA0s}rv<3QQi+$x&!M>|*3VFIu$OQ9;_Hzbv +YBb*g=ETsxADADV;(q|lAKE_$=0W*?70k8r)4^OT|7Bo~?n0g|nlo>E9)ol09%v6d@4Oe<6VMUArviE +pJpT=FE-r;Wi0xt;k8!x?(|9k~aXTO9Yu{8Wg?&RI&f^DyfUotQZ3txCIX)HuTep#Wz<1dBGvvb0v6=9PLhki4Zcc|bjKm(@)FuLpwC1FqX#}RK(d){x8pU4lz0&v7%dKLxx +;L!6ew`5*;1i31EJ=;>1Ckp1Notf4fiEkMU2$$gZkuKF{b&SlCn0w2<<2YArAYfGJ}|w%`+ubWg^|vq +()+ugEU$m_sPvQ}DOUd;8;@e;?cu@5d0J2SCs0cR1QY-O00;o{l@>=iiKU-(1ONcf4gdf<0001RX>c! +Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FJow7a&u*LXL4_KaBy;OVr6nJaCyyE-*4JT5Ps +*c7zsrImH42ilP*p302ESGAP9)6sCPn(Jr1jyU2Aup$oJRZtZgu0yMcQ;KjGP#Z@>BGhpE@gALtDpMp +GD%`h)3W0KM^J{~J{J)@yZGZV(<7f8l}!(3c(p*D#U)@E~CHzTHNGyUa)hZop9(aLLD^z$|toxZxD~1 +z$0cAu5nQm=aL(pQ6z&3-JJ#OQGpig;FIi7I`LBYIhYfgC4Bo1hIG(Qx+?X>8g!^M!yN2+uJ`0qSW1i +ZVs#Ki7WsUrhdYV2QP|m;RcAJ0V81+n~fB;R6G(Z;A_QHY<2S$B53K +GH)3`Nv5dfF0u*{&r|_hN0VcfPq@wt(^tc~eQzSgf$I>>awt6Sx!}JNpsEH~(pg=|G%%XL`T?!s^7ll +S(8bWK+n_Q})C9=qfz)%u=BJUj_r*nJvD=JME_~>+Yw`GVeplUamvHYo=p$%*j=@%Jhvo3)TpcMn4K#gh0OVeYE`g__T!X^clW)=kxA#`FuydBsHB<1ydxx4XFz~ptKYdC +MMhO(1lrdz8v+R#@#v0p60X1#lQhrAnr7_YL=tt2Tu +G>iv2%l(-OtchXZ!G^se71~8kO$Cg`B#bYrVj#s!k}!qjirxYDK}gerH^r%YsQ(J}C6v6vE$VyMX~7> +Ia$@3VKs8uU_>lVqJq)B&E$B&Ytm~vpvF(qYPWz_wd%FYhv>;2>1B2<8GZ#y}R`ZqIf@3RY=fe$6QRB#w2AAfRisZv;#cBRmtA@tF&+PU&@^ +_BC_D=TAS#7(np=wT}E!;!<^e{!xboArz)3Y9G^AJ(RQz!D7N`bXKIYrCI{F>Q;%XzeHi|#ZOCnWPr> +_Z)uIv$(t6CPgPtU6{10lIyuA}lx+Sbn&N&ZP>ypjl;&u@Y>Hr(&g3QGs@xSK^c4N#S!3g^MStT>xeu +g(gxWC0wt_zL?)}MSisNrpfTiBb|a0&0HlP(MyzR0qaGF`drivHu5Mdsc4E=JKE5nPvs>4FdAXy+9?Y!JRjgX;g=HoOI#P@O4D-vd@sDWtl!V9kk$2-h8&Wvy3)iAu +HH|oT96izZWhSxTjw(!7nvP&mh1oL?R3ExD{t@9q1{o*KVnF$=+p5x?Sk)Fz2w?oebf#s{4Y>T0|XQR +000O8^OY7y_!;PfTLS<9ZU+DWHUIzsaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4C +QVRCb2bZ~NSVr6nJaCx0n?{6A85dF?yF;YGRbg&0GRVOv-2OyB5BY;>?m0nLP@9r#EH8!%nNwv9-n@C^nX9YwAN2uAo7?GxwwO8Q27E7KD7)m`HwEJP2&ey5pK +D=RnDA~5vi4b3XQHhSj~uPgk7GU495)VovYAP^)~GPS~1LEXYKlQV^X2J>60Oi7v0WI2~^pC3wj5<36 +gSj2BkE{iIdN}Z$LP?l%AaYvEwCrcW$Ln(C6nk~}L%2de=!DE@Rc1*(2HrU+yB;_y=i4R0*XaK*H|CU +(dKI9JVhlOsU&N15ov58u#E_~pRc5g#q1EecbXqP=kMrS2BRhpC3JJ>avgFgU7q0e}Jlroi$i&8a#0A +KntT6~@^7u20R(wFXh-kmHSZ{dqp;1&(uBgxHHNdTiNE3~gb8~_i4dH*vay1mhOw0I2choi-05XUr}& +Z$eY?tC%oFUQ?E&6e}oG#*4~F7r|1Am%xdUnDL7xiL@@Ln5Sd`_doLUI&6Ir?q%uv^ir;RZapgWLy2G +9x9_(yLu6F67-g2LE88xJzI&lgXj6CyFfYhw~499q9%Rlz)9%u3N45cK9mKZhsqe+q@Hm;xIT0d+rH^ +^+O5tX?GDj0hUL;ngUQ`Hm(NwLR#*&86dD%BD#NsUG|bfw2GFk6G9?_A1NKkMer8R|_G1lW2bBv-5{d +avlDcD6H1_uJZ4py@@v@k5|Jo%Sqhu3%yjJ>jN*?juZpTTzIw7psCx;c7XtCkfV3vJpHBF4>Q&7R2?; +M*XdgWz$0o(-|7f^p?`ihd#h0IxJmqOc7`xib^VK9?5R$r1rHKSE^o?kdZ6U&h+(|USc|NGmIcDwcM$ +DhN08oymPDZQraL)7b(!T2WUVMY_ytFVF+#U5t&-t67hSJC?U|5Lv&FV@ubZh98?9*$_0~0{{RH2><{)0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FJo_HX>Mn +8bYXO5ZDC_*X>MgMaCwzg+m0GJ5Pjz>O5$N)L)anFN}Czw0SHV`xQUA*6pfJSt_CY^8`)-9_Ure!ySZ +eBNwR*T>vDYRRFx^0uODi49(qIS_u8G|v_q}_sQrari7l7PG}|zZtXxYi6tzvvBps#ZU#XO+8@r|mwt +DFp+SAfYM1JBYR%XkVOhWz&2I7b8T_m;)Q=0CyjD(j)JAB%$vDpWJX>4q6k1Pw%F|7_6;>)Xq4OrU)u +G)C2w5!zk@ZoPjTn(>NQz@E+SVt3fY@ayJD`^|;tz7NAu@zUngN0}y>~|VVwYD;)w*-csyrJ>IZ;USL +hcrsAtgwfmQev6OnZ)lw?4Ay0N0HEEIhHPmhY+5Gj{h_k`KgIzatNlKj!{lv?b)X8sNutKPJMP@N)N2 +rqMGq;rDTNUzKmEqCgErsY;JQ_svC$*3nJ7tfX~#uCzkMsyPw!PSm<57alEZStdX%)5kBxoH@6|N3ep +Es=!QLJ)~`x%t~4g8GuREZ#}5Fa&^^Y8R!lp`$xhXPfLQw4n|&V5XVe@n=xcK_X%1(Ld&EL%c+tNcNv +2yR0gS4w(Eb4802p*8?a#<)wtD^EY!TRZd$VC@I;HMtLQNVsC$nCA-fvE5JfDn5(@vde%6ybKhDI`PR3!S|9#0hSd4s6v8Ms^)+E(g +kNxOmqQJ&PI<>J~kWad!{vqJ;K`qJ3WrFZkg^m)PRrtN${j7h_xaIaE +yP|~0OVz`G2K!ARba=BV>r$3gyX-{hVD391L?Dni6_;18mHEdty}Ba8AJEO?4>g_7o1@y*U(DE#&}Z5 +x_RQ?@7klyMBQ;JTmi^A^YuBA88G0FBDT3t|PeB|9%XB;8SgtgC=| +CqYxoc|4#GI88%C#(<2_D0E_P~f>8ZDx9+o_*N=`u_b%vUi2tb;g>W}8J2W4(#jt0Wu(3DKp*T`}J)@ +@t7prrc?+WI;~I+MZJ1a(gWctP51)K-}h>UbeCDK +{q+&4eCXrzn1h7+RdWjxhRp~v`#*S{s?M=4I`RGv( +hN?KY5yRVwR*%Be5>SN1cyJBHleD4a--)~lF5{KESUP)h>@6aWAK2mtey7DxP5z|Xb<001`y001%o00 +3}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyl*q-AIw*@tZd@@7Za$FF$k_KO`wll2M%IG2KmO +qu=xew%uw|v1OWBxsh5Z8kveoI+~h4QYk?TEnnF>?37z!9eb+SbLowx63}kz%#dj5C1Cgb%F687l3A0 +#Kn;A#-j!m{2<>(UElc60(GE+yH?~=TnC8YF +znM;SY|uUs7`85!-ZTpcjqmAn3l2+>s77n)18v2sT@gbqDaHy_IkWa}=zK`EIZ!DyS+1lz)`wD_gs#3Bi~OCb4GNgFbX}eW{dLk! +%E2#$rD+!c1*(2KE&MiL&|YzBtJDmV*~m|{vol%eyAPnM}!95{<+$Tv4dIZO8C$}?B0jOYcySxf?f8U +8LYgZ!N;f-N!{>n;SN5)h)LgY{%FN?aJ)XK4j6!?r=)nCEeeX#B|Sx17Nx~<2rRt7E*w5G$=zN_5MwM +Ww6D=Q2&Qp1dPGKamrRmk8QLEwMH=Thjb|A}G>@_(87(GJM)O5BpXG5E?lPY>4r*Rf`Ca2RD0c=@;+6 +=h+-deD40h;HRkRha45LfNy{bsyjO^?Ga#0z*X$D5hhoVE0YtqJd=*>!;9vsk5{(|Mh;STOa+3nD6A0 +VM$6gMdaihN*w8QPwOV}N{9L3yu +DNM9@mTa*oEkr6d=7xiy|Dg>iLHg`4I=UGjL08nSut7^&&6XFV==i8=iiOU?6_V-lby4Fcn3qWh%Th+TqvkjNShLnC8Yd_SCZQoYA`4Bfh^%*cxkB;i|2tPIN`R+uMHua +WOogP$`P*SVu8Cw$Ge3l|)8+E7zqrw&Sk8!a_6=_9xAy+E`i8HG!cgZ)jfmt-Op?tEc7Ml9dA1zcF9=k2w(F@H+Oa76-Za4&<%Uc3@%D=t~4 +X5_pn=Nj}HK%&=-smt(i*4d8xWUKrHhl$&9^_$~C1wp +}h_SRYqI!%xH7U5)(xNPh?m9Q4f{Tn|-}VISYD6GAC_(mtL&I>|pxdbr&e-{&q3+Y0#yAdI%Ewr$P%7 +qz`2d=%F&kcByZiuR|vxa&Nx$dN4h^RF|8t47Tdmxhf`Ve5ZiRL1ch;;?Kl)ccqDiT +|>{p&6coX*Xz4wrV?IQKYd5l^i(yi2dOpErOr1nf2&oKosr@5s+RdWr1CR$;fH7l2|#bRmZW)5BB<8P7HnzKSkGn!Kye^JE3nE3h%rodr +rlMoh=4m8`kw}6y!=QK6Id-M(A<<7@6aWAK2mtey7DuKn(m8Pi0046g001%o003}la4%nW +Wo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyNpU6=U0r>7m#QcdbQG +RyM3S(TDA}np}Oj>R>&k1ux?^UwrMZ>>vxBJagtFTwK&Ya6fn)xiB8}2d+1O`|-5@3}> +(xjSE<85T=T+xnL3WWq`mn#PVMrMa+?E4L;eNMgbiOZa5(y@C_rGpaL0!so@~Ji$?n_K{CbhR&bvgE` +_F7l}MGo5HZZ8%Iv;EW-x%&E@eEuiYd#L?C7eEfo8u2-RtY`L{STOpch3jw^$8x)TrJt$TI0mVH96&j +Z{tDx*-d|gsGn}C?!;zUeYDJIO00w;pWVBUWskKX-gJX*Zk=!c_)JM +cUhPUp~rS#Q1=^v#B?506fG(Vk>5y$fd*~QO1A3wh=`8hEDzByhqX0JS4XMmNa_T5xG +$P6FOErw7Sf}}t%U;l1;2{WU+VHM8^$vC4Np*>3U*9%0z3;T)_b!2$_!&_NJaQlMkf?`|l&TH)QX31M +^vJh!)$MjJyWcupfESM}=N=fi51(8j7mY@!WDJfin4KD*hS^ZTbZ$rO>$o^O+gxrnZMxzOLThT*^^0jQo6*6?dc +5mu2`~^Drhtse#Eqff%YpGH7jqlVr<+2hOk_6T2#wrQ)3k7cKcNDP8C&x?3=TU^B^a12Y*)tI*ooWcd +Pw>(BpD^+M_Jjr#%izSAhSiW~pdln`Wy~3YQr^RP6v#BJ42xgFn?VNd3&o1 +pok_9smF?0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FJ*IMb8RkgdF_~OZ{kJ} +$KUfQMwb_tNSI=q$BX)caFCEA1Od@0_oiCxb+FFZbZv5?Rlj>@`~a8?1lntRssf1|cIG!byX%>M%-I? +Lf~(GTZvg#XyE7Pf;HrP${sen`&kAQSnMt@;?vv{a588n(!3|*^{N{R|CXEF3EpGS{B(MlO1Ol+V +%&7E(drK*YpA|ACA`ODrS~&F4$swM66weuy8{B2e)M3=G3SCF7QoB9b;tS8>FbQwc?}7Au@;7QuP@0` +z9HfgxD;60|%IM&uj9NQP29OFLOfJMbgrPM1-j&clljI0A4d)K?g~-jj0YpaEtWK@`An70m)aT|aJ(= +T4PSE7~PTNeN-#MBgy6OIQUeGQ>>b +TKZDqYKF_H=UNE&T}%3*1QEi5#=_ZVr@EBLI86k)0fvuv_Y$OwcAEQHst`xODCya3X~ZG~3eH7D`QvF +W2)w|gSK#4ksEjPJTd-NF4Xz)Do#Ec&9~cl9`VDU*m`YfN(ph>%jDWuIxi`7Ff0#gP@Cct;{Yc%P#ANs8k3?D|r`* +EiPFqSggV%kh@lh<49V90rZJ88>ExL%kn{Sl8h!~{JXX5v}mFAr$YOQU8G3>L6t5SN&4ylr> +wq6bMfj#%ym#>KdvUrLWplnoyy>k{5vn>m3ID5yM=(ab>pB>^>ji--!c`DP +k$o@d3_c#&M9vBYM+I{zSy;po9#lvtN97~Okx-bA>?lR4$X*oQ$wJ}g%P*D}!q0GC(2M2V8vv6mWBrx +ug)(Prkj-IjI&pf&>3JJ*I?oxz8T@<(aR$$s#F;#25@+&Ug}4gORfwzbT$Q*g&sB-5@?4F$8qd{;tMO +c&xO&D_@V8ntG8=Jq2hT76CR>BJMxD12*WkG(aZR3U64&H8L7d<@L7d>ZDREPtn-VwWIg2=p=PcqZp0 +kOwdCn%z<~d26R<86ii`iiQlDMQ7Dp?H+Hb1&^iEE#~P+4nO) +H}vJpPN6BR*!}$nNLp(#NhNzFE?r^a|2ybY+cjg?j^tK^FnSSSE2-FLJIh^ +XU(Ctr-OU&6`bslQ-FWv$q0k%O8)d_257xck_@R2g`49E}%KxDE@7U7bZxr+I?cUGY(%#S6vfj_y(%# +S6vfj_y(%#S6vfj_y(%#S6vfj_y(%#S6vfj_y(%#S6vfj_y(%#S6vfj_yHobpSlz9ordOz2D_q4E70y +up*;2qeWv^LJ|q!eYhEU2{@=-2lL;Ofa;F+9JT&L0{;5^W?3^|kzh7jc7A39Cf)z8i?kdawd`aOT%Ui +XtYKf09>!I0k{;&Qc&r}Y4!891)962cwllYEn`gVqiEVy3hgg)S>*2ru_1-}}O7-x-{D(yDsAs#wU(dyQxV@)Gd`q|XeN6+Bwt18W?0$83NCM)6KS=`e%Q +{v9K8;8M@YeIhSK0Uge(<@vIM5!@J&RIAMF +%ID`2H;ZE^27c7LH^bxp*NPg#G$Xuz`;E~L26s7~g4JXTMe8f<0QGpD=)L@YP7>)MW7D*IEvEUvvTnb +Hp)mEzX4*|nOs!Z-FWCnd$B`IPx6jK&!n^35Y0jJl5&W8_w5k#%I3*9h;skPNGMUCna{j8Fn6h`q?Y@ +~8@^PD6ABc{H=gokUzBX|Rpp#dXdl9-JYdHqC9$XAM~#Ih79M9?xYPn6gNBr*n%2~g;Boxu|k2AJ^wl +#2W#>GL45qFDG;j?LPjigdx@$MFJ&s3}wUhyoQ=Gl^Fr_sDt3Jro*&Y1mqs-t3vWv5Cy`MBqjee9G-B5+6TT8*dQXjZTVK>A*{UAUp^ohm@RtT}iAP!r +EK(_E@Fu%Q9%%MBJhcDgfv^$>PUyv;^O~9A1aep +?0o4YA=VbYz>2ff9xJB7(&I=P$mU4R*4L9r#Xj^rK10YOHRnDo&w9_p<0dup$y1VbM->=CKW9&(x}V0 +1;c$uIRVlwzIMOD=mtFMtOiq-nvE;xs!neUL-?Khow?GC_VMv_wp`s3>tE|IfFgF0oei%xVSP%;7+a*0Rx+EDKbd9?C2OldS*C09gIZZ?WT +!>HWL)gn2% +)wyOf4P05hz&^kIYoQ+1b`NBq{;e|}=Oqdno)YnIghxQIlSpdr=r}ed5IvT?um)leC=pLKztnEK{8Rf +K$;If7x=P=odYlWNd)TGPPyg4<&_k0~VmuM{eDO%5lggZhq!OPeDCk)i`T3%X}o4f<;&ksnEnqz$ ++@^&8Nw$y<>prr^YQ{SMi|>8`A!|gb;<3YIX{{SGZl1bXV8tv|Fj^fu}w69^SwEe4c{Z4a;cB(=MGn%!|mGcL@hJ2xH=+Qx&9MA)lGWVL)G`J3bIoLnqb=5fMub}gQjIlH$tk|# +UYv$XL6vH2KIxu>KRk}{cO&@}R`TfWwQ>Gf(wj!J5^6aFIij_il`)FRZKU>z8OT6~OdETjzjh +udQaXz5haWkV@AU2_9)PuqEru{74?8eb&X6KyK#C0BiH{mMa%ci}2c3G4+>8?%fU7 +ONHM-dM(5>iJAo&6an{9csBOm2cc)Tc +hh-qF<;Jar+xY}ylyuC&vh%m4dsGMkIO!t($hj3^K5#-;r%LAUMgqjnt$6I`qqxdNq{`{h&?++8m&EQ +v+*BLO9KQH000080P~d=M=Inlk*`w#0GhJ^05Sjo0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgi +MXkl_>WppoPbz^ICW^!e5E^v92-EFUINp&FT@Ap@v#1~sC(`QGlm&mbtB#d!)sWG4e)beN~t0*q!s*A +eJt-@~R*Ux@df<2Pm(hQQ*bxvl)-aBH&+Y@o}e(!t#@&6uw^P~Ur`A;4{{``kO`pM6K^!S?}|MZ9d?e +V|(?DyV%@9~S@zJL7m(}#ch@XeQBKYsY}*Y6)6zJ2`t$N&4o*I$2m|NOh({o$JrUw!%A$4`&1zW(t3o +9`Z9-JkjXyFVxW{F@KoeYjKp?fZXz|Mkb;zyI|3_?yRf|3RMj=YR74yKlex^7rrmU)g^6_|3QXkDq@3 +@zeZpXZ-lt$4{@{fA#78m*2hr_2XB6oE-oCrM~&F* +9`|ab4_usz%^v~~q{d$rge*EUUPal5uhx;-A;@iLc-|pW$9)JJkr~mQz*@v(H>C=bbJ^t!(-{E(U?>; +_$_Q&sj`|+DUJ^x))Uw`=3r!PPKQK|jr)BE?2Z$JL#yMMWF?5`hx{P>5*S6_bf`1JnQAHIEMe;34ek1 +xOZ^?&;K=}!N7Z~v{N{?3j3{7*OX_`8pH_EWll{doW3e&4nK`TeJF@83Mu_pd)+?N2#= +_PFc%FTVWF{ol3udkO#YzUeH#zuqZ+@He0T`14=`u>+`?Ei3A@VECJe*NpmZ@>KK_jg5q_ +5Q;hQ;#q2M)LbV{{O1QuRnhCPxHWcl7B1FzkYo9&EuPo-+lJ@mroz==(*$X-_`G(%fHp|XLs0t_5IHt +dEFoS@|*wh^<4))zmxynhu_>;|J~OgKYse`@i!m8{mw`K{s(v3w{=}_e|7D*>+$&I&+p&-um1P=(NF& +N|6{lEy?1xUKmSr~-B0zKPal8x`0`h3a=rci9pV4;yT|W@(%m}0y@TYdum5oO5MSTVclQB*xJ&tNAa? +=&?)QHXZr{EC>bKu~{QBcR{ZXdZI*-R+{nh{ec>8`o@1IxJpMQR?`{%sYzy5qmg0~fa{>AedA*s#(H$VQ-KmPpl|KmsZ@9zsP<@Lkge)&n%+!6DC{q)mxGGG4c>-Ue(9Sd(_+Wv&XuY-(8b%-X*XVS09D+x +})cv;dR|VKkui1ocrxNYd3f94?fy6Du&B7JLDeGZ+97Xx+S&Hxm?9(QhlV0q>JR8f4zP;pOZt%q1<)3>$=mP`*ZIedv30Ly5_& ++;0_<>si^MD#dR0jd2{P;=^15MvYv{%>*KD8Qa(A4>{2S=y1d<&vUkx|RP9PVbu_=bGt8;cmj6UZ%ep +7+(<2|DJN0-!{2d|_4kFphn&&=3si*qyY*hdKVE28UrxY#MBe1VmhIi@i*DpgPc;q{X?+l+V5^DbbbW +WiOk=k+<_Ulc7tGvG6+UV_MjAKJ(P{w +&#AjuerJV)7M>l_kSrgH+SwQx!&%Qx{kKImDG8gmpcyc*X=*Ui`#s?Q(oH3QCm;{^_2BI-d!}&b2%Tm +riTy+Pc7wW^yj*>(c3&+7?fn3tQ)qL*0Tur4M75r4X`6? +h6)yKp{f-WI0J!(!_=w;`wpK}ZM8&4swCLWr{UCY;8UJ>Y)9$WMYhtN0eDNVoIn$UBe@xI6-Qs+>vB< +@l-s+)dy--94nf<=QkTINH{9lh+nE9DUe2(fv0Hp`Vfo(A`(eS{7pJXqXybU(7*?daV?L)}XAZOt7jf +jep+uX?;M{Lni;CUSKc_wVM0#aK*V_ck4@XB0L@pu53&c>T$0-Tg$G&hF&grcPzb;N{0^}D;L((ybeIHmKT`8E%rfCTKi=8X_uvgvulEiGMIPo-%6Yr@88x#m*y&cu1okFGqur3Q +V(z}-^{5xGtop1GX-=fRF1`&v_(9_1+UX+xsuD87dlu=O!IpGU>KA@G!3rRFHk#peBn&f)RUCA{*Q5z +ajbpk;)6zD;lG4yTXw#x$X=Uzi?S|8dVcWO&!_T`5|{42loIa@F)Z6YL&E9G2*N>ep6JHuG}d|8-5jJ +U<>6nOfGZmRzSnKLv|9#r@oxtU8)%jV0@+f;2$nT=Ui3h2`tH?^?d*%1_n$)B@g&%QF=*WL`$4YwFg+ +Uvs&~p0+$?sC}Qgx%-iyms);mB%x2!_1<-6NEYl*y~b1Dx_WvRxoXA}(+2vxkj#esc%7LpXnHemdaC- +Tye=K!Tg@-QGPhGAccUdH&#czYRq?#^_AG4xy-#B<)A93<8to-uu$`xmOuP%3Ad$Cy3FUy51$79r~dJ&Q+(zGtg4>sF+YrXsJTea%wbX} +dQtQ=?7ZpW-byX6HE*jfPxkgU1B*5@y{u*ydWh#t7oQVPVpFb{KJuv`b%J+VQ;{`Y(1eH%_NgsDYkt( +ebu`-qZLJCCnYk-#Px4gO(=*mo)ZC%@^quQ;G$uzZD9Pc6GI4?0O!Or@BA&h&j|ou2lZ*qjcwgu|OL^3qFPlB{X(lf>L0YkCcrt63J!4bRP~Tf +@n-r$2Xxmr2B$72cj%x^!-Q$cY&nd&1V?WItpE`>*(d_}^^%U +7q{QXQ?#vkLPom-g8z8Qz;W) +h9*^U_sse^{keLZhgx%`S8Telap0jd*m}mLr96yq4_)Z}$ohQqk+r6m^}93usBUPY!O-0S!OyHT)PgUR9tZ7l&_ru`1G?M$}9`)|m@Sihonk>!4ex~L3r|& +mRDPI4j@hZcf4rxs`ipI<*M4Q#;9fx}Cy36K%TbRxVFZXaw%*jhJJZ3BnpS#DI`$gYvBwx!NUDG9-+g +wJ**N`v+>Yf~|E?!qI5fwZG35--I +b(x6yu;@Hh+OaLxHH@yV9yZXMrv}fn4gH*GZ8kgpFZ+Aot7)@$;O4J%3_}Lm7#P?uHgZ^v-EhEhPs~f +JFRD8M-bPHj?>6{28~HOouIH8p1G`8^^}jPE>U~OlVYD0s=gvL(QC|P))wOg!m`>k&D7r=K4vBLHnSH +Idd*b9FnT>_wL87|^fr@DSx=!&^~d!7^IzW8Qtns9nJP(l{BZf_Xwx;nGb`NlUwTw8*K0j61u|)8QEu +6CgiTBv5*RT-mh)l?R*LWSG7BaVKRvsp%+h^bbETRW>y1n25Fu=8UIv1uBlBeXrdiJ}A!5ROcOo-=a5 +*uMXD(+7JaKowdq484GF_#;{c1?w?x|bl)#_0QK0I=cQoTxj#*2xk$>24NPLkmtBhajBdfryptpuhX= +WYz1=1$A1Y+30n3z22X@HnqZIWjyFPlKMmZ*tVu)DH-ZuXBiU{1p1Td +qOaHTQzt)hKJh#2nWJu>ZsF+`o>OKf(P2!9`##q->t#LhrQ~!amy!K`Ly_h@sA`>ckchnW71vnHB%4` +zuHil{MYRIS`^C(3uIIjHf*|_tH}pWy`LFgemy@-=?z&szx~45_8uyF5E}y=8u650vaq`zyjf$+9plN +#aSV9@zpBZshB7>r0dS?7Fig=xR+EnKzcNCRA?3#kqeO>c +-uN$7<$x#1v&DG0=r^~q?@y^hYql;U{fptx9V;Wnp-+9KlrItg>p{ESzzZB9K*$lU4U-vH!$?mWxmS* +y*p-yjLQMj&|k?;9Y)@Pi{eN1GTg6)aTGk5r!t;*|+QW;{v)=UQWRDe01e)BF@xf+*|&3&7mRu6PN$H +{eHGZvLz(2D#1(HQJDwbn;WWzG~#FQo+Tkx-X5i!|$?p81Fw>z;*=;r?z0Qz>eBrrl+ZK#Vzc8zx*~nqA4|Km^|NSzLYyy%@AkNHIU0#=9C|_$j0=*O*yoX +UAR`WWa2L-#Eaf_1uU^dzpiIYf +SZ+<;;WXKekb6={0oa%WPt;xnV8VCdB=s=`Dl9!<5+g_jtv`Oh9HqX$Y9!a^<_$6MNM}+b)<)T%(PD@V!U|hrys9Ss;Lz7rXIkZho3Oj>FyyLgWxiYIuji; +fr`0E%g}>Pqfq|+TG0!PYqmdPdV}F!NqQ_t5`z?^yccO&&x;b~!Q?gV+pNUF03kP+kYZg& +*7(VfMC+E+HNsdI4uYdVLFY0IWj;9;$~n=@~#sA+n`$mf^QN~~gP1E%L8?*R*JE^G=9SZKCj?c$0q +8NicSG27;WN^HrXPKJS|Or^t?3#0~tOrTdy4*z%w{#k>7k^{e2AF=e*qQsLSKyc5f-$MXyo#?n~}Yb47S-n{_# +c>B!d-KG$KprnC~8QzONjE>LNc#Lz13(KOlU%L}3;lBEPhdNkY$$^4am3?((rG!}+wbnPEC6e~+SqC!R_luwUEYI=plxlkY9!jqVU*J~MYb4ONeX1E!Ia#5F +sodwv{Z9L<`|Lr7w_{g`gLjC%Jk=N=S>{(VAl>(KYy;bf>EwI#A>%F<~qZGO!(z_zQS6Cz%JI6ILz?t +ambW==FPr)QawY9?{}wW}p)XUc5}XRdkQmu}m@wbNQ}W-ohYV>6#NF7GKD^RU@9o0%w?zQfBKHOt89m +8K7yIf_oCEqwMoN=-AKwlEN6FqmAG+>DWXW@NLp9D$rJfr-bgLB`2nm101e(+BaoymzjV#QAYv+^apD +c+P*#^43KRCpP@no|WdzV2!sA*m(!1C(|?TX`UuHyJv7S6`62;4s+hOgqN&oysWg&KQdXh73nR{&g;hyd7d6cOcJ&;IPd&=Uq4jN~k6z)s^<0SK=0!habmQCR`+e~Yg>(>k?rkORPsyD8ACvY>r;wzUoVa!%Hh!~E#Ura-2w4UD7Eqp|%q5HwF=(6Y8%Gqn*%N}i6>~?hrzj~R(ooBw&LZr=g^qDng4RI=o<2$U3dfIm2=i?V +$59G)O^jHI$q~_dNNc$x}cfc%zU9Hru8fa;>UAhdg9eoZHDBS8NjSdrv_gic4o;TnPnim(Bw7ZWi(r_ +nm5?w+|m@yOwe?zQ>1Uxf@k+&ipJ)`V|K7+T^F;Oo4j798)oxZ4o0sz7BmM!wk`FQv%fs#F`eD?Qqw_ce-8)5mW +FdDk@Yn%ZbbJu$dI#M>dDoGXL&2M*2KhA=9Gwgc-UcDIq4?DNusN=!?*IaqW3s^g5Bq4FTgRXdje|0` +I^?sdQV%EjdkxRx08;`nTf@d?iac0i*m|(V1Eul^_+`*o7L!SR?hlH(=)ppczDcYX(T*mnQElX$!pf7 +W3H|lCY*D^X{MApOF{FIdYyIh@G)R9pLSmcK?B#tWUkl4&kA*RSZBRFU|(-Tj`Oy}DKD`zo8N|j$DB& +3*|{NovlW!)Sl3vv)~_SJdmG&<(q4{CEhnMwm(jV|w41D5N#{0OnUC2Mo^7kyo*k*2N1WBDjn9=+UD_ +ksTTa!jeChT4PKH{rBPVN4XE-i+O;r~iaPI4|Um1$fJ=+I!ife{iQ<0pzHb&ZqStN0d&e;LD<`|U){u +OV$)V$PjRHlktnM&D*{I_G$d;bo37K4xj-MvRfT`T?mQX +Ru(7iL9ASPP?7YscJ*abSwtryHaK~H&e1v$=Pmk<;k!{2PRmavp~{q?>Xp-QFH2+`OMLpl%Xx-W%0FU +QsNZXnj?5I2Uv5Kt$N$6~CdMYk{5Wf2ccfe$bi +MCT3$|mqYHnoBa>UfCrjfhhDYV%Ym>%1r;LMo`ZEFq(l+8&yl=tjw4(UE8!+F~S==N$r$FNYd+xgl$8 +=aFlCu`57Q>@p2iNNpuX%{`~-S>X<&+k9|@w?ypV}f73|N7&<_(PMA{xIV4;hXQ?e|rDzck?G2zkdJS +`>*B*{qO(q>GvPMeSbfvPQ=V`Ij^v4%2kKtVb@T-o&Hr*33@b#otKkntEMpZO#0!aZ@4p@Fwr47HMtx +>T8;uPLc3~;Mz`bK_NsYoJ&xj84iB!HnlOBGiR0PJ(aGg3%9>r+k#BpP%ldLTI=*J|;*9*7{RY +RR*6hL81mDw4-3hbhIMlL@zZ^_kWMs|y)$!9cHgDE(%>d+>-!jc#_LmljTNV_{nDlO$Yc6rVobO+bp) +Uusms88j0n9a6I_pVCeV5~`i+wCKxU8m@t?6YG>&{RNJ0QCpHC^`F*PQe>jxE#tHC=!MT5C2P$ofLV% +aC;$;FcqzYtHVk5l)NbrE^^?^=ET7g)XdK~PCVOkzsdMeip2QkdH9W1+aH6& +5Ap7d6Gtpt*wVV=Jm}^;jF9*%98Q2{!U(WWfIY~ZSmyYZ%XEc|iN6UbAXDCjb!d;Hau9+57;bnhjalq +xI_i{RWIe5HgW78()a{7BY?7T?fa$NS^a@24+kF?Bruh9UvD2v&9M_3ertqzI(nV#atv=dw6&b7S#$Wq?%*Ag&Z;hFRhP4>%URXstm<;uaycTi9D- +R6f2>)ATW{YPiV3TjF&Z_VPz%xyVSx16b4&eSbu>Xri=%Q=HPLy>^m7TQ@HVp)$bXW5oxY}+xm?fltx>TEj|w4F- +WcKWydnT-!OzIeAyXtv{G+i|h&u+e2Lu^ndFPIhd&!P|b^ew%qw&hIQ@xBM>|EE(XW?cCRP?rS^twH^ +D~j(u$>zP1xz+Zm;8mwMaz-EWi4mSRh>rPxy3A#rE8CE1dMBq2#i5|V@@AxTIQE)r6N6gh3)yD6CyC) +@Jr%3+W6>3N>lXXNnuog7jQ<(egNxn{X$Nl{YVadBrjBgrJGd6BNAYw23Lmae61>1Lrb`M1lpWbMa0L +hcNYbVs^b^-X;oiI2p`Z64{4bVs_U%RMD~O7@iEDFv_J4vcJD``gy_w!gS-EpB^D+w6U#$W5R&Y}!^f ++e%|!W3D+Lk&Fv$>!9tt&7PBJ7KR&hZD($_GdFwws_;*rJ6Bwl}#QaM^a2w{3-OS9II9zcUmkHf6VsgUygPIlFE3Z98JyS%(c(H+SDQsJG4M?U=)zp-8}E+cAd?ptoI_ +?U=)M%wgL++KxGF#~il94cpe@wn@4jZrC<%_8e~5YgR-xKT9VZEaSJ$=#BWd?YV8|Y1_cqsCHwz4Usm +$*;r*;Dc>0i2aDfrIk*i0d)lAV0NXCZw$HZh{%`oc?Nx4@_1o^?UUM^|!3N)*p>VL_zU{Sd+w9vm`?i +n1ZJ}>|v~7}a+v6KKY`al=w!(Ar5)HP(?+k^5ZSZXad~=~~M|#@;-}G{0f^Elp+wtCZyf;za_O-VS>T +PR!ujw3YMsK^%+wSwWv%KvrZ#&D|w#BxAyloqA8^+s)@wV-@?YeGzZ`&T!rf=`It(tA4W!pd5c1^b3i +EWc$1MSVIH-Fy1d9&utL^nj(_;3@mO=Ip11%Y|%Hq+Xs6MF`qX)Y7pc22iF(`{>X+w9!-b+*mUZO3KX +?A$gx?+n$yjm~YObKB_LHafSB&TXS}+v40dF}F?3jb%4&-ymj#*KJ#J+mXC8RR4Tx^QvusaWnSobze0 +v(uo0Egxl`mCfM7?;I=WiZ3%80fp><2z~0Zcsj}_$ZF_y&2H(a#+XmmZt+#FKZ996~j^4JTcfHC&49s +TUwwbqi_qLh0?c;6xc-ubSwvV^%<8AW2?cQy>ciZmWCgj_e-L_@7ZP~rs$Y$HA+jwl-ircp0HUZxD#< +sn&ZEx(FO0oI1ZFFsWT-zSko_%4pb!R9XfYE+YbWPKiL}1w2+BUT|aoo0fwymsfD{I@t+Vh7t(@yPV- +5H7wy8zcjg8i&*KWoR_jS#UVb>YcvUuxsfZC`5Jm)iEFHb&cs?9Nb}*pu2eqPFd)ZTo54YT9<0cDy7> +lGlr@1q&M7Z0iD{mwx%qaMmPt?{Mh0Z?x?j?b)%QquajGjwyz@O#u{>qUXbs&F6YD6h?FUDqsI4u~4# +ev+dbzdp6si&9-N=?bK}hGu!^mwm-A&%Iw*dxu*HpmD%=Uw!N5bFJ{|t*t1#xHdQ8`?7M7REE~RW+ai +0mJ4o)f+abgI)Al^J{f%vFW82l($bH+a*fuM+&5CWaV%x0Pwj*}V-h%2uQrm9CyG^0Dors;Y-(*#$m2 +cY-+a|=Goh?$lXJ-o+Z+j5i9>lf>vF$-@+Yfh!Yu=Vvd?EM^r8iC9%y`4!4Qw}?-Qace!p#CV^4pkh& +q1Y~bH{T_0*YU31hMJErUTo8bz7WnOVVwnvu7GUv+bF|nz3#();mM7G}FhKc+F@(gW!x68qS`EGl4DK +wiw$JV-r*pI};&l=FU)@yb5T_Mx3DZjnemv(&u-AWlmwf-W4$EH=7dn~ZKUy2SnU+dS7y(-`Syq??g$M!Fg4W~7^u?l~Vekqk;VDBYlRgVN1OHz$3 +!LFopi8;J44ZdNB3)M|IB|$CpsAEW~7^uZbrHp>1L#xk?t3fsysw`XDCGQ=*FWPk8V7=@#w~*8; +@>0y7B0q@A;VN6(ik87QdmhSm0>*?^2 +>7GAL*7X_nd{EfH(+y8IJl*hg!_z(AU@?6pLEZB;7Smf|)QwR$M%@_ozC#hjQ8!239Cc&VjZrs7-Di$ +X#k?z>06O!?b2IaX0Ai_kh9U^2ZkW1Z>V~Nsqi&3PO}EWbH%r|Zbz{^`P&Yx{1a+TL5rn!C>Ygu8nC> +2YndOm?40rZi2cA>L#e0pl*V?&!`AO-3WCf)J;$~LEZDE1T%j>>jA#H=L-R5WdK<>WZlo15>wVqSvO_flyy_qO<6Z(-IR4x)=gPAW +ZjT;L)HyhH)P$(jaoNq-Kce=)(u&&S>=<~YlczWy611*H*ej%b@SHETQ_gr +ymj-|&0F_)>kPlVb@SGZTQ_dq^Y`hmaT&Vq=akYE&=iX(g0367Zs@w9>weDt3n1vaq3dR@o4M}ite1J +~Ra2%0Dd@VP>xQlyx^C#Yq3edO8@g`jx}ocyzk;4M8+g4l6hY*5lh;jNH+kLUb(7akUN?E&soX66@av|pcZSdTSvs+UUpIc;_%-lr;Mc&ffnNi^27V3v8u&HvYtYwsfnNi^27V3l8ss&|YmnCbX&SD-FBtzN?VF8#g<}Av88}%SIxbLbRk_x7t+PNA +zerp(uH*CN-0H3ky4}-{-7dIYoOLZt$|u&zM7||fJ(ZOuB5XPtSPi|xtfp6kJ8qZVY^;S*V46g?RqT< +Tf<(#TZ6Y=H5Je1#}JQ8Z0%KYcSV$!CQm325$}C8mKi;YoOLZt$|ttwZ{DY9QX^|8n`v)&-> +@gL;|`7bPebl&^4fIK-Yk-0bK*S#x;j!a{fy)!9rdGyasr^GZZItdbj4@1q*%+{2KT*@N3}Lz^{Q{1H +T4-4g4C{T*SgB@M~OCEG3CJ!LNZ|1HT4-4g4DTHSlZT*TAoVUjx4eeZ4ajBKS4%YmnCO*vZ*Z +{EsVgtkmhz$^XXDB*AY=GDRu>oQO#0H2B5E~#iKx}~60I>mL1H=Z1jrn7MAh7{r1H=Z14G`jBMFEN5E~#iKx}~60I>mLubTXY1c40j7kn=mT;QZYKzD{>0@Q@{O;|33 +iG7%shY53-yoM=Qn0v9V_)nP(IeNH&mcAlaBd-KcqZae-t5$p(@QBpXQ +f&QLfo*829gaV8%XxfP$b~kps_(?gT@Ap4H_FXHfU_n*r2gNV}r +&9jSU(bH1=KK*ub$tV}r&9jSU(bG&X2#(Ac1{L1P2N#{9(r1qm7(H1^JLeijZOHb89P*TAoVU#}T~7; +G@uV6eepW4`gICat&_gAE273^wp<;Mc&ffnNi^26+wg8sznwzk8gv%wU7T27`?;*kG{1V1vO1gAE273 +^o{SFxbGa*F*z@4F($wHe!CK!@#X~hN6SF25OC%=$MBW9lSMoYoOLZt$|vDv<7Jn$QqC}=1-4;vIb=h +${Lh4C~HvGpsYbzgR%x?4Za$DHTddfiWHDF=2Ul3)&Q&lSOc&IU=6?;fHl}^P}QKSK~;mQ22~BJ8dNo +?>bt&$s)12s{y>0{1xpQ#8U*!1W_O13jyU0{!BGRF21X5x8W=S&YGBmBsDV +)fqsE-m)@*~N-WduJm>MuOU~0hBV5u?3tj+iXs0L6Cpc+6mfNB8M0IC60?+ir;Q4OLRL^X(N5Y+&x0a +PRB9z-8d4WJr8HGpaW)tIjb4Wb%EHHc~u)vM;=1qN0Psv0@BY5rMLDuM%^2Fwhc7!dK!P;^kMn6t?># +V15iOwf)%9DyYQG6Y%(Vi24lEYD-Uu8djU843~0;;_&SE8DQL4U59CxC?8zu-J;3;m_oICfYMOp6RZs +Va#dTm`TLU2xb&FxLss4rq7@LcDmK+RHh@Cb~IrlPGZVuilJsqai8(ZL3Ci%z^Xx11E>a24WJr8HGpa +W)c~piR0F6+&4iPv22l;78bmdSY7o@`s@IGNR5hq-P}QKSK~;mQ233ukF@>lGQ4OLRMD?2Cq+T!5i4L +k7R5hq-P}QKSK~;mQ235T?6c|`Fuxen{z^Z{&1FHsA4XPSc^?DVJxIn9cRs*d@%@;bq3Qb@D)&Q(g^9 +?WaP@;pf#(Xd0HI=9TAgw`KgR}-|jrjw!psYbzgR%x?4Zs?JH2`Y>)}X3ERb#&Tb7r+@HPC9H)j+Fvh +N1(j238HM8dx>3YGBo%szFtQss>dJsv1-^sA^EvpsIICrP1wwzXV&XoiNy(D4Za$DHTY`q +)tE1E7GrmYf(5V!U=6?;^YzR#o20BkS%b0$WsNzAI#UYL8l*KKYe3dJLlHw+gR(|XHuGu0LRo{d24Ic +(>%EC{$QqC}AZtL@=vk*w)}X9GS%b31DC;y0${Lh4C~HvGfUE&o1F{BW4agdh_0G^hGffJ$25Jq|8mK +i;YoOKutkF}q;smV*S`D-sXf@7EMc8Vv)fiiyhRRlht;T!>@w8jO8hka-YM|9XtASPntp-}XGn^qu?E +%&RtN~bqtp-~Spc+6mfNB8M0IC601E>Z|jWbh`GhdOYQsCR~<1EB^&4T2g3H3(|J(}1S|PXnF?Hw|tY ++%(QSou1^(It82tHw|tY^F^`KXTsB%uX~=}lb{AX4R{*xG~j8#(}1Tj-`N`UH0Wt?)8MATO@o#OC=Es +$j5P3Q;L*UNK}Um*1|5y(*cTp+`JOgCcremnr16|%0}2F`1}F_s8lW^lX@JrIrNK$#Ia3i(8jLg;X)w +}Yq`^pok;WM53>Azt@Mz%Cprb)YgN_Cry)zUOcr@^6Jm)qiv6vvEK}Lg&1{n<|8cZ~pXfV-WqQOM(48 +;T#4JaB=G@xie(SV`>MFWb)b4ox+;LyOKfkOj_1`fS56cao&cxdp@nAs5z4IUaOG)QR7mqN}Ei9-X21 +`dt+K1jpnouM9M{*Y)!P%;{1G{|U>(IBG%MFWZk6AdOBOf;BiFwtP5?-Gh86iq0aP&A=v&bLn)p>w`C +#4w$BH1TNS(WIkEM{^FRvb#IOOAePD?&wHHnv66VX)@Aeq{&E=ktQQeJeqVg>1fi?q@(XHi^622$w-r +tCL>Konv66VX)@Aeq{&Eg{_xbiB0*^)(wx7;Nk*ECG~Z?qucV84k$4_-(xr4MUAkOKmXcY()a%`nVM> +?MrF7+;lCGpH=}NkJlDS+-QBsr?Ek#SwbB8TSOVX0GB=EfEZd$sQ?nrn1?zqyC>_~PbJCd1-BpFRInq +)M|Xp+$+qe(`Sj3yaPGMZ#G!Dxcf1fvN?6O6t~GMZ#G$!L<%B%=vMbB^Adza<$>>(VsANidpVG{IkT=i90Ug)O*)!%H0kJ_q3FP)iANKUCLYae%3`iGS&I% +lns_wvXwuQ7qe(}Tj@}v0=I-m$(uod6nv66VX)@Aeq{&E=ktQQeMw*B;5osdQJ44aINRyE!lS{M7oG< +jMc}5`uN)wdke2bS^deYLQrAbQ@mfp48^BIuoQMhSx)8wW(-_u2P5}xLK0|4Jif|>+132GA5B&hEap( +Z^|c$)Au;c3Ftgr^Bl6P_kFO=OzLG?8f{(?q5@WSYn{k!d2+M5c*M6PYG5O=OzLG-+wl(xjzHOE0UFM +5Z}pn#eSf>1D-o0nmh}2~QKACOpmgju?=YYjO}V1U0EkQkR_Xlgd{PA_k!*K}~|11T_h264YE%)>F(= +q*IWSzlh!x#rpZl{neY7*2Ws7X+BPDmy~O@x{VH3@3&QT3W1r4uI@H8E;p)WoQXQ4^ykMoo-*XD +Bc@YI4-%sEJV%oaLV4o2+#rmOE)imNQt+h&CPSbXWSPJ3}!s?QfdiG_z@36LYTu5)<$=;c3Ftgr^Bl6 +P_kKO?Y}|C>-c%!qbGO2~QKACOl1en(#E?X~NTlrwLE5iD8181od4a)I_L>P?Ml0K}~|11T_h264WH9 +Nlw4Nl=rZCP7VtdS@sm=xM^!gr^Bl6P_k +K&H2h{@Q?&G32GA5B&f+vlba?ty)zUJ+%&mqa?|9d$xV}+CO1uPn%p#zX(H1^rin}wndXpb#+1W6^4x +=PpruJmla?keOFlba?tO=Oxwri +n}wnIO;DPkG(l;C(gdXmN)wbOC{0kBj5HBxBGN>pcZPz1ktQQeMw)mu@o3`F#G{EvuW5vg +G#P0!(nO?*NE4CX8Hxl(nv66VX)@Aeq{&E=ktQQeMw*N?8EG=oM5KvGGv|xaW?lwLlaVGPO-7oGG#P2 +;+?UP)k0u^XJeqVg>1fi?%;_A+Xp+$+qe(`Sj3yaPGI~u%gGUpOCLT>NnqV}+XoAtK=^V&tlF=liNk) +^5CK*jKnq)M|Xp+$+qX|Y6jAqTMwdY-TNJf*4CK*jKnq)M|Xp+$+qe(`Sj3yaPFq&XA>0dIwBwTlf!h +u?4&B69F??@*ms7qp&1Se^!pBDIOah;aDY3Y}id1-BTXDB9S-Sy(p`9fBeK1+{T3d|gProS^Cof%oZJ +|eBSm_gid`|hHkIRnykm(w#&S2gYSPwz@M?DhID(`&&(OOuu+ElpT@-=PqprAbSZmS(*=jQO1_PceuS +WSX=zX=&2Zq@_tqlat;ViW5+ppfnk2GSXzEiANKUCLYb2NoY-q`-PDvB27e^J?j)knmtR|p0~?OdpTa +Do5hMJqooN-6O?98#GLsty{HsgnzS@&Y0}c9rAbSZmL@ID`D6VlDrB1TZ}Ta%Ysw6sCOo|}6hZVf;c3 +Ftgr^Bl^W~;J|K-90h?^!iO>UapG`VSV)4P^c1vgD@n%p$GX>!v&woiar9Oo_Wg%=XA(B1iFi-aS>Zg>?b7oH3^IzIBJhFS*&8z#Hfi;lb|L+O@f;6 +G~sE&(}br9PxDM~b0!C|15cBiCO1uPn%p$GX>!x#rpZl{nWp%tXSOi%hPsH|D|;zg}Eem|)bLe>W>RYI +4-%sL4?iqb5d8jG7oVF=}Ge#Hfi;6Qd?ZO^ljz$}~A@&c8b~9UDwdn3^m#S!!a`#Hfi;lb|L+O@f*PH +3@1G)H_4bflw2nCP7VtnglfoY7*2Ws7X+hpe8&`c$)Au=burUJ*h;fiBJ=vCP7VtnglfoY7*2Ws7X+h +pe8|0f|>+132GA5J40W4*B +BjW=!;~Z?Nl8+YlB6UlNlKEEWFDfVC@D&clA@(>BB;P=ans_a#Z8Nw7B?+qTFA7JX(7`>riDyv{?S2m +jpC-oP45hkbVs@)-BY?LzWLx&x~D5WC3(8iQ;Me)0)d+rH!W`ZuE1$=)8eMZO^cfrH!W^j+_aEsA=5& +pWolkVp)v{;GOZ!gqNPPki2P+C@%Wu{o5v_NTr(gLLgN(+=0CoN8TXDA#%X@ +SxLr3Fe0lolv0P+Fk0Kxu)}0;L5?3zQZoEkt@}C>$7RG16kB#YpR#^{i?Ir3Fe0lolv0P+Fk0Kxti5k +d6!1HN`UNgabAz{b4cEVx+}L3y&5aEj(Iyw7_UF(PE;-MBfz@Ego7tv`}cF&_bbwLJNh~>oBQn;?TmO +g+mL677nd7odXXo9$GxKcxds^;-SSui-#5uEgV`nv~XzQ(88gGLkoxA843a(T0FFPXz|eEp@l*Vg%$} +d5?cJT=3j9#hc5_P5VRoZouNnopann+fEEBP09yR>dX=VVm>v#-76dH_S`f4#Xw4VlKfdQ*QN8mO6)? +15Xu;5ep#?(=h87Dg7FsN{SZJ}(!k~pg3xgI0y)zUL9JDxSanRzR#X$>$76vU0T5IZNo>x3z&?2C<$I +R`<6$dR2diCq=^ip2h%kd(yj)H|23oRB}EVNi?vCx`-c(Y(=!O()C1w)I276&a1S{Sr2XkpO8poKvTg +BAuY3|f2o2n1RPv=C?^&_bX!U)9|6JVFD576vU0TJz6d!@|O#g+XgiAHhM3gBAxZ4q61X} +d->PajT5NHw5f}aIH3w{>-EcjXT$NW84TJs{=^brWO5NILLLZF2}i+~mZEdp8uv8R5NHw5BA`V;i+~mZEdp8uv +-EcjXQv*72Qp&+22ML&yv7W^#uS@5&qXTi^cp9Mb)eir;J?pfTk=4|LSa?| +s)A_0LG0xbes1hfcf5zr!_ML>&y76B~+S_HHR=zWJG0f80*Ed*K!wBTpK&w`%?KMQ^q{4Drc@U!4&!O +xnrp+!H7eir>K`dRR^;Ag?lf}aIH3w{>-Ebdv{v$$t*&*GkUh9Uuc7WgdgS=_U@XK~Nsp2a@3wajuEaX|pvyf*Y&qAJsJnswz0rM>6S;(`HXVK20omKNE +NFE+}7V<3QS;(`HXCcq35v!i35Dwt8xMy+C;+{o2i*^?6EZSMLvuJ10&Z3<~JBxPScPI!zXMxU|e}}x +MltcpUEZSL&v+!nN#6pBc0t?&~uB-V5(re~z7_R7A@vWj*#f%Dx6yzwXQDCB&MDd400cG`FH3f3!4u! ++4#%A3yGx3>k&$N2xoimr4`H{In&4gga*XiS@+n!!_zURKCkxW6(gObf6n*}usY8KQis98L-cxK_u!k +L9L3uo5+yKu!bi)R+ktnthl+<0d3%%Ye@F$-cA#4Lze5VIg=LCk`f?=FMl^|~)T1j;OwStzqmW}(dMb +=RVUXBNpUl6lR5iZcsm-ghWEcxLg;LYaj!3uP9{ERy +$}E&wD6>#zq0EAq1u+X^7QZZhS@R8~)${KUO?8P5idhu1C}vU20+_`wi(ghx2@8&%r=7bN96hTGfLQ> +u0A>Nq0+sAW;hqLxK1i&_@7ENW +S2W)9f0uw`M(!j^?C3tJYoENWTQvZ!TI%WI}c=(5mdq05?YAT4%T?6TNpvCCqY#V(6o7P>5SS?IFRWu +ePLmxV41UDkX9X<^I4mW3?~TNbt~Y+2N@sAU1m0+t0Vi&Yk@ELK^pvd+vLU}eF|f|Ug;i&Yk@ELK^Vv +Iu1n$|96SC<{&&oGdt5^RJW_oh&$6aI)ZJohcwa1e`25S#Yx8WWmXTlLaSh{tkZHJfVD7h_Vo65y~Qz +1t$wm*8J1%(>V~zdQQ66kCF)lLRo~eo-R# +G1t$wm7Mv_NS#Yx8WWmXTlLaRWP8OUjI9YJA;AG7|%wBY|;AA1mqLD=-i$)fWEE-ufvS?({$O4fCB8x +*7hpgw!zCdJw$O4fCA`3(oh%69U^Dlo-2TLQ1Miz}M8d)^5U}QaK<^Up#K^B8723ZWU7-Y>q-aTsu5L +qCyKxBc)0+IEccSQq-yfYLIAhJMYgUCxy-!!smWYfr|kxe6;MmCLX8rd|mVPwO|cTFRkMmCM?x5?|0< +dWo)0{_dscpQ-N2VM({8+tO|6wsc#%E#3CH?MmB~wiF>nNZ}}FgUAMv4I&#v +Hi&Ex*&wn(WP`{CkqsgnL^gY-PBqd2nQj(M;B}qwAE>cpo6fH$d(NdT>G>B{v*&wn +(WP`{CkqsgnL^gy#8#*?0Z0Oj`v +6*8t$7YVr9Gf}z{6ljM9UD3}bZqF@(6OOoL&t`W4IP^~Hgjy|*vzq+V>8FbjdzBso;NmcY~I+sv3Xy#8#*?0Z0Oj~v7uu#$7YVr9Gf{db8P0=^M# +=e9UD3}bZqF@(6M=A^Ty_ljT;*`Hg0U(*toHAW8=o2FAQze*w*5W8XGk>YHZZlsId`aBgRIIjTjp-He +zhV*od(a8BPjLjIEF*aRny4YZ`! +D55O28#_A8!R?h?D0;Bx28#_A8!YyGVQ7=ZhKdap8!9$aY^K;uv6*5s#b%1l6q_kFQ*5T#OtI$+LmMhKRBWi +&P_da}GsR|#%@ms{HdAb-*i5mRVl%~Nip>=74AnnWY^c~!v6*5s#b%1l6q_kFQ*5T#OtGz@+p?=IpV| +`W&QSfEF}DdqPYY&>%@ms{HdAb-*i5mRVl%~Nip><8DK=Al*HE#cVnfA-ip><8DK<`QoY*+Aabn}d#) +*v+8z(kSY?63qsOnK-lf)*8O%j_VHc4!f*d(z@Vw1!siA@rlBsNKGhLFr7#D<6s5gQ^lL~MxI5 +V0X*L&S!N4G|k6HbiWQcxR~UA!0+shKLOj8zMGDY>3zpu_0nZ#D<6s5gQ^lMC|!~&!&hC5gQ^lL~MxI +5V0X*L&S!N4G|k6HbiWQ*buQHVnf6`LsbtE8zMGDY>3zpu_0nZ#D<6s5gQ^lL~MxI5V0X*L&SH@51Su +0KWu*3{IL09^TXzc%@3O&Ha~2B*!-~hVe`WtKWu*3{IL09^TXzc%@3O&Ha~2B*!-~hVe`Z0hs_V0ANK +fR^TXzc%@3O&Ha~2B*!-~hVe`Z0hs_V0A2vU1e%So5#}AttHZ^Q&*wnD8VN=7VhD{Bd8a6d-YS`4Usb +N#YhK4LsbN#YriM)on;JGXY--rlu&H5F!={E!4VxM^H0=2r#HNN#4VxM^HEe3w)Uc^xQ^Tf)O +%0nGHZ^Q&*wnD0VMD`rO%0nGHZ^Q&*wnD8VN=7VhD{Bd8a6d-YS`4UsbNFIo`aH24VxM^HEe3w)Uc^x +Q^Tf)O%0nGHZ^Q&*wnD8VMD{7gOW`Rn;JGXY--rlu&H4K!v=;83>z3WFl=Dhz_3waqrygocZRB-6*en +uR@khtSz)unW`)fPn-w-IY*yH)uu);7!k(|=Y)sggurXm{!p4M+2^$kOCTvXDn6NQn1HuM`4G0?$_Iw +>@6T&8hO$eJ1HX&?6*o3eNVH3h8gbfHA5H=ueK-hq==j%9|5H=xfLfC|`31Jh$CWK80n-Df3Y(Ut6um +NF%xJGR~5Y)7wAwXNe_N*Icr8bklnE?>OCWK808xS@iY(Ut6u-Rbu4D@iY;b6nThJy_U8xA%cY&h6(u +!&$3!6t%D1e*vp5$v9Uo(47zY#P`gut8vRz~+F>0h +2(S@gBfv(0jQ|?~HUew}*a)zD26_hA46qqsGr&fGP5+wyHT`S)*YvOHU(>&)e@*|I{&mklkN+C~HU4Y +**YvOHU(>&)e@*|I{x$t;`q%WY>0i^oJ~Pnczs7$J{u=x>_-pXj;IF}7gTDrU4gMPZHTY}r*Wj*2n}eU1AX_ciWo+}F6TabJ_Z +CVfr%n)Eg4Ytq-GuSs7&XP_s2P5PSjHR)^8*QBpWUz5HjeNFnB^fl>g($}P~Nnbx_peKDz`kM4L>1)# +0q_0U|lfEW>P5PSjHR)^8*QBpWU(YebCVfr%n)Eg4Ytq-GuSs8%z9xN5`kM4L>1)#0q_0U|KWCsPeNF +nB^fl>g($}P~Nnb<0hI|eA8uB&dYslA-uNhxIXP}3C4fz`KHRNl^*L<(}Uh}=?d(HQn?=|0RzSnrK@m +|kgZXdpP(B46N2kjlSchKHJdk5_uw0F?nL3;=79kO@G-XVL3?A;k&l3bEpl3bE3NtPr_k|oKKWVy(aV +o9;2SW;{$4D^TU9jbSz-l2Mj>K&?gsNSJ^hw2@wcc|WhdI#zqsCS^=fqHj_AxTJ*lB6UlNlKEEq$DXx +x=2cqQj`=WMM+_xKUD8fy+id5)jL%0P`yL-4%ItU?@+x%^$yfKQ13v!1N9EnyE8nJ97&EON0KASk>p5 +nBsr2C7kNtYl;SDHQ;Me) EBBu`16lH65)sNSJ^hw2@wcc|W>dWY&AsCS^=fqDn(9jN#2P`yL-4%I +tU?@+x%^$yiLRPRu|L-h{TJ5cXHy#w_Q)H_h`&QR4;y+id5)jL%0P`yL-4%ItU?@+x%^$yfKQ13v!1N +9EnyE9bvRPRu|L-h{TJ5=vby+id5)jL%0P`v~74%9nP??Al+_3jK+J=Hr@?@+x%^$yiLRPRu|L-h{TJ +5=vLy#w_Q)H_h`K)pLdRZsN})jL%0P`yL-4%ItU?@+x%^$yiLQ13v!1N9EnJM*ti9IAJy-l2Mj>K&?g +sNSJ^hw2@wcc|W>dI#zqsCS^=fqDn(y*ohf0KEhB4$wP5?*P5S@(#;8EbpMagYpi_J1FmM`EIcn9MhjCU +~J!FUJb9g24--l2Gh;vI^2DBhuXXU{;7@eam281G=bgYgc=I~ea^yhHI0#XA)5P`pF&4#hhZ@66vtAB +=Y}-obbW;~k85Fy6s<2jd-zcPQSWc!%O0igzg9p?GKhLF|L^4#qne?_j)x@eam281G=bL-7v9I~4Cwy +hHI0#XA)5#0>Np?_j)x@eam281G=bgYgc=I~4CwyhHI0#XA)5P`pF&PRu}$@eam281G=bgYgc=I~ea^ +yhHI0#XA)5P`pF&4#hhZ@5BuB81G=bgYgc=I~ea^yo2!$#yb@6P`pF&4#hhZ?@+u$@lMP@kMR!1I~ea +^yo2!$#yc4AV7x=|4#hhZ?@+u$@eaj16z}8=^ce48yo2!$#yc4AV7!Cz4#qna?@+u$@eaj16z@>HL-9 +_|K#%bb#yc4AV7!Cz4#qne?_j(`@eaj16z@>HL-7v9I~4Ea4D=Z9V7!Cz4#qne?_j)x@eam26z@>HL- +7v9I~4CwyhHI$&Ondx4#qne?_j)x@eam281G=bL-7v9I~4CwyhHI0#XA)5qu +;|EYn0|XQR000O8^OY7y1+&KF83OtSfk|H3flyiO3O^nl>QmSZmBUfjOPq(hpV&G?=u^ +}?-F8ImlCjhgKJZ63ccJhKq#IJ`hCNkA7cF>IT9DLx*e$%r3jiVX8Dm6irrL2?t1b|bOW#L}Z?ols;^ +`xOkJB`sE*@`@3#W04{vD8HwNnznP-TVo4Tu9^GDwqesEGTc@o4cF*bhgG=^)E!I7=y}d7Lgr$#NX0G ++(CkSvH7>GUk)T!OTl0pDiu{Ss6H4uoqIfgY-wV*MXoaXe*u=ZO&O@qDbHu*)@OFLuK@4uNNh+hTf7a +NgLm#XDcx~n7%jN1e9bGBnkaPp#>Srhq46pP#I&p)HlwD)Jcrmn@_#o&2{gen;y|JL*%` +O2GhI$xkTEnR%uN|QMJyu!aDXlYu3<@{)L}tQY$a}jpqcX8Ts+RdWr1CR$tY>Hl2|#bRm +ZU^kMZzaE{uLpKWB%pXjL86PU!0e;hkT}zA1ep`32s8ecz7G9|#t!(Ia>kwqd_Ic5}#v(1 +8%r}NI$fG0#Hi>1QY-O00;o{l@>=OPoosyKmY(ZhyVaG0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L> +VP|D?FJow7a%5$6FJ*OOba!TQWpOTWd6k`SuO-Ei=HK5>QIfSgC&mVof{r;m5KK%Hz54Yd^{*N +F0&+WhX?oS?mvVH!|6>iNsa +>PbF${p#)0i!Z*<$NcG=pZzl5*|tACfBLuWlNT@l`t;)4?dMze@a^{Y_4dh+Z@+o{>VEzls+TXmczXW +yBct~9)8pgz=JnTaf5?vgYWwl^_uH4xUu{p1U%hx!&F4V8-JZYt>KCt{^7?OIfA!+)A9?HhS6}7h(Cf +F4Pv5?IH-`WG@t?NeKfcMHZvXuF>hUR`=9BNgc=_VXy!iJozI=T3=5c%eX8Vr!-hA`-k@_7S`Rwk<_P +f{FyrcW8?eRr^&b|Nk`1B^<+4_6!-QDgMpKUqUKYjj|{^x9d$Av%3PXD;Q%-MK)cjbHka0veXq+e|>U +fJw7IrjOFY%m}6hcv70i^uKzH;-R`|MFS3kl)?@^`p=K<&S^*e0%@nKX3o~{->Y5|MBO4{#AZAM>;>v +`Ky**eEVIR;8$Bd)zkA=Z-2~=X9Iuu@Y4_eC9in@Hy{1}qtE|L?|=8v=O2Ig*=O7D{`l$k{`SfHpML( +)2Y>qg`=4%~{OQwA{`lF4?`_*>kB{$$n8Exdf#LRUw*ZH^Za +j*In7@_zDSGOp63$z?#KVHIehv0)n9$yyyWi#`m625*W0VtZ=Y>HJiSQUN$dMhvzx8_eSV*%(SP~gv+ +Zd4rRT5y?PX5EXLdQ3C=U=>htd*7qgn4}Z^!nTFix+=AwjW+U{Tr6>U%zxA4D%PYTs_2r9~`NjY7&D*!%{qiS2{P4qjk6(TN-rFC38SNL}<`qxB_$Th&dTiUzfBsL~{@(2 +UZ249{&UbGeD-PZ|T7UP}n)O!O`@G+ZYsBQjea8LPwT>80{YPItKHq-(&eZALr;Pvh>vwJa;-~HB_dk +EO{kp%WQ~ES}n2-FQuX~jjW^aD+(_`-K=lQRn{d#||?MJP!AHPdS`SKs#?)euikAD0&Y>hs>++M%R_5 +0>6tL)qFzx-zVCcT}WCH>H+zy0*#!Fl=1=YRg>qYvKy{a=3j(Py83`q6Lx^!Z1B{P-`QzMucAXE+$f5 +59T+gw3VB{rexEbWlv<_Uv6F@BilaAO7XDkN($(c~Rup-K}%o=db^M)vvdoKBPZw&syyJvv%y~v+VTo +tj*D$rN@qE`RSD}(fQZ;Y>l?(2W#c`_Wo>~Ex(*I_^ijCUv7MwGqYxY7;7AP(HPH0pV?Z@cK*5Y4%?j +1(zr+dtL2qf-mABm&syWt^SGXkIJtE{pN+Zam(Mw>-6I|v-O4ZIw??)x_cQM~^Ts{fe7243)^=R^UUu +$TyH0Mi1^u1*uOpt#e)%AL%45>*nmG>n)qK12k{6A(p0%@a(aHzuJ=<;Bx4dEYcjounjGZsfXXD7>8# +|rueKHtVwR`Ok*$tj~^KtWAv2vv6Vlevkj9ce}=TP-HIz7rOW964~ +ox8&r%u&8K#$u@Q4zoVcZpt2F#6u2m{?SKpLsJ0xVzUM=xN%?#`)1KyWElf8*$X?|gG_jR`=9dp{!(+bd@7f=>E1S%R^y#w;M?P +Oq-@_nBK3~Vg@*#7c^45z^G`fG}nD?<5^GjpP+l-^^A>w?Iw +vkCV=$qt!6Rp|t;YEFM)$kzUb({C$l1!l$}ec!Gq22%wv8MS>?a);4QbtZhiwEl!q8%8IRugSI`e^#U +j4mVJfsZ{h8C|d7fXI|cUD7V#_7jNyXj}r7hshA;)dBq+8OqU{kCrJY8_uA=WRK$_UOQ{Sj?SnZ8?pt +rD5gFco9aNgOLkNo61KDe9MdzKaw+@y{>kT{UINmc004%b9~cC^1)d+__$nx_!w8zKKQiJK^#(kxsN0 +7HF(U$nD<_GcAe)#K1;eXJY0UC)xeTyhaQMQj=_xQ?QjT1U93|V0{?Hk>Y?t +X|+o`jm&3X^vCC{I??tz;LOf;y4E +)H&Jmh=%<&N10lc%RRnDe0B{OWuddZ+F>%FA=Y8<#Jx%sb@dV6p%gV(%brAF^ATE(?JrH1qj#Vgq|Pc@U;d-x(|zy!p;BZu-gXVB}aF8G`Z +-XSKT``#XFahcIvhIXx3wP3JS|zRyQPX@Gfa{P!3?fV#&tB_zq$6c~o$-b1%Q-r@F}@&8+7N +rtb5}I$E&Dc%E7xw&TKuU|T-?hz#A?X6iBHmZU=IyPvoYM+4_8z^sgtspvK8D5@0g~{h#1Bv?kYRBqU +<4^Mf!FAXheybD=J4MzkjAvOaJFr36x9}kCdaW`QsSz=7-BPm+&BD<|OUaF1Y0EjyR38TnQC9PZ-;9q +Vj_aBMy8K$?EgyJjj-}{lHe=I$G*+WZQlC~Utf6zDvgHJqhOieH +&LMiLQuY;6`Tmy&OoBoVd({l*&UuD1fln-f~t_Gr2Fuv1eg^R*%0T#E*sSRC2P9Es3odn8B+}^_`{h( +F5iA$KhG#&g2vz0@ZkH)gxSb9 +v&~5@KLZ47|Y}<5|OXaRCDz2N(SXk{Q)*;*$K9GXpqDCy@&w2Llv2#n3A!Dlccsh@~s=8I53+jwXQ{w +nV4TCG4p6mTM^2v8y3*-!!IAf)~Di(EUNU>EPc13~a*7E3IYF)e$*B)7az_j=YwRs!Wrg +#x`YQ`Nn5OT6PI)s^+i7hi<#A)u3^W$9NYm+%4{*n=_@Z_HsLOZn*@cNCwNc5RP#2#CH(~I1id_P2zY +p2TGt6T6B?FDI?H@;jJ-Q@`jHc_07&cF&E0O|lF5q7iP9lp8A1m`0H9+|@dl_YjVL<^Fy1w`i(8YP9Y +g{Q`<(YUBrZvi!E^#0*3`MCfv@R2=j4f$GDXYQuzVa+XAR6Djyv#5hgWEOce_CzaM(+{6CfY7m(~U7p +@YZ72_G&}JS+pxFgAS500bw3+QGy`q)~o-T+G|WvPu`3^QQM_7y;u~-Y};J8zEO@HRSR;c%;SCV9A&` +fIt5vD6eWar#Srs2yB7$7Y-MkI>8&HqabGiFCGgwFed{~hS)$^m}h><_qcVhJT~1b@eSl5q&+49P+W3 +~!%YOW7Mv^N8^kx@UBm0OvZJ$3ocoeqHFo!sKNzAu$o5P=EX#TJI@XvJBdiAaZ}57KWXdBX~@_tDI!PkI@qwM;RC0sd@aVp5hq%DS9T%#M-n`ue@bA+7Ntn +_w20ve`5&7v#d?T!YNaGA}f~Vt}UHX+eXPl%L{q4!?J|3obc$3_|e~hRw@0fO~1W5)(_V)XbnGkm7U{;rVfb-y>Z`hFmL$Z<6w$ +K9s-2F{l(nz`25Mc1x!lq91y`={T>~b&|8S{1~ityOU5GN +^NKBiEB1oyhzOYHC9f}KkoVY`nh+G5Nb5=+?A +MjydP*HZ48PY?pR2)Bm2)vVh!5!jboZY2i!RjtOn!1Yma=!7rnOi%05B4n9Uz(5GX +Ob-TGD6pH~EXRS=W;yTc&@-@ +aB%){Ka$Tkw1oFF1o +AQL2N?l2l9{z(%={E`Lv%budp;bQoZmCkfblw`#y6woL-)orM=M_%FLoae1Jtl>elQp+rp%-W#+C>QB +Y;1(UC{iyaY$UU3_JmGB@eVi|- +?_$}K_Oqlo=2Lk$TkTF}6#vyo;Oip=ErhPljANfjjZ|!BKbHoctlcVM>5|?z?*=_(1vE#tNK^}noZC1 +$aEFEZOL4i?t7nPBa=Vb#F-J}g@H*rZbW50@#CPM^eu-fzKaZxPNBbRH37+!#$2FIC$nomeX?0}8@6T +0b+^8qf|$c2~D^{^fwIVX3^%Z@L~g*#z=H@x{qh;N{`%r|)v*AHUCjVCjs%Q#=?8+1AZ!6p>=bu5`d& +Zhxo(Igb@kUJ%fnPl<#TxJ9pe!A=-5|>Pq^~)t;h=mSbPr42=Q08F=Thsy(KSU+P1_r|WAeA+ +f75mC4>ZmfFiFN9(qcjfWPh=d-2r0F5;VZynUG+1VcaIF?ed7AmK#4@;u6e+z&fD=5-a$mw2NQI9cGF +}^4l>i)`}~H(nUM%xzr?a2r9vL!6i-J$an||OM2bu+h$$j3>P>vk~NK}dO&)z`Opb=c{>?i%?UHL2EsgF%hf-(>0p5kz6zL +X2H>Vk*R!zHf)VL(|G*z|+ht^?deqyyaahb-uC3`5<32mlb<}9VrFR@N{7$o4&|KS~|5=4DQsYDHp+V +jK4dUDMo?sz)vG7lZ+lM@id8P%pfx{&st3xKqx~#dhfYmZt;l^F@g@-w1jc-Ej^pgj}C{u|0h +RtXUa`waTgF%SLBw%w?*j<2jyW_1{d1)y5{CB(5ak`}}@Z6-f(RLvh>l5TY1yd~b3@-fHu`_)POg{}3 +l*MOUx1BX{3E`i@)P@bh)zLVt&Y`V3zIX~MA1wM&OBhm&2;PAyi)qZ4S{IEv4p6S&3_8xz{NL(AcR=l +yE(dOL_()LTq-TYR0g04<$TO>5amgt^X;JCqg|#JIgQ;ZPGAIHxSt|iI4N{w(^d1<6PJw3x|$#q0_dR0!xc?NOD_j?i9ycV<< +}1wH-YJDx=2_L_^7!?wM!jmTID!>n*hP8EP|v-IO87zDNqSu-Thz(Wi +c@98@7Bm5>QmBBptl%)Nk?P*^n5cRpB3NI+cR%G-(@WZRF7DolX7>87@Hmw=470eP(a{zlDKZ!nRzp} +ZRU?PfYp9FTiPn_xQSH&*O +rd2P#u9E!RrF#2jziw-TrKVONiguK~)EYF(BVkKXZwpot}#}^yd05+Aw&YvV24ia&|N%wo4snmHlGxq +$d?!O**H=J(5%lQkKoE8xVrJss|?Y)DvI8;oF~O`t`6;*%?qUU1px_d}D=dmqQEtvRmh6QfQ-F>NzE$ +!LCq7-K2NF|zNMK31CU#FY*I1v$9PU}!gS$ +--k~r!me`V>62;qnxCxJP44eVS5vXVJIzuqgsb$=dK71Ph9+2VkFm_N*cIyX92H^l`oY?pvas>2m~1e +vS-t-3+@RrK7khvu>9m8X_q>Vm8ipdGq<}gnLnski@2^M%yd~rtHL9+cz$JBCLwq?3gOd=1MOPJaUHX +ScERl>CMCpoml}myDvd*qia}edxQ0>@vJY6h?r`^e9H`@1yfj{rnGDjzC3eJ!7QTL($sMY#6yp((0qy +x^orEUN;<)a1(U(LwjbJr&o7CRvIUc@u$Nb;}*h>xDKmr=Fgai+?s^U;}|HO2OCk-eP^;dH~uuJl32D +!`F;?IU0;34+}fW_j6f;R&CY&CLazbADZ?Y&jmKI1VnxLD{*Fb=T5pE80LOh`@(J;56l<3&`xyrR}|T +IfUXrCws5wHm9tbdVBnTUIr}N0=$h7%x1bk%RSv&S&Y1&U<`M_!3rS-WXY2SF~mac{Cp! +Dwv5qOfv__jfDdrSLp^5Nv5CNqhK&`-c;K3HWF +`tFVg`9L7z0S!F@%Syplhk2p}BJFd4Q2dD+pJ6p5j4I+zfF=pWhR|RPpWZ +T`r6F~sLz4e)H*v`TS#{iD>tb$Tg36ThvTumiPVWGSnAZ9b35b}Ru_?G0POWqxQ{C&;ur8u7Yo_6bGW +Pl>P6C#X3jE^ohV6}3kxtPDF2@=sP;wQ2HcR)~RmVbZOjneByI4o~9Y&Sf!$3PQC@18oGL6DyPR&!`KmaC?scJD%Zs3PtlCO@QE5Enk|+QZ +LA%M01wRW56r0mAJ2%vqa^>zJFP&F*kOUUIkT@0`j3Fh5y;*wT +^2lY_^Ju}rq?qIm?oow}!E-(fIsRm@lXyqqK&-ik?^G$TG9d+11EH-%Xg=gt_|Lg*(rfz_ByyWV3jK^ +rQT-!jR-Ao5@=ACDudu6^EcG0~KShE3&>vG;liC4TFpJ*sn)5uDtlF^hf?ScYq9~ZI?MHn}JK=<0=cP2%Q#qg{{SB8TQ +(Erqu$w85$4UDpp$#ueFe&E^$*PHYncf0THHN;D4Z&?rOYGh--ZJaEVzN^q1=92Q~dJ5RI +yvNLqAlVVDv2-m=U1MO^=j9#TL5hub&AxCJ&UXtlbfVzJYJ^=DSS=&YTiUyL5fNz29;D6yu8i-~birc +s=!qM4;k}!|A@B*4#h68_2Amjrg+lO^;R^KKWu1ow@yi$DcmatI~82xsM<2z3hB-Vj@tFI +0QA?ymrkJz9(q9D3>NsL_|?Fj3nkowI$MWO9opjPce|(SO;?65Q2B#{Ryo0LiX~IX+8z+NgZf*OVpHT +NuBSNOfLh}!{rZ9KwV^;7m)L?z(Irl0K>|O90(+LY8yMBD2dtK@^hJF>1ofS +4DnNwU6#f`vZ?aCyzTFZQmaNXH^bNnqrV+^PK~ +A}-kl1b~zFoRQ76;!_$Jxm!W$zS`%Ox2C0X=;gs_-%WQjO1QbbzWZa-e%{h+|qe*zzxoGjSAhh^cPRI +UD3S- +b(6SV4ng)qRf(9C!QfteWgTKRcf=r0a;P>t!B^I}=Z*b16a#Vbn643t6)j7wTnRsESrF2=%l$*Q46Lh +(dM{8*S2bVy$phUh)hCdvI{*xxkUaQn3L9g%2MQ|TP~tnXm( +oC1KTv|RX@c5SjQ~ag+gha64}J#5RMnFKG3~(^T^fo04`>FL;>KG42LRVUr?j*Z7HgCy}>9dkc-lD$& +Z#jsCzZ+!U-(ddbUV3*qX)?p2X+{JBwP43I+LjvklF|vEj>8O;P!s(!G)zOGRB(YKF`sBVbrIs)R%C0 +P1<1Qj^vTmk!CNVG+42?6}7_amiE-M7gFBXBVoD1^>Dfv|J)Uctlv5h94P}1t(jga&5AhJ1z%q@hE=s +K=;~Dx0|TV0I4-Yyo`ZQ+9l_Reo~VJ%1gpdCKwZ|^6*sOQtKGqYhH6={?KHnc@B_d2@!dZwPM_~jH(j +hlG!CPQ@$j=)f@V=GyQ3GHlf8f;1G(|Q0)2;oV_THyX^LZLaGG${!JdQ)aRbrQAS(7kpN$7Y +z`WwPktCHhBe;kF;kvu2*a@?IPq5QDuYO#)0|@F@M{f$nvXE3LD{z2apouE|_LnTtzc{Dt1lvcoVl!W +~<7b^#a@?sb9gwZUoSq!1M0<4a8jGgUiB6ew4wL6kBTV;wII0E;6cEj6|`Z-1bBU8hX`w9}Xv-jPy3K +8R!P?g3XG$Op!B!;iQNhumvpN6G{Nj&|Dvy4Mzxuv#PDv6)`G3#N_MjQy}zr*S`0`;I8GM1fyFoUQcNW0no$TT8qxa}9+Ya8 +yIURWj^GIL**%%(Ng{FCX8|0!yzsK%-r+g1`*Y71bd1NC~+G)t=>&sL4_0>#^tUS +l0$cmO1JOD(;nzvCwo4Y+f^+*9%|L62@q>Gv^bV9@lBzO5flLoOfN}>JN(p^-s8Z2oU@#(fd}6;+{Iw +`aU6gd@{z`lpFxlt7lk=fb5i~#uf1?@SM94i(7i52{g?Bm;=9{@+XZw?=_$q>KEV>?>FzjS$E8%dOE? +o`EAKwgy>@E+qZ^OGbEL}?c(;ltt<8&|J@uY?b7Y#Q3S1W_E{FQXwyK_WpnDzWxVv7=5;~-&Nz_zBtl +ph|ObfO6f3*&vq0SoI+;SWKtN616-Rl$IACOctRkQ3X;o&SdAdSU%Ug)Mfdm<3|9LK4|K2VwC=>DSPr`d9r{`_BjN=L-=Wk=X|-g< +VL&@vCKxt2W7a93b$B6zYX>O!UiRG+3(OLvUJ#b7P3?fPkf{2k}fy*7|@C&3#gq^!5 +)-oT~bQRQzj$BKg#(DDP4S-0k5zqKi{>Np3w*Eucx8AeW3CCs=rE^<~=9NjFb`PPfqAg5Cpb}2DOx^p +;QwJy}X0;CuH7)znvWoLK~s!vkBqUtgtFqcL5K$=jryo`QshN*q-hq_nw_LLt+Z4Lsazz;UdOI?P}z5 +2D@h-wh}Ds!T|qq!G=yLit7-Roc%?>dFg?!IQWFtKeb?KgCf66{IF#b8kE=)#|!l+;b9T?D%B@kRGaO +`(Ubm$(TwUg-7))v-m=U-RMBEV+e%UlGF)R>((nD%l$a)32Ul4s5f_q*6mLUy6aD#f!MH{ +G94<;si%Qj(0Gj@3wN(Kb+7IpI`uoDR1UpS$WNkmv#@}}wV-(ly}@G5JWHO-{iD+cYQ3R*oss~{(m4E +%`;Q5>jcxsd%w#%cDy2vcJHm*rrZJqBuw#Cu>;c^?B6jEibxgVvfD<-lS)0w{bLv20F5HjK2Ht+UelA +x&b;#Y_u(giSy$%XDov7U@rnH*uoyc)`5%vJfNbzUZT;d}6v(^3&DNhrGb+^07-%c!Fpar$Q3p%ttQz +4N1Y1-aY2Xj}+Ha@&&H7?!esFvK9!*PO$%307>H7T>h ++g_gaG#*Sh^Wy4MZ|*LJB2nLkM^cmj4QFLre=_b?-nTg&CA#E~0PBk0q;wN7L4>nFO`!JrI+!2&rq3v +N}5!ca)SHb}H-<{3gb5FHY{#&B*sDANB2T%jKpzK|7!5&y>dmh3#^OffiN`~jHO$4=T)_!E%z|N9 +q|n2yuJRf~It?GEtQ3*d&d9Hs(H_`hfC&bOl3)*_C+9dr^P|zZhzS +5Qrl)N*s>>rVVTYhNfF9r^euR2qN@7XCY!0S!U-EBUafpdonJ0#CxB_iSD(LZ4YWkIXy%xl2pi$si0b!BsJPmf_a%VPHfQOp6>7i#M~P=Y8=qLj; +^+ybpiVCC1eYynBjI`@pR9so0IGypb~zPb7$5v8+A|7ez!{<#{|B%o3N}<(kxCR=^QE1hWqN6Y@{ulw +RrcCK$T1dlkN}OhINssc29J8p3&j@1RF=8bQZ1^R~)lvnk;p!E-OgVS?-wm9WG%2ckK&3(Y+4JjT?@s +d5VncHLHn2W(4{j(94pMaYfn_u4IEny6sqBNR3g?k+bydEAAP?WQ?7KsL^lP5Na1rn@R0@$BLfu$VimlsO!g5hyES385 +A|>%bjyq*Iv#j+sGLSi`F6OOH}|#1q|XFAOU%6dP*~=4GynsoTO0ussLc+b-dnX^D~w_rRL;mOk}F_c +}ZZ_DcGvUe5a1Xkl +su0FEy-m$n-atDq>nmh+czUC8pX&fqN7_@a9q*5;;B +5GxQJ!iaRJsBX!}J?#=^9!`ai=~0oxVjWa9=TAiO1n2Pl5>Z)!MHd2q7gW?0(fA;WZH%~ZhVXZ7xf%% +GySbE|E?Na7YQOySo1c-CD@PjEd|ZBgbr3v$pN*Nih0=TsdbZRmwc`c7m~F0gS +*{}^`@7Wd}IQy+NVGfu2O%e%!hW$oQ@A%?RMyS0Z#FG%OCHycz2|3MMmgx@peAP|QS-6DZQ9bXmR`QmI@Polwec#xvS8DK`%CL_XIF|X--A8izlo-yKd@zH@==RH +yM6@?wxTqztI?*K+PD8bUsfVi_+-i4vW}u%kp#4c4yh#nYbXUbmwT0>rvpAv*VZ217iQr;2m8aU0z&m +U;9U0c~2kR_auGxf9*%Mtp0Y`6k;~$Ddr@L4=@jVh@+nRG*ooOp0Q;iHVFv*T3%Z^;|XVS1$&RnO!J% +2_o2#b?GGhfLz!ThcZn!z9_GCn{(HKDjuVI&ZbhVHegVUUWqm@K9v%SVQE>(r7Dv>1Oeeb671C;_l2cNLBHK4Zp%r0R({OQwpS=kx7*Hx1;JqJTQf!>roUZgmZ +UCRRz4y8lbbhry0d`5)v90TTN#U1C-y-qA?_BzDL6B7umpr^~CGlT5j-OCER`U`nXXgApxZG`GokK$o +YbgzxPr6CULhr4jV1^dq9Am1G-x21SAB3`UIZM#4Lb{`)5-7fkP3# +$~p8v(7k%O4=!VcI)n*HpIP*$s!r9v0o%szQ2X90VfwdE;MnubYBJZ_hJgVn7B +*j-%Xac2oWmODXohNppd)-)?3yOciJ}=LX0X1~<-rAWXI(4&zNY8CGILW?mQOV>tJS@OCH{_?QT@@M9xcRNt1d)iiXN=%0|j7>8>a +vxUsX&c{67IZFAJZTxg!rXL}IZe(q>U_Bq-RpK4Y<<$= +`7M_1w8mJP`=AYRpRjvN-HL-=dUT69?gNMVIF7qr_TyN(-8JyqpK5W~h|e>eeqckGg6C1g^pm434|(> +q(C{3u(q*3LUZ+d#a3irt^;o(@4O_zbs2*X^4qG9IsLBdafEFvozY&r7MgHNorJ0!#yC5;Aufq9ucq{B +7CRT6>_#}_v9Qy&q;9iHBiG-u{=OwXk7+z_ec)=YXF8KfKBnt4@ckX%I$X+y4Q|9G)hU$nu6zMa6VUu +h?~2TOvcv@OP-qt_q04@PB}fy*x0SS7r(yHz4p`NWz4QnzI&XAgs-PbUM}I`u`28oAYO6E$EY)+6=S2 +L+SOJSu3qR~m$h2AJBP7>Z$YEaI#8p|2SCVHNBl8p1uGWml}A<_IKz0k+g3OewZCPddtGkkw+P2Bu7*8KPvY$Y&0UZrIFXUTk}0yH#vE#TE*%{Pc< +pz);1b0-aI!` +4penH4pDEx5+cG`Rms2EOf68q2BCuoL=KI_#NB87kLso66gV&z2F-+N*5haId*r#u>-+F5^f#HLiaj7 +!?#4sQ*95kb$R?YVa)S|mbZcOr0CvEln}+RyK;G`+tAm0@d(T04UFOxr2o*HY7Wfn)$k +%`{ut`R$LKvPM=-^Pn4d3}2;VTIgPZD=#*pW(fvq9@QNX%B=Nh8y>^Yc8b)Whg`=1Lh@h{It7@FHvKj*{E|@uC#&yVRM#-mq63TIybxtH)jbh +exj?R`6`h`hYYM`$bB-LHsmA@dW0#T4gmXe)(>feZp5=&SVd7%w!|XrDn7)Pej(l+#0qdNl7S%v!%Cj +tBUKV)*HIlDQo88)atalX<7*Kit{P^9NVhy+baz)m+3&E9qwLW0rpRtcMViOxlcG=0b=W=LKq3RI;_ +)EMBQ+0?snXa{vuD}Y+R{QlhNh$LHH +@qn^uevm?o#Fx;5*T}|0H(m7Vm4*YVPyckb9rceyW0hqH2DY0``zPkPTd>%Ub$X!3Al8nPW96ahXc<% +oHi+(@I0uyUCu8d>1v3a*CkGcia-3BfI7j5uhE#OJC8?snlz;CB{P@#e`OFopd +x3QOP;^9;6Xo}sgvXJsSFA4_Lx_+s)#)ulPeA>$@{;N409fjMfY6zr068aH2|a~W>)fFYa4Z7tbDJL| +yK-Nvh3bgvy0*=wMdvw+KS`AIPPJ13x)!@Ub?U);23SyUM=g?P_!yGmEVChPPM?!)%SEvOtSmtxo3L{ +hOlV##gi9x~@C#U6fuq`9Fu@9eH$6iC;te_(5D`UlUl5EHuOg#^sFf^`#77@6)-{2U83{gnfwrL3KTS +dXt5rPpBFVaEA75r`$M_{oztJ)uty?$pkRLv>yp<&35&_@2W;7}w3$ekXRAJ&fI-C&6vG1M8B_^{_~P +rGw(IiY;T#;XZ7Zt0%g+o5O{LDz@$I9tU);dzQshQDq!%HlCfB{6ce{y8f) +sYBeIZeqZb-Gte3;|A8L*D29_ifW&k2-&K=;~B&OCC!Q-ZoG!2DL!dBLimEn=KXj +c`)LQb;tAIipJP>GI)fy`g*U?h&+B3n5!9BI?nF7d?2vHHXLs6Kz# +EItf@#9eqCAyE>!(I)KYi~6rOnY;^nBqW`8{+gHSO%4${VlFO2zVKFw`B&Qx**zcZaEVYUZ>dz#RlZ= +!ph>dZY>#S$wlQ1=J{H%Onx&4a=7gc5uwg}K<>u_o20lX9cv?I+Q_4o^3|ToQrRNDYRjLs_t{^e2MMc +csdmX*`NrA(I@5>8cM=Z(tmldoy;Aszhm5OrehPJ#+2g3R4X +5zMJ`i$@$_1)i{o&ReQ^`#-7e>YHXowXL`50Cg`I^`eGz0R%@K+ +t}C_gs0!SMU58y4NO$QRnPC7$yq!yCt?u+=2$(9a?$fdInM;7^RHN?`{fCTxSE0q0;ZN$}!$u17XbA9bEv+Dc?&)|CZ+;I;r>i&kEAKc^1K4Ea +zgt?eyp@2H;EpWHt>EWK8zVzmrbMOovSknA5KEwD{c?+R9{n=t@fe8fmc}PbPFVrpo!RPLw9E}Gz`q+ +kgaLR|5)2LzBdLx45I)*re+Y3}aL1}&hRvVllN32o>U>q(pBcBULQw?R46jV7|gnzYam*2-B+vWskR2 +}dNZXC_<7?uZQu3-_vGc-NX#beXavW!{hgPWHwzH;}MeZpt?81lWt!(=_E6S#yMB99CYt?YHBFE-A!g +g?kLc@Ml(`~w#Hu!Z^=gFWG<)!7vOq?ApN|@0bGJ?YwLwK>@@JFd5k^& +?DB>bCsd+&^0xSe8R1O7s6hk2wBo`2WzL^`__xQWAK!lS;?-ZbFCJgM{(&Fsea)}SZZBTFeSCU+^VXl +a{p#`UI*2Z~u1&n`yS% +L~?u-77x>j!G$fTxI7J5>Y4EHC*EZmT(o2Umh*NYTaXkZAyJ;;|`3MxVyzmZJY +LYlXeKW2v@DD*y4v5i!ybpB$fp{;Fy#!!9sGvrx6ZZqfEHAvnmBE!RIeZ7j_dr7&h=7AUGANNn4LmEA +5F1UKVwJbrAs;AadEuSB5+zo^tp%E)KwT5iH~~rz#313a!kmK$8ic~2S{szDqF1B|6tleW4p(AR$N_? +ieNb`_%HVCtQFMxdDGg?G3TTY>)!n9YF247kgHZ4B7MfbR?Fw17zqc(H(#3MixKRRIbVv%K&QS7IyV|3 +R`IWa2?49;DYn+8iW1L9!KOFhSlBqyPaTk6xKnpqS-_ceoN;5srdH12`BU!4NKicLMYhpqBtx1ehW~4 +FLd%e%lz4{s#qLpsx!gQh`b%C@Tjg%K#t;ST_Kx0l5%R3PD;Mq*yU3LkkqMVXB2!54=rq0$1?6 +H^IrsL8&>|bQ*>mgaJWOAQ0vT(!M~G5XceY-U%EiW_jTquEbW@hZi{4fQ$$Vu)%R_!N#6IWF4G56%cR|VwM-);Yw@;kwsA54eGK%!8oWT2IPIf=7yOOu_0h&f(;j8c6I+kR-l;Wg?G3TTcH +jY)Tsg$Z6J9K08XF+4Ag7^ITz@d0=ZJaQU@in7^R2{6tleW4p(9;RF;COMZnAlWN^Us1|(s??FFP;z_ +JB|QozFm>`RQe=j~$Nuod$9Fi$5t4^v*U(jaRKQzsIeAR`D-5kWkRn*_>0h#9k#Yk^{x7v5RC1TS2Pj +gSon>f>PhL_p66XUqi0zyu1N;5?8(FBcql5wjFffnt^y-r-7Y#e@RkXppuC;)0+!9aIg1a$Hc+2>@Zh +p#&*buq`|8ljZ}(EHAvnmDmcqeuMqD!T#G|A8WATEl|k?J2ZnmhrzDGKuZ$Ti~`j~sFkE$m=;p9puii +bhXR#NP|pc!XaRv4WM}~u6!JT87-0rXJPuUHfxIcnOY5}jH4qy}Fm!lZ;Krzb;?{FoyLPa|$ItNwbfM^VgtwD`6sD}mx!k`2g6#N3RK +Pa=sapMvcv%K&QS7IwL{sCDTu;l@n7jR_(5f)@z0q_q<;DG21xX6HpjN`^7C}w%dcd!)*qX0gKTn=na +z^VkSO2BXgY(~HsgcJc;e2}pR*>fB>E-!DNEm~pFHADd8<(J%<%M^+5?hfPgw_jo9tC>OpfnzwauOU^66}!-G^>F)GsxJ3^e +^sTObZmVyyQFB3I&5e!yDAZg35D1Py|3aP?H5Ri=h4%@Q6X`AMAGuWc_j8xCF&4FTBH**b1eYV9#Gru +@4gvPF)DjQwVk_1&1F5l8S%~5B3@dJ7wd%aS4i9UU-Kqu@!_2fi@zj0SEP@pvDuVZb5PuBvCpd=lXF@qXcz}5#8ULX+*O180XT!LbjmwX3XK|2u01_GuzARK}kbWp7f3Y9^9F{s=HmAj +C+fL{-&^;kD9K{3k@6aWAK2mtey7Dp|jI8+$}004{z001-q003}la4%nWWo~3|axZdaadl;LbaO9oV +Pk7yXJvCQV`yP=WMynD45=Il9V#?x+JeyBgVA5CdIN(R$(K>hJ7`Jdj%ZMWLA+%e6p+)6DJB_?N +*j!N@GDkUOgx0E3kwN9xcExknM9Y3)$6hznh5)y=2C5~Ea +{rS(33Ybul>&GMn9}ka$|+9gG+^FCT9x&3}Uxbn>}ShljU5xBRq`oBy|4XSk#v$mqi^yd!0j0VC~tK? +&RV9bVXx!U`qF_*+R{Hzfm$n@mOZ89g}cWg_zsDI5iAJ(uN2P4d4&%-V#fkhr6HHIz;G0)H~hQAa==E +>IfhBqnlMIyaMT(6uMzgm7!A?Jb00slhg;?9n8lI5TW!Lb3_}az2jo9xh4BJPjIqvd0uKO8NmgEXb#Y(X*2H9~=q<^DwDDbfwi +45W`Fqu0puBXri?Pq5F8$X-lF;83dXS=gC<{Ojl`*zUedBycoy4fU`Oxd#T=zcS^oUj|B5yr3nBM*68 +fmv$g*7Eb)2P;Y@iaFt_wo+s}srgiv98S`3GC7`{N&s^n +yfD>G!C;jvAMSoRh_R4rhh=o8=Un+)b~>40U#V6rQ^L7p>`1S3nKiZrmIWrGp!Hf}=d9Nq$Es-J;kjH +G{hof#4qwr_Y{X9J>jmANU%9?2eWmyZtpED98=XH8EOw(u@GNZ0e%&;3twqUy3bgF^R?|D&aJ_tZ*ZK +)iO9KQH000080P~d=M>&o34eLSx0IQ4u05bpp0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXk +l_>WppoRVlp!^GG=mRaV~Iqm7QIW9mkQT@6WF&Kv=*A+Hz%PL{`-pvw$Sa9%5ukpkxfZHwHzvtj17mO +_Q>r`Slymlhk^F@c_HJpvXSw)X9(dc;k&Xvp@LYAOE*~{ORwXeZGD6?2}JF|LW82 +KG?qg?tc5?>ESOAZ(h9KK6!j~zdgL&{_yyp53gUpsDFR|{f}=RUcPwu__V!z{c!*0-S)EH^Wp91k3M_ +z@a~~L`P=)y-oJkQ;r?lR{C0cy51v`?|NQ>l+m|nXxc|Q%`|$YYZT<7xXZiUOfH8s(t%(f4{wb{ +Px}7YGA+FetP_Id->wc_H_U1;q7{SEyTO+#hX{ZetfFWfB*RE;oG11(T{Il)pQv3yZfi_-~POYzyJJ? ++h_N0Yoy!n@88@%)oi}}@tfBVFYCjfJ-obs^Y(sw@pk)xpS}I=?<@5?2J+SWfo#8ftjD{$zuE2|>UF; +RulG-H>nB_Pu>JgP@1Jj@9GKl-tFI>ef=+A{PFAUqtE}e{o6;+pMUiE*MIs=y|-4nUakFGPkQ+NhcdxeTg +~d}#hZ6O)xhfkfB5wIC;w8P_~_$jpFR8fPmKO|&%XZr)33hTe)q-m?W66>kDh=1?2|u!_R;h0%RfH<@ +{6xN{czj9y1)NJ!z-FnL3_xG-h{^f^vTef=Bi#PxNy0+k}`uOi +2zO6_9?)Bs2)7|#*s($j{{kMJk`EUOpgUScDdhqW*?xXcuwzu!_i~s +nsLdWZ$*!Nf4%kN%1y?BW&y?gP^>-*(_^)n_|llzY^o?iX@+ICl;e*Av>?my=-2M^AA>h`N&{m*Ux@V +NM!f2kMR-sAlXSAYLP8}&lpxK5=zW@9}cR0^p-4i-~wq`u#IZM3#vtQRn{`wc~S +MUG&%lhe9gLq!fUBmsaAAD2qVd%f!eld>B3MlojU;4O~$MU70eyEW655M)rH#kDi|AAGlu|2*iPks9i +fBOE%m)~vQRa`TMl%qZW?ep7h?ZBVE{?nJwKKbagKmYdGS6@GW_VFLTe)h%Ze}4W^{m(DI{{F^~KK|^ +}KY#V?e|^eyj=BH*3S0B_yL9k>YrohpY5(4d;KhCy=7kY&us +pYWur&G8?AoU`<{2VdO|(0*Asf?dAG$;k3Q<%+f^SPZT9+E?02!x{jOd0k$%ltf5dS&^4#nB{Ozizj5 +B&Yu(thfJLh#5y@s@12k$w~yPVz6)i+%^Yy9<1Q6_@h)L8RkaOZi~YS?%E>@}0vue;mUgE#WZQLnV~s +7dYhrR_L^kJQZ0Htx0>&Rwhb@T?l^UQcaV`~93HJDn%F>7Y6W_F%6+kVa(X4Vt3#??o!`8eBN +j~Oj$Ehf)zXV#F8`rMZOMS^(f#W6owcy_IhKY+s=3!=X02=O(Ov^iHod;{R+G(oV?8 +xG286{#y@@d-yFBkAc>ZY2yOydmy=|-Y8uizjPQPk!gT*~Gn;Q1${1Nrx#`o1|YKeQR<-;b*1_Fzz(d +=h^UF@|MM{Qp13{Nc!N#Oiz{FczHN7l5EXSxPv@*Og(-pvgu+p^&&CP4Ih +FOo<23uX>rao66X$LE?*92<6YkD2~t*^R^+DJB-eXC_C6X<+)ut?=rwf30J$zwF#dUV@sXM!Qs_Dl?~ +zL{<9?;W$=+%&w7VY4)~O7+?LrZVi>l-dP$Z`9W})@xoY#(@Xmt+SS8T=lmxds)M%7s{h*5+}=W)$)~ +X*4MR;Q?z7u5`WmsfVSxfG06%EHHL%5J}>^Mf8) +24O*zUs$|5l(JiW7nd#|D6tQ7%j1$G>tpOx8QtGI0CzxtN5oUq|x0}rV2Pofkr?0gQNWT{%Ray#FCoc +Mfwd(@)UrkwS18394XU8n`xMr}aUWAAdu#96*UaHzOhEpVCMv++zB*UepD8R9kz@8C|fF{V&zV}s +Rp-g#K@hcnq?DhFYhd0!Y6Aq6;rS_0_=uGUii#j)>giZgV%=O^amrXKLW2#OluHK+u_dFG7Ljz!-{-9 +f$SvOu);kJU(r}ycJ!*rmxY%HkJFf6e_Ul>We&`d0psb7NMA9GC!B6d#gCnB)R!y24K{$O3@oi4SRRH +$FwvtHvJA$@G-71%b$CC|KQM$NeKf-?w<9BjU%y0+!2p0Cmd{JJ#Y~7%WMn|7k*fja4t(2|l}L7`|#Mt}YR&Y28W8`-6q0;W^$<`0}C7#Cr+0yw$*a=q$}&a4x$NrIInl9*3~BXeA3*iFy_jHwYO=&O-xE88^oyL +N#mFeJ9HCQ9nS7`JW5^@J?s*G2%Z&{Rf5kSdeAl{K0T43Z=VJa`a2C);zKqBeGcNfE`%^G;%ZeG@xh{ +z1qgu91vymHG?` +FnP5kxtoLAA-FQ_~xlF$`kVXtErxV&@UPg%KmI3?9k!2hBWXHN$m8k>Z4*>#u7No{c +2o*))veypm!#F5`S`b+3J!Oa1DM?^U;&dktt?j`bcf3giFl(1L9@xziQ#1^u2-meXJ-TqA7W~%uv+_Q +6f11)jFIG*Abz)x?1PBCV4b0{+K^TxQUt)I+i>KntoeR?>!vn&UBOMraZSXlTXHvP5{t}xV7LSaTB$dg$LAvJe-C}4r+EASi7FM*~*nq3TSLHtvc{6UPY@ +YT$9)SE<+296n)eiwxazD5C4PFVjmsOS~Kj2$~X4j=8;H3}b=op9f&0y-br4x#RjIRi&mI>AbJYjjq) +5&`uSCc!YbDVVGg21u@=MhC}GpB)5n61|wK{t9NygT}gwObkO*tsN6dcV0BX`jh%D)&g`_@sN +spkh#VRdr4t}{hpYXU<21a@ikC-2QZhJLtU^c*iKcS9pm7E)Rx;taG15XWf#;%R9CPAHBl^?5PguLfk +Tb;=~R%7gqnPDX9sJFjZLYw8OG6JDGNgDIPV7R02fy_#He__IP$=VPu@HZB0B-^vID%*)Z` +<>gBA#1-YmZL7UJsuow!@azFC&WPh@|kkoL77xGgB;sg1{ZaN{|1|@vWhtg>WtxW21+%d53lkhbg*_f +0-vTm$E**!x7EXC;t!$S~!v_2Ac=VMJ=)IgmFG3>zgDm_wm15)5)DiU|$8yIdFA|rwv}BK1a=d34$nr!}1(BCkqx#ba89edILkiUPITTqQ{nk61!7@ZLskTsM{&Pb94)9m|gw$ +5)hokL%s>x12jM6yD34-mkHKQD1zPZ1nbiQQ_Us0=zv%zNd=sB13y=IKZ!dsS7vDQ0KtK0bzKqayMf= +@V$VdwP^R!)1uiU8`R7Uo;1N&`WJEbW-rqzHau8FTZ>3I|gs(}pQchL1D4r@q0J5~cz=gnz{0&9A%G( +3pMy9Mm-WWUNtl?YB<_=tnP$g+hc)X4XFE#bq36KIKa+|S9ULNT_(5#rGZ= +fu-er?fm^cBw5?9LE>m4#*tU3Nk%&7rdDAqJp5!xmBc|G6KnkGQV#Dyv(5H+Ce?Xi}>lARzfX`1nC4h +zlj;2isD&lA}QL^8ignE$tj|)GN#IWwQ_f~@eaLRL0Osp7#e~_f0dip6#4Duba7M&uHCEY|J01o)1W< +P7Ob23fTVl_Qn56&GXal>r3X^5sgNRrKA8N3{hn9{7hi8c~!P*ofJVdVi_${@)sL-5)$>`|l +6W^kYy?PQ29DKok_oWP0aCl5RzPAKNbu20H98Rl%&&`!evIuYX5F`f=8X%t_T*JzeZNor<`DJ9%F)pb +Qn>Np@IwQ9vSNfH3+395KgJs#Mv(sL$bYI8m?OLzy ++CluViDp`mKLlennmcVx*%3;Rt$VCN(h`U4`s2^HD_|9_*04>q-#$Yl4syn116?ye^mj=KuFG)IbJih6t_o6CM03gtq2hZJj$?%-A +y($4$=nGpiW`sDlyhq;R|Kv1aL(d^s?w4HKO2PH7hg$E+-8W_9I9TfSv~LJHVf}E*RLIPZQ1UsOPLZlUB9H_} +2ixao}wD`3~ATI06W4HZbi9!fH7@@=;3D3@ESpSn9p`Bx~u`p2RI~qWuM!?_pl>#vAL-41x0Ixgc81Y ++`F}(Y*ldVQ3><8fmrar1&*Nn;>{l$uZ`pZDtTt>1Gc!_0$ezG!hU{g)6|ElaOnGe84Wvv1r%p+wLtT{gK`ZzGMJVQX30zs|scYjiJ +kZvAC0I7aHnLR!h~HhN?i%c9`L{f9E$$(MBb!OL5VC7vhYbQU3^BBNsZ(~^0MJIRoa!975ZOlS*$FaP +=FIjJh?^}vaYbJ+A0C3vV`H$bDL#TZ30-#eQ|!Xy&?|1iu}k)MWeFr7ko!``FthW +Ns-kwK=D`!2gayo4l{=P3bO}neKNH*G=quDA2wWWm +#{D^^)O0eLGvn#WK-Wz25!iSp3vRXFNBt?aXb$5V#qZQk1_z@gBE6`}2b?C%I?-us2>0nfny2Ku+HNY +b>?dLAXPjHZ8wh4@3sPCX27~PJH#hk&KoC4_D<@jw3&oZZTcm6-D#*DmU(u0ZS}Kn5^)3r5P +mzC7|)8>N(#z9rCQY{h{L;-hk>8HCFgdfNQQ08yu-@Iv_l&%q*XCp6%Ukjeah#m-vf*-rjHE>(Dq5dP +!vJ8Vq=%v<#N$n=qewFg#&Y>>hE-4QcqND)a+VA*#NQ{u{DN4s@r+Qk9HeaT@e&XOGo7+#uGA0KbHtm +;6iMI3bU_g&nRS$i8d4~8#GQwqK8V{Mr>1ck)jwZK|)WgJe7ulJrMphyLUD;aZnV{Z40Y+n1I0WQW +=WvQ&Ay|nq(kawq_b_fY&l~+qIHPuqhlG +c`ss6`@=WoTTvvZ%PxQ9joKRTI+xEHW*JJ{)#T`rKow(&!#Oyn&^m!JJr=jk79#VXl}|by~HFGab0$A +C2DkoB_>_6ARq=PMSxxx!{8e;e>GoU;K`Lq<@K51DXD7|3$T4oIYNNjqO^MQCVUHoAA|4be8)n0cRS5<| +82g~NgUsEFdSw|msjRM2!QbDRF6Ld!RBS*qnASEtcHPhqR=Eg5Zu88&DD2_5pR4Ga7!wwX57M4oHgo_=e7CSlg$4Ljqn0 +Yp{c3DCWgh;2Ce53MvZ+d*R5&8_k%$+iURAvWCoL$qOg~sbV&W(oJ8^X)_wo9!si%nF`aIG8Fp}qzR0 +;918;_AyMUrMGZ-Cld&@@0W0yDs#COy?i&F!t~~)m(6bI70FkKrHrZtQy<1mi#-=w(B}g9eVUtlEih( +w|)-r@$*#mh;sH0lnUIzX_7OG`HG}NUf2qM$8IaKO8N1zGjyzf$6^5i&#+920L(}n8pHXR{TY}Dh4od +(SY{=9X|D+LStDgX?ySnVmdgUdEsb8?nA01Iw)c+}6biSXG~ig(ThDBzOq@c4o)b){&^Kj>mQ{#{zaM +uLcpvO-;1w~NK*p{nX2z=y!b-NVyN%f@4R(c4AFV#g$LCRaG7)h;_q)Z)3Fv-}L@=z%u +TXih9G7GAVjXq3g%i5`;kcleFwb>OTr8n?Zr`sK{PhFMUYF36!2|6Rgi#6e4Wlq<6w+6AdO98H +lsF{#ZfP#ucvFGZ*kfRsBsRhKC&p_r%t2PFb2)(;N|7o}5ew)fOn(n_>;hwE-$@rzsNdt5GVa#4IswgQ;#dZ4Nuz*r +AX@K357bkW(_-k%}*k&}@Q7avJJ@0&G+Ty9^uVfQcUp$WO^~Mx!($ZS|{%(a>0Hi3b_S6SE1KjkLE2d +D<-;RP(AAQ}!nr2n~YXW;!H>j)ZVq?G^~tFBEkqC&+COnyTHurb0xvvRESJP^c +|VQQT))pm%xNf0EnZi{MR>@XCr(=u47T9L!HD}i%2Is=hBWTVCKoqg%ItP{zO;M6AiLZq~*O^F2`SVN +Dr5aKYAcCLmQHb=fN|0$Lee0$zv*?{;^h3}b4V~djDV8KLVs!~I6yvGzqa#kd!64>)XA>&W$@(?VMUI5h_?T?Gs{E;55%u9bLFoGDeDUX> +pM7o8G3GyDOQWk5iM0bZwJCx)s?m!4k`-7q!QWqQmZyF|8LWu_%bjL0aJR}sbG!hpC)rRhJ<1pmd)sV +^6su-tb)h<<<@=!!d(nMG3;-?MQN>J3{76j@Y|R1&oo%P9acfQcHM3KWY>HLEJ +7DFGP`fML^VCaUQUcb{0_n1mN}FL9R-#!Ni>rVx>u!oIT#Ga)a=%10>E?NAU|Q<|>Fr`sa1)g_Xvdne +A|fKT6dHE8Vb0Cg+>*FsMG9pcA!xXrN=A3j*jb2rzy(ikj* +!V9as_(TXRz>`>#Q((O|wpG~n}jw&hAV-FI`a*CeZ+dYT~XQ`T6l^z|RMhmIQE?W#wQKt=u6|BuEGEy +pzKxBt{Y4~(NG=x+?JVuCit}R8W0-M#3XE88-NdTt|t{+Isf}(trUTO +5+>S?TVXc^PiPws=9U{UP??l<6U4k%0C%nq)cXi-z2}kd>Mxg&>DgV9H_)_EL}5tWXKecFrl9ksHUZQ +q0p=stvGQ1tVxxIkL@)9E!O;<0WrHK8Ls2*O5C5UD6@@Ha+m7E;2kX0t>d$*7nHP{LCOCee>|bXmhDGumJ~li!;vg_IffWDMV_!!;Q-g^7&NuwK_3kcRA>Pl+0!Z7L_C9F!W73BNoQZgZXgWxqXYzZ+$t=oYW#SqH+G!Xi#ZG +>D+Knyub&u=pM_p=WPx?)jJ|Vc}f?lFKNi(^E&DLgGt77kzQVfUyNY4z;UHuX&J+Puk#-F0AbKF+ +NXae4=jF?W=*!byw&JA`)b!D#w=z6DTqf_RP*fp{%b-piR4zp>!+BZDuwEefO|OPNe{wL_(9LG!UwL%?0_-_8m<$JEF0~c-Bv<+%Q!-Y3k|Vl**UISDSS_-*VaN0P( +MW2RP#p(3-GS?ty4n^;0@@w-;*rhT?Io+SvH+=_T5{9#=84tm`V|ra)01jIqev&0{JO=Qu6=rgAEeQO=3f7FB@Yaq?=ORBHDoU+qacFBj%R>*UVUZM%gT%F&eJMO6*U?YL&#|V>n7o=};fZn +Lm6Mw4`>lgXx}o~q0~Vffm0W4`MF?L>Nv-(AN}5*M);v5sm1(g8=r%mHJZwUV8HLw;F_Aac!7=TX(h| +5>aE_!-?_?tmZA7=t2Il2y1G$ziKsWZ0jXg=w?Ke`00(`9&@M;dc@R(*rjDV;6Zp#JxHTV_lrSNK#cM +MBv`~hqU$1s{IJ#U;KJ8xZ)!OHB4h*(3~ymtN%^-q$gP14GfLmn7saMEL^g6Q2NidKs#$c3Jg6DpL~2 +~|$&5;auH12a1*xm`>9Ks(#JW#I1MG^he>XrY;~C#7n{J01vWRF&g>3?qO$3F6^WJPd&lvs<}=vSMBG +V2_OnNP9KaYHknGMzl`jSZ7r!6xBcBW3A +G_5zmE3P=TQr9mH=Tc%~HK@qK=y6x=9;m5|^h{jU2pQ`=$ykFb?Bw}Q>fmR-;9Ka^SJIy7OOxU-NPo9r=Yv +Et``Rc!%)XWPOp5$Knx4D&BrtD;f-@BAPOeg@!2~HKXwux0*25%c1&J{@JdyO?l4PG$vY}p<8Yj{4C5 +6XetU=Q+XbKEAC1~>AQtqD=oE+1b`1~XZrrJVikASI4@NB{oW-Og3^1y>BmxZLK-oc=^pnW=}P{_jxu +azFDg-Z)MJYi1)$;5yh2*{>@Kn=9RGn8S`+J$br1#mhz-xjbB39mIVhap3N^W-`Q#}fb?p`#ON^Rz>Z +6%lEtx03`dq)B&hf+G|BnW#}GM;e0Q7O(~x>eV^20&oaW(_{@N5jmOs(1C*jV3K<#U4aR}3?TL-YQ%I +twJHH=kxBqKt2n8dCz)cvJq7?d)05<|2m!N@mu7>~ik@AP0Vd3PQ1(u+-=uUIHouS!CvYTH1*z+UlDS +PnZ6dEr1Yx0i42+T#^aBnnU|Iw2JZzYdcoW4;K-MJsrl}Ii0xvwP0~y8ex0+5 +v?>n(1m@EZ?cXQ{m9%2!q*oEQW(h+&=sk0rup +!~ts?t|1lnpa2^X`)LoD5_jS_$qo*Crig!%0z2Rek}gbwnr;c^&0TcIl+ld_lZw>Mm>y?_l1@k9tx0h +exy&9N#Q1OXhJU~h&9u%w~gCf_FyagI$WE$mhvIZDeL`&95@9J0|X~#lG1gW+bDh~XvFm5)?S^mr`9?YA3NlwoaHa7uJnd^aI4|bH +p89|Ad3RY>R&y{B`6Bj9S#X9z_YvN)_-Rf}41k>S~dioz%*Kz1AaZq=n)*Y93d6}BZ#-{Y->175aROv +iAI#qQeP>7W`u}EC%vNz3sqkW!6REq071yzEVa;r&_ouK5T>yt<(3fr8h`gymB5?UqM`Dotmv1ZGVw4 +LUc*vF%8lh46B=~oXstZBv;RYA4QT#*tV#lxn7|H4jiauJzeiDr7ln$zS}!!Nt6)i#A6gj(vL2_KfEi +NKN*tUo{)iO?!pi@ChBx#<{kHz<;%5cp1nW5JFl9qBwA&2Enqi`RP?19G%U;XG)NB?vQzDMsH#$Ue*! +R11TyVtBZZY@A$glPI2p5_%4uOK=J13L`epqTfCt(G#k+M(7s|p8#x1rvk}J!p43RI65xp$lBxNL1QS +<@J(of>E)aB2r4*W6VzUbFlHk4?qW^!jFVzFff%Vfs$4%^Brd~*K}!&8yl)#~HtI9!XNK_l5-NmK!N2 +)th_VD>Os~K2YKWC=2niexPH5~2mvWmz;>*iL_&yhsj$YE+3tF$!E*uqUG*4}?0Ym4dG7y@dYu=}82u +wRYvCn)?pD_4?%t$#7&zq_}5T^#YE}=puO_bSu6$b+i)fy(7)LAcD#NJzRt#>nvZf!vb4IFN;d_gGee +kZm+yf23V2cB}8^+Kz)3xG{`e>PdUMxyuK2ah4#J5jJ-dL36XTQ9q9rT{lQeIp^rTTNs%*-^w3gGUEE +R>Fzp;elQU7yR=g&w#_IJInPh({t$wbPZbft6Ml9OhePGBA^Rbqkw950@_42nE|x7Z@++N4qIXKN +HTE(ku;yFX$@N+ty?58Nzw!}ikZ=z6}J|~=X{#qqlbAlxb_bCqfs`SAi2gIvY +LqZUzD=Yk6FwmTrb&N4rpV!PFIi2_Kcu}xOQQdjgW0_`QL*Uo +{*=S$21Yfv4r4i)$`i@nO^lsD76hpxHF31{VQo)CDbZ>Kd{M2T=xcaAnoW2&-8tf6JPTBt1dN=5N&FV +TF;!rB?!(iXXt=5xB^q${c@FCv?Mu;Ku!UYTNYFaW!9;&3niw7pvO7O){jgDNN)ke+#&5IRE6q5rkkY +h-ys+@LYCCIJDIS4*>9OS1?hhyGj<)1QoTSZ?T0Z;X^^i&H0@la; +NKvt3p3mR{X;vfcjhW88|TNWZP*sZoi@yg!PHp2z03yvb7oK +rruku<8iBi3DqU8qwp27LVfYzOL` +2PYAk$>mLe4(r|Aa>MMDAy3)%fYeUfMY-g22{laS0pGfy-C`ed8Zjv)HCGRErx*|G`0sV=t2 +AlaK?mu&$JZxssmsE`lE>p%-RqX-j(|OamtS7EEL}46SHG?53iFG +)|&k&Bd1{7zKRi%=eo{{gCNlM8*#&oEw2K2Zo#KTL@ +lA2Ain#4H8Z*rI+Op$a&Iljf2G%x?R(83&KuYomzwq?TdObZj}pP)~e^u~gN7t>8|Yq_ZCVR>R2j;EK +l82CxQWFR=2xm(tIL6wlzXX&h#mMnt|Drfd8N#Q9e-lYQDB~m<>-$Z~|Eq-MMM)f|SP|{E+Z7wsWARV +}V;}?SPrNj=#B{~Ap3{<$`rH!X-(BYkO#uzZlx~2_iKpMr}6B?%;D6}G|OgS0?e_Di4z>xQ6szm_Aak +ausd0#xyT$iE_kK!qqLw^=j0YRf84~btQ1VwuC)IhV6h~p-O!gRJCa~6+Gui4o}qSG}bkx7jKk)W%Ck +e1d##L-wL!ltV~;O!`cEv;KMek#f<$#}fUA`HwDvmp*w`u}PdwzX`BJNPrFv`aIJsL{4FbWj4C=keo=b$mrTMeG-fX=4yH(ZZ5>3F=B! +Ux?$qdE1M4KF=NV=Z29?g79*xz`=^11U<*YIj}a|jXCHk|R@-ILgYqlw`YgzDsq +!y9Y7w5lt`^z5@y5byE0AvN^-UlKslvJ1F-5eh4?FG^F&)P;0$CFcSA!}vjNSgS&R&Tk+7q6PllL_OX +}b=cq_GM>hK95uvdzR%qvyflAH3Jy)3Nd69hZ>^!U)Je=Ylu(17CK1Y!DKiHB8ZtPiZ4#AL(0$%>>}| +#;=}@!js`QqtvxV}Lr}zz6fG^7g&^VgAkyksEc9vAKVv!RCeNEdf$WW3BFTAOMS0+h)3OJ1rsIJqik# +{o=bL9A3s+Xj(Hm7Hd&-HtPR499S0_cSh+P&bA;tthA?$&iABnvleU}|F|h_nXrDz`+75X9EW*`@)y4 +|uvc<;gw5=Pj&oYwI397&RKtNfRn@y#zEQ^}ub&D)@U`=$t34LV67{;=6II`;qJx5(vDFlpPHDb%2)` +rAe8AzLFz@!(U^8&rFVOPx@kcd77)a6&fDc##)bVi`R}@=(7ED8sRwgmto!ve<+ivoiLV}xlOr +9iMhj+N%0_oP8ke7PpD#CPx6lPGxbNaIQTPcq-#ZZ9XmtcGk05tn1sCs0kgpe$E-9eVQkn2pG=8<;mV +<%>l*xV+6e}0QV(=XAlVZJ=gDZ|4pjgf+3f8LzyS)1C`a#5M-C>)4IF_#a*U7!nlSdi=yQF5XPmyVly^?|_XwZ-GeZVmd5xx@Wk +*AP&cYBTE|HaoVgh&|4*gvF%A*3Mbf8!xd(5r?0X-_J8r2!)3S}E87TY4}TXKXF{jk6ueNvWQ=B!jvbobSK*@#P +&xs1CRFj1Sy;ak$cp~(`c|xcu?m!o-mFOFJgLf3ba&Yo34cA3v-O|{j}c7r?U#fkmvDvhT*U4Pk_+U_ +2@V*${S-wKnAgIQY`<7}+Bmqp#LrK_5)YG`$`#5Ayn0Zy%@t3?g1af%@)J+*zRKo-BTtE5Rs{%Lo3gG +#!%oZ)6jrpPvy1L5%Bd*)I&a&c0t~Tfe2{i#T2Vaaj=HuwIscdrgB +;HTE8dDyF@8(!(~YeA>3zpPl=_nhK=Zk!e^!OG~`e++GAmHX+}>u9}-FVa{3FYoRo;1nq+OT1GWXD+} +r7S(XA&ycd@N$6=0Wa&UiEKCQ+qeeLORz_p1KTIOX? +aW04sBW!?y`})lMrZ0NPFc&PO+qC#?V*RfJPZg7w0n%`nC(m+$7=w2TtkEb%W5D1yNTu2R5@|@P41Z6WO<&^ +^-N@VAZSkr3;n9e7@{+W&Evh-o+Fu51`-YBH1M*{97I=pP71>tX0qV-e4t#63TmZ-~ii?mI_Jmd6c@Y +g^RE2y^hl1tm?r-?@RD>qDNr+=1c;3f^yfFhXw_R+Lk=y@%#l*hbQPs-mtX8&|5{vxx7S +BNkMr0~hzG80B{bgxl!-!LV+;+WF#NEZ^wfR&gWCvGe2Lg>0x3h@ADA4cu4mz9yVic}= +~$J;$}DMQPN2IB#7w?~M#c0ufrxyxH1VhT387kon8F&JzEM)(GeX@TB(G*$5Tq$7OtlexI8g&JphOjq +<09lp#xHryX>edU0UKf4eesUomKLrdxei~r6x(+9gGVbLGTWZjPH`*(Z^>?U9OX2Qa36qOtNG3UZ$|VfFhcr6YVPh +4YPELC+cC54$QXg?A5eZK3ae?=p{uZ3e+XF$cGdvPEB`w_reTZ_$=9q0ocx-RwBwEhyuEy5E0m6eC;|VoZkNK8G51$AO>@QW&1GsQ!`Wi6B%5-?FfHi8+O6=pZ;b;yA`2BgfzD +oJ7Oo2_&ik|`eE5}xdHB5?bcz_NfBjAo4bP;_7aoYW@6ZfEl>~78*=1eu_xpt6OqTScxc7+(0Y7U{v8-7j^OR115d40xnDJ? +7*Q07)y+iqt)rD2Rfyo95D{3U&f2TuNhto0P047la~x$>l8>NN}tFzyrf>y8gbR6u55iD|CE~+46(|_pyb%ZG4Vh%pMw|}rROH`O>ESLSIXkBcc$%KV*#TuQ>ZLD> +0`$w_L#(FTwZT+{h>?`Yu9Oejm`A*M>rbx!vID7?=eUZN_Yx$*cC7jC?y~`A2Lhp%uo9 +J2>h0VR}>cc0-?k3MZICubYH({0XKFp?ZDXs<_KH@8qy)5i%l~2R29LY;@M5I{(8$x$Khm{`$j<-CI~ +rqX*-n|9zj3?G){lRm03e_LhYQT4a3|$@sP#^e={y^pYCV_K3tqG#BDhL$5i29EqOuF#S$V% +K=jYnPU8fC719=qv9>*3mH!2(|M>aQ+I3JA#2bZolxJ?hQM$~oufyc+<79XbqeV`3CZ(NiE-#=E856I +(H^uU#p@Ik+9|RjFgqyBAra9%mRf6knH +2)_@Wh4FvWucMu?xvDbxG)NDk{|auHzsuo~t0&<%4jP^qzd(8uc!6#4+UjggYNr+9$^Tz);}>b)BWN8 +MFj$hVqtNFq~IIIRiUJa-U>_LiI^Pfvsai4rQ#Rqf(%k`d^6M1?^5DUsFJ*+QVmnk}UaKAGyi0N$P58 +*p+dMbvHepZ-ow3q|v*PbIv_ge$U|uBJa@xs(`n<%xWF$x1C8F8{#r)O~>~sEDRlNMK4qb1%Ir4z4BD +puRU7t%@{fVCLxOR4#9;#u^Svb{>n7BHNor{jHLEETH7D^{^B{G;-H3OILW{Q8fKqBy_l%gfvpVIvse +MDGpN;s3+l`WP~A7z-}qSo4t__EL%`y8G)~`d- +6humCM?IEg2R4kahnE-Gnd5~oK92}mrdo@kq|H +sP1I+XvgXuV4K8{rOMZo5%lnar@s;O9KQH000080P~d=M<2D@_8J2K0Fed&05t#r0B~t=FJE?LZe(wA +FLGsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoRVlp!^GH`NlVr6nJaCwzfO>f&c5WV|X4C;#mxY{_y0^1F +GkQF;M)?bip6ge5RG_r|Oq(M>%)L*}kw(M*gcd@IJG@N;S@6Bks-RlnxM~{;^O()4{o{eZYT_k_eFLJ +w`F0J-V3oCb03q^@3n53i1{E$kC$k-j_h((=q>O@N~k@>*StjvKenUee!4CK$*yIdR?p{lC2%!QXmJA +B%MvBwVp)6&>eJhv=77qo4Ti0`iwHeekZT($SqOKxcJ`STxuxSAeOtQ4go*HOxj?K2lAC5h4A%5Ck9? +YWyj5h0oh`<<3j?X0ZmBY~kOZ)n;0z0s|HSfk|D3flyiO3O^nl>P<8?x`^~M@=q?(ZZ)*|zWGwZB5B$;1Lnyof>4p@#Vb7JJQ&&8Am0FP0N8CNk#|sdl^aXQ7Tc+A^S*tz}kW1 +ettFMdoisJbbeT&mHp0A$nkqfJFiUyvLWOYyyz>sBy_6?W=U^YsVuc(NJlj&sj6zGp9tNAF)XuL=%re +&P2Cdqmlr?gzB%SASdh%)B0$HC2OE?+z@0a+PXS+EyUxmNoV8tlMO6|@)6j7H}yF;gV)lN_4=)kS6W? +kE@~ua4f6EJ+*Rrxz<|F}lFola>@MNzfQ_rf~%2Wz&_j|PU{XjUsPhmGe1ry2X@@wBbMevx|TJcg|j`Ce* +1mnFxOES$_vC+8BtTm~;pbzAT_y!$k`d-%smjE&SdY@-W5=c>2q*=&Z5r8=El3Fq42iDBnP)h>@6aWAK2mtey7DwZfttM*{001vE001=r003}la4%nWWo~3|axZdaadl;Lb +aO9oVPk7yXJvCQV`yP=WMy=?r;F-Ex8uhMB7D=vCbymbiC00#~|0HRu)%!eoG^NFxXsJtUDixc`L{(9$2unu?p28$gsszhkn@5 +utD^sdsuBttxvA+4aU2gD?PKyjruZyxuirlKGG`cdenr)cCE@fRBP+M(4d0DC6SzkRrK7IibdzX*YI8 +D_Jt+ndLSW`ZlSQtMm@~TW`HN@%J{!3=s;ourF0$<$D-z?G^Bb-k&UMef9fg3@GG>T*N6nwQ2XT +g=^zh`K01UXx0HQYOKBI-87%C+hj=#GmFU4is$K(-rX# +p=V-4AT1jJ-AI3K~2!>}$Inkrj)x~d9G@ul{uWQ3`cdas +ufH*sJUcj;mqn&VE>o<^Vg~79Jqn>SJiIm4H9zzV5$zQ$YW*T}Ra8@WqIu0pCdn7g%4|iRB+J&NUfma +EeBeFN9TgYG=0}LMsH%0EZpb#pB2WGURl|$(MXeWx97X$V29v5uMINlx(xjAJ94#_FX&oNxP5Rc%O0% +Z$HK|)>4@h;5g_GE5yS3csO~(t_OL5{A6T-zb%;i>DWxgPkD28M^<)p*O?YrTRKfd_e@W(@Bq<d211#Fw3U}T#5)Dwmg%L$omneup9IaJ +>(T{Cdr`>suf7332Y6oMk<1yc3DS;+~$N5S+y>ZVCHk|$}3VlnaS4pH=oYg015{a!7(Eh(nbi+lia|} +am*%g1r448Dn4Z)b`}&_$6tOt9v*-B+XZD=TVzIMiH(qNb8;-UV1_DT>Gj$mv-xGBs-az(D4BDp$BB* +*#7SgXy5RVuj|u*;%OiySLRU2eh4yyX0W%RX6aR&LHB?R`lTETD)n!MvRuP^enG}-U4coIhLpn35YdS(ntJBHr +iCaOU=yXxQB+G2X5;R+_F}6Jh-be0O>b0eU%xN_>bG8KIDA_G6Ro0|)iqpK|EhiV{qzZ-+zC>-NqX)1 +R!+vA987Yi7>?A0)klcuks6!7_NlMMDxaV|T1P9exx=4D2FF`@H5!eSsiGrwNN30FR67Y`pz=DSGQr%P=L^DXqGPE2QS{`zfb +87pSf{p7hmX#SX!9O}vC|&9H2tKn?Yh}va}G#H5gv2o6%Ii2GV&2;=#i_C;+J-XqMghVKBL(3)`}8@U +8Q>CXz|g^x?puIAQ{MC*ozzAr2|k#Vp@Uyh&tytAoM+Ib*YnncR`KcIHPt_C&iLZv%(6du#hNapoP2u +Tj#Ems3^IC+l!Jrlr;q|1h25xJW^%@pA#f90)w=3Kx#wWW!58K>*d%o52!(6XFJDffufeFdd2z6saDU +5M*yM#PZ01Rdu0ZhC{Jvr9&(g9T8TuDS{Y6mvWFWN=!`#t{m#64nassi0&anseK#C40j<@UX ++(zwDrs(oDSL`?RhYo8}aIyQ=tb3l1sTd&J%7(x3LeMKzX2D#DF6>h~mh*eYn@_7 +cPjDRZ$V;W1)jx5L1*}Ro#U!bzBHd$2GwlY%Owt1M2bu^n`9`&4tLSUr~Wu(xVog!)^dkNCD1|2&4H0=qAZaJSD-L@Kb0`o^m62xZ$%7KIRpU$CkRitBb80upngE+~@)3& +oWg;Fy$e(Ja^fc<3NA>iqAq#C%rifb<0W^Di+G&RzHgx_e&!|Usc>tjnEm;q?TV(Gabd$Ea9QoTWy{jhv(ow#_9;8I5h;ccluFD%65>5jgdV+7*|1Kxm1`78yL*y^8O +3TIW6z2e)?~z&9N_FQeM^A;~GtP3dn>SrFV7ZNd(MP~-^7=LDogHH900ZEvF_JzzxDObWvMIzTmsEhG +TB1PS>ycdxTLNgZr<&~TePp{62b&1U*RL|y5m92Rru!5~Ah7|M0(?kXXK*qlqTYDG3pU}p0Lzd%Oxe> +KhM*h4(3>`8mitdCURd;kDK2>kF_>>td!k83Fi%BR76UrE2z&5bS){6zz3dfhvF +*2y!<_zH`Vu9RSUkDQWZ)zTm!^W-goqr8HVy)9^YbfKUP|tV*XC$>s1DYBORd+V$xV4aC2J$Sqq2U0th*e_|G7`No={gphJ`z8L#{MaqIK9|3L@GJa-Kf48Yw_`Mi{OE;W6FmD1NjU`^$j~pj{^qgi +raH47F-0)V;fb&4JQ(r7Ix~Yp%t?NLEJnz^q*10VQu>c;33o~JjE|<+M0z^8x)%w~-i~kXUr%oD##d( +~+>5WXEbjBa@(R4hkTDNpX+M+GcdyScL;jG}P7V(KIk|lg=HH&5-kg89zZy^JRp?&_m+#(8&UTk{obu +q{AWD(5I#Ji_RL1_x1A^MInXCJIXr;Qp?@?-W&*`VLe$-vnEaG%}pE)(UeDF$LA**k%5v6}+2_nH%z5 +YSNnLOBH%Tc=^M<5p6(YI_m=<&&ga{lhR7BBIzDeSALU2wT#RibhhwRL!H5Nyw`@s4v*c50AQjQmZrS +GfuWs^RLvxQ_@*qfAd6atNqt>80U1NtTe8yCz^}fNvRqyNpF$$F{J1@+)+{y;Py7VA^K*xzyvU#AO59KIvbwW6PCVArYEcw11_M6t@68uL;imi`x5lp1x^y%DmR6)&5Z +sEy=Q6$3%4l|Wu;^yME);mm)Dog&7Oop`ni70sjStpNGdS8(wTBbehGX^@J?HrZ(zlzt;9UGEUqG0pM +%eRIoer8Ax)Ke8b+3s=ZivUD_M_`!bu>^%=%sYFI^si*ru7VI<{=D20(R&qXv79G3+|ps5$@`!J>#0M +P{B8FacJk-AzNG?3P%l?+`)Kun;u&=H@b6!B|KH{+zZ(QgG@3IAkZgN$Mf%!aW|?ad6zGjHT?igyfY+%AQ`Bs$>3mhK5&u4N +p{es(o2lAnf$kt2L+4*2!yoEw>7M%+>Nx7ucegn$qn?E>6eund3*t<>*KbS+t92=TlL><% +g)@Qc*1Iw?5^W#-@Eg_uUM;I9eU3Tr9?&#utuouRzJp;TyZ`?r4;*nTLS6U@`ls~VabUTtilSPe8miy +2qzc5hJ)KDL_q@D=wS_owp|11-B^daUCwwvhhZDRpmBZOIJAfku^>i{KjR&_yRba5j`gw=+iGuA%|e5710q6`8Kweaf7%0Goz7p}!7iNe5E*N+Y+6I4YCtjh +32>S^IQjz@sv9%^81WRc_p8kHjmUKUnt}O1c@TPt)c3* +@31x(NTjevJqK=KA0g-EEr8Cc^&u@{kYmEr?kva;R04=hD0~_G^@RbTJDQH-SoJ!wd=_aQO&MFZ@TP4 +GJ5xl0etsWV-9LE`2y7gw4sMl|E?`3Hxuvd^eXGL34eIv7&$73PYkPK*z`;^lXb9F4u%!OuEe|D6ZCx +AVP5yH@l19QzN6mX&!&)OukWG0ei}Z1NjxxrpFa&xUWOs{`4g1;Qr?SHvSZBB%Ps7x(#HueYZ`WzXyLCo@m+*?Za-c%$l3sE7~upU +|$?><^;Zuen95^}Uq7OKbZ&@__$+YuzevauDRp3+$(9ckDmbL?1xk`8qsC8N5cWN|8i&vYh0rfS6=1) +dL2IQ;$>HL66UG?T4WaPNzic2B!BkM%|v+JX2FY9rkGarMq<8sWm?byWHe$?=(?nX;SUn2V*9usyvWM +98Hyjn#DA1J!>_+KZ1u}vt(Fd8iN0LrJfi%zT8(I_KffLlKuNDHT)jByMx2fQ6|2e?I^24W#!wqcElQ +tEeU1tMMn?Hl57*=?_8di}leGTb-Q+1c6;Rnr{&54Af${XM#F2>xAE{S6equH{<}zP#X>z<{ +Bt`=TkB-8j!3s7!BWbYpddJ(j*>?_$YVZ$|q)gGR-_gS%eqvg)|~1i8=u*MZEi={qL*#)`fpEBX}Ox= +!iOPWSA-nfeBGcXEV)v7O{_WB4Oex>J4R|E+>Q%J=ui^L=-249IDDM@3Kj;|>gz67jE4i@m2ja(DAy? +K|YR{j|-O{{>J>0|XQR000O8^OY7ym#>-*zE%JL)3^WtFaQ7maA|NaUv_0~WN&gWa%FLKWpi|MFK}UF +Yhh<)b1!3PVRB?;bT4XYb7pd7aV~IqmAzfBCAXEPd4GOI0Kxz^Dy`o9T8r#LHz2FzYSs7)l8lD?rjVA +7%85#4sxniq*8KY6^Ds0Xpxi*WE<$m}o(kN)<5*DpW&$IpLz{rdAyKl|;MpIyKF_3u +9YzpwwrZ$Ena==$o<&)4tXz516|Z(hE>K7ISm^Y!Ze^_#c<&#Tw3U+%xZ`|gJ~ufBfy;qANY>({TI-+ +Z{f-oN?y>8GNfzj^iH)h_uD&wqJ-{r3Ckch}o*uMdBt&i(t}K7V-s^~>*{|9{oKdi&=6{`1}UZ{PXHu +K4=>+jr;luirht{P6tE^`{@L@ju?`Oc*KYzG>_UX^Bvew*H{LP<#e0}oz_4Nh6eSdxN{Qmjf +U!K1?Px9&8Hy_@;`qK~lF@N^{=l^+sa$Uc9`R-q@-@khOFYjJ`cm3kpE&OnOczgZ+#}9vg`{sWB-Bqt +&{psDycR$i=-@bc(zTUt6_QSvLhW-8ZiwyHcf^P5<(qH*)7y8u{C97^dG+m&eDu +ScZ}#KR>JQKFzI*>uAO7QS|8V{K`TcI`^^ebQp5N`K`TY-ndj0C_UHI3pzJ7l5{`q?O{`#KJ-v9ZpJ@ +qRZ^5xx->sN1g_4e-HU(c`h_uTt0&+p#vPpS8+cZ*}tj*TvuND!+TXd-9v-4=-Q6et# +bQk9&CE?*_j9=KAx?zdY|@{`&dVM%49kPm%9`{68AQ*Kgnai_g1@{Ix^>{(AN8_2%t|7uUbPd$qB%(f +1!lch~aQ@qMvD|MkZ&u2J@nUcUL)*Lw)Q+{J(O>f2rQuU@}>`|ic{%eU`8@YCOXvdcbdDUV;2_9)l&h +cEXh|EvG5&wl$4|C>hTqo-Z*moFKt{Z!w+d;8t>@=pw8ef(zQ`+t78z5_^mZoc0b`TF$_+djPB&$lhW +54)51^w=Hv-Su(HvPG`=e3nPam +xsZBX!0`%fR`?nnwg`uypm)myRYpMUd=G5TqKF!#P-(60aTQ)SnGx_(xEasTo2{duV$53Jc2`!RMW{> +QR!_K#@NE?8HLzl-{Jv;EzSU+fQmZpCGtyMOiL_uJh5t^2>&&-s4=*3bXpi>IgEY5)AyAAkS(r=R@#p +a0?WFTeWY^I!hqtIvP;+kgJzll{M4W&8L+cYXTjm+$E7jm3Za-8+pJ<8Zw=HGJ~RUw`(`Uw-~SKHDXF +i)qD_`ReUoOZ=DXXHVDFA1}7CEnMQoRc76n!Da3*>KZRJz~D-@rW0##CXw +0*(I>tC7$*l<;AY7zNooN?qB7LQdWCWYmFDFZO8pueFQq4jqp@4 +sG$6Yd?tf&d1aK*r5oXo`+nI-L<=?OQ%DNb?mXMV;8Tp?l0P7KXakw*>-dKexw>}*V6KC?~145Cv`u| +evIIfv|~SM-=Nq(-Qxj9>Yi#eb%KJ$?|81sb4{LW@?0~lx0FhIZIQoXbQh1d@3k)s=%VDJ1HcB>1c1m_ic1m{c)hW>_(J9d>0gMXpq~45O@1 +W$M?e5)xUAuwT+Cx_RgDD(LSEumqf;|jO;YQ0BpY4I)Lw@kE3+#G>dND73Lu~(Q?K!aT&_!qg`32+ +`kiUP;g=g4^-|JZ6cWc|pUFCk5)4%(3?9O5yIfWKhtYPr1jo$~xb@yPycI{!?#i^}fi$>X#sDaTvb^{ +A^>_g4^w12Mw*|jBg1ok0!v-W4Sl9^ZR?qx-N_ZMdN+Hh`k#x@5PlY<4U$FA2opBnaIo5O7tn2^^sxD ++k-p6%D}!CeKm(?w&C!~U^L%HXrkzp$s&OMg-CUQ3>^!uw+@Fa8T7yzzUrWxWlfO=B)DjT-{fplw&B* +q%Rog>WG|IBWIsgq5I5J|6yy7G2cl>eFcI`(LB74uTA(Q^CAlU~fOsU2ofVa@f>8>=$!<<9)Cg +?UJprZrN{zXSR6QRraNw!M%2m6wLh9%E50N_36T5?SI;XG__Jkv6K12*|4m)upToT=+)g6iZM;Fokbg +Wm|FKI}Y-q)X)@?)grE%$81{ZqTPId`Q>fIA;&k}lsR$`ANy$Ww% +Otnz0P}Yk#vlh|00%`vGaWJu(l@`h#&}Rcj0}rgvL6>ezj`;p0HDk^?pjx;?<&m2_Hg!* +JnRK{_k->dmZ%kh2kuabuW(_}D#uvsXns +Ve)~EgZ#BJ1pqzQXr?clOAjGeA+6Bmw2+KaOWtB>2!8LeF<4P*7K6#K%Xu> +e;`h6R|hA9}VG(_e!UEWDM4x5nLG{1S}ozEF|{xcX=;z?B8KvH)YJ_Jxuxqm^Z}VmQF)zEEOPVxDmu_ +$9c-0|#Iv9dc?ca6$l7U~+FgXpA)95^$&_VDp@RA2U=3wm~ +I*=@ZgTWj0{-DqIg%W_Gl{4Q4eo4b)Yv8hh%LXnRxMT^~7fRx(HSpNLV*`&3JT~yyz+(fC?Y0j)9@+J +R%LXnRxNP9E;i)ws+3?gFP;5Z40mTLs8&GU`Y7I}V;i`rdKWdA`)AlZQ= +9_zkP5=eGz2Fv5VP!cG1o~H949Vm97*nwiN$KT2Am+U_%2_!p^>_D;u$qpomXa|Aa(9xq;_k|Kbu>-{ +p6gyDt_j-}rFWG-k5=eF+*?}aX-o8+h;GqM>4ir03>_8E3dS5636gyDt5|;+J$F*?}Z3)V@#>NOmCEF0qRTkv +{Knn~WP+>0kwieqSgFMmiYjV5EbQ4n{f{!KEJqj0`X`z{mh2a+zEx2}WQ&228}jk +sq#Qt}6qK3@|dl$N(eb_N(XiOZFd>1SM{{gV9$CBe!7D+9ANz{mh21B?tXLbS3k+zX5 +hFoNT>FO&cyBhI)@{E`7y23Q$jWni`j7#Uz>fRO=41{fJ&WPlN9j(wp77#Uz>-0{W4FBxEEfE9wMeW4 +^68DIo&eqSgFMg|xeU}S)i0Y-EkTjRN +RswqxU?jjufRO+r0Y(Ch1Q-c05@002NPv;J$76O2qSGQr3MBcwC-B +K6=>xKu8U%Ne(dU$Vf;0xJuwEbPewBMXcyFtWhN0wW8IEHJXb$O0n^jKF*DW$=t!#V=W4Wr39iRu=XI +7Ij}J2}a0E44A@!r$6xU2Oj>=!(U(oW_7INmz0WMvcSp$D+{bF?8yQngbe#aNied&$O0n^j4Uv+z{mn +43yiGemz0WMvcSp$D+{bF?8yQn3ydr<0^z$almsISj4Uv+z{mn43yiGemz0WMvcSp$D+{bF>b$Cku=$FtWhN0wW8IEHJXb2zjSL%4xv*4hXRAmf +YjE{gVAh;giaxap_zJm*A3ICKpO>j092JzEGl2qEMnx;`k+HhvU26LdinOLdiur>5lx&o2lx&o2lx&pjld&1iKIkQA}NuSIDSdl;rOn +1QgTvqQgTvqQgTvqQgTvqQgU&xMTtd;MTtd;MTvEf+hW`nB^M>Z3N&QEa|N7MKxYMXR**#tIL;u87G% +)^PC6hdgDhH<+b`L1@>7sV3leFSp{Vp*$4|XZJ`{?U5U&(-53t{umj>Ywq~3zm+XeMd%DukrIQgkV`& +698iVxDTB0=_~vG85Etqu0@A~q=Ctl^b4g5=7SY!FWsKB||KcPcwhe!5sjD#oW0vtG~!mAIi2z+c2j# +Jew;ocq=rH)n1y!Q@m})Qg3uK)qfNY=wDrVU;d??TSYQ)3jT;>uoS@)eQMXY98*bGEJ;^`y~ZGs<31>@|y+ +A-Ee6ek?MsXUT~%^7T}8|zTxX$Fpn2sRD6UA6;|$icNyeySiB0!$P4GI5Yq$+tc#er4BJ715JOW5gD- +rsN-SKlq7`DTvM_W=KkMCoNyC6t=0JgAE-VlgrZUKXHKtmJAFNQs1unE;Pn#({;?j$>KWrYVX%<+OdTES%@o-eG?7Yk3pA*`_P7p`n2cqzCp7a>4d +H_o=tMPAP*pwXT0hVyuktpse79PJ=Ch>8H7qOd$)4Cu8?dyrp+^{6=%lL$ +I%KY6mmXs(X6JEkA2ur1@8&`3-~4V1!+=E2@ +^0DmeB&eS%wK%29F@85X2RESMnzp^kXgeyx4K_whx#&n9w$yWlk%NO2xcXXH)@&pmva57A?nIVLkXUJ +ov?|vEJ>MTr{Dg3ApgF;F16lCWm39FWbY6Iu((MXijG0^NQW8nCMcqZ0*dqKwkpGdf8NB_Y2poLI+fO +^)l4~K~l+JHhl#I7Z-V%YGMJ`tPnTVcEUH^5x@W}ycV*h0RRf|CVhw?z{xD +^CJgr(w>?Ros+nA~{U{NxIN-!S&~lOpwYvK4rT8Mx(8ys@fsSwSc +R(YacF!DEw+31yC1e+QlY;(;kz_A-NlmTZu!OMvZZ+cx4@Tq7beZR+tX^WWC!jDWR>yY +(Z5N*yoFQ-D0BMpcQ9a(q=j@`apqAk`Vy2kb=Vj+Vb}*^;ffh(-Sy&34uD1OmoU8Haa^e!Lq*8R0-tf4=u3t +If`z%?^Q}Tbm*Z_=zFDX*5;uj^Y9;Ym;lVpemy480VdZG#1KQ*06!z-QxY4UDEf=}OOFaxrMIBBitQd +sH1@&-2XG#wthHqaqqgzxq=I=-S#tFuMP_HtQ +R{@-gceNhJ@%%d!l5IL@>)U_udF)?9otE#|@^kK)Dtd5;)d^w_C^2_wDiM=mxP5M4)g=m3(Z0Dyhd;c +{p(y&&BB|z_ +y6Z(>qJ{xJs(_>mO0HlmFLDaSX^o}0bRyJhLNGQR7O3Y!pjH@+C^vq$NAXm!>&?Dg$4jS0h+^QpFS0^ +~)JcJVE=9;N%gIy`_+SgMop_2+-`2bRlEQl2;K2*Ruudwrk`KLDMlZ5m4WM*b=T=UYe5;=t7DI}Npyk +#v?T+cpW3uhcW3oaGTX2ys3Pg4VhU0>xuP{?(YCw4q9O?2NK-R&$I2>M9ZSMqwHq6!E0f|9E +(?*83=NxgrMp%G#{Ga+OlX1?J03$#Xo6 +0ymEn&p=cfc93ej{;Sm=e_}6Z+yJ0xsk)D$2Er+@!#bT-HmhS}>&-8iQ+|^`fGCZOq=wh|V>VdscLYr +75*^_JY-+`Ri;|tUuwHoo*jRa@ +yFaZnHviblgR`-Icu#yVCbQJRN%2nMfDW}R}R8j5JA!&kNFb&-vdUk;kBp4t(L50)9`{NWKTPTXvbfu +|x`z45NfD;{R=jmJ{Cr3zemGd7+|NMY$R$k&8KobD878`tUaR%^lMDd<8AH}xFK9UiPi5dbu7esLHAl&M2m7`2tmXa%voj>Q-YLqA-bwKSe*$|(RT-9*_63Wc`Hl<*+lEbFVP9 +aZEGZd3f)-4Fj%qf!lcs~I8JRC=qsdC@FpGd(0A1bIygi3dI6`pq`#!(nyi^S8{B_k7_7y@5h08~v2a +1lcP#v6Fd{t1y>1@eD^E`{vccd~4MNrFz_LAza+##?>sK1G;6z~h>%#yHdKZ0asb{|k>jpYqED_NaK6 +E9Q*-*w@C>E~JLC1^4Sqxb|mlRZQg$}K_I@dhD{+Y+D}gyDuBLoiex;_>)V$akMA3ckYnR&bX( +v~6dC)vl{|Kd9brENNk`^o^ZlH*H8rdIzA}ympnmBK +%-ggC;yt>=F{gQ$f>B1{(51(}DRCX={Zx2O3f_Zlqko9Y1H8C#qK5mM!UzZ*`^9|i=MTT_o(}L?;Nuk +$t-WzA7y$=bX^SR+V=1oyI5V_Pmwsz$m+2S+kU(hvFnJS^C0?>Kx3F5*L1u2To$lv5KD3*x;Tv +Q*Xscl2L~_<#+j#MQz?jm+1IA=w2&Y +^$VSDQD#6^9wi6QN0&`mGuDO#FDZBwjqd5FO$&@yA^mbqZH7TARv#y+42vJ$h$+bvLNr_`7OsBsrWM_5nXYe|K6T +!1IICDagz%X8=FTp*S(N2wwZ={mO&;E{!Ss^pIeFfS?)7R0>-c>r5lF7Hc=A)01;U;(Rf8_$%;g!mY%Mn)(7hJaf(7=ubmLQ7i8EtFK;rRY;klM%Of_)TI!j-(c)L$c1A2Hwmcl1QF)$){5MRI9iXI~^!ahv5wh&nld0Gs<8z@MGROIXzad)Y=oka +IqApsiXc_Wp785O%LY8kUOJCq1wxIYUqf79<|onP+Wa#WeMw_lC!wYlp|t1#S@!zfhg7I#KEpyas9;n +#6VcGos$O-X%RVi~MmK@noT+b^lZfXP4*qdkqWB{iY-iU7c)>Ly|WdQ&(X6g^}(Knr)c`M#R^CGaqk5 +H6Gi$rnn|izT*T;V($d+RxAuoOZntmIKxyY1lkF?Cx>feo3%B@WS=HPW}Lg6JDVqMQlhBi|HlAInCAQ +V$oP8@(2~^)k5@B`^gtpbgxB*0gK$yG^V_q=KBF1A!%Y{f&n$f(e?Y-`bP4rObyb28`p3d +q6#0BNq*HO{EUfrF`^h|T6vP;jD)0Dvpryq+9L%`H2Mn+ZBO9?kdJF&=IT5qub?Zl$^C3yd`hYttJXg +f5K(x%urR_l98xLV2>$Z!)q-|-u|*A|92$N3@zfJ>Qf##V3NC4BLeFi2;hj577LX)5Bn0{2!PH*bXQw +W<5Zkd|tcxuje4fv`L7p`*`9k#&~^7|`Num`V;H(huiz$Fb;MNk(F)92tIkXeYL7fjC`0G4e3xaFZC3 +PMT75@x~p;5xeTyk6zKe7PCm^GTFaVFs{{*1y>o)iiHO{mMXQdWTUTXC`J%x_U1SnH89F3=(s-F8=wTWy +Z{%3;)~?|jA$-RosmMib@Ovqly3-DjFO>@0Ffc`qYiOh~yC{rJhSmoQk@IQgN9?)5@fR$PzyS4CkKl8 +GmurJ0A6V)J0Z6Ru%EeDc@WUsfddL-rHLHgvBw+|FJMh4f?i0aVa55rX^(2EU?aW5*m5!2pvmhD?g=P +o8awk5eyv33=1v2Ib~nRPcj3tP-u1IQ8N{CJxq#wpp!#7`tbiDFc!XRjWk3@Fm2I#UVahdF_Xx905~p +HpFBg69LD+;f6Jwv@)eb?CD`Fb+?y14nn%}i +2h0@?{plw+w85z_2?CuHGHFme#7@GjAMw7|8fq(i}iBSjc6 +iF$YWWT$uDO#rpeg$BLX_(0M<7%@VG{1)a57fK`vA+RXr7g7L&IgzZIIu(JKKt69Q_Z<;s67zKOMJnn)Ozu_wsD{qowM$c2 +(!s%ahuSFl4lMRAPg+r)CMjX`KSs~J$)xgS0WW5+a)EO$ +Hu+0tsxMt*5ZnxB4PtvPWayW}<=w3Ei^#}C)w>Is{xmTobb<3@27K9BJTX9#P*BRJ*sPXD5Nt>LtSdX +SV?vzd+zvABgK0;_nGSBANMxP0Jj^dlgvI1zVy@k`hvcIEuR2=Dc>fL@xn7?HeY-s5&My3j9jW%p+V^3OT8Lduhe6docV7h(IB1=!#<5zPU3URmGgq+f%kRz_G +)f2@CA7)c=8-l{4k#X^+(~>FfdO)#aQG#4=8j_rt`aA~d`wmmqLPXB0y*6*tt +2zJ#3{wVB=@L|0~V@l!dYqvH5?*IslTy-5ON8esbC5`gNRobN|Z+t9r>vXxcdQ9qH8tYMCWdYecZdI- +dp<}ct8iy=SBhHI%W!Gx3(2Q+lA7Ylo}f?l|w8R{%v^>L_pGb&76Ge86x&7jv@lx`K#E2+%_U)}2QqZ+!`Ldk*$){J;m +v3jV1Iym})eV+SCnO4M)mwXt`bsNX{kn)!j9P`wR?$tDL>I8QQApV7YF!CEFxZyRLygim;x}Dwwn240 +62qgXT_Dj&cws|}X0B+>DB&czE7$ZWbG7P7x#3A$r>+8euH6MU!K-yjNp2z53FY|BgyDdwn$A}%Qg7@ +YTL`WGfRA;5TCEvUZ>y<5GS3)VK9d5gh?zNgcM3_(&%bKNQ_uZvR*nZE9Y`811g99DW(Cn8y&KI7rCta{!DAb1L2t`C@-Q*;Yrnbk43mdxELayLas*G;>Qc@f`9TV=r#9VjLaFtL +KVa9j&(v+SG=PCip?Wdx9EpTO5YS%GfN)(u+Eu9Tm*slC%3St6sl=o`VWO1t!U14|QLEWpwx30Z3q`V +Dkw&sx?vcBwms>6eM!v5lsj{M2sUuKo0>^XmGLhM_{k=5+7c9f#>85lY2_8m; +lw3_+2k~oaIDM`v~Yr05y~Uj2qB_JZe~lW^f9p)s{3j+c7-IjU9ny-18XSYgsDzG%q^51~x8t7+hBC4 +xQF;FE2RR!a7*bILQ8JyH$Tb?*83=Nt?&@b+nkXE^V$ale3Acqy?5RRn)^K1NQX9sji*&NGdtugEMun +RSHiZj}ukEdsRM+bf&9`Q0^z|;qDB=+TNttoa*uf3Iy-<7~ShNoX0p$I_QW6>NtvM7j_8`O%rpaSsQ# +`mBPgIn;W(J?)XC8>ypO7Y{4E@gDAvAWD9_Td3OnFB$;f&5YyzKJ2)@Oc1`H6lYeXKUb|-i4s8L*kWi +mS70d>FAjO>Jr10I4K#*+0TDgF?F?~7D`iAbcz{Iwt9z_tT>;mfe)eS1M)6^@~zEm~%#6BU|2oU6OsB +#>=QA787O~qwM8a&U7Ai2WPSNNR@4|6ReBW1AqfTKAkm9+kBo=lAfdlJ?#MWjU1aT{K+pa7?1AWr`D$XakOHr19{F_vibNsDndeINw$E{obzewEz*J+t2**ZFF?yZ-_X5Y%D!(&5VY +y>*PXcfm~IV#$e5n01efHrZZ;Zog)HPDztiu2NcEGlF92Y=zSw+R2YZ^Qf!-|2=8%+hS=Ut7HcVdeKJPeVz +p+AYgu4GU-O*Pj?)aE7#^XSc^;!Kl3#-K&;peBVGl5NzhUvicwC^>$mY&H)GthfyJNAn#H8IA>j9i}I +ky(oD~$~N5g4BacyERUvsM<-aBg~D8;ZMR6sd#XajARQW%AQ_b@)31f8;B~hbzXZOoz|1$-A)`mRJwq +0^BI*S+*P$YRr=nF4ltc^)EM`|oD1C(VkbP7bLG?yzFvFnU6cwzb={uAK7o=3dIVtXS(^+07Vyd}Rna +XzR#V?_bYQ|G-1dc#EEGm5ys^rXku<$5{z*00K)E@RZo&@pcHP&74_Diap$eY$&rH5;}QhV1tQJ|*}b +HWCvS|yi-or*joGb*@sHeKB-SZ$sycv#2L&A*P$XPQ43WSvH}Xl~JFniq?uXmcB5J%9@^%z-j?-U0{*N(Z$o3>~C?W6pONcDr+ySS(WZqo4k%|rswWagW}9QI+F3JaZPqAErk!60V?f?r!-qH +VD;I#22B;6QFwV=sEwa7xg8|rd;QV2HUZJ?oPlKuzN~f`n4P_jT-*9QLa)38dhW~``upn5>NO&f`fEn +l_JGERT~nzjdC*(fvQJgXK_QzP$+X416Y@%f9U95n`tY~>nX0nrX}4u2N&86Mc|>UO%)GnwB25zU+*l +_MXqtzyZw?XX;D=#84Jr-Y@H4FUlCFh(iu#p-ubCoGgCBU^Ewk;zE+Q5{`;_q +is*D%Axa)-SNCvBqPnOQ8LogFh(l=#OWj+P0wn(L +PZltgUetU6v;U?=jy2!-D^>MXpRz-Q;s{q)9Z4nRrgd+rKxy!MFk^7T$O4hS}6dk-RIe`=VZq%EP$q~ +>xrM#LP-bU*(va>4kHN`vpm&KBlti1d5M1q{@~2>UeRO~$kM6;mcX^?4d|kpo@M_~!HbO|T^QaFXXE5 +14dM*Q?|wjE!kXIPayZ_RWx?gf=mzDH>!usJxitc^qHo2P)TZnwl+Vegx4Yh$*Y(lsm+wD##N|hy{pI +=Hk01Wb%K-lL{QB*`^PY&eyx8D+_2$F#yXXBo-mvh^^M~iJJ(vFbAKrcc_WkoyRmcvn*3ylGWE}_`im +FS`UMSiZjv#<22wb(mi-=+ATpARFxJ4Md}X3^Ak;*j5<#roWDOHdv>F)M&u52aZnw +_+ZEbF-NdcH4q*M?1Dg`u{%FlM1l-qK#7M(B2({nZUTb4^dRV`}V+ddqRTYg(sBCH22!BV0@ElzqF+V~4fDxHg+l;Eh +{$b~SJs2C~$K&a5>zO#xO2kU$g`)e6pG8XfU$a|6UW6synd-FaqC*{IT(F6!W{8tG3v!=HF-oDflUk~ +SUjY#UOcF?=5pMF{g?MS74}!&^;mt&I3X`;fTL}_tK^Cm +lBa`+sOgCAo;kMj+ULc+gi1UshC7@UX9x$4Us68cuC?oKsJMw^*CvHzZ8(eT8rr6^)M;zA?&qi~1L-% +7UH~0WkP-?Bq@X=MefNbLmSxV24IpT9h#GPB~1g*TpV%Ll9fG!Ew7W}~=EbgADfo~Rga2*|1Cm$EhUc +#6-BFzPs`L^z04e@L=Cjuk01ePs#BjB_)I>QHV{)<)u1vtdcZ0OQ_hA?+h0U7_U7m+K`Z#1h!U62l=E +hj+_9Tx7}h3x3*TRwb{ZoS-fSoz)F!MI81rr%Y*!}E4qHPDsRBE8Vb(zN3ELIpgmhz)QscF|4*boVdL +4H@)a6ob0pD<>P;7=&#nOCvX_GM8si2C8iQSIj_z0_`w +?frH;5sXDrs=1CUqkR$Zl?gvf}!f$N&#ewG(coU)d#yWQsBV+)&9s^c4G_Q)Iv7Le0?0F99=!$1)R$% +oS7B)0s&BsmubfL!hOj~Xs%fC!RINY$|kixCq_6+fCSBp1o0!DDUrAdC%Q*a(0>_e1{!=Y0!Rjy*dbp +LVu0{r$oNfdmuEn>`w08FcA{7;19Kg_;1eT~_jC>;k> +q|>#1LQb@f=;m56?7S-3^_q;R#|s@@k^Qy#QSPU9EPDuI`1*sP=C=hYL2RH)9SLc694toG+_1b!-+fM +**1M&!ti5CYX6ph(&x)n)jzG=Z+GPwq!7doo*miGp>G}WY*+W<=@n?^0wHCn2Q&RgZYa81VSGdd9=l?$Iy|Fi{9>j&@Yi8o_7DY%FeKD9>l^@8kJ3LZb=U)5^5T`w@yS6;IgCXFDnT +-V{m!Q^moEh#M?cL(vi4&g1Ab2~Ftl)-_;_wT7jb*rt`A>Sa^U5(O90TlVzI*6K*wXBxM0JZwRs0 +dmCDOGz6DU;BoX4-U>8kv1z7rcEOID6`T-jrHp%<&AOS+~AQ%tA#?a9;c!4JG+3)_{eo1%Eo&#lU!n8 +^xQ-mjMPOhlEd$IW#3HP%juZfd9!vRR4cn8CXXQK;Um3np*F%?RRfP9ZGJREWFzcjs8R0y;REEKF5VFMbKCz(6_?NXG)=F(6`sN +H@@A1~U6#*HetM4q@EsG%`&AZyV%^dmi#>AfD~+N}$h@Hk3nZFdUyvktkaz7Qx5Hg7Ncsi2x`0>?Na1j=sj3+EYlV@~ICh6uWbO7cl6sNDLFu;0LeyawU}MOpclT9woitn>R|(SRF?` +@7PUaO^dmif{;9CrD?Bik;Apcv~UZ(KyEh@Nct`{DHGSt|Z{=|gb>kx0p+U>=`@z4}DRrY@T2gvkch_ +(34if9p&V>q`5s698t^RXZ9aYH=Y(GHR}-oNstM~;W1<-eHGu6c*b!i$Al4?Ma~7Pq34hc9JD$EjDp# +P$+wK@|p^T(Fm`GRrFDPdoj4zU5FU0gyfjV@U?$p`7E8^t>2r_k*4aYsv5p2TOD8?+IR(PDfA&&!D2v +U0v+qQUk(j-N+jDeh%B=rBc)j-ME~`RK)%@W6+_mlGaB55)HZu$<-aTSfHHhuJcMw))4{mDxh62yEaG ++qut>LFs|;}NdL4Dy+pW?j+=;I`q~aMh;!!O{eXD3b@v)+v^6;dD(5Ub{-u&a?}AiZJBJYB?}SKZ@Xi +T?u&?*#yrFm&Bi{)4(f;Da;cdB-4HpV7spF;uo3q_TJBJ+b4wt9qG*o=kU%ZyqWlf9s(`aEncDk**4lQDC!Bgef)*E!%)14*xI|&+@B4tI%)`ngS($PYRVUoQQOgEH} +*T^z}fbrOr7B55HweiM!tIm$ZIvEZF=314}1+S}&=sAgm2Vbi*Ix6%r|TM8Odbi@kaL9p2$WlGL9H7$ +?G@N}dV}>jA)VTvU%a;R`&k5X8D)kXLAI;y!$TcxWtX^dLJMWWgdFx3Do>lvof9gmUe}(9y}M0d*};? +oXr7=Dgvdu_64@S!q*6mlbhCAKb^aS;W{{T}Z!>$&;7E0=9b3W5lyfs#rEI^pB<}@H2p7cuz=}=O=z) +y-ZwOoj4cQn&a;vo(=QL2mY>aLK24zLMJ42U}-`|<`6Hqe6TN}s0aGG8ph<~?gzxPP#Pie;>Hor9+NV +cb1@Vm4hW}Oy3xm@70yri7Do)`q~_sEc)7|`Kz9U0MjQ@fieLYvUYH94tANdDdI69SaME1--Q>a@&L( +kQuCnWeCc`TWBKz)EeGaD#bFm73!qu7}nFuWih$D5nNXTNJ;`GBw+VFA}>ZMBDD|4Z#&`=2p)V47lkx +86b!f3@YnwH=;=O=W_NrDW;vj&2YSRpOK>e@Z}+AxA(pnC{5E@z|;8IBNZZ#So*OQM^dM+DEyRd#zFw +==!{7o-%k_w4ec8wwnuZdj`mgVzwO_`&kr +Fiqi_dncL3IW%_qK>psQ(l-1k!y|nrHww@5Ex&W1n5L5YGlPwQ`6~FkOS`+6j3(+Uo9Uh +T4@^90jarTZlhyjr;ns5#(z3MV-1^`F@oY?0(cupWCczIIV +mfUL6m@|bqd#;p06Pi4;MkN-Q~Sej&u90z!Iw-o6NVpCCGNyS=b-y1?gU-yMwF@R0ANX)$2pvH+0*>w +ja72wTs$vmCl7+;Sr$uUbJ`zW>x-@;LZMy`PdnD=p-`u*59X91<6}>Y)Y%c! +W-{4(#;S1|DaV7cW=AkD?Bo2<&7(APPU@`2=A4G~CeHa6Y3-;s6jA-v8co&C6AG|6*uBUauk_Ys1k!F +@1qH;c_+38h%SR+TDaPQ;y6M*qz56A0wXa`VVYqZH6b)+3u{I4x{zbKP$f1q83eek+P}B| +i+Hw%UF$pZa2;T^o5j-xvY_E%cNo3UcV+4X!C`0yQ40rRl3wq)5bqAeV{dU9mfE16t*-cl#yX_dz +UA4j7IgdhX#s5&sXr<*vhu=x(zyxWfP?5H5CS{{51Y;i0iCN`aUolvAXy4Pf1J=g0EEOm5?rCXER>kd +8&^DqZ8Grs$<}m>e%x+4HR#h0t5JylS)?qs4=Fe@{*$ygwc94Y>_8X!xQ-klFh=l#G|FJXOy*)0bx-R +`_y*-g27coy +?QCWDI$pp~mlb-BUN*uUaeP#{c52N^@B1ZDZGCm!PED!aYu4`?7}mXv$fkdtK&Qo=!YEJ*u?IZ{%UO| +Q@lqnS83;noko!^>6h`zVh055wHxQevIYs1hd$?muAb0}e3Y?_xP__%ucukSl#2yUxp1c6(XGr6o9_J +&B6*VVtwaD2Y6iptB>kNy5K0#FMb&6pLfF0B2 +@_{qe_OFS_4rSLCr!$kC;^7AJ*tbD6;l=R5)qjwhsWH+dY*VS9-8guVg{jZ(x8sPm=1~$ic6U%RSxQq8wppsML*a| +zo5z?TF$s3o=wj5&4+Mec;fsEo=Hf;*y^D?&Vi18OM8PVgZ2jX2KSG<-tCvC0j+)U6lBE`EW*wvq|OWCsgkF`1bzfcSk&nUTxRQgk+ +3baf_zY6}!riaV`-pqC=bSkm2Eo=c~V2jZGz&PiX%$rpLQbP1u=w(CC2q +`0vMcBv9X+Q+_fPJHx999Fwzv6(e^SBWH4xoAB{5Z!sZR2yNzx_BAM|P=d&Cx5xmD@|*^*AnF$B +dx?eNt|OSb=OsOPwejA3s<(IUWEXD#zvyk2H6(vto-wfQIa!bp^}$pDSWZm(DgLGOcuspZ}M0(p7Ut~ +)vGU%%kFgx#V!1TT*xf=BqV>vbEIW4in)Ywxlj@Pr*pCJc$)EUM$NHY8MA_X{V7%l^3Q-F``uhfH&c# +RGG2<;+XCGC$lc2Cy`s?yuE~7NILfQzDxIJ#itz3+kowbi{~@RU-Cdbjfg0JIacF^l77cl$d#blG$KPR_}*UT*u_&Ev>vVP1;4K^uK8_B0dh{ORi +F(V5n}Te-AFSS9F%tmn{8)Bzi3z{Jc4BD5sDPl9?>v6L)aDxWd8uyKUTN%&h4QTBC8c$?F|=w6e^wtF +4}9&QrCCN5voU1Kq7WJ~+9w&L)x$YFH}C-cNIzV7E9H+8STuPT2eT4@BS={$Cz_$&!Q($iegIwX#CCn +Rkij|1JG?&s_$&r3f2sS~8u@MSd2qh)(NpMxpyVGG2pi3^qZFNxQJmWB)L+7#^G^^6<3*Tiw*_(FbfV +;BXN8?1j~W)lON7{*Q*+)-k5q!+0PVGbsfsK)KDqkB!^w|sD8H5~8ZKy`~#<=Id`ak!^(=8vubE$RM* +r@8Gfy4SwW@4Z+hd{FpP3(#VTTzf_z2^nG*H+KG08Yi0%WGi8K)x^fW8rH+tP`J +S6`8}@C{euws5&oCBPsdR6j~9EceE$nr4W@TTXU$5MhoolHZ;o<;yv!1srE29#KXRI<|O`h|6)=RCM1 +dLBoUnCZ~IWGih1#{_37hkw(zUr1p1J#!T3nI)}sp|5BJoO!n7&|g|6yCr{<~BLahC?cZja)XGo2pS+ +t_MDfJvqLB4E{TcsVCStK?I)DuXyu;qA9Rc1;kfU^Stw|mjQ!^vFj>4RT%ul?X>YQyo|1lLQ>X>g%U44tC%iU>9_PglNm`+hY86hd384Ll7HIm +1t!SP6Zv^Iw|3E6O_vKyL!YFwb2yYlah@p76PQmb^bs{+Ptgt`| +e2k{t3T5s{}mEMRc5+2-UoyUZl1W?E!vYk!LknOu4(sxx@2YsLZz<&` +WpNh!+65=)8{b>VnaBRLWW^|Cxz5_UN>ZOmI19IfpS|rdNA}*W#fbl^zoT{Xk*2dZElu#AB{N1rT>Rz +#bsbm@oFVUwa3e;>`7IpkO9o`Vl{u2ulv-HSEce&GLnhrt-{MC3b#bcmEBbenjt;*mn?w7XG2Xif9XpQ?n4&gRjC)Mf +`!#h;^+a>6BL&%Vx`ePBN3gX^cv~TMyyypbYB0Alvmz)9OzIE1IK-a2f;QcNsNT_OKF*N5=r{FozECD +SB`E={EVfT#iiG~AMi`;c2@qRqmt*#Q%ChPr)%;ryggrF1u2G%F%e5NPpm#CyxhDIy4OVEkczzxY|tb +mB7~-^(~UtjjNNYyPY}(e-=gk0JVx-GGQOwTpK{{P^c%$^tSZKghFpgldE!k1l<7G)qq{n!r5@ +CFbeiTBq(kLkXi9a5vUigx3HqYHE_#pi}q{Xe=Z?ThvN5iv_^jLkD8x9L9$d2cg_u(H9MY~=c13@;%3>>AFX(sREbZha>84gAbFDEJj1@=iOfT62u +T)uh)El;SpvlyNCS_kGwNlvN&kr^cf|gMVY1pZ!mrMsPxd-B~}3^GQFrIrF>fZ4iA@}ZImVdSF>--d60c)d-gfvCs<+N~k3=psd9*JSF=TZ!N+1EKlm|%J1f%VY93PaOnH +r2qB??}TVqQP$FLw6tEvrf}h7(c@!74mrwK_ODzb|CS3QjNzsYF18%TJP^Aq@tqOo+#3>pNqy +N4e{TFTu4>eEA&byX1n6t3Ig@3C_CpZtxtJ8fu4JP2yaqUi7GUz3?SNCv@3m+(BE5-*w(nCO6K+C1IR +;miULMFNhyC%>3X&<*kb+-g+7jwGMLnjuDHI-pe>PJSYj0nI^?fW1SzG=xJ@f>(OGzPNI9wp(ly~Vck +sEO;)gE1xr^j)|^4|DLoXO%xtnYNr9Ej913`@1P~j%_PLKF6?sZ_PL#-dnVazQy9# +*vzvr28`ON02yoV}Dwdd}o9CpyzH;&`I +@!(vl8O2_;A;ZP&-qk>Uhyzt1 +X}@&=f`s>atJp*0&M4Kr*iQ$5a~mhgr=CaP{X0@RZi!42E(#XmEng3f!Gb42W&NW2qOccSG^#oKODkY +qx<-H7osoXp;)-SxtkKpH3fSsKrquE9e{-{Pvbhd?gTVW$%8VUO%NJCuk4o?+}4?d}J3ukuldtlM;;^ +ypZ&GB)K&-{P_2&|6n2-Ob=gYJiQ^7g52a#Fn?BpW#u%V#WRi$gyn|Afh%3$gSJPHt+ +S#{M)3C=HSsI>4h8OIO%AHGss5u$4;Vq9prBl)p(*BPqgA}jN<~qNH3jt6@@>+Si0MQ4suftY-=}fnzua* +{Sq<{2;YY1OiDSz9VF`V?s*XpTf_>QW+|8Vr{!p5gtI!3)*tN-sgN6w=q&o> +uG01?8hdUr1enAP)n&ocq_DhBdFU0AIETX-Pa9Q!T^>iI0~o8i~$)JhTRfj{>#3UhE&r^F(K!>ESOP?89_LXP$6yDf5(ztNX-$P=Ke%Ufs8DC~N1W>62MJM3i85q=EPH +64mJ5ojcejB(@$c#-ZbBafblFf#R8?zk{Lzoh!H#r-{Zz^IUo&J=NC1al$Xo-#7ae|c+W2#);Yyrhrr ++3igSipGQ$QLiV!I9G5J+}y!pp9C~bufb_8bK<%C(sX(9Ej;+PlR@7H0C0!112Fv+)azo5&QEBdFKcn +r3X3N(bEeZo+}!p7-D~Rg>K*!48>U~^{Ybl(-DYv3HsneVrUdaLUO-MEPE%PMbDsSo+~lc;@5$0C5a2 +a~7oJp0j45kO#AK%C)L{u{jc@krzCJM$x!I-EObDn+U{D0TWWI|4u$ +o>*(U!vtp#CwTkFHz|wD!oLJm*y*_?x5Y0KtGL3?|tL^f7i?Ujs7c9eI=rZYHi(Iv=b77Q(<8g-L25_g`L|39VFl}TK)wooexS&#1SCzJ#*@bL+up7P*u-YJm{bDfgb&?hM!4HKR6&vMP{_IJ>|rVK02U +qU%1j7aK`K^&%}pEMl|UBbqt#2O@8N}@@M$#bpS-$D1vg-<96U?6W&nGoDeDqw(?N$D0T6*&|Fij?|* +@JJbhb@JU4-7A+Dlc0VQwok(ANoYKYg(rdQB;K4vnUnZ&67fwUxk-#RiOeSP*nFIIexiHj!Y7n0lq{6 +2l&qAjl&qAjl&svVQle6#Qle6#QR46q6WuEpKA~izWTRxGWTRxGWTRxKWanO;5}gvA5}gvA5{Flw=w7 ++-2_*+52PFq32PFq32PFq32lpD37?cP~1SNtJhbNfmUb*lIC4-Vd$)IFVGAWsqOiCvAN=hUpk`hUYq( +t81HW{}`$w|pc$w|pc$w|pc$w|pc$;rJIB^D(XB^D(XCDuJ|i*Z|&T$Egt+*p}t<0jg;i8gMch?}T;C +c2f0V>1SCzJ#$NS +G!PripNAB3GIyl_pB1iBf4IPMYYFCc31F5NV=8n)T?xC%RWId_qaEg4AfDGMc0gCSszAOlTq#n#hDED +wv4`WupF=WaTHx+gT6qInljx;S)-N71)7EbTx^jCQ6=(l4qjinJ9TCN}h>yXCmF1NOvY`ommgBG10wp +*`I(F6d4mS#zb5((LYQi4HL1#L}M_~6HJonlT7v`3p`2oPI9^P*4a#SuUzN(PtV2K>Cy4|^|5$)c5(Dq@kHHcvuEOFrNl*3-j`Le7Dx3$iLw=M>;Em+>q39u +Y<5*SFS@!B^L44JPRwE%b8CtUJ|gTFCJA`8#o@T0K+oT2-pitGV3Wt;@M?d{)j?)hbc6Vr$CU6 +-nyEOyt^4M4Z&R`(C;~303OrX6(rs2Mx^rKj7Z8T_kFew6B=|YrM +-|b4vUVqRX>V-aNScy9&cCA|O){*W(*A>5<-n_YZcOwqZ--}-kudWWyZ{Gi;>uO2st6G1yr*gB^5L^h +os-~#AM?G=f!Q11jqc^(6;mgyr)0_8Z_9v$|=f~IA;^g8=9E!`stDDoKcV~xJ;_}_q<;C^!fe_b9LBv +LwQ$qG4Ug|D4wU*>Ubw#;u?b6?C^|pF~>xEbqpOsegT$LJ8qR=L?ef%aJuIuW)U$1UL0{uypOHtKbBp +#YlV@IQJq+Q($={M4#pC3dbm%36>eOhZ3Tb7wrW&B*Gu@vInwJv$;p +Ey2$^_8UZY&Kgq^+p`b>&@1vebd{{LsM*T>t->Voxgi~dvS7mba-?8`r_)ncp?6K_UhvN=Jv1W7r*Fl +&*kj+{Nml~H@8>EXSX+Ru8yzYT%5hqS7aQ|-X8wXRJp!zdVcy=cm3+{<}kRL&45(>e^oZceNh!6c|Kn +ijcC>1cdD9e=@xfu4SplxYPY%5`qI)<#e5~^N`tmh+eULnrMaW*dRyGpCzn(ZY~razjW)c?-fdEwlChG^3CpyyFFPySGBXqXEpqs+a{Ss?Vkc_mp1U8rj=Yzsl}+AD4Dy21AUo8{y)5u8bH8OTf +2*h1$=JNxUX#8)N!0e3_dmAOynBiMzkk_@5;pNUcTyWmj%1p-SI#7zJ6YsCeshLG>9LsklH84uN8Cn8 +XBMN9WAwMa{@oaj38N&<*h?tsk(Bgnl3v1gz0%17D>v`Z1IgVYP4?)s?}_^y_x0@v7+-pcLKg|x;a`u +@f0Jwpqhxu~bEtH`!KZ0N$d!y!Z424IGRLy9Yh~@->Pz}%Ko3dZN66!ZdRt-^-(ytziqwD`4HQboglk +v;2tV<}LL_7ROWdMj51Yg<%EH4cI%Wom+4PXI66G8^v^=brTRTZKbJuexe@rm-*Wkn8&r&y?bTk5IoX +la=dL{{srVP-a<}6Te7W}}aO4q3zkXPk;t1#<4?cm|vLTO>UGkkKx(8k$ +MN&E9Q9Gb?rP56hI^gmJ?SS@aN5P{2#G@&9q1@Le-g^1aKoy0}NrbHi{mvZ1tzO`hh=!!ccj%cYdP1} +i`_hzx5}K&=19Oi&!KXJEiHAdIA2JG=SHhUEqC7%S$8jiom0 +DQmtP_fffYoqgoH(45XQItr>OZHxHup@4xB8e%G>nai%DH(-Z@*Z3!c>X)D2!O40lwi&g3p|`s3+nP0 +51(wI-Eyy&!fbr3F88IDdGqCEV`aMZ=d>iEQN>(7EW44iVRjGiARTlGl(~Flau~8%EApq;=*TyFBpXQ +6cJX;g_jpQ2MsOTxoibX($Pk?!eGrdQ6h8FRi7yQ +?M;Ii@#U5KSdJ3IXEAgV?Er;`w#G^xoi=9Ub-9fmsk`4}-vfXwM4URJ@?G2=p?euGOg%S`v2{24R@a! +7j@^R&oA;GV34=z0w@jMnn9&Sv0OO6?3L(fF(A&F7|E2A;dU{A%vGy({@O)e*b6tOAS0l8I1gUFP~0Y +zB(AcGlCNSAM&iF6vn9>R}K)(MDK$WKcMP@QwmFa-11k4o{X75;H#>f@H}ifQ@;`qiD~nFTs)0BKac7l}f)Xvi$y4NX- +y=*Ka#V5?qP-J;r~FD1j1;pab7Et6?!pZiJajTB8wP|xELkewnEZ3k0Hj{C45ct8vOJK-Fwy}{(cL@{ +J0kP?`nCp3B_`*#kK`zm~dkXH&??%F7Y1Td0LY8-vkPtP2pC~f9yoLkCSXztb=@iKj#2FR46c5*}RRJj#=dq3SsVC~+$T8Nx7#@L_^6>p6shZ5t*xDN-Y23J9N@PM9C1j57i@$|i +BEmyz_q;DOyxzM-#5f@ScDa=u_zAI9(FT@=2{QJL*(oc{i{7auzv^)fIf%H@;UBn%j&X2K`3OyLb4eg +hIFNr9qdZ8+rM>#Y|=)|yFFvWixzHd2zF(eQ9V<{Q(k1&YLxsvuvVM5O4k?6Qb64NoU!UL1C$G*mrT< +#1>Hw59&zTHp2>XAk0Gm`ACVjL8Jjq?n2niHL}-*9IgpD6n%~C +Z4;1iSKlkZzM8+59@UfG}?R0D!C$f1&Pl(;a`<^`1pk0q-OBrsW$&pC**;)X$h6Jd@x8zIAh7%>4=WI +xuj3h!r7D(ov3G$HaGn{D{ijZ8%EJ0PFF1)K9-(n1h7>0Y4HI1FBQ-3XqXj_s;l%JkTjpMP*@r_JMbk +GhfyJ=$TYoSx;u;~TgQ4!00KB|;mLsjUdafqnhpxhL+%crq*WHJ}tIZhV)6(hjuqB +rZsqr097lFb+?<6R{2UOxTXV9KxJENfv8Q{6Zi*+R_0kaKOa1Bv;x*67;ZPM3gWJoQFBmrz53lJ`I`k +DewL*uK?L$0)lRs5Jo6!luYHYVgzK^Z-z?)9VJYPaEs)-(kPr->UF}LO6ZyL(GaLk2nttA55W+^;t2W +qFYQ8kI5U)ZGOEEMe0V0{1cXC@o0YH(p8+F#Nj88c>V~SNkIqLmghzA$ +QxyhbD!5EUr%@RW49ds=Z2odOiT#U_)Z)Hxg}ZBXI}PeDR<2-@uklz@=``0@78&(NJ;iY@VM1b3vg1^ja +2k;lNqqnYoQjXgcl>8#1rwKN!rHoA}=4CpB_qytgJtQY=D#?ccu33`rme2bBu&j;nl0W+i#X9*b*{|= +vJ9^MNLdDJeH@o2bb;`9{WZ=z|C3&7nCP!qTiY)s4%CeVg~Gj1{RnAZZ#sD6Joo3D$u6+ai-qEfAL=i +CmfV*S{b?T<5||1H!~+}@T|+1=jmwQ9ZGx8>%a`Fdc^&~;&gT#D4Q8MRzb-c0wbE1g5PuYZ5QD>uZ0vF=w17Hs +_t^FQ&UZ~?4ou(emP>P*ur+5n`}2iVtzMerqN}1Q=6Zq=>+L~_N~wi8^!cf(AH+)kY|JTK)2=ne?Wb~ +U#;MF{Lp#WD`sccboBCQ;G$#|!cN-(gVWl%Y8*}-hF^7=N@k=wlIow_MC3=qAMtv^pUE5EUP4aYU53D +ZN#l2aeR;8KQO|w&xIW4Q^=2&WfFu1OiIr*#=P|er7{_OFpXjxx(N>zG=3pJeIE7SCaI4RbxBHS$X(t +6lLqIkJ8?`NuF5YpOU?Wx@SYgD&usu>&Htk&sC3;tf~Nzd78s4=JB)gtO=&y=O-`Y2j$3q}Y1@!)Qyz +v#jEqWV7D197VHP_&BFZx&TIqI;-4U@R;+S~#+61H(?s^`S?;)=h|s9xfIzsB4d1`x&#|%vyT<==tbb +Sxl`|qYi}lMfJzl=c~GI`$NZWv~E@Vs)6Pn%=y?}Iz1QIMUtHA-p+c7(jv^U@3u5o3cg6+s6Qxf>}6A +YQev~yHoPc}WQ^5D=Ae6Pj)On;tJs#+J?o{1d#7SRkN%cEy=k$AOLC1J!M +9|(!;9M+)#=?_wWl*)>}{1PeflsZ}+OZ?XT<^*nTK~EX99`!r)die%Eh?q9^{IQaA+Y#_%chNPaXde^Ap) +0bxJ9m9w4*!PF2<$wIpi|OOX>9swfgT4(Bo+hPRRn@!u)$O9_ilNK2oHik#siX9)R}Du^$;)zK3~Sga +9h?8#&T-a*W<5hO#d^Loe-J`YYt3?f7};;91i0<8{^n +@?f?8hC>d+0t7DJMgI-QzPdt-t>hdOtaQqW34bc&NOi%OBF@yDy-TrX_iF;>2tMR +m-==4RrjkS#UXN0r&FT*VZM&{#)(ItHrdm<M3Kaa<9H)-vv}U0mBkdvd;C%5=e^dvbDT|?mA__< +>-gQ#&zIkBUB3@#k1%%(%pFc5{^a;80Ik-#>ru}qPc=+`x4_g=$~-cyz{bc-zaE)~@+*<~%AK+Lys4Y`4zkJKwoA+8@Pi(OYyPPUd0aCKLT*9UKeoXw^%(JQ_ +q_LD?hkZd6?bfNRFdQnGmkfmiFU#}46>*CEGR)qK%O}hh$uyrE`G^!=-+3H_~wC@R_Oxa5b9Fr_l4o`!|5k+q6;7uA9 +Sj7M038nPU1O~PvW^w3oW8TENQK{vrHWkkjpg?ag@P)#qK+yW85d-Uv*w!MW`KVysa(z0=a%2m4qMJT +$17&fPN4OvXL9jon8uTqze(JmDxLRj}I`2K)<1^#I+WyLf@08AF*F8ZpG=DChhQ6fT%EFYef!z4>@t9Y +Se34JHx8B|!=TeZ5?z^Kuo{C0dzoOkV4XRB-k!%NLcR+7kgfc}DmS3?%gVav4MND!NYe +UNtAulk~s|H>axKKc(f +J6ldESTWh#Wlq>tISLh6u7}`zy)!jP!i(A15hdnaS3s7r4-~8dm+?9sD)4qX$`!L=pFLmv@#RH3`7M)1w_OMvEsHEfl8{-5q$>jV}OS#F@gzFtxS<#P?@jX?p8$ZU;9!_0)1=>m-vC!l#mHAL^AendggXHY+;+L2YYn? +55mH-Y!Y^EOYmzoyb(Q|X7NQhUm@$BU#fvSGxSsYGqD3tlEf8L7#t&ZXR~M@nl7wMS1gm8R7c;uA)*2a4Fht(Pg}LSio*60LiZ +)BOZMF9N^TK?>cvM0$b}d5c#>-jf!}wxgFvl`8G6Y<1VN3UpM%GIo0n&-4`cY>BN%30t!u;-kgDiaO` +-=8s4dre>cDueW0xI%)Ea>r;y^wZf$X4hztppEIKx^U8lRf-O1V{jV4fGe#uK! +n%<9VpA+?+4$PJ4#IW*+g)0JGYI4+4#FOvTX4{>0sGGJY}E^W@orrQ28~>EFMTr+6br3`Ksug&uoCT- +QAcV}gliOP9ldmh?o0N9jWldLOLkW^sBA9`>`c$<#&$Los|mLkUak&;HRta1GxbM`CM&Axl1H+z$!Gi +J*=+Z}f;9r(8R{_(`a5p`fnvUR{E{&fG~H3x3J>pP>R{6eK{oy9&V`Lrc{~2sA+)CupTCm%w}&qG{h5 +{6K~V3yX74pSQH`MM{RKE+-Dsm$?6;W$b`scW^k^?Up$-g!(6{xc8ecpsJtS_Q@qsMx^AGQHPyN*321-{vtZ6z99H +B+AQ%|YH$We@dM$$htEI`hExo{d^E<2INdmz9+|3fW=C|L9tiX!|hm1Lo0^XXi7gSgqZ7ih1KrY;bT!+{#df1A7WJCo|RY#aE< +nbHlQrn9sgEv`1=_1($=66{+DsF-&e@tvTTSc92v&_TxPKy5(4eY?hc5V%CS^I)J3-1;{N0^hB__DF5jf$ +0Tz+Ht612Z7l^SRL@GY`1!z1&*M1BH4LlOoq%`d#u#&9zRAYCg#ovp48S@w+m)JRvl&jU9mNWKsl;GO +UT90gMcTH4^!^d{%^}Q@)D;s!#wXX>q9nSxm{^$*5mQHRo}NeyOpp;z^lGZXa8{RsRNfTH+}qDPZqjW +zTL~1@i<*P=dS3MS?E)+l=dNLP31Zvp58Cz5Ru+m%*$I4}o6J7to2*|;-t$bs{_&A0pN?9O) +Amo1;|N^E68b`W&yefW?k?SHbmFE{E(5QHt>+Z?!O7S06gMmJjNyTJ@1a3@fE_PKM|E%`ME-5TK8=uX +5Q4(gj>>vkXHzP0E7)yB`nF5?__eW6zU2;ei8svtmT7#RI;(@>7vE&M8{hN)oA<^%Y1%xWV4h9* +wWppoWVQyz*d2(rNY-wX{Z)9a`E^vA6TWwF=Iu`z(UtwLeYAdCz?T~qCw +I3)KdQo}PKvnhAD$E3kIwW(G&|Y@6|9zj6#Ic=t2Byqas|q4R;v65Jm*+fohRN2J`-i>Te}8zwjt=+s +PtNz*yQ9;+4{V9-mbb+&Zen(tC)Y_D&DmZyi&;{z-NY_VzAKrcs&YY&uWkv}9ArYJ54rJC5=%>@1mI=gBR5&0t~4%8Z@emp +573_>WM{lgm8H?SNGI)m(Ji0SzX5YZ +J}cL{^TP&iVIlE-p6U2!<)0a%Xu=z;G<+3r$x-7f-R`8xY3b1AVba@L)bwE^;LA=vN*wgn)_><7wBPf +Td3I@jXp!JUq&U_k8Cbz;42t?&*sQRu10P9xyOYW8$;IclkVT|%7x}9-CASMeaK_+O9;M|y42Oc_{mI@R7_s~A@aXX3Gg*IdcyY3Se$E +a~Cv2CU?M^NZ_dXu&PT1MU$=T`o{x)OhajZg2!E^<=4e=FJ-e!p8EH0yDUevCCMtTbvIG?eb=xdBLPv +ZoLVi8JYalcj$=UIAP`HLYspl?}n#nP)5Fp02_TbR-$mCkVLhHxrQJk%G$kAzM~g)Q +w=bg0dHlws0h52z?ThR*M>*g=`xkrZ$uRUE*LIxejKNL5h8lMxHG-l +aP~;ld@7Xh8hWR32{j=fSAM(i6N5CF(kl{07C+(4j>yqHh}5?a>1}t6G2S?@c`mG5Z{3~k}r{biR4Qp +Un2Pu$(KmJMDit)FOhtOB~o*V5KGdCOBl&u0TXl!#zHmLQ1p@i$QrC>aF{WYA!n!%M5Sg5HSnDY5~bv +kN}LNChK5)%#DpOxKs*{`1Nuwqp{jx33~B&3Mn1v`2KX^J#^3-WgW(XP^4lRyVL0N!c1Rxg5ib_hYGS +AfNQ{QiOb|zm7=a$hW&uGF;sd(I-;kz51F`{KV2f93uDJKg^S&jiK-8Yu=$Vav7B+e^4_OSfF8dJecn +|STMQba#$7^dmXzIGH^Fdvdt7;t9c>T%_YH}dbpehcVil%C&N~emaDkp;3Aqy1eRpd0*yhnsZB(;k31 +X<8!x}YITB2i*BVmV?sf-^B6F<`}d!-^@1U9gQ#((svFp2_8zTv~E@=7ySJYZCpQ&0ScL%WX8>yU+2I +olKt@=9ytO#V|j``!mP;)IGIekesLhBiL*uWfwQx_I +d92FPQ9MwbEd@e#%M@2?-NA*I6Q}I#7Hay{(M4@=1Dy#~RI~6~6d84Y-0k8POTSg#NDOV(-iNwVtURC +eJyj1hVzEtOW3ftjx-2&WiZYy +EvW3#T#UZ{{#J3NnVryhcxevhuebz7y7>7a>o>q+d(iI)BQZgZSz+3!?y+ELHE=6Ix3T|u`R;4Ip-KZ +xhsk!N{^!Sy0(|-kNd#`2QXrs*MDWxfWn7{n+LCkse|K?N`Z6^kj*fcm9-66WVvr1(&uX)tpzR{mRlg +3h-}6J9noc>Tb3!*uiFB#ehik)u$BelDOoVJ))^7Li9D4j-rle0Uo#7?*m!-P%^9WPZ4F;xfO%~sy6! +%*n4}d0ZPTMI5RbD!Azb!iptGRPM0ISg8oSZ&=S4-`yxJrm^lLymdTJbKR5)U=x(?UCfo!;#H_;YNkE +#XHShJ=D55_=YOwFRBVb+3ZuGT{0nptpFqsqHF3*1Qjt}JNecaJ&>B<4cqrdFmt3)NLGd~Rf+c2ASO# +>FOZz?(VyeyZH_HclEB%C1dVAX^J$gMNib-p*rJqiC)+#YmzP1G6H7HU`p)5O1U7tvjQ`f<6xP`d0^5 +bAoyO_wYeC65Q7;q4FXcE1VXrJ|4L;>FQS*4_Y45d{E=Tu;4M?J1wyN7M6CkKT=cZIy4k)APcfx1(g5 +7U_FgQ(bk2zPHbwYYDPe@eqcmjuL~NDn?j<^iK^0T)T!T!2Sq#kQVYIwWwH^dqMY +~}#eu3l-p0k;r#hclp2P>D^;ToER;qV}Y7%|*bWT*53)&Rw*sD5NsbB*Z==>@q*fqg@-o`*0=k=Lq#$ +8zEb~ED6kWmYLLA6r$Rdp;-RHZsKb&K8^H+~DhR}oYYHw`gK=>veJe#o0_?jVe +;joQ?{X}5SXshTWvCV?CW_01rR$?u#LEB{_!Tz{OWkE$rwu*XLa6xzZRh0$(T+*#|UHyS03RVo<#nR2 +Yj*h9u>#xlw&blDC!@Sui7L!h-F+&}LZt`@<8yuKb-bLmz?;9iv1BtvvgPjFaLE!6X7+J8fW)6`Z1zo +1_6x-NrsH>k_b}9U67dQZGpPoU!BdcDj8w)8aS{S& +z*CZ6V2LauaD-_fzF3nS_s*QM4N5Y49gSP +xM2EbCafFnz8ax$pjSkt%7(U$e}@Hq%()TSAKb)1KZ$lZ(R9GvJ(-E_?Gw%UZT{=__HdxkuB-o{EVOH +5*UPo4QO~q|7FYBw1y4Dw7;xWS8&@0OGLnmx-R3^Z0+a9TKGPn(b~v&itU0^ZEww<+XmgG$2R6O57Ia +CYE54GIrEjl)57TM~2dgbuo(th~^TD&bz;%htML50x_PJ288cJUOiDaF_cy@N9z#S2@$6J4M+q1yjJ} +DbqbO6W@*FZR=GdguKpF3UKF +z(F)GVqY0m#N|nJ8>9cX`bFg5y#IOLr~0)%_5JwOuDIU;{K3w^s9E-{cukg7E*(|x5IDQ>g?i}m47gqbS{56Lk?2zFBJbLSShnKgb!Cb=*(0$Raqey!th}idfy8F30w$kU~R +FhdGsY7y@6aWAK2mtey7Do{wLmg!a002}m001`t003}la4%nWWo~3|axZdaadl;Lba +O9oVPk7yXJvCQV`yP=WMyB3I&kTpOp}oEKKYDxm?);K2&QDG+Z%*m$ +#ns6l)FHd)?9uImpsO^z591)BlVmO^%;m)7vXQ>EsF{itAf!I_Pq!MenhN_30UY+a{n@q-lXca +%8<0zu3l+9==GLe1}^U{-(B+k?DZUr}AW&20yA$lLApXoY`?$hv*UK1?LDNpEnoj)Y;#(z*1g?DL?t| +e=WR0ztFMg9cC-q1Q((JY8574tAF;Xy=BK|KF8NiqL1nTLzD>{`WhxFfC3Mf#X24&PmVpbL?~QhFz1k +;0qn)m;?MF!>^!i8vD!WVDoh*@I^4Od4{tF@(+%z!&VkArWF+>i#0q3_ZjTn9{aEbP2J3739)>L~|)8 +?!)LcMTkbKW*)Rspgo;a7#FY);2sYEgriSLE4mZ3%EV$7xj=v{eLTPY{p!Ol9bbN;kH^#L@#XEOH;@I +>7)AU_r0{Wx6r2;hN`p9G!*Bq+Kb@ZZjv2>q&o9nzKS}G)&TlVIZ*J)9YD&j+eLTHAKlyNRJf-Uo)9b +67(*vR#Ar!@u%r=rMiWh)L^*CeRYvy~5=)(5b7|v7r#zL +zDnbw+drag{dfo5SIbpA%U3~}q6KsXc_#`|!P!%i&Wnlsh&-(1iL~!TnS^z|T!xUm4elawxS`5YiP_}=6PrXmnO1}@yuMt4sp +jA!}EBA`v_wk@)&1wUg^}pb7(X{mz;*KF@_GM_yBE!Dd?ME+(X0EE^CGxYevv8@&F?n0~GF)Lo}%oaE +DOCWgn~=p^Y(ii2e=5hte8pAU+<-hT-8DqS6`JBn+(cq=oJLNSIMS0U!4RGuh;g5921@?zu7=SWX2k= +{FdmfuBQA?SrcU+6d31&9q?&!8}QO33KN;s6G&9vSeWjx(9N)%pLg|V@N#$G!4)vVSK0<$S9%tlLBUj +Ncr$@Aag>(L0mdGK;KYCO(uYxJ}LsvIG|+;BF~5eo|W9pVGV~EVVDD1=7tm{sa1;M&ZQ_ClMsNG))Vf +&yblT(0c%Ja26QI7po!#kG%htt%j7f04$(#uPO1Y8A5|1DJZIl=p2C=+=SMaAQH}o3s}agZ-_=No{HR +7fRU@3W@m(%bCnbE%N^%@$Gx6t2#50i{!2<7R^e@5`$GIWn=GbI>z{f+T$FT|rh5$Pld0sJ`3XGal<) +3%p`NN4Ej>SFBXgG135*TKK@z2gX9F9L<1o3@os;rcr`?9Ma03;qRzjm?B-K$2uP2J +L#@0&^o>9Kd(KNYP1c0rNnuTwl>=wuh7xPfoDANT93A?vfu?Aa0|0}NeNcdt^ON%&_fiwn%-ugIi^@C +IAA+lz_wXXqN)L!0~1M?5P|yt1N?)#zKuW=@(MG&6c~y)bs1RD-w4-%kyTn;;y+8`{TewwyTh;R;Fgf0@tgtem#=|JN9Ot`_>q@dib +XGQITFu;`6n(L}6P^)clxP$y5~l7StDIqPbVwW6U+{G2bkJzRm~rn%9;GTEF_-c|K_4KOenK#7lF5N`mKU@7S&ep0G;2>=Zkkoucl)l&CV{5U^{Du+Zvwp7f_g==t>MPl){12A4d1;Q% +}AS>XJ;S(%Q&d-#mX91Y3IiN%{Pwrn+Im)_bdH>eIDqO_qNr@H^)(KaL{>1`p&(PS4^nN?^|HLYaWVO +arJ#lW3IU_?DL9_Lg_uz06kdHRu9yA^DCXa;)EN_^vQu8JX4?EHC1CKz>6)=mv8v2>w;#ayjWF@Hkqh +Dsua(2F)efjpm2GO6Wwz#}%MB}x&7WB66Iy?SsjmfZV}}`yZWbKHJ +g?OnGmNJ1t@}b-J?Lh?B@eijiAra4A8MA9zSe?yGHho5w&|?S0jua@u9+KV2pb&e-vjI@sC)aWR8NhH +#A}+GF4)P`LZbbZ>stpdr|xfEugXc@n&`De@~cH-uR(n`&oBM`md2|LYnJsU8?4sXQWI?`oeA9d+!BR +4MfG!lX@|*B%kIoJaQdWTgE#VEoA*t#w{XzrVRt=HBaSA|^t~ITUNsu4vAJy6E*y04KJ9yi#es>rjq% +R4&|L3zZB46c7PLpfu0vgy!9hL3>VNl^TeG0PWzd`1 +Uf=%2@T})HSpPb7u~=N1)wNr#-&r>foJ|cO-GU8_&!Gy*{jp^ervhMr-w;UVXlO^_R-qG_%^1>2$+_u +2kyUIsPlY^8C*O>^qy6N{e?B)O!j4bclYLS?_iIazw3fpSn_XDc>)i%hw&=2YDKPg|PjuLm~BeyIzK~ +Ai7SnP`)EEmG8zv)H|4r<=Yp9&}Si*r}4dfXZ%9sxkw>!7DSnFl}(w*FM~&c{-4fou3nGF!^!K>PtLy +_=VSRs+77O?zq|Gy^#vx)lc(&pw5#xDj}}qzS&WY;PW}v>e*;iU0|XQR000O8^OY7yAEJ8-o(TW|HY@ +-DH~;_uaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4dSZf9s^Vsd47ZEs{{Y%Xwl)m +mFm<4O{K_pc}&bTlA&IPP{55=N^P!+{yJ+!R2gd0LsI0c(t%V>`oSSNq@hD?3iNZ@H0uSXv$1-PKiJU +Av9Ex7YkfpU=KrT+`*n>Dl$&8GXLIIsFH<(C%4#bpN90Cib8G&x{Chg2Z2Wqq5o6G31&tw +UYw|u#wt~#G>T~i(nG7@a1r{c53)biPZdNH6;t#?X#;D}FaGZQ*C>RnF!i3Nn7EDN)Q`f1MzQizHKxZ +|#-q;Mixn77W?=r3(*EfINyq7eMI-qkodf|5nKq%JN>uz)jdSd$5FY!FQ)slG92{rpuDtjM-TJ|E?7z +}SngA805#7$xmnh6A?p|i-UJ&tow9qiK$($fcUc4~$Ug$iEA5~JPqy4`h%*_Xb2mWL1#WS}3Q>+vv(N +p>cEkDsLn$pM%DOO`Y$+5zYDS6@ek0{3a*J$iN&3I@Uj$s=%L8{`{q;SEP>j%123Dl-9DpWBb+)f_@e +}u)C{z!$1A}^r{k0meK?B@*RZVm)`fW625`9#XcJj>?bzzE4hQAnF}w4pEUdnw~bFid#i0YJ|vfNSGo +&?SGom_vXZzsdy$@TsBPoRa{FpFTwIr*= +Xzz1V!6?97nc|J-x>Y+#r^f!-5s6Z4C#b!Plopwrw^AWL%Mw!-rn4u9m3B_6(( +k5HW_(g;wP|tjbKTnkmmqGU4L$cI4`K4D39=I#LMdqi`KT^l*ofwm&+%{&UUJv +}b{_>~@dy9F6i4;V?_puQcP(0SCC+_ny@sLzPbBFdKG{DVe=K +g75xh8jjMbmxpM^dcpEhWk!X~-lBM%EtJRPAe{${@0%ZvqqpRv08j*W_&kLa&PWw-aVY?!q)aA0_}qJ +sfjYL{{E%1tlL_vln;2;e3i=!ETNt+2>z&4XBDllZfK78}HiFr>_Io-BavZjOd}1DgiIrXy +VY4(=tcJa&YR=U(3yLZI_F`VrO)pin|k?3I2?_epqbiz2T2a68-_vFVRpFoSxHu^k82lf`mJb=97{;V0F;mbE +*-vyqz<#iGN*@rgwFQ^TS6Q%79I2g^ibH6f{ny5p+X08JFEuoUGxDM3dYIAY%OL2W&&3UX0WD3E}IUL +But4(;qU|&NFK)`5DOqfa;UCHKu#fEUGnl}g5}{ +xbv0uRe5DB&*Vh6D#I2BeVs7J&|fPf87JdS4qE!4J%!xn}jSen>Cf|)@Dj#n6w2%V#aI5tI=HG*w5=w +;Dh9dKE?;sR6@8yt$F6#GS@{+g^JWaDK=5lOLmAc7-(O2K~d1<8<^qQlnE^eApfI1<%I{)8&GxnWN?6=h$vTlZ~VKIJ8Gce4xYruFWj+2a!$lH7Ai-6Z0k) +S7$!QlvcB()lJTuCFYPcXJ^sG0;oAse%cy=TSnk!+L;K%8VH>25aev-T(DJGSC*_>w?Q3=*v1C3vPEVc&DL?CgFHjv7z1sRb{>gr3&%uYdO;de>X9hdMbK6c@;PDn;~j +C(8i{fZ6v8fyU$cQ33GLaa(XQzQS&2qn;4EiR^F-zxEm5wBi3I|&v^k|;r}Uc@l&Wp3HE~tjDi_Q)&j +nqPHfby4Kp54)^hUAmh~{iu76)bPtUw^9hyRuR-?u0+tB6LNtkN9WrAJ1>+yZdza0V_g-O* +2Fb)VVVBIut9-I?+GO@h!qH`Nz{lyR^*k(nleF{URbpgu7RMM15FhvpVQ$tw}D2m$?h!M5SUoph1CmO +=0+gPHF24|@(D_}#yD_Fao`##^iiNzk?JRdw%A({2h|)X_CeRcpbx!<7es>>*1@xKUnuVobw#Xd-CKT +Et~aY{0a>zn@hleF%Q>1-9GDfUDIQjMK`#>(7Ry=XBCX{zRyV8I((C)M`P_c!-wlGY71|E9Eetk8(D= +quue93Z=4)U1^{;r}%w9ZoSeQ~)TO*4D9dXN=iO75b6?GeI+N@;~>#h7!W_V$F2CP8fw#sWqm*=A}<6 +vt9%@wIo%glym5gU1-iG}4D6{qZh>JFfz!Ng=W@BACtp!!davW&LMT(UuZPcltr8ntc_t4Y_Uc+~$YD +SN~+xou?wVYfxTDN|>lK9J=Wd4D82l`}{aigGn7D$=eH=p$y`mCKhd_QrRg)|bg^I~A0S_`YUU>wa~o +uF7uAg|cZJyP7!FP1iA=76(o9)l1su;m?eLdP?oW2CIpdMMUkCW}cXI9Vo)u{D0$oYuh}0*6>1E+Oos +ut`JmhAnkH630vn%4MDXIJI1|9T=zt7*rji6YpGzqY}NO`dU0Rrh5FJJ22rn!EybcJ +6h`!}$`+FsaxQ)@v`4Jos%=nOS%&{X@{-wrlFAWKU%0$mSE2zG3PayFWq?2Y@3m`WaIiO?S5x!-WPP;uI0kc5&VBJkYxs9F<3qYJ9ag7$ +|LiG=DSs>*Tl`TW6fNsD`lJyHj&q=LLGr-YaWIhDw26pHM6p9Z(eJ6ewPXxGiVyDo|u}?iTNFWJn=36 +G%No)q4+Z4-xkq_QR!o?569H}6&HU5@?pZC@s0VLhbu3Q{a>K2eD9Evz246z{>Te%qr~SgC5HSB8fcx +vL7zXu$cTO@H8~5P`PG?zhbb#Vq3t?l9Xf1Degm>P21qoBuG*$`stw9Od?c~y +pr71cewxk9xYKMCE9VeJ}eHn8mjeUIDGTw&5#bXx99&y?@m6Pp3~Xs@yYr13B5bJIQ~1WvE2*y=;lGv +MUmVmS)9^wK9iJ`^eO*mlBO}PA0HQ4GL5UeplO=OtfDDw_5(fiG)t-kBY%_MWSY-qLHQk39-pv3msL5 +9=hAYUvUGo8s2Na=&jWPxZd7q@9L#o)7KD +zj2jT+&?KD<2F~?-h{i1_-^+;eN<apQ$tGU0)qQo5%`&`e~cpMON{VJ{$eq?j52EGR9C8fwlp-1j} +DKL@FD9KiCAHY3M;1Gd6K~{7tX;I3%MLK{7*wXK(HygwqH=F3~yf@wTO{%TLj;~Wy +45uz&MtXcv%9DF*tI{t_eNAFJ0PH(;_^zTn^&QGqd>HWnO9ns~{)y?Vg=d+_Ly8L`~d2xNRPjoG%rdW +~bBe|vc4lW;aFgcS|oTOzP`WK|P1i*Ag5AipNG*4v$MNy0rnJ-_I!!*zCSMg$qA@nUJca-JTfS!s3+J +X9d*@YLA-vLBF-5<~ahf$n;O_73Y41b^8!S(wz&x--Q%gaicemcTfCOBtrc*r=>=WE +;-Tv4h|0MvdUAMKEy>lg?P$Z2#azNr|FVrxhz$HB)>y9N-#=hmHb| +KAA-|@Xc{w00{wsz& +WXB%0`WWbBcgK;9{hVm7(HUg#-s2gGRU>Dd%bs_aop3lK~$w92|$h5#ku)IKVN&F~$+$fZZ5&2$zpxH +-_DK2nS;rj$t^4;TVQv7)CIRU>LzLf?))Q5$qz^MX-xt7r}1A;9vs72@EGNoWO7b!wC#02unGiz<4ql +2*z+A3vlsFDxpacT)2;>R~M?e=si3vp0NDWrDcn0AKh$^5+r3r(P&rZ|K#c-&7E0Ek3KfHdy5?<_1h0eODa +kl&{@+dh(rzODr@P6Y>>|2}1l=y8N>OzZRW&>4CZjF7iE0A7=_X;_O;jEK*Sd*n6#Z^8Y`V!o(@hi_( +R7p0>L#jDV0I8$cN5iF#=dScd~r9yW*0xEQoU8d@0`5CezKH*EMzv7dxZqzJ{y192O3$HeS^7mZCt2twmO3Z*x=891dbH~z6Jqz5QG*2u^R-uM&Re(%*~zqno`!F^&$wLiQE +1-2!!+9&rO{#(Qr^-dl7VJ>Bha51D_svGo!Fnp*aZGaj-3d9tU0F_K}%0)*uVCU)%GhENq1!Y*bdy$u +0i%Id3>vqr~nk&meFkw$;y_I?1)>1%ZsaVqZ0j^@YTmN)woHCViN*;HoF@LC +j((4yUCe*>`GEJL?AL;+M`qOm`>}Ol3j{jf +rU%tw@HWt0Am~@3XtPpRot=TOS=M)%1z-HaSp$qN?OJfU^5$7Kp$p91CT_bcYbA0EmqxJLTBudWt@+K +lu%3(Nn>A;#jcOuGMu*1WZ=wOM%a%G9p~(K5qZ74oJNaSOvPcWFikhUvN%O#a2dRie7uRTf +;uhl8#r?ERVD6L+D5`i9AZzS7-?wROmvKHzSMcGDAmI~1dNb7e=rlihlo1-%k=XV>4R8|a*9Mz%u0J! +cjIVP)H_5T+WrHE+Ey;cZu5%fSnkXyP%|7PdKOR_tCKn4zL|!`g+zG#c&3U}zRs?OE3WYn88!ZEU=c; +D>c!YQc0n^SemT7dkVGogy%u-_%^#u0OgzYmI0GX6e}#0+UFs1H*x6EnG~N4$R*JT$#E9`@>gKw%NB8 +&)T8P8f4sPw}EgVy0dZXS=f1^9R@~!tW|`b)nKc+u(4PO`ZF@?f9?dc1p+(AymRHMv02(gXZCgMn+$a +j=-t1my|9he&5vCNreAtFaFf+%#O5RrZJb8u_H3qo2n&HX3$_m2Zsg~qLBOq5Q2!P%Ixq;_a9BHCV1u ++7w!?Bo)XReLCmiqHYIJ*|erk1P!$W_reqrhJfIHn!?|_Xe4F{n!)X74>TwNU)epu&uQwv=LHt(CV;H +d?dgMK@6F*I4w!qGcHdq-||V=i?D%a3~pil>g;~p +1halm>?+aDPq)c+s*$&;vejm^;AX+%Kn&b|z^!X;Vd$=n7Kz(`JZmHGArKA%SEJosLQ_nAmff=PtB@H +7`k`9`E{?U;Xcj3uPGJpn`*t_2fv^m_D(iCK>cC24SM%#S(#C3Jo>_&1K=(pnU3qlCI{$aunrCg)(d) +mF_^Zw>AtUU-Wx2l}bP>3yoGiFpchkjtPuu;0uNJo3A9RYz-G|ux_rcp|yZF`CC(Xss&xDO8@a+M+ih +HIO{8DkX>2CWR1im$)yP*0Jv>|j;)ov*Kzz!xiX&ib-mi@=`2_h(Vxy`T%UyB=s< +gPS+4mKiK_fvv7XLdH+`@8xJhOd1v@72aEbah}j>B`%3@H%MT>}=mp(C;SvDb#fr%OP!k4RoN! +%+(veGxh$%r?@JT?-T4%%S636ai!i^g*n@w4AmO6jwxc$@V^~IYgI+(l>KL!5|g5NuDnQabj^E+vOb!b30%b&_O3gRlbJ-SQduQEEMEdL`8{sT +};0|XQR000O8^OY7yOFe&GZzxytBVZp-u3^Z52qi`uju0ZpXsl +(3&^F+*B3iTGnz6RgWd@o$QmCOb#KUcldyglZ0;d*n)0Vq4KY4UR! +dKrDY!9uVCh0v44aXqRS}%LN{^pkjGE-3jtwCWkxsa@-a&r`$1I_-{(=j)~qdZrKrdjg7JYKAI(<+_A9F4kE`BPyy{CM?=E>r=e^iicMhc!2=`y`%W@!^ca0raPv&Xh$xD%M3(DU`7p`Shss_|v4p;-ctL4a`t&W25j%*!4evsV^{ +6A81i0#yX^ou>ztd0w?Y#`hK_-%|VTZMnj**5+{ZWeGlzIi_-|vekgniR6>lQ1}Fl|86TouR$@khN0SkT;1QZ>3 +^dx9K%el!L{GzTAdR%%XgFEL(9-;)yZButoS4A6b3 +pD|HlqQpe02V-IgB_Sq-P!eKH2nFE*1cW1i!Nh6+fJ@y0@M9fLxIz%Y$%F|=L(mRILyS8>-@(}TXov= +Fk&eG1u7F6@AWYEY4l$6>uE~^I5&A}2Aeh4vfB>xtjY1=CTaSa_5w4>U0zd +@99*yYK=18p#=MZh+fI_WJa|2G$CWqhwLM713p+=yi3`EgTU!heKq){C}faZj>MqEcY$6BCvt{$TWY7 +R!43{8}_4HHNDipgUgtNIGT2yF>2B>0jLEJ3DOJ>I@fJC~@d5|e6B@?<5pmO}lxQt3<;M=&w?2ig~Lj +?{V}B=4KZ!6-Z&*?z?FkPR3QLNOleZe+%i_*DH*3<5-m?oQPMvM+W&J|Y+d!w|x!NTnB1`cNa)i4WoE +hs_b-sIT^yA3@t@`@Ep-szue$vS}5~UHv4RGpI)BKCA#fkPLxv(73w!RW^5?og~^Jq9RE&q>A=lbo2+7gV66Hkv% +$PW1?uqRstl`C|b@r^MdK@9v;`{S{SzOwEDSUY7CwQ6}Bjh_ico7-6n2Y6Rf^&BuYlEXvD}yylL}{^| +F!L^|@%LZXUvLu!+FLyKpQHc16IM=lpN=f{iRAIb^>!B7*kbBJ&LA0YhML7$o5q7B)C=z0H@F@kcivL +KBH0(`j605%lY?aeHRT@cd(1_}bt>6*3`SAGz0-0^~By7^=`y>4b@bMLuwO*B}bf{ESCNP*1< +-K;1Ya$Uch)oG%%U5$LzZSuY?D>sp7q`BLN(P9x8V{8JFwHLUyey{hhMYa}9G6{XNp#-hHVMD3GWu8U +T>KU#LZIXFK^m^XK<%LX>;h(QXo{hP8%y#6-cDhT}wk*_*StlRx%wUr&7jCcZzF-2x@L*S=-7VxZ7@S +D7DW2yj8wo)NOBIPB1LbDr%~;%I#n~IBZ}(%k~(l=Xlm$o{{YPk=-vgx4dd!aJ8A`WB04RHjB7q8H=9Xt9~e?t*T@H`;lU^ZK=lcH&M5%t|o6wOZ^8piTNbMw&O*KJAv1= +Xvm~T>EZpb@MXZ8pRW@_q>Lky})09ZLw#IUbhJ6ucw_i7OVB;sA#q}tJN*Gjn5^UXrt1OU`h3D2MZ)# +3GGg2Pb9t)f!SJRkA0>h;iZoB`SvdQ^TDPcw!JU3f5DKxt2yYfZ{x80a@<6sY<2Rt^lnD%<-qdZg)G@ +q{mVVnL0}xoWp`tvKUUf|*IH+{Dzj1Va$wp-{pQN0zcwa4(Gz={xwmV%eP)a4ZMBkT|Bh#+@@&9GKU3 +la&H&MghOQaB#j~}KXtnWL!P;$^4_NODd*ky(W`)4iAQoWP7k&P51U%QhgBK*@pr5qow>QTNyX{3C0Y +6e?ZXkG*0OMP`Bk~yBR`f|Oz;y6R^;ITprc}NX_}@!5%b<|g%6|)qn=#=Ccw;2;!bY-R(eX;)^H6K6v +~4@iZU#7i+1};Y^w^I_;@`d&y0m)RS9>3|JsIhTIdK1bWD~55Xv-_l{|Lbw1-y2GEjIpN2)g@tPeKu$ +!S3Cw5bR=Jv$@*+mlO3S4qi*@3trgaweNNMdIaoy%|}`K(**Nb!oNMDpJ&cjT0b9A-^W|N9=X&X`pxy +X4wq4x$KUl>{-HxP=xMrM#Jpi)zpprIx4ZgZ_5&LY1Y;G2kpp3gsI_g(| +P2Cx!N(faezg`pNr`{`g~&L|@e55vAFmk@sIvO9KQH000080P~d=N9CHTnR^BR0B{rl05t#r0B~t=FJ +E?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoWVRUJ3F>rEkVr6nJaCwzjTXWhv5PtWs*g3qAm +QoB!NSo6KaB#~U0vrtOWHKGbu|?3tSX36taDM&Sm9Ja_p24wK`|YOGqx+S9o<2i$YEQ$m7=s#PPk&<(lbsCLI*Ss<2 +7f|!BYV;c4QOhul%WGGrJRw4IX#YGt5t6U1HU(hfNg^cB%WUgX9Jgv3GT`E_St>qf2<_gNz1=MRb6HV ++@uR<#bU_`nRj9A3vEA!(>ED)OIlB0Y5`cSGzQB+N&yp|T6QG9*lz`z{%|)m+ocS7mZXjq}Wb +x_@B?-cm2K-67a!uKtNyZ=&Gxdg^-@;m~z;i>8%;!VpRGx>3Vn>1!ct5wqBP0h` +xEG~2t$GIEMyYthpVT6dkF4vkA)EfH-aU}qIsT5n;dZxN5B?nUZ?*S7{_tqrt+f%>QyskODt9}Rw%oQ +{Ks-H33!1{uOYy4$rM@Ln}R%2A9$$E&apW7fCe$pH*7z6Vz7$XY!y_{0_wuA?)b-GGKNLS4@9)u-ClS6K;GNkalhj@U=K#nf?;bk?pl*xYXrl|XgF +{>RV*%JX^JVC`;wfcc!nky0yBw|#N|O0hyH-&jnKishq?R8u*@FAS>=O^9kN`XRl`7p&pKX&Ozfs));h!iq+z66*_f&$7|QlDa1zdXw&QDx_~1_Nepk +)M|~V{mDIigG2U|g8~J#&aD#l +*`blJZ)Wh(X1*6N{eNw_zpqXZfD0vG!$GK?N}L1<1X#ba +TS6cx(`u4RB(sGM>mtF;;~c(vyFxEsRRXX8xbGtcKUiO)QruTFgR^ZDw;S3jSxL41w#`5MI6DDYwDzI +P+sCGlOxd?!G19PwS+XXCDj?`kjK(fF>2?`k7H=e--@u8HqD<$D*B* +QZJv>EJN#hWKu_`vn)4;*++OKWQBC-Nbx3)%$(+h4{Yg@MSLQrgKa|)52SPWHb`!S>kwb +3c@i$YX&mu&QoccE_5dV{&n7yIVQKr7p+yR9RF!6nP%h2uS8rYYNAJbHO=H#)N~GN)( +d}26y2%p)?h=^++sHi>_3lc7X2JhISsw#fw(B~Rr-PFpI= +&dU8FsaH&o0^OTTlTc-bkTDoMW)m3S6Z!t3U1*4Sh#7Y)6_S3to?=$P~6NOaIwIeyYkG`G}&iQLwCWp +y^>6=WC(w~@z57<(I>NhRsSo8&lvMHqylbxRRq#2dZ%5U@c@0D(g9`4!e=^cPUG!xRMxNzMMou%PJSf +LjnU;5lCrx|eN6ZDW$)tm1`bcve=-0r8$TVuP%8bJLJkyGXECK2I``z-W!S_A{#hEmXRNSl!-Otosw%< +1Dp2)4>)*JJEB_NL;2YFjSK%Cxk)pvj@FO0#^>0}4ZjPN+W8ZGF +F}B(y7Yc=>=1H5=Qlk}DYh +15ir?1QY-O00;o{l@>>(oN;rV1ONcU3;+N)0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow +7a%5$6FKuFDXkl`5Wpr?IZ(?O~E^v9JR$Fi4MihSMR~#u13tE=KR((m7N`#OE6$s*@Rg^|(u#aIBGlO +QvNxi?m-?mZ%fzyTpKx?I~hmMj?0(Q%99P1Su(h<1=*TDDL*+8rqqUADCG7wH`W$|iO+ +GHR| +2~kg&R~pE8Zsd}_5i)e-G!0U>&?-ZW7AgKjti4|E>dhF+00X0Sw9-&X?dgx<&YGXV*GuQj&OHXf@WfXc%8{4oP7Z&*RnDaGia*;*D;u&*>EsW +P_(zmwkWNvstCz8UP9P8lwd +xnBU0=uJ2;4O_gr6bspMl!nXds(WrlG{911iO-7KMd#K&N{p3ZuD3#DDzhpMGrO05ZYP69AxCRcr+sZ +dLX=U^b1Z_Yq2uJJ&nXptU1+lO=Xi4nkP3rhaT|Rol!ed#{r--IgiL)`CmMzE8M(&>@eC-&u1Npbwba +}g-W^miYMM!@l$!qFs#ivl*Myckb-WhdQSmz@{{amk7{iU=^)Zl)(kFz|0><}1@lhAwXg1k09itLN3E +c8_b%=!K2g6Hg}o4!w#Sn_G@D|CC0j+ny?Q6+Jc9O6V5cj201R^?2yQ}}(A{`_DE=3GX253L;66s(DH +xM^^5%9i54+|+ty=KEQ`RF15{-jRdr{bbj;ZHzu)aA&gxO+%g~^E@b{Fts)7@QYw-+2UvA*K)K~3XOB +mSNcMm{aWAxvrmq2jb~UTsJ;@KT9%)8_NV%i2XFY>(s@8eU%MXX@H2c6ydFt8{*cp-vpvq!bv|x(6+7 +<#M~2L}d}QB>^#GpEPS&Wz7*^|s`2o!{hM3Yvs-KyG<28D2ydY9Giddx&3<`I2w?hXWtJ@0lsc~!zsQ +y%t^|Ih2s&OeXERC1y=jQ74+2wZbu7HLuA=w>3#FtX;xcOGBx43fB)!XbN7!A8T-Rts4Mb5RGveL-IXS$C=I81^ +si*WeP)h>@6aWAK2mtey7DvvEk2_fd006HC001}u003}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvC +QV`yP=WMyO@Lq8!kx)LwKSj0=>OfMpv+(dmR1dkx +zxUTb%q$oK2-t$`2&mF_G>if7)uoq2D(wA;5I8jYv31_t4;Ba(^8AA$eAQxrJ +RJJ2lbDTlF=#`FI*dBk{#2ATS~d*iB*~sKzpqd!z>q80QQx?aH$HeNo8bjPy@f<)+DUp2<`V}E)r&i$ +_-w1p>+KMVhWT##1qY#>szGNdHk#?mNuFu +W$*9b}Vw`)bR7nZTN%K^gLsO8?63f%ylt%qtr6Q|bsLWG{;AXX4@6Ad1>0(85ZZIEBdCoO@3d)TX35w +?;;kn_&3>7YBc4vJju94{22u&2|YftWp3*_C|ZYL0-VQ+9c?a0`L0MudD^^YAWT;Uy>u1LZ|eX6`I!F +ke@L|)VG;28b^AqIWLPSS=`X?Rx3E*OBN$65Ssxr)hKJkg^UhTbB6x(62iAPd(IOk!V10b)$0S#B#d4 +uXeq=zl|nH=507@ssO*GK&}ED5A+SB##0wjA#C8?u8Vr!eAMVdvKidlf+KUTOz+noPlz$pd`K=CZsux +{sems8k8yR*b9fv3CE|F62saQ)&KHPs(f3|i;}aT_arjP6;|$53+xVd_R3wboc%rQW|uw<0Al&Ggar} +GCn5v&L@K4bG*ZSo=!1va{%|npe;9o14~SL~BENcQy!iSbZ=`msm1%rQz2k+m)v7ECtu~MV7P_y`M<( +KS>M}u{IhK?*``m=C;>qU*#QYSd35mYXq6UPQ$RbA@4=0-lk%6TcY0r@&NAQNJBiyl&--_Ca*ZDti}b%x +O9KQH000080P~d=NAcxnnoJA;0ESEe051Rl0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_ +>WppoXVqql>mX5R32;(&N#u23vi|KG$ll1Ye$y6lCZ;W?Z5ABwFI +}N+d?*(&F&WCW=5|XuhuhsuyG=jX>E!*z6`Nk1O|Iq>b~^oZ_K|7owp(qsxZ~_o?BDvK8?duz#h +IV5`{$Zxj7onf}Q1e&*$b;yC$1Ga2lxPF$U-2~Y+y@Sa?(a9D@42ZTg$cZkAEG#W0 +}Zq5D3-^)n7b)ovE?>vvHDSNEZTb5!bjbu?Dg3jW{t-VG(lGHvXdZSGf_8TGoJAHk*{P=&Z01l{pBW& +;@8QWU*HI1mu~zAyY_?I*uQ56g9uZWM(lc<-bG>Fe;As;U&d~{6{EC{IcG_V{2u0+F)!JmfL-=6bUXd=JP|-{WDznVYZ&aV) +vpkJPycWS$4Y&Le0(8{M~z`+$qje&lfiM_8|G6`z*3*kMu3Uc0G?AI|23Aija1w=96O5f{uZIRyKju9 +zQY&ECP-!ynKfbo2=>BevvhlkoK>=s*ilmwmoi{PyW)!A`Eeu+Jy6*~!)7%Uh@mBMm5=KiQIh{}A}lF +!U;R!*mOQLj#wS+1YQvI61wTUM#+d=+7?}SCjdioqw9K6Lx(vTU?yoOiyO)`et_hX+G&PHs`z;VlkN1 +An%5F4NcxhFp?{tx_*$zu782kn?QiUiru-798R;xeYm2S3%AI__F3mJh{D^fzd+d!=v(HmSs0}q_7wY +Y?ZDMnIlIux{`_{}qW8KTW?N9n4gUz>6wHBs?ysTg^B{`i4m*vKR8+k@0j}AzEYq<1rp4IJ9FFK7Y;y +H$LlJ4WTI)EvXI&3&;uKC)BF>z+efT_eV~B@O;#h>jFVf_aw;+zwi}!Y`CI0>03ljE@y>7uR$gGa~WD +G(!;chfX0&crO5Ir&TD;$ISAmFz!x{q$K;T5(C&y4K|_FCJzC0e&e2sc$+@GU*RC-}XQ9vA$cp5GVzz +MkI~{J!M(I_gv41Hm7R^tj*;^n6?JZ9U%>d|S^S3jR>f9}50Z&mRf?h~mrsj|6`t`Gb!76u2Y!&Pb07 +zN6=l1%IsPj|G2R@cYVB;I81ilHaFr!FShMd@1-#J%1_qOFiEcd{58!1mDy1SAxIN^H+ku((}3Cb3LC +6KG*Ztg1@HtW(EuTdfj@Hi$#*|v?3RkTw@BUk?j;1RkTghFh@!gd6B78eNi;w7`dj9Q5-JXLWM_JxBO +fC?9Pp+JY2ZTfQ$ZtbXnO8?h!MuGrzoqFIEA-|9a&GZjxlRU;V-g5$$C0pogq>?t1Vo2kP0?3ZT|0SK +3KZq8SvOs88)i!HXTQB3!AV}RV2qoR1ghUGUU +Wjb;WU^2{K`L|c2{uJQ2X;~{2^F0B1gX7}V0MPelMTxUc48|D6`UeSbu9=Z<;nJcI@xnCr;;$z6Y>K) +{j3tk!e4qIBW1&pf~hei%Auq}K7$}7u@S*U8kmWkyhC!8Yr~!LE;~8$#p&KEQAK`aNAx+XMTzPQ3(;owmu$0vG#@TRoAMhd5vMBBWMq__3n@ +68dl! +VT^o*(%M(+P#+KRcnMQB48{)F_^a`u#XSQP&^|WrY6Yhgd0&9NP_vBfFvG3fm2dBfFt+Y&Rs1?8a-MxXuZ`PgnK9NUeGiY&0~H=qdGDY06y)lP{Wp8cZqn&oa&M5Rv-iW+s|EOqXnI1d_#b2dPY#90mcf +H;4g?ZtWVIqTBmvyuu>=N4=h|VR{Jix9`1E{1 +R&jWB2&zvS>?Ve-w_GgIjDHF|IiJYRST4z{N`wtq{sDWW+S4|_sQlqaitgi;&ct-jpE$jVhuW$8QEm< +~Qe*eG7C#ZWCdsaVFBz->dV|f-eeWhFTk$iGZ2zi!%2}sY!o<-rSh6CS}$88LZ;Pbi +%9IJb3JbpgK>1S9by3wZ__)m11<9#Hq7=RLN&SlkM+bRxq;YgdAiBA<@t%&XU0PA@gxyj`O-*i<;i0!>Zs-Qv1h6O!wjHtOkv;Kj!{(zK_$xoW1vYo +RyKFxxi{0=x+mIJ$I~t#O5Omo*%G*!eb+-F0;aRk)=rYiIOw{k@*Qs{X#O~GGUDI0c-kV_6KbzQh*}! ++V5Z#>W;njYStir}+b!p=BJAa-2{^4TYYR%!_zm$tp_|I)}Iv20b3huxE2)ti$aq3$Vc5w>FE>7ae#o +OjrFm1Sv{Xp)}^h1{X9o~abL_!HV*(Ts5y65b{z2ym8MLdyIFA7sv)Zc(oEVn7|vd88d^F+UDcjw6&O;JtjF@-=M ++MrimYf`->ALD}?^vW^oH|XtLM4HOY*}P|*PFgMT$LT~d6>7Q(n~Iqkf|*T7Ql>)jv8l+TeHBNhLh-S +wm>u;3Et?9($EHH!$W$mCn+k~|Q=xEdDkP3fg~G9^kT^0G3dg2G;{Q`iO;sGrJBcHCr*JIqB#z{r!m+ +%QIFfe?$MR0%-)U#VKtb$CnU)kJH*M?@SP= +ct8sY6Fkwx4H+2ji$+!t0wxf3!c_+HDr5{9{*9>wJ43ArhOzJ1t87x4Q<(##9fi_JAT4K6tY@H>~051 +liy;x54R88~ka5KW*@*4eo4kI;n2)Q)PCfy!(DGXqO6lda~?-8W!uU+03A=&5Pgyr{Tf +qrTL+;8gE|J;ep5^)5L5rY<;rh6_%g>4MY31>v0oeOsJ6&3~d>`hl+d!~H~;!hfV4iN)-cGPj8Qk=j8 +2Eq|g*ZICbTda2;ZA1NIBBZ-&%@q4Zy7Qdx)&~NInKkkw79!LIY!L4Nxud+{Cy^hr{UW1Nhi@R9>s$B +~4(9a6ixE{+tM23XDQar{vZYjp1nvRX#w@>|K_qhe$1M}i0_REPc{1F>oPJD3_JDaR?Q?)2{M7rcrW6 +^hve$5$a62-tY21iCQaEyU=EJk!uYQi=R`^YG4$FL7yowZR6O=Eau6hp@tYR6(s7o{dfrZGA)ijiZC8 +sDjO6pm>)M@Hc|hNBw`DNNO()Wp~{#z#gmc8u|}#-bX9YZ~s6QMiubHXaMQiKS^QkBnmJ7)x?28vm%Z +?U{ymR1~c3Ifl10H+pHvL@)WPB>Bqz&j2j@F}`rAVcv*7amc@WA6huF4y_#JK74THsN5y}%2AdbK%(# +;P)h>@6aWAK2mtey7DxIT6}Wl^006lX001}u003}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`y +P=WMyNV*o*^(Y9T +SyBm86sU{`!5C64xZx6t%r&;!{_w4NfFCOF=erm4USqGs&;F1*=)7|anig&?IIB(qeo6_%@^ya4g}cJAHB)_XgZq*YxWzj^7E~;b?kyA9!v*n +B04=e?RKqV6)Y{{KY}}dz0S3;Bi0lCf(`e$fVi$aODi$yY_1)%`3-$7<5Mcpxd4VBk#ubuzq>fbcWMG +$Mu5IZQ#5Aw7Xb8I5Jx(8@(fl+V0fMs_8gR7%{EM7x7cXI~&7~c&Q#eLDZmFXwU@(fq*myK~?i;QMV$ +)qdL0N&Mlu`-?GTgc+6HjbG;tQnCJfXcZAzGLaXhJ>{BCH4JXW(z45=LkD6If&HuIh1Lhy+Bb{lPQ`=Qn#ciK|?PB8LsA2HAIisJ-Jymp?NW&s{> +a?{^ZQ3l3HZS%O>P){E4C0NV+4q8GR*a!q(3vM*M1(|r-2v{{d*UX@2R^Wr7l}l}l&Z7ewLitpTE%6n +MhSXPK1aX5hLZO1=SuEvF)Oou%nP({K1r;zE<_7$E}(qjJaI9vcpdk-0dEqF~4j|&@l9CrVFnwB33uQ?>f&PZtMY4MI-W!`>eiY78`%>hd)v(H-@u7w1uFe2FCxYj`9E=m-h97T^%WtngOFO8s5FhdIczE +EsE+A{x@SsWJjw|EonE;j{%r(5;z30BUZP)h>@6aWAK2mtey7DuGq<-a5Z007$z0 +01}u003}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyQ+(P;AQt;n0@>1*Tyt|6!aHSPAw*l}3#p5v8etfEwx>slZ25r*> +c%3uYLaeWx#!%RN;fLogN8Xg{My`(#g1wA;mk`NS|OG(M`mROtf}!(6IN?kh?R4PcX`jHj-MvRwNFT} +1}!{RXsKEf*;&%^m1+4hw6mVL>%jFEq$9=}Tc0+r*e(T{r$h3BZ)7XP7g-Rcr@e03$SDB+L^NNs(H3Q +G!3hrPa%~eA5c$1;UbYwoybSwz{FB6toP@D@J|?iHyM~0u&9H&irGg3=k3gAr<0xGGJk1MX?AlUz?Vp +YNroH9?e!Tp&CuFHhygP-U1sKbOIdPr4C4^vINIW17IShjj%cR2MICJR~$dsP>3}RW8Optw1vm<^8R79gzoGK9=n +T0ceZ@GLtAVGYO%o?6Wi@MLt@NI5n&Px90{g_MgJZV-QIXIUOw6AhvVgJ;CV27SU?x%-Nka;Uro9Tn6 +DP|2XEkDb16NP*cP*@$ZsVMk#Z-olDH&Rw#MCu`zQZ=C`wXvqtE@E44*KK`qzqVX}m4}jZ +2L`k67hXO$wOXifX`K9S*(w?D_eyTC1lU5mXnoXp)QqfVo@#Q4-sGUNy~o6s(_Ug|jx2#V5nCT`3653 +8oud2zt3NW~wmWV=S5B?62|pzJrn3Jv_~1;iu%h#hU`qV5wASstDg=Zz7lMc0vf`4&G5ytUe`6{VJ^4l6y%gm-z@Euv)*M!8 +vcf#rRg{`%9W$qXkG+8&hv$UilM#``F`>*gcZjB3dCVYu1Kn|EEmE~HtMPxmKW$Mm+q&qRV#Rv+t#PB +?^d>e`t|lNDl8w4eQ_7-$MxWHi(iKPzHI#8F&DT0(QHh|6^`oRto&IXn%5D{Yj2j$*e*sWS0|XQR000O8^OY7ymtp +W${R992v)LLZ(?O~E^ +v9JR&8(END%(cuNWyGYE4IJQaC-hP64d1mIB* +;${QG#@x0UX7+O9u0<5ZwTk(o5A03#P+0h0*ej8jpA!ASOfzZAaD(_{LZ6@xl*mcCz;#YnT`ZEoGdT! +5hJ-p1u_KFfI;?CG}>odBvBkEg8R&HDK!06TdA@?1Pn8&a=EXN84O^RW{CArOj)dLN})CeoIx9UpFjU +W5RK+8^rHyo)>gwDHL6Dp@=69$7{ynKk;>8SFC+n&F!ca49<3FR;R8^H28@JRYBo|7^%FG_Un!r5tSwhd~|!eXa!;iqymQ-n?H4PYaQE^bP5r5L+w1>M +hXs<2EauIyCLrB2LV!{Pc%lbLP#`*Nz@?(vW2gs#r4hY0{YWC_}ZV(`_skUDcKU!q^17lNIc#~oPen+ +#e_*IaRQhO=YwnV=%0_qqs5)g{&KXK4m}SpZ|2a4S%1D54Q|K%Im~Y7vm0;d0(gi!iY=K2{M+ +%WPpb8Nav;BQF}Ed7zMClk4SCyk<&y0qbssaf2xO(6zi;Baybxs3OocMO$VM7r`e(Dt96%94*l)W(ED +x&e(#YH6Aux!z$5od9uo9rB&F)Wxzxs*PWt5A{n+buKlDCzdjPi{Nsb*DPA}fLL{3^Q>Xf}MI@PUE$r +#*tF5sl0=4|rv?Y4_0Y^RZQ(@ +-9m9J}stH^IdlTZhc{%%f@yg;IpaNQ59OpWjk*&q4gFO`klt7?PX{}b*t6#Bc^p`n-}La*Gx-?b`DKg +2+Jj>)wNtY8l$j~+tcjmzBJ!k+kfsdE~uKoSp#cMsf3zmjj!+2x3i;EIt`%@93Fft%vRkL?PWv4JsY{ +;ZB&$Oe~?T)&Kk|Kn9-$RF;+t=G>H<&;A-9_@1WQl8+t>~CI|GMtY`p8^&V&%9sYK(f5f}Galzk?&Jr0@X(m{+U(v_O!wV@!uW~vvdV+Pjj +>paR`pEqM$Rtyy9@(}cAHeGDWQ|IcLXkJj4rrY*ipg!H?vWYDLB~uRdrQCd?kQ3>irxFy9I97qe|^ee +AL)y%$p6cI=WU&@m)<-wuk63ZWID&;FwzYz|535|eWgk5m8!J=KmBx}+1Z2Kzmn>kDlano0KF`q-Y-y +}oqZP7HN9_ecRwxJlB9_D2Vm})*iYV|T3u<6NfG +h@g>Pg3Sqkl4-^>?-+r@HmJs;Aa@kP7+E4RM!;VBhddASbhRNgJpm}fHx%h$Z&?JAYCcP+l8%D#=GaT +K6PJ!a3&E{)CswcYv;P)h>@6aWAK2mtey7Dug|Hab@a006ie0024w003}la4%nWWo~3|axZdaadl;Lb +aO9oVPk7yXJvCQV`yP=WMy2g6N_(T#g;$bl>B|mBfenIzcR7<#L4;t?{a*1fyGnre)a(p(Qt=9R +x5|v;xLN5dMw$sU}?(N>1l7>Su`B8SVgFyZkGRXzoV$Fjth?ZZfM5&xgpz-PHH*P>L*T@xBE26iCBY5-pBYE~74zw0t+wLOM}3uAlJJ$tjC?t~g#i($ +3S5$qaJ+sL&jacq^MHCJ6a-uWk=hf>ohcn9$Ydi3I1J$v^M3+D@m$@l+>blZH0|uR4PqU21;dp}esp) +F7;7l>8Ul0|&p1u333i(LK*I!fiO#_f2#AV4VfewEKrF~24(f=2wD4PhdUbOvNPx>pbH3@t +iuzh7&{oACGR52&cAic3eT*=FE$dn;nx6NFhO>QE)d!Y7~^&5Fd-G`bsKrDrfpjdyJgt`w-eksw4gV< +cwzB5sZT(l>X$V(X^ +Y*IuPlZnN85EmFxbne|>vBn_i83ldGG-1)PIrHmwR7#hkQ-N2%JW5QNRX*%fkyMoSl%$27ciSqtfRA;AxN;OrTc2BujXutXdNmuHU#Cw^w=t*0Ws#)yZi4St;YR#$9bsM3aqI9A +vWXQYPJ6S`;S_QX;re(ISg4yiexz&fkbx?c@mE0UmCT_R?l=przDQ7n-^apTV4MY4e_q_PAO&8yYzDb|bw*4$} ++#N=DsWpt|gWsw}}J&*^E@;F-`EC}%v7u3P+#QToOL{|39V{sy59#*z{?f`qiIRqp$5{!Katdz<5afA +(F-V=Ei%*(WP`^rf|IZ~w6xpQ-k#hAd?kUgn(hPC>3>g1RaUrBa%)_Q>R^G$s-k#UBUAM+Qbm-QUzbf +Dva!fJfn-c%wz60h$P*2biN`K}nY_I}u^MS`u2ry3bs&Do%*lhbj)>49abzeLm))~$d_iFJ^KKE+YzH +Bz^lgWkU(bVn<6DlW?HI6I-|^zm&HcU~j$yo#l=r^@C1cgs@$Rjrv5Su-O{8n;q*fzxw4^v-_`Y;MZHT@FEB)EfYcaHPiu&c>yoH@)(}nmwDq4 +DLIMB#hG-UJ_*lv%ach6bk`3Mvy7q@3OtzAs`ZU{1FeNA^*xRH$lwgNDX|B&^4JEzfZg;_hdVPVBJKV +eF0Y0lXU(gqn4(>XxjLGA3rPh3+=FF3gU8aX%t#zLI3=ykWGJOXBx&cLa7&?uZ{B3JeNsU97 +Fz>w)K|^n+>idpYF{yNenjZvxgVhH^VELcdy+apNRHk&X)bMELncXHZhd(`3 +Vnhcy5y0_+2+TbS?I2aQPUT#y_L_eqrh82qxP3xT3vo5p{Ms&7OKa*b!^Do^HupZPsN1J}J#CQCPhIAFL@X?Rh%Owl^QpUd^M(?Z#bM>FZYgvK!0 +=)eQdM{97c>jEnH{R4C4rEEKR`~}|O9KQH000080P~d=M_>COYaRpu09*WppofbY?hka&KZ~axQRrrB>T+<2Dd|*H;WSFLvvwb{1PCn`Qy +qu@j@dL6Wh^lORhYn+Qc3B$d?t`VJ-eCOeC6t0!x8&dixJLnc>Ommla2o<>s`kNShDKY-qN*8dYez+O +355UdeqimjN4IP_(Lz%*p?Z^n7#O0|NRVy?4;js!D|kdOF=Ty9W-Ou<~pLHH>e9Y-6aP?qI_#gSoBXn +Iu}sfrg$40EZ2gclQomUBDPMDTOB#sHmHHzT_+>@|eXaG(x0dV`F-KaB66U_>~YCN=je2dk@I +yyRH3(N>c=G+|I6Am9Yglh@v_`N*$Tg-pZ&3 +!q!uL_|JX-|NoxZ^LuIF{9!OJ~i$!YpZ^D8s4Y{MBPrmj>Z%$9^xg2}+^KNF+d8;wW7i&Z}y1=E4=!* +J$77v^0r81)z9t_SmlH=p?f7r;l{S!~U`Wb)qPlu~AroJ`O}jO()X7aFf7fjohA^oBI%7#VF8M07+p+ +n<^tmts})OO%75_rOvR(zM`RG1?v4zO(64mcx8owDhstf-fBcMdFpy2z;UsSxTvgTuRk~p47%dCtc#U +Z#td!b?0-t1F-NZ^3el>>Epk=M6MhsRWbwD4$PjKm=3d{f$1t9uOp?=Y?NG*D;20uK_AV$2=0J%K*Wl +;2D2z$Gl6?_@x`}aCgqokk}YGcvmI;^3~&9(gl-`2IJ4;>q)qX{xi{;<1GL>Qj^o5U(z*bar5h(g=q{ +kEfCisJ7&5w1!my!{r&ZiOCwTW1wFlWZH_R&86RLjRLE}hmjj8CiGL5FQ7gGj)sN@Lpk&J!b+V^Rm&C +*HF=CeK>%C69a)$~FUWms3B(Bw+Mr`)91x1SEY6fr5VEr@#gF~gp%*j^PjehAwqJ~%`w>e2=NWx`@L8 +gcW4M~CKw`fyl47Y9m7bz0}B@m;Ya!c>|Gp5d4Dr|I=1iu{LlM@CQZXX+NGdSw28Wr`_tUYR&`ON;5| +N}(vH%uzI&@a+L^&gn8LN4O^vI%Nrp*s{MJk^SeH7xWiF7(9C +edKo|d7k}%!TNhkg{)3p>>gR&9S1hiTySp<7PF?x~em|9JPXV*1fNt#-HrlNVtmb)l`MtBUtcb8d4*JMkJ~m3{_bBvizmrk`>!SyZS>AisZxBhpW}9=&e%n@H5=O{$x?qcTO}2mC+h2FO7!I7$x-) +gs#EjUGGR>#fn@D&PDG}#&Ql1uzsy;iv#S?TXTkuh$8Ev_?tV4f6Rqx^yQlTl&nxYOpfoL_TlY})=|L +p_KLmwk^QnRilVWm1vVuV@&Va)#(LNkK;Pqjzk74l??}JBzCV9WF@f=b&Z!4QnImOv{8C{TY}}}5q{7 +ZPe>KpRsgbw6^0E`w^Tyb=7G8|@A<O7%7o;hj1Yyy2lmKS`P|?TnZ8YhdM|IswWYk6~R-G=D{vd +jsNZWDTni=K9!}Ue_zQ2&>7~v0{WAoeKiK2e^UVKL(RjMv}Pdysk!q +sAInv8Rd`1AkRktg`}?QA#-M>}ah*|hv3C|e_p*9XLx73YglA9OZ6Bwe`x8P!X7I^j)2rZEqyi6pic& +c=p5x&x^-F3a-6Tj7-pfSknaLcLR+Zfv^MM4bxqw6ke23aEKBzHaO>7^3(E%BIO1#_D9adw +HwuM@zGJkKYQdu-6EZV2lDz7z^uyojY3)F$ix?an4Vb2Z!;o(PE3U+LgrkryXY5>ZSZ`;ymHh{H3!>| +2_z!#AV@YA3=+uz~?v(K1z)s<7qt_nJf-cel{RL@>#yjY?;0#<4UJyH4-|r?i>X(^)Bl31}38rt6cO- +c&oj54uIq0Sm9*@Qj53?xYq>sqo=X*kolvnD?m+6eo-M>+)JZd5qRhpA2i+=%7O9KQH000080P~d=M; +Ssahs_KC0M;k~05t#r0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvaV{dG1Wn*+{Z +*FrgaCx0tZExH*68`RAK{yDcP1i!5eh6S-gUhAOHE5d)()2^&8f&h^wOMN=Rn&TSd$|98&kRY4dhy!6 +{SsLk4(E+C&kVD!%Z*6OJXdL>%fbk~smi($zsRc6#m!v&vTfulSMKkVraoMp2>jNxu(_?3%<$eX`|@* +{-kqp@s;WkOu|jzM{QGwhe7Tf)zFdlhxQxE26n4uGzZsRiF +N;R%Le0 +ik{{APQieVkJ#Pn^j2)}2fZ+2TZyJ*CfC;+xi|W6b$u;JSt899F)Vi!d~zob_)CdgNzQENhkXd45<)V_c+z9u&i-BL{UT?M=QEWFW$XBj~-KD;7n`CRJNka@fE`a0wovzKSE1(v69vC0x5-s6E{*qL#s;ldl$ID*zE{LuRDeQx0AFw +#!CgQJV!;5g$f&cB`a)LVQi3l*FjqE42M8ob?8|9i*)G~u5o15RCdEbN<5c7$e+I!Cqu9cK*++fEl)f +(+iOgP;h6eu2n7L&zx{C~^UjLS;lQWwwUgOs`duQ4sJWc@2kN+VmO^dKSlhXMa~ +@IkW}56tk=>%acsPtWE~veO!wj<(RC98Yd!7TwlUDk!HSSoKlpH^}xm01H +DAlTiH8rnaYoxw`0L|L^pd*jw`wCZIcWQ-17a&q(c@1}EYdEQYGo;S-br74-+#I0vo>S4T##>{JNjuBNt0UB3TbWPp +VD;j@hAiz-eQVkXCaQEIK0wTXv*i_XM`Kf%26h%Ha$W=MEDE&)pMJbTWU@1AGd?9U%dW4P7q*llFU!h +l3uw@fJ*QE--;^fwk-`T4vry293Bl@Z3NJ%Z+SUis+<^iB3ym+Fzj53ULpB;rxltCOuPm#)G>sGR?c2 +BhgyFCb4&`h}LYl_Wuc|qFUzT@TQAf8f%f(98(F4Tr@>$vvujJp0zqb4RnEEoJz(<8TL#exIZX<$Q(V +J*Y_v;T|J;y8l>P47~mi>6ud&m7}$K9@U{M%M#q7`u*xbv8cSFdaW2=cc}gTbP%`k=6Q>pG-EYz9buj +c*inbRc6#J|FmE_CU2k_N@*}LWX{2zw{}fvImx`Jq(hKmqDIkk{hmZHh4-C5TX%V%zCA&qek`Hp}n8Y +Mcl4^MpFfH>MFu2H|9MX%0e-j{0TflmHP7h;_4Z&vZszCo!T;B*p5)Dpb@$C`w?s>b)pc(g=S@c~QE;{$pj-GgfgPhL`rdX>m-7tnID0GZ=dkVu^ +<-Wj26zjJ8FP_QU~sOn2=hcED2=| +1~V3&kR*Le2}1LXi877Ooci*$)VUGaR{42NRqK25tu;q7;tF)43t1m*!GL+huG|8_sXg@zb`nH=5kW~ +?>9?>&$miD*eP9!jwz{~d(I71XepPu#){e~mFKlsnj?v9z?6}yQXH=Fviig?Ud9b>T3kq9xDqVQk-)= +doN64HLq6I91nG1y>`m0pd*<=D8=|0W;sNUUBpLQb*^I$;(YykYHVRK9{+z-7N?jkNrWoRPQf?D>LYa +-V)=#x41)rUYX^m!iM)9)xcBh(Xh$ZJ4v(btEvbg*lh>XNWi)LAC-Fe(a_Y@cC+B^Mz`6BMNOJD@U6X +N>*K_6WlFC#5QP$~PMvC4#;}-T`5kcED93-YKdj;6Kg4@NZ>De_d=j_QOuIbCMNs-pbMgHm!gzh0ybG +M$yvjq$RSWT7^_2xfKFDr%#gP1>)Ws0ZexU(h;*c_wW-aj>m^C5D=<}6&!!Eh7mWty?4q^4kdFM@u5u +;BrAev6s1oS?C;bWX +(k$ZN5g|gY|s&kb2@E)m~lGtP53*-R$F^1760eIw&KoC6S{7dP29>70B(=_=si3*5P5;kDM&?-OhWC( +0P|>j#Q4u8pcVx(+F`554|P+NGuu2L)T~Jf`Zth+t=nB6+sUC;l&8Ul15AEOpzidM%@UpuKC0dHp2HL +o8qv-@pQKPY@|=EBk`ZWjYDZ-xTID&uK@GA`*v#F0YO_YpUXK0-gv4&(G!1KIob*6&(~a)FoSwyb%ACDLE4mh= +*v6UTL(!2e$KV(^R=$`Ie}IG0utp16+ihk>27cP19)GQ2AFuD_5&(>e9o?div7DFU{;!ycBWQY$BDC^ +OwuH?HoDYC^2kQeWQ>Qd);+6T$yedk017_k%T+Vqbt~v|Be8L?@NlpVpwv?+h#;=h2T>&f&~v$TbKS? +GmsUAMox1A1-&+Y*8i9ctT$@#nX22R%g%$XaM0{XTG^{AI@2~%_&S{aFG`W-TkaS$7(u5@iZ8u08u*G +fc+Pq4Tg_bsxr-n^4`VMKcsL)zmA7#AAsg{YYNb@GPuJOh8%nG?`2E4 +bs`=a2THV^5Hge8Izgw{5^nt=Br$e1D&auXMHA!pmBn+5do6%bkti?q1)^7jUwo+Kcl&{m-$+-o}I*J +MrkI$}j9PX;3vpFFa^(iVwGGGP-A@AE7k*FDJ-Lbz=ym#&N`P@JAC3M|<=OD*d8uGSAMhMufpPPzL2* +d;{k7A4P-*-n%wUt*dx&r%OK?k?LX_jLjy+uo@r&nmD?E?B{(>ZNqGvr$Cg%?;OCHHhGzDa{fP1O9KQ +H000080P~d=M^e;8_>~I)05c;105bpp0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVly +veZ*Fd7V{~b6ZZ2?n#aerF+cpyaU!MY(Oh;6z(2kupt)`wE*H(I-y0*_&n(5>^G(h2(6X-6?| +!>@kN_#i$vx&YnVJNF-No*2A6PVBS6nEPQN>igW`o?k%dKo4d3wjxU?KS0J`?)|7w}pUD#?xhFf#*g< +%WtfFPGA+jVqeo(It~^xy&C110}W-LY|YWty=Mt91aNl^!$}lRh$+%D;tJ?o6W9Hcv-SkeZL+yf +-!l@*Frq@(JbXbp_G0oUUb|U%#i40R^oJSOLSadv(f+JZ+81u~H +(R*NW-)k+D@l)q;!lOIfirU*ze8TyPXD);xeHkiOt08|ZhVC7*MIFO4FtrgrSyfx=994m44LC4b4QG1 +;)8V1#BFK#ZtWE>X*B#YjolOaj;#z?I~Rq_iY+W;MYwBV?;4r;E;rQ^y5RGsy8II+%Dn>nw~uvN7Wb% +uQ%qA@XIiUStfQKiq7kVrv|KZ(Pa_v$Phu+BSouj;F<7ieybyx=L1DDpZW)7>+v0YLypyQ7D*Tk{9h+ksf`6mNi9=V9dafTj^|NPsmkYh0ahgi-7*2lRU5`i!ix;vXql0cZQ +#iuQO3r{j=>F(B`wGu+itkX0CEB>tH3UVf}_+n4gvQ?zO2!8oNG(M7us`L#TzF%P7$aqpp})&u;TXf;o6Yf*rr4&#Ln!>ED(mL(UkOYB4v4$7g3{D-Zl_q +U)r_CVKF!Nw$CkS(tvrO6c%WF-i~kPZ2fv5FiQ`8~v{Qpa~q*#>u~gmFU_$*l9`O6edwnY0XDmV8n(< +V*4)ScSjHn&sy5Jh{0%`EfcMlV&LSaXP&^K0o_;icw@7EdI5X;8Gaz=oX40z$4ZHTIVd-44H4W@CXJB +6YC1yKbH`HS-gzLVBrtH-rkPlCi)CKKqNY79+5CqelQ`@3iEtIPA%iUiGjN%6}!p6(Cz>1>gxJ(cA0= +}8U=W8!2N@4fj}MY9+A%?)=2z*#Xw8KBzF&FkZaIC4EQjG!EP`$p_@T`H=D?1V&`Qbz*|~K)@Y3+NnY +kENdVl%VoY98v6S%V#ofls*#J=}QRAy$4*M0V``vBgidWIlM8M%#mp!8v0I*E3mlESZ5W^7KDP#|*V# +taD)TxW`mQ9i0F&%^&QYdQNp>l)*ESUlUf)7Ja1l-0}#x_C2#uuD?N1}rVn*pA0`x*`c&Uq493xhPv$=88ZoUha-o2oA@(yFCFlq{IM~XWJM+BRe@gh}nZx&@u=m5 +;OG+i8TsPrE!p`aPj-VKtt$_^m0(aIvlhQ&J;OtB +V-c%p&)?9;6IFwVg+7n9bve`w5(^-VUnQy9!t{_t_c`@wV5*<&?X8xvnH6)f+)K^#o?!QT`-`vM%n$e +JtFI0gBMg}4n?!Qa{>y_ARO}u-4AnY%f^h5D2PPyNl+W&R=nL)w#FatM +D}#Y%mOYLx{3?(%q`LCY>0by)mF#a*vV0OjF61gmx7)2Bvj#lb%qqJO_NrzO!1MAl7=98I(ug(eQ6pg +|BEF};RO6oyI5=@V)?>594?m5f0zt~x?nj4>y}k-K2_H8n?Y_ulgXVhR~M+c}Ia)RG_0FTX!NPfn+Ak +KdiolG)i$)5~|Wrf_PgeLMlQGL9WP^Jj-Rou3oP3ot=w(Kc{f#$;$8!wHQN&>7vcp8~Jh?{$s`LP*Gv +451juW8V*)L*-14t7=*<^OBKQ@wf55JyUV4R5uv5QVN+{depSt0fxWVOe)=_T5@9hruYpa6ds$;q^uc +ve)!ebeN1u1Q;uCV3xNL}Sc3^RU}2ZgYv<^h<51V*j%Hib|7?r!UFg5*!T+P36~Ehwtre6>+BSer=GY +)Low1v9??lifcSpVHW4S)19;CXz6^wbEEq}P*$_g5uXcs6#G&zg;&vnB_Lbt#Q_t<+Y= +r)=cuaqa)oJtGnbK<5J%$rHyMTF}k)6{+GxP_abe8AXKJ!nI_JnDm^Q2FC#ewdJW{IzhUhgyt)ivrb4 +^g+H%W6n?1D+6`@|t?)KTP03brRGhUbF15vj}6_UK +6pdf!_K!*hZhj$*u_qAKz>G3p1--pxudBRChohiu~#O|4sX0pG@2f&&OloXdkcU(~=WOYr-y;MXSGoqU+Og&U +W%-#_jG&dbZ7K|#q>C(3nNLH{lzc($pHT?}p%mv>_eMJU(g_EdYD4(8i{q}?$eDms?M_K5qUDxA~;g; +b3^*ja<_vDKHlW+FyP1jzIb-mns{p}kqbO!l1FJwF#J_4l9t!{5lXtD4fH$uyecLM}?yXWqSDeRR;yX +qJZnb*_5zdO60o_^E~fZJm=nnkK@q7KkuW#O*)f1-Dc;2mjY4qeKmJCo$zmG`?(6CibGM9=TfdgL@RV +2#&2{l8WG3s6e~1QY-O00;o{l@>=wyhb?lAOHYwb^ri30001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L> +VP|D?FLiQkY-wUMFJo_RZe?S1X>V?DZ*OcaaCzlD`H$PynZM6pLCnCA9M}tK +YNF4D=!!<=}`KTGIi`~C{zw6!9Sd+9xfgJ>nM85NT-+eq)n{C_mnd-WxJ*oIh-LBVFvo>G#UYn0MMc2 +R^eR8tu+D)e0G2EvI?eiOquO2Xo`2v6c654pa?*GEi!3|K-tPOWw#lBHWbj9`{M +SzHl$qpJwQB!@52o3R&9>i9vu}5GeWE@u)wa)GQX`uA!VU13BL=|6(t?}AdgrvBy69JJw|StqYFVwS< +wf>m)s*cG0D+;9^W;_AXfwo^#(P$`T9t3xwq{t+!?#`Ax69xWts`poeXILtS4Fc{rT6qzyDV^`zZUgQ +dCy-LpWi8fU^vfb|NA>tlmdG1>HGJuyl?6ImyK4-U8mkDI0fDR$mc&jnaI|+#qv|JRyx7rUS6q<;`Ke>Z8rO7wu8X#!-u!tGy4ACfAC +k;!HQHFzp%Yum=m35e=4-HP|93m-iv`l$M7)=7I3{*fXk(}ZS)p!!~zBK(EEFtIgZB>gfyty+3z|fY}TWC*QQ!aL)YbHl~V88=@cqp9o6gVYxK +>1n2S%PXK=>Tp4gFBW--5IDmkE1EKF@IGph+sWwzV;$_}hqh7lg!sg>TEjETRJd)aR@r=BHB~>KkF}~ +-(+nXxB@~|F0J1gWI;*T{durew;$K%(u;G;C$EQEE)I1ZGq{{qsa$@_QWmkQ_t*gtdY?W?Cz|gBtfOW +vWuT+!Wz{h4;?@E$ET4_5Nu0E&9W;AE6`>xuKM?d{CnuLuAd1kal9}3W3fZ +**J&~?`}+321g-kZQ9JR~6ui&idjLAQ7<+M6-+Y^Q(2fC83?S-THjVpU+oSthheWJ+wcoAOG9qllf&04}gQrNdZAp(yAZ-MBnlkPrrNm@`q_A-+p}a@zwJ`y?XQP&%Y +oeVNQ^e_Bi}HjhJ!7R6bmFAQ&I$Vx?kkLR +v>kdVl;5=@_k?QJN>F^2tFy6&b9!Drr;akMf5Z?DA3m$nXAJ +V2Xcvj;vT+1bp~SQ}45zw);eEQq&#es8;Ky?PzwZ#fBgfIqZgKjo9kQ74jay!jdJNDnOQ +ju324I<*x9hoy-o2?(o;YvhsuSb#U7uR=1*v)8aqe +9>f&a24=ywW~b}$~K_=R6TJR*t@R!9f@+-=*v~MSP=7DEU>RuM2Rb8@Y4`}{%US2;ODS{B@Efake6_j +0Ifa0Ks5qh;(AM9Tub8Z`_Z)up+}1kU_lFUkbuR>dOmb$Cp9gth_|{}2;^YlLrWtLRP>H=>3H+(N7Ox +Fq*bR>D2rg^;<~76ltxoNd=y(eAg;`gwF3cJ!-yWE2HfCXb*fec9gC4vg`5Zg9&{bGT0s{?d{4H4WwP +AWMR)L|P-TMkA=^Y{ia>l*Fx!OD!;>QT2y}uiZUL`Ihk{<)PF*A41yXHG)SW}Yf(z)hCtLUd_B2}C4J +?!dyU-74y}PCcwJmD_c%2!80E;x~c!c^43~*WX^*)>xt%pi^vyugYTUb@=T}PlWJHFhb?m>DzEyOGW@ +tx?AbqRm?`4(+aPf`*2X7n`s`0f>GX;8o2Nk0s# +r2&l#;(!z=deaKK6p}-xnC&cz+dnsJNu}0HWbc`A4!2|Yy2$GpF{`~oiZ=ZgA^yadlOB)f!Rh?+KiaBsyBt+YAWvA +}a`JO-1{KsCz5%)HOhESQrLV){;k@dc2`oe?mRy(=$g%zn)2May@S%BS$P8$>=u-AS>Z@n>Vej|D9vg +O)G^+OiCah9TB4lhYn}XAr=)u@69@`S1Vnt@UqF(4p94N9S&v>6Z14vIPNw4w>;JLuXL$2}R^iAXjQP +IqGzCWW(&EvAYVPY@v{EcRd*df$QMIl|r+zL(!&zv$3WKNQNsRvr%2{$mx@9cik3jOr3|@Z+4rxFZ^c +N!?b~w8p&Is3wR-)0t9jZ4tI5yy=cgq{h?UbYJ@7`y6u38Z)gM918`xAOtQFc!HU?D=L1+}vEG03HQknBANJxnGTk9dZ;%r +Kf}KmFo6H5zq8aF3lDzBMl%h$0dZiA6Njckpn3H_IN`7InMMt7g@XPr>5r2xDMTY-4yT+xT8NxybJ6) +9hZ#7{^1?Or1w(;$bVcFti*<7d7O6&%-=s_$92TZgU`Kl +MSrY4R~t`>y@>uveFu101lHn@6{(AI_=!UZQCmC%RulKk;+H5G4(sgfN=0^bv0$c2Ce30&!gaAAogU_ +OjEa!YpI*!2tYLzGhm2mrtq2*f+B+lT+UJ4N)Ye#t@ +I+dW9V|0`3QpHRt(RMOw4e?5b`|Vao%2DREM4tz-W+o)n>QJ$N)nOFqZ4-k)tIzUf1mn@6~UIUM2+Qn +=9b)bv=cDM;MJ@^}8Uh=b<;Ezb|87uAJurZ9@$*08K*IWtzc$K*j^~0J+y7LCQ+YYu`!7z6#pvV2Egp +k0J%Yap`v;>U(0-(%f5tFldkQCK#G{xMfLztOXz*%{|RV#jbBbXsHGy)}u)_1BsvF!I@{Zv#>5h2!b| +bP5sTTXYa>;U>xJ+oA*2DUW4X@&=EOooi`w7Ds+&bN`+S4z(BAEBzbaK?&-vd8=&qnNt*j)J;cvZ>my +J)G40E4P{n*6ADx=dKi=*_-kx0+h$rZ+b&mX)g<|s%=AKiSonzJ`xZHIeA|v@L5OfsRDIAB6!F~aT=o +N54yR!vu);=}jYY_?*pR*P<`dvWP+#xNA_s^3J%y3N5Vp(*hM+28?iH>GewvY>{lKB9#0CKa%ByC4PF +$79z6PWKLsf-Ip4E{?Bn04%3I=Bg5q{zBx57uoru#sUgk%)v)ZD-Q*OxO@31@TZTzE<5Hm<`Z4tg(cd +_fs${8kK)RRzzxQA~y1bA;tq@T17kz5xMcBsB2QBf$=n*tIt{uNnCiJ2P9?nMpNr5!d|LS_zNE#J8A2f&cjf^q+xPSY^`dZpKD&6YIHq1 +)0+jJU(7%A+U;`Y{4g!SPOBYl`A$C=G@tQM=KS|;lfoX|3R;ae15b3YF_9lqy5m0^DfYLe5dY5x+B4eLw$-{qi_-6`d7BMo5WauKTjUTLs&u|f1yNkHzt%#g1@2fiMV+HNr%~)EFI +(2Yjq=d0d{!oT4VSyM_A?tQt#|6t!^dAg_5nPyn;ud8mSH_XTpg7ahYOG@YXznOL1hv&^phSR=U@HP; +7&BWDLyIVi}M)!G~19%Ii%&8VU>q$v-|f&`8Gp_{_Q}GRUIZ(deW*z&jf|5GG^hv0wp@CmwVFgyg1&G +N^hVy^C%5Pw_&g(mF!4A#H|5*#6Q`ei`Y}7J{aUs)SlEvio~Mm#*|7k4;^F>%fvrV!pm-iOW4O9g{G4 +5{;eL8K#)!cWBoylKh|?xynl~yw!!|}os8B&Oddw37Yil>LKp{0pgveRHP9i~=#?~9vL|~<8B5{{)Ft +xx1)g$XEO1zqyrn+(o#dx*u=K{~HEyfJYJH^kk!lrd)8jy>g=wi1WQ~dT@OJ;08Hi?HM=3O6HtXB{6V +s$38&3!5Jm8m(q&_gPnIbMROQrtIhwCI|Y(6llsbNGDN&wK-l)rD@Oby2u{scJejbRYhQrt^a6Ll-2A ++N)vG-Q#>YYM11%E&`xFe?ez;2?YRH$ncC!89A3aU4zQxe1DLK8$|;D}Sb^+imuuSyz&lfH_mBH^2eo +*yy?llz_-1gKb9BEb<`p$W9x1lG$WE=0vP|hzdjgRaO@%sf3Y4JXlcgS17IU1puRs8w-GOy|LM$9~{5)RO8pVxa*dlA+`YhuDP{qQs!b?0{}CD4OrAF!=K){=Hyvz*r7M+tVczX(3YO{jq{UQ-ySU`N(Z#_4^Qz!|u+q#TQy<=y-lOUSFzS*FeWB41eoG5PrODK +JJLAtKu2o0`?+~Fi+SXnU+V@F*nwG&DDCu*UeY@{q$n6ZKK=Rhp3dmMpHKP!NJOFZ@Ta>&DtmHBIp@3 +nrXgz8toy4;5_yap#;NAFM3(E>tIb7@yBmzdJ#IoE6>z~(u7+me(HejK{t6RHKt0uvx54f7~0Sdl +5b$lHLQ75@g^d;Vyln-BjEN6SoL={b2=E%YlrNA;h|a-8*d=p;~wMgS9iImk}?vllr(9^k +zz0}J&I|WVTDlg=lrOZO@g$U8+J-^o^_Q*{hhN_IVK(^QQ9mNii-uNKwi@t55Xh@VD +C*oi3}m@F!JbpO8LYlr<3aq5Iq1&GVgxfs_)6J*ajkF4*J!tgQBR;{j8&1ubuXrcjH=LcmAf%1$&WMe +k6*Kdz3)p0UZQi>ZmjlQUAJy^Nm1BVjS(F55wlt|lSV$>Eh7P<-})soUn8wL~yy?bd*D`<6Hm7zHgD! +MJ13v&+_w(`zI{$y*zXvuT^1$zBDF`Ei&*yP;l3rlgu$~moL;in%ARSE^ekr%P7&=#W7H86R!2cJCM1INtJscOJ!H{&sR4 +k>V8af645vLsTmvDBt%rNqL{Y=RLq85{epM2UHqClNX(X>sOkB{us(d%;v +Y&>J0p3_SYmN1JUjVVt{`u!)(x$5fb|UqQn2RCRI^Ws(7UQsIuOXAR~0BCNni9lznfz3*F=t8XlC+T0 +wC#jeC0FUlX5W_lb9m4b!=6Nipxnun6bffA5SV|Ka?1QJ6|mP8G${Uh?7Zqjq@qFup>qcFTcuV@}h1d +N&=3Lx^C4Dd$0_kNM3gEO?m5Y?;i^U_bU1UEL=osp$f6m=W$aL06v0*SX<)H +EYbHn^+R&37*=QDM2?nDisw0u>#OeQ{Pyy6YrH47lK;%xba^+7s(q=UwU;htSHiJz}gJlsR$70dt{*j +C)fEH~NZU`D#Sx%WKcLBVoHB}skWzyt8WJEwPlQXo)U>!v;8%>FqPZk68^mAaRh1hkt1WwXq`Vh~>7I +Bdw(N+AbS2)c@TwjYrUJj%64OT9>S|2u{`Ri?!RU$>ETtzjRCv1dC&ipEuf;4o_7sCe4)Q+H{W0FuvCy-A6IyNH-U=OCw5maYp+a1iuJp~mh&gldmZn@UPa*g}R7tWKDq~l%l4Cur)noLt3XKqi^U3a*6RI*u@j@gd>ET(mr)O>SdmF892wXg +TCX=4Hw%X|m8Fy}fyS}7I>|NU5*LZ6mF*6Q`++ox1_RSMGR3VR5#;sszqu`7ab<5F%=k(&!Hbdh6hG8 +X&^L#ffj1pyk#~YqgHub<`Jm7r$9VTEFagPac89_x|IeM!EP&Ln7%KE}$KV`FGRD6T!{rLYIqs=O%!4 +?sFV#gU^Nn)V$JNH%K@k^{3=C70*!`%`*%{>_P*MZ>sRx+-;aal{Z&ahb9V~JjDt8-4cLPQj9S)~uai +BCNOkfU0WR*#w5(T3$nQR4vyppOD4Qc@q+PL8h~)q9O{VA*T(=qDI~iP}>YVKdG3(%p +DWr}yFtMDG)-a~K3Uxe +s#)W_;Kb8;!-sYek#d$S#GV?e%l;FT7lY?`+>t11c2Y!&y9aiA*%m)lWzTOnSsX73%jQG8+?IP +7xbHM~vK9hO~kqe$V*!d+){m*2u9+CEBvIvs= +fvLM`$&B|!RCex<*u(JUzL5nm4YLURFUPFI%Qo=8#90TvJ^g(cx%lIW8;zgLYq|TC7=Z*Q*wHQ;65>z +N+GDOnH___>$_g^e(4+9=;ggic#5Fz3M&G^oFba7{h1@)7-PF_kjdQ+pgpc4zvEaxcud6a4_g9LCHq?Rw7vOQUsT4i++&B;*;9Xu|fr1Z;Qo}7ae>Bqgu +HG_fqX-toqH%n5dCfUTmV$b_?YaX>j*<7m*YSD>PCYe(#hh7{~ZzJP=A9m=1NP4EQfkT2 +rV5`dOGH^N&9vnhwtDKnu|B>G1=od&f1jwsuKNPARa^hxIx{nY;zKJ=6nEI&Bw5TJu$3zF`oyT;31kO +_&I7K$A~TDW7xnuSd3%1Z(+0OaG`1RWU#q+>aK_PaNzci~WMYjxq?sQp +KnnfAk$%IVMhOYQFYJVxdy5{*`SdbqOHj!?|HDG9516;9_;YQX2IMUh6w-?Cm4pk<(BER3+rvnAuz1%!zs_ER5*a19nJ>S5uO&z!!BAsaN&E(S%`u60A$iJ8U` +z#wjo@QT7v)@m`OpNeq>~Pm#<-b2rOX%hu50{YGeJAm!FLa#_EGx?LFro9{9;M%K7png&5uw&QG{|qd +6!rb!t*9yS-n-MSsD3d~sJ)px=)$MKgQH*38cM&h5t`Fy^b;MP1D&_>@!cy+kI3p#&Aj#6#ZxwBO!~r +bq>Zl!n#&Im+5N`vrS{3An7z576>LgG$FNgzk7s#ewIc6ZoZnuF=Q9%h +5Y?&*J}d(89>nErUcmS@tL4Bx!rv3&BhSX?KmGT)Ls-4MAu!Nyf?>8rwxDYEMR +1x!oX?w#URQd4E!t94|0=)YND+Z?dS$@qV`DlBaeGHWd24hac{WPBVumK(wdcix=QWrymksW$*e(v%&ixR+Gwo6SnGO6YqFEP{oIsHl@R$5*4n|d@!QGfV{4DolQsJz*p+nf?ZV8XH7 +`C&^14Pt#qCAEdkJR~8~ICn_o@CklKrviJy`!y+d=c&E|!e2^myBxh_3DJ+;WG0&@EaWtGqBNR>-mnN +uXvoxa9kssjH#=Yy@0TYobz6g;LQEdn1jT)^SO!x9&F_-9<>mZiROqph(%x|JpAoG7?}2E#&0{dRS29 +nQ-tPg)M!iZ#JJg|F=2#(S%G{*1l6QfGKtGV@bh_Bab%ra}kMT}kd@iv3%dchp=9_N}-yg!Kkz6abZr +e3Txn;XK_ihuw&YjWZOr{$JT7X%Yh6V+XD0&uV5G9FfFH2NVcgWM}$tBjphzzJ_sKR+;95=-O0Z>Z=1 +QY-O00;o{l@>=HHY}u+1pojR5dZ))0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUM +FJ*XRWpH$9Z*FrgaCyB~U2h^c6n*DcSVYkhiKP$whBo_9O1hEKGy=ALBxdFUR%Yy}Ka!xT{q4Qi_Lvz +M67o`{Wy9FM$3FMm<2${J3-&WNz^1PmR8}ZydcCaR#<1^;#luuH8H>KV{B9&Q?2Sx5B +Ve<*tBH-_NWtP&3}2TuUK0gZO_d-b;A)ZnQeygHlD4pIx#+JL*-hfvzEU8N^i$zzcSRXQ)K>R +1ig#)0Hw{Mrncu>$D6TTP{68%jJ*_?v;cgqwlLk+zkG5U~J$nvG@jeX^z39aLcy*85l-Vncx=L{4u*T +?~&;AX(n+DiNx>pI3XVL*yiqkpswEFA&K+(-3jr{xbPC&f}~k218v1xWJncTb5R&Z%9CCzbCxM7AtS2 +WB99u^>UDPpj@?2d60?e=O=|;USLk0LQ#qUwn>(vYZbgPf;}Rlq#c33QCQ4e6_VZ#_!D%Qwg;m+fYHf +lURRWbJ+JJ=D3eSThTV7Ql(F{cXSqJg{q`_2ZRtMH_F-CPuUg9F;poPm;&N5yIzjadeif2#gIXRkwDl +0tTN)*EGM!iWQGAz7q2O^jYb_aajVVb}3*BMwHbJnc1`n3I{#FhM2l&)mbl`GIptx1wv01CzUN`xHpQ +PBFh;+mJf490BH&U$j9v88l`Ib*-C@#DX!;X_faZhH->I*S-V~%p(k8lENRoG#X6;NBWqR#A!{azXQU-E)5$@czy3&>ML* +4DG+@cySUmzH1pf-R4v;}1@T=OJK1u%f&8>kS~Vzf-@;h$V07^1l$e8zhD=@8+e^GHLAVqC1 +bA_6as%}51>tNhko^27Gc#v4vh7v2}7PPPd038yw`iTe}P1@Ssh-55C4<{^IgKx7@H5;QY)7?}E +KksBqltAG~m}Zufr<*?XN0o(aXU?+jkFqHnSv&Nkv1XOR|!tekxd{()-~;g5IJg^eb=^j3%JGolm)*R +g}c~T)6fJz<+()!?Dp9k3>u8qN39*TUiAL!MY|zRPFe>*j1+5M>7ju-;cq{P1x`svtywN4=G@;hG +L~b!ca5v6f^G@_I@M}_VlIB2-cM(@ljU?a`+bHx`D7KUmCIcU6gFZ$`RVhA>E!mNbN=6C-OenjasB6b +b!yE4D-t`o`en26;#r@Lex@q|^jei9EE5+p|1ROLjZkA9qPmrSHbh6Pu@11i@Jjv^ZzLzt9PrfuN5ac +MEVwQa&v)2$mE=wzfHHoOw<=#k&cu!ym9~OVNN=3&q2LyCUVZ?PUUpC{;l)SEwb(cvBq)M;^JmmLU!h +kj?`#pG>&Uf2?-e#nPCh|CXf@(P)=|E3&HggLb7o;RNmS{a%uA7c@qs0Y`{CA$%YRTy0|XQR000O8^O +Y7y^G0R)1qT2C$rbqUqN^XByWzoCjC&j5U`+2w*YHb^yR~l1U4;E4jV~SMJkOqY`=YXBqfoOoOH$XB@xAY +?(N~-(Y&Zctq3b9&!a~1T+X;zDtN)vzG8AV%W6@OsG`X&-7!h*2FdSdvsubAvTK->>qL}_m1>PbVa9V +-(t<4sY@ki9;(%6F&J(J*D4&Q#F?B3e&1exURx<+6d_LEIe?c^&ZWx)rG?2$10CG-5MkqnxXr?!=Dq7 +Qmw5kjWJ|94~T_s8w`wk#Bl9xNODnz>4bS`fqSAq4Q$G^x(DTY`HEywFKfWm%IW$Y{GHUv7AE1Agvq6hZ1xUTTC=l*ec9UtU}o8|9MZ +{MO`?pzSh({BjAXc`m+4^6u43a&mI|bV;bx0J7NuOBGAWc5l9(K7UT$Gvm~==$TKSF?BR;fEq}c&fq1 +wu4*I;yRQHY@F75uabv6~^S#F!ZM_eymnM*_THNsz0I38mP016HGOKMwnNnar_8|n1mlhHuY~F+U)zw +vfRknx9P(vaSV-g(6czz`30XZTb54x?Y-uH67Y{W`5DGaDgI1l>$>^@5_Of +K0_iRP}+<@yOFCVKnF>57o=$lJZTf&88HqQ>{w{OwF^RCfH_n%M4e%A4J{uCoML6Y4EXGARb}`aV9A) +8Vp4>lHX|Ne(`eckDAzR=wgZPeZZ&1UwlWvNMuWMO((>af95|MvQDlx_8dV*Ao@aLyM82ZohtkLSGP9 +o)|AtrMG)rlFmvZDm*+i@5`!X@nNmz#LH=zlqc#~pKB8>G#8s(8s2r@1L1Izmd9^iD?`O)PTjHEv( +8L&@@NNo>~v50{;_@f%UXqSc_^ob!Ql(OP>IYw^LC&gZxT^mpit##*QUp>-)HfBoHk;n_Gg6A~Dr(7r +AV5q{Dn18&@iv~wSu^IA1k&SaS6a%sXeuJUf!3=vlvZngQRsq>s~Pa`cUBbUS*lF>wodav~mk*CnL_f +U$p#xYm%dEZnxAV?%R6tM;hFSgjP(*{~Ppbj1Bam)6WvZgRfa`xtDy^2ZE=0xCB_d?)I^yzR15>1WQ7 +q8C=cGZP-<;xALndVvd2_ag_Mjg~Epd-7d1qiKHGcScfCPc6z!Isv+a`1)TGPD6chqz78G3s6gP`__-!xnd5zwR5f%sEHYeT!aq&05rEB(1&L#F>VL;)$O(6XZTp +HRG;UpEm`Oo=2IvnA%}#$EDRhbvma*9b8b;qe^PKTOA3!r6!e=NVp;JQ!m2_;QCm$8S^K}7zoWr{cU6 +W$>W#JlN+rNV|>&tu1N;|zOuf#u8+?`Uy8IjEdnI)_TPXxEP#AyQr^HL3=^_nM)AiXiq?F ++Zkop_03Pj8MJ1gCKMdh8Qwyy7T6!4%f#!DXnSG#2x?7fdt{B$JX}Cy7HFQoY=EY$PUN~CWQT3f*bmvV(D`+@rXyz;TfV*5Amx$ +m638GJem!Y9x&sK|J*`k3D5cHkiX?_l9$z>+Y=^=V3pTpE{)6oxmFz&2j6w&LGv|ILU#Geb?_uqv1Q6 +#wb;@o0lkURWQl-;2*+A*k*cI%S7qR>1R;|ypA+6=%IXGQE4rx$fmFWcqo#efNxD<)<3rQ?NXm?hH4d +Iv$@_YS-23mo9qgWesq)^*F5HW%p;3H7p}q2BM%aM1ls)oj~d+VjC)NWAW-mnMB8eQVDxS%!BQm!Yr0 +2sy!L2rpD5N;><7ba(EEAZzX!M3`0zi1P_z&zHmB!Jy3dRt-5mcW-&_{qcd;>jr7uA^l@Dyq5O2+X=u +nmJfh-XLA~OGW_1*nJfm^IAx7Vfz2eqhH;EDSMZ+ze~6vpc@6aWAK2mtey7DsFm5gCvDnpY>}p=zVGh7yZd|*b)$`gQdd~oBv~0Cds`K4h@_~UQB9z+cxQ>b*tH +jN%rIHSCS+ZuAp3NZE;!XR#n_=(rlgpJtrq8;s14O0PBJqZmm!^ax=4(Pa+s>BrmZ>OI`fN(%H1DZ;#M|aNHs2J1Vb3uq0T%wT*9t1u3ipy@K?13U?W}mi +SuWs)9;T+-Z3AAWNv=Ixi*FH_!jJMoLkf#n!Ujp5`%4Pec%BYKe7Rl^D5BLx#vWfM^0VIp(XQzj`PtA +W&KyV?Azw1dH!&H~^tQ?4S?RPe&TqVd0-mh!JqZ`8fX;wHtX2lp(*cdEnVAXsM +Z`u3gKSTV!M&MN?oY2b8@L7|An%~ld-C9^!wW{>aA(}3%mgtbdf;xqqTGU#Exd+YjL&@b+xL=EM9c5~ +tFAj(iUZ_R(a!JJ-l*Wi&AO6kDF%Zm`pXZ%(p3?wmkI<|Th7@mnikZ&=SBtAlPp;-JwsKAgUPqGKHhdbzkE@W1+BO_F)91}D8)xdv+v +ZxVKxx{_4VHoekcx=Dq9P3qQg1!rUPuWA!VRh*@T#kJ2o#0)=&sDidMI?Yp`{Q%7HQUtWXMN)_cPcs9 +W3XEi~ZO>`OnhrNwDxaNsDwco1NO9=BJv#DWrYutQVPox-U=a-LmKxVlsoOqI7GzhG=Y>WrItY{CP)< +`5(z6YtGxIMBMEyw-~@W6CfGDE4ZL9=RG&1ic;4NccKtdxXsg{{S9*X;FfOF;9im=g@t5Ktka#|b +=^s&pGR3jhGVBme+30001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFK};fY;9p~VP +|D>E^v9R8f$OcIP$xH1(BkVTqx=z#qGj?3-og7wzxJelI$H0*+Qme+U7=WLLQM%d%3Mjaxx+CSvS>=v`ta)Wm?llFv2w$to>f`a>DL&R!j0u +t)4Ya)yx9GQJ{(1O|!fz3YJS=mBJpmU^y#gvHw-D)oE2q%1hRm^LbU4`gmPcg@t%~b@l1A+xY}LiCVi +17azodf3oF16Zw|ym^rFh^ND+3&%Rxz%}Z9)ut15a0Ynjj+E^#Q`@tSqw{vRWDOu3qL3B +IDQJr<8DL{%#YIk=m7)Sx3r2*595yacn8pvzt3d!|Tl3H(S?a^2R2jMo- +K5oI_dd%8XD;W*b|bLpeaM!**)FW1)I$#9mZF$UXh(P957Jdj5?LgUrdAJc+h}Y|Bs_z&aTjM(Pw5)p +KhvZQ!pTJ_cZ!{fOnJ^-;Q8Uw^cQEdBMuq!YbC>_KQj9Ch9@O6S(TUDw$qcu{FsuUUHdbv0%kIaaKKl +{w%RZGDnbvjOl;s3?OvUw1?QBa^&H1Iz$Kr4i`fp?NRgbbmNpfj5H5?z#r=hV)(i(^Lasc%M~T{jMQm +fz;ZmD`Vxa%Sz|c!1ONfQZAwLBaQfa81LUPl?rWx>ZfRkbmL48083+kY?8Nm5QwXAeLkmdC;7$!YZYY +OmTJ9l8NT7;?^SR8|Crm+ll$GpGNy?C>lL=_55;9R))uYJhhOJL;06*F*es=z!3bxg +~Y(dbQ<(?3B?Ec(TEQ=CXzGwYO0NqvRl}ZUH0S(z@8W+>;q%n=L#uvPpEINB}pgX^B{N##YHYiFb3*D +%rw4eR-lw(y=0`BFUF)p8HYZ3qY)@(AQ +rt#(x6ibIx^Xcjw_<}kmYtM)DHj>BeIf$^=^2*AtZb-_1V=~)xx#$~H;?cMn$^B6l;W=YrJ_sV<Yb +)I$AlAh~;{ljfU@Ky=Ee>V$uv}j(LLvHgj#@yfLp#(lZ&=O8N9UC~PDIUezUFL|9(mT;)yn1pOkRuD^ +IC{ebNvOoA)#0e$2LU%{A?QfIuyZJ43C6RM}VrxJmV;;{3c}W5$XV?8sagukX6N$T6R?CTZr>qNUR^L ++AH2Pn!vPi-vsN>K+*t8wN!JTK;+nR7sd;&J#iQyybv(y(e#1dV9rq0Uyl& +*v$fnI9vU)M#a1k#-eWmkzdt2(&*NYBKfP73?E$YEG%`pmftcn_lN`=cd^+IKv>WF57Wt-{;FXRGp^Z +=tjo$-|(6Szuek@;2AGM%FiDHlXRsIaBQ0T~bb?$q4A2%~^5A)vIWgg90)%aVf4H_ugou1ctW1QaAfN +!)Y>$8E!dh=p~G@gEg)F`{}Y&~$fp H{fC!A~bSbK$m6&l_h%0hSu~H+nhK8YTI22#sZDW82F35pH +Q#*0_&GvwIj8rqxGTS~!9+hpx64(wbRw(IYKk8ea`+fvXDx9B{F)l$j|lam2WXU@ +ojMUM$38=Uq^QIqorNBY#N0AaB@LLQOJwpN+4VFdu*GV<%idp*9fIB~A^AmwJv83zHPJ23TcyLfX-et +L28JRz5+EBRacGJWZ@)3Gijm90Q6o;*7V`7yl@RP)&L2brni3@dpk+A$YLW+fU(j0-y#iOrcrPaLNM( +HWF#H&spqU5|t6LZW@}IL0CK0d(dmYCWjfp00H@NFR2p4M-j$HSJOct!kO +AE%VokJUh)zMOw9Y8xPa~+rOrCieRB1{APpxPWy+fxEsjOdtC#O&(x5dgbtmLN%>u}K)KugJUGl>WWq +QR8Vj{a=k4lKpa7}2Z>)o-0VfARBR%K02qv=Yp>Pe@;U4HmzayiBWRGdAJWu)X=_^YD(72k#IMU(&q% +DzpR@L)mm_2s=vRNpA!@GH~ro|H0YoaFiLC{KErUKU;X2!n=7`xb_l9cNWvsV-yGcdCVgWYTaIH8#1? +|Dzm>lhjnmaGiS}$RfyfmK`OL*XnOg;YwmkZy@nWT?Ss43DM&VTK~Z>EZ1x&_T~!hvAG&|6>$XJKZ{l +d0kl%tUqH~~I=+eaoQah!1EKtTiN^hd!%EoywG`KBmBKAo44&mg>9}d~ja;~FHLAcsAyyGxLHmG`oWs +ifl##H4+qePvbx?c|hNx9j+b&mr^|6?a^!OYcYakM5q%+Dwp1IO@Zbc4p_2i)OwVR|NS!QAQ=2Ay;!p +neZD>4qX?yGlaL(;J!-1ggAk-vLgTP^Tt{zhuW0~%$U*hugQji0f<`N9eRD74Ub7M5(x9o=V5quEju`3jZS|cC!VoH*;rDTy}|i?oA^81W-!@1QY-O00;o{l@>?l-NJu>2LJ$f761S+0001RX +>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFLGsZb!BsOE^v9hSYL13HV}XJr#NH}vQt%k +*qZ@k2-0i`&@@5gVh>GV(GnfAkwlH6;^`$lw{d$iWU=sNT$g9f4{qvR@>jt&ov%-d)sGG59`HyiBRMP6rGAUnNSNtLHev(ad@Sg$Oa);0|9W8LKMjzZlEqXP)SZ73k>b$lOn5@yH8-yg20INfdxwz?|n5Y}S&b$#~8S4G +g9^(wfF7x-5ASLvBciP}RxWkYg20&EaYMuT}T=D3L{hjD;*pDYNK&KEFQoOV_v*11nNHH=#sD5qd>_?`kXz8;vN#2=du93EpdZf0Wk(;ZQ>-aJm-`rhR|j$lC?QQN1EL$ +!L!slgeYqXb;X?wHzgiji3A<84egRMQ{;{>oF`GK7(``ctaxEaxh=-j7*K{0N~O3VWDll*ZqaKFA3wZ +&g9==Kq<<&#)AIx3dy$=2S+NCtNIUKcL1@^BEQ3tS2dGPu&xT`JDp@MQG;h5}k}*x5Coh65c%u?q%0 +~`*BYk+Fr;)EE)=}DtdQk{1SSG%31*kj2Q(RS3r-xaAHD{?=1b3a=1tKkqB&$=7vTHO8%HOyngu2K$r +m#e&s-Z!CfqQ}Z>WT5EG82i=**5ZNZ5}!?w`i1^q1*NNQ((g-2qC~2q8mjK-LJ0a7gz6Zg1gDcCB+IB +3xQfL7UPO%tFRGe_8!ePX_cavQ6uKe3yg02`rOiTxZy}O;DM_lP-q#VeHNkT;5FVs#o1idc&J6mrL2p +TsqKOD$Hxzw$rRu>I9XO&u|)eViV2K|_flUpkjK;U(W%2i{-j;f^l=qgTg-MSc{E_zyN=MKLV?^A5PK +kPkTg2#Sl$K0K5N-L-DfY<&kR% +BeqG)rB|&^2FUO5-0xi0)J$vm1|MZjxw1q0xy@#u-Yl6(+Qf;6g*f3akW%9br~Z# +k3N-W>je~sSw;V4wWXTpn5@2?vR2mS<*gA%oH_-lzc=0ATjMKhw>g7Hfvr07BS3H3^rQ=5!yU4XU{z) +AUyES0CXF$m^&PeV@)78g1?QBtl}@$guL*pRQV}gc9hwLg|6klhY-IU6FNEH_6VL9?Z7jUPjpPkRh^kCzT1 +Cg0{ISFnGm>6_6Ih`t>xYKDDs0>GYI|&;8ojNkL}hr6uORYs!`8wFEhFck{`n5Z+iY`Yudr6`G0&()_ +A$Icl$o)YftfS0@gU*YZH`VjP78#I0=b&v5U9O;Lr?H(ZMMycEYBF@op09YE`mrCRw__5MtrdRP1R`h +~SF4v<)^7`=yC|JhnU=s{TZPpd-W(C6A(?9%t%zCN3tq$!1_RFN@E_lt(XQb^se&_RVh +VwEh|GTXMz99wZW<4|Xf^})8GTI5ucrHtSl3(_N3rt{9(7M4inq49T1NZc35(-%jp_0>tO*B$Y1ur^@ +@r&-LEV3u{G&Ue;S{2%!C%_GZdD&q=iS8($FttUlqNkLs>Hx|JO_#d|47}M_psf9ox5W?lf<(V<(1nf +4nmFmZV-$EoB`6Bp}>hlw$wr@He^-|JJQ8V~D$kbpZWiW+c$y6}R<6woENh0EwF>R&iNIz+6&YknkDC +=GYlRY%h6Pc%hd^$7?+_f7fSo>Hyp6sJS3a1@1UksV0C_EXr=Ba$IxCJ7|(f!TmlHc!@yO87<$Fiqw` +^K7f$8yg**nxh;yfw3;@qY-V`ApER5IGo=b5}xPqVyuHo0KLdCSAwFvZnTwzAfN1V8LT)Fizwmd1yaG +Af=^}n+hvHC)RPe;I_rZIu^&SL|~B9Xjjz)0X#Lx2EnN{!RtA?B5>8jjJci~CO8hPYNLe4o%l0hE@xA +YKEfDuy?DAsm9cqMnD#P~A@3XAVa#d|vU8PS#yBDxDk- +M2#e@crDDm8C%Jcs{=iou}^=wvS8AxEDb$AIkyh`8T%SwJUsk~5VG$yS{8}2sJYijLkNyF$Zlyhd#9`5$zvFWJz>8W$)*O}8Io+_KmJ|r{!yhqO6c1!+2^cJ?5|ZzU#}@=XM{fBwa6^Xw(!?(2%F(I +c74spYvAg5K#72+ax%-G#%RS2dl=TXMtCTs;hLvI9Yt>SXIsoDN_u^{M4rK0J5}w3(g% +2*@iYZ)iY#I5abv+5I`LsqSIk3kFZG5%eLCn381-7i20#Y`q!pM+Kzt4ipD$&#BuMb3DZnKl9w{#wpp +pVTK&%qL+zkB)2fBF15x&uOCJnyGHSv>XRSsXdCV;sDb=z0!$#U}cC#^W!alEaCs##tsfWP6-vT78m8 +mbFAc7SU6oA}(dM{7hDQp8S$uc +b(U=vEnp+x$SiB+>^yGHFGey9_62k&+OVY%8%K&mN`)TBMf^x@{?caOKg$Ucd +xo2!PWTZHP7R-E#lXQ(z?N!U*VF22qhX;6nwvu?1L0bPc2!l_k6oBYH=MV!7FgD(G#n28#F8}YMYYq2 +TenMrg?)tBObj`1JpBkg#UU^yzJuI)4> +424X-I+F-VP(h;bAH;#s)=8}?3tsX_~gwwzp&$&=1&eL!~wj!E&d&Ot=Z6n_;WX#D%ow{Wkx2#WyC|xZqZ0R{dly& +Y^{}a$B16S=uQ40vDU2e&>XWjd)QUg1bHQLS`+P1cFOcU<^ +s~J^;(W0FM76oecA48AE_JO`@!TSA1(OZLToz#K#lR;A}ap#$IM?7n|eT3Jp{QY(I%}Agds?Ci7J(?@ +ni_Vpzq@AN*}}x0Mf~Uy=xHqRA@p;U8Sc-{ol#;`I@K!#-g2jLAvWB_}587hDw*>|CP?h|R9pMe?sCS +9?Dhh$M1Qf^;slwe4H^?)W=&tWutC!l1=FOIj4gsiX68h4zC?L)mOsKo1y0@^26x76nGo;PL7C9#oJ) +`jc~&ux~k-9GRn`$0)V4)3A_ltEQwZ#Tg8PGXPs1ARiKXGhZ(KV3r6m3Qv2t;5cka#?gfGEgBP%tY^% +nz9O5(PeZ`pz;S!gCIy==S3YHBgg$R}ghLyLpevP-jSA9nfte#$aa`Vj_GvL6q$+4Q8epukVUS*=aE# +6&co1bRwS30N5_Y=(aKnCkd3E8zd$4+am0Y%WE%ZeTJ?1e7*;3qLwkqhT1)qT@$Rw}*jhw0J=La#@(1 +me9p`s7dug91*UJ0ciuFqIrH1);-J0e6=y&xe{PPgNzK8QRyx(XpltWOzeW}$%?7we!TCi5O*1UaC4S +o^Y7uVB@SRlv#JM_ah=>VZ=%AoQ|*ua-U;&@;M+vjDoAbpZz%&HgTP_8Ulku$(g*!pONq +1JtGaQYRz!n*lvDCZ>Vm3>3jD0=-rut0q4sjGzJ@vc}bW5yIy^2!z#S=t#RVwDF^0(v6n$t+x4OFLJU +;W?=Wp9Urq?aw`k2kdxN>#wrTN2pegby4Jp8Jj)~+8Q$d@U2SQO6|?{~u;IwtE9T!KD!E=|gB@OH4_ +zWd*?d_UbU`%kL>`B8Vh22t21o{n*47X9Xa}s5_`)9sSeQ6pC&;l1i<=kagXNw_jfV`|qZJzzLA15rTFFV!brRWsC{I +Tw*w0qv670LeD<*L4xT~TYRx)CISa2)cU|pj?21LI$C$+B;XZ24Z&&~9|j{8!=nMo?cJZhy`8hWOi;w +T7vszv++ObhQe4-9>JLp|v=D);Ew|V~Xyi)@k_NryWWpid1ZRk@nHn6_46&`PA$v@)+23~3)dFVBghO +LoLlY(7NgJK`B@2%!{(wa!Rt_0cTS7Rfs7BXfDKMEYr3xCmcX}`2L^`nbS1~h6rB;RtXX;EXreo4YNt +LGwgm6aTb4>r9k6K(hwdO3Mx!qv*sHD*CZ%s|mP;XJBfc_Rv1=Ti7CbD(>puM3NW~>m{N8-Fmcn8bAU|1P~?TIQ(uj7c*JT(i3pBX^)n+*6}2j$<$>G#TG?c3`EdCs9JCqQ;PXh%np0 +E7li)9H0FcB7<#F +GjjiylmjhjX_SxGnqe;+_eCM6(p~4Y&ja4kno1hoN42Ee?1xdv_GS9ZPTY$lY$W_ZO_;-P!DT!?`bY9 +_ECm~z&6?hHUh9Cr?yzfCWi8_aOXnRwHI6K9?xV0~NUV%_UkAUHJiGLK9!h1hqd<_|PaV~${Z +?C~%yY{)rrHHn*|o-xp%&pvZ@W%0B>a_avG?h?y*Y);_gMUEwNZCN*m6h@0fIM+gXL^naRlW=tqg`h+Tj?i>G7iSvRf+1ESJOC1BJzv7(2T5ze=|C+E-npB0q +Bo0p9!cm#aCZHYR+(8p!&kiGu{J&bIE?%t(=6xgmQnRU+Gq(WQN@3 +MV2!r;dJKt5x0b39`g9X%)(SmvoOHQKLLWR7G&;I$LPskL_OMcEGD$+d1UM!EToldJ9QjIz@lFJM8FH +0IyQl@X0SxjsDU{aPtLGXj1SnHiLY1RrDUiWz)6Iyq(g%$DQ*wojxVdNzE`8w^E*ne(O?geAv1tHDcC +N0Kc{L8L*UMLSE`?rn0z6YW)F^W*azZDwhV@Sp?g`HK+xYwAv6QAQNrsEK31m+^ +lvB{aD_M;EFi%L&8QlFyEKY?>CtDnyu$}ViDW-3VUTpUv1sF|V;=#zQ9=*U&i~C8MLp& +dC!StN!0d@>^IJOAiO@N(68aUlG;;L#OSMUi2El-u)fv+2R!M|yeoMtjAd)tSM=mo)eNymb2jBC8$%< +XUnfMQ`|RZOAme;TQ9JQEBI4))riUKW_4q;CR3ZNlATsVg_*_)Bhx(QgpdVJ5l?$B*z9uAAa0_(hae7 +bmo3^~1b{@FVPnA7U`tMP4Vj*+C>I7H-z7T?t(8-^LyFCd`L<+_2$34bYM)?-4%&HPe3spY+F +-ohV1*i5OdHJP6u4QDgF!81?6qV;w6l_GqvR&2|~c-uQ@b`}1!lVGdy?;&P*JN@C}$4+AX()(~44wPk +rP~g=s2c6*m#u0+s;qO7-u)EUCCAo2~oh@^;9W4knSC#4&-a1zjZT&j08dg>aJzvlp5KUnP-KFyb=O} +D$)F1gf)p~F*wA^3RJQs_$dFt_Q8WEzmCH;@POAqGdl+I;UoBrU<{hvNC+bI*Ee=a{qSTRl>9cv`Bj# +U0fe`QFonGuQ8JLpdg_w3&}$30K;g?1d`c|8F3e?|14#OYTNiHQhyFo4ki>;pUv>1QkAKa=)0c=nMFe +NkJUc*W?!tEUW3P8UF;ermWNHe2v3FAAOP3Aas!d$Cv8HP@b#M;}Jx2@)ef^J^o+B-eN_b%6$>fTCK< +^yJWPEV3K^wskV{!#ITD27+V5I4138!)fcedu@zhY^xy|O(UJ_pI1O$*cxqv_1g&rD&uc%-@PCAeViH +VUeWJXY+$wSq)VX!zDIGCsC%ximCFq_s30t@jAZI+D>l`h#6Uk$rk{mTJx9rBZ2MR*$Sj^;MUMB7sHj +uzHSSFv4|O+|$Hl^@5MCsx83uWHt$moSIQ9K{`B-U?w09|3V#0~)#(s3!;YeH*`c#Vf$ry=h#DkqGt*~+|iOky54z +Be5WhV^sEe?dQg?{%{&Jsd?wkx%?U4X@W~Z>*2=zfem91QY-O00;o{l@><;00002000000000v0001R +X>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFJo_RbaH88FJE72ZfSI1UoLQY0{~D<0|XQ +R000O8^OY7y2&0?NmjwU-n-Ks2IRF3vaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR +LrZgg^KVlQrVY;ACFZ)`4bdCgZ*Z`(Eye)q57QUsDZRk7Fg#egsbnU@Aj)1q1?x+MUAAQX2 +bsb?nud!ET;j|VVGVlk;jjB-`#zrkB*K;SM$qvEH3p1a?O)i^L)(;Au^vOBG-~HOARSoJ}{8{E`b!J( +lX9RqYI@Hu +@L5T*H8??%arB4rZ6Ty)Z|Cz5*JmQnA<$PU+WJOcayIU9{eh|Izk(2b%z-a-_4IG1FxQj7@iFLMt-c{U>Ahkh~C47Ny#VsXv}ITJa%$Hd +UDSdm5JYqA41N!?+Z7nN)f6Ww))Gv(OP6jm&Xc+PbcxeBtC&q@W-XGP_kO%dB?FJrk@`1A6vqPN=JuF +Le)=8U7;467zZ8b5u!Wath$k98x_ZG4S2nG{lJbk>#|#Te{>$OAH=Ri8QHRI2exieK-%gJru0@(_YvQBB_P(@T$rZzfxf5AS +0B(g2JrbaiIa#U=$2+90wK@BP7r)0UfaOP%^VK=JA{~QG}g%NCfRSy>$Y5!LA`sSq^KVxfQ1^C>5_^5MJv!1?Tp7bxcYO-$sRlL;^Y*(QtG%JAXgFIGxX; +ceCs3)AO0zZ6MD(lwtqdp;{%dryq6EJ(hTaUiIB#m`!_FV))a9gjU-BNcl9(%pae}t{L2h- +pZRv;ly@Jm>=Hyw^#idykCOJeFV)8Xv7dhJrl{z*URNYqH`x +y%`)NELs8PoPCF$q!WGF`i38^Jm!WXL}bsnayk^*mI&XYyu?C$rdo6SYOqqhfl{cONhv$rLr&B>FRbv +R#-95@GZ(B7sP28;h%xY|J1YYDoPxv8!8#*MW|2V4DLY>Sx|sn1M>E=Bqf_R6&WLLkXOg|CP0DIw(&y +$I*BL`$R&q>dE*OEp(K8tz={F~Q9Z_2B97Z(LtZ&`@ +6aWAK2mtey7Dqx+F@<#u003?z0024w003}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQb#iQMX<{= +kV{dMBa%o~OaCvWVWo~nGY%XwlwOMU*+qe<_&R>C!=SGxIX5ysnOx5ax&ygqU*pg~F$z0P6O_7j?sE1stOiK +rcwl(0-HQN)VzOcJ&s2VRgTUZjbavIj~OCy!LH&4D22m_VW=ZcPyB}wQeDpEyKwic0KK +$vjvG~?p?Uc%8oHClJHqqPQ%}_ImWOm-+5d3- +Qc|XFQ;wUS{qE>rD(bO;I`+bz5QUpFZ%c~XnfrE-trX6jJT-Y?&3S9T7t=VJQ5onO6-gr}F@%a8fg-F +3GZ-ba;O0acM2?$vB6OC2KGQ~qnbx$^e@3o0bKgT?w-kJiMsCL5FPWloAr;@Vf7APWZ_kq=1?T`mBSoU@KseY(5XJVC)Ux1do~O7wz=aVkNg+}2{e7wN{ +m6nAWRI;ul{k#`5B#vb4u_+5s0jZjOZh{+jy}gUS7fGTOoia07Mw>?dfptO?qFe2KlBwlth~CrUU>l6Tu>>|5l#*uzND1gU*67crr=5iVRs)6LHf)ll?Z?fkqjo?ux% +k|D_ck{&TbGk6SEv~APWGD9F=zSBvpE0<@FvPy_;TLe7L>~LF4dpwtPRm4XeY%0$hYA<+S72BB +^K~{bu2I>jAg&ZMtdOykHm#w>JZZBJmpM5S{e)no>v8h4spmXfsg}qt +!Hn9ir?`fq>x(qOV#X$mIv4n8R@e=sLS7kC&B$h2bXL*2mtPu-N1W)u?msht6chbb8y +Ozn%W$!|ZnY?kIg##af^5`xabX%&x=P6)2|HhA2Xt^++Cty&|@C(y0=+dA{;Ij|;X9ksz!wr|IpbA*k +afL_SX<%0nBM6DO#G)8v1G3g#P)uD4c<3t`4#*2Y2EP|=znr@qGyD$X$;{nA~I#$oq~k4F1BYI_ +6#<(k)}&3W}dR9xZQ8y#VJHhtBUyD5>lFGFt}LFgL6!!Dcu7HQ_yfIY9=~a)^S}VaqS6KdF-ZOw%}0h +_e}RNJ80zg*sHEC=FOofYV_gz=l~7YBOO_01Xt2WY;T=$g=-opBztN_KwtJm2iWgX?1`bFTQh~z6c}p +4xP))}+HR&HFWYEO$VBAR8* +c`L0usb!Tt;?`6hpeqjpuR=8OA|4GALxh@-2A?wCy+U6;vz>u(?=zi$my&C^X*#>qhp1o`@voe5j<)5 +YFO_I-D6tJ%$46XhQ$bzdN_jE@NvnA^rnqoE4nvPBtTjmYE+~&(=3O*JfM@yaC)C;P0@0f<-H#cOFe% +9A~efkXF2FzaloYpni>GfeAVOm7j?%^83X}L)-+3ehm>fuQSyh`e%{?%(O$rM4(F4UMI}~&Sb77bWo`WH9N`_l7R^tVvY)q~Oy1J#^LJ +p0#)E2xH+i!RRxhg;8hoIEdNWvTyLak&f#2G5xjGP)dvK{|O7YiJOLlJGafH%rFa&jjM7eV@Ts$Se^N +18-+Ur-m;`eBbKB<;D~T-Y=hEO}jT5pQQ)Z*bU2k&aG*B^=gEORm;Bdx*CYl!6Ubn#tLD+W;*szMqiu +wmfHW>SGEXNV%lOytN*J#*dc#G!k3D!|Cb66aI2kXdD6Qm6+rvZQlf%S(}ZM_H+~9X!8&95+qSX9QeaQLe-FX$JvMFrJ%QcA~Ydf;+BY-O_xUrt62vC&3!CxBCeJDtMR&1*HQP4TcUr +zP))NAB!ceOn*UdLaNK5+4315X9?t~m;8X8OY4ErTlXs_iMQR_HM~u%`1Ki=j=$7O==|L-Hf4T +k6^Or)^Iqt7{9omv7hvBf;0!BJr5bny`*Up1t&P?!i^L(szISpJ0ZT{c=RdvvOHcK{yjXSlb^!F94%I +pqSNHA>A2g^P9eNj(@Q%eHS3F3Hecq7W0Y+=V)$DqD_v3OJLa%?`g){2osBeY-(x5A6kHMI9#rggK-) +-?sH>V@bFepbqjH_XAIUkOOP0_8(&U8aQcLfdJ%~v2mpC5MP0Xsnb2>bNz=xO%pF8ESi{put&(_6Oid +$hZ$*XjQBH^SavOb5W;|{2eLWCJN-w7nm-N<@6#2Lz}Y<+KNvEskBoLh%M +K7NhJ13jP~lQ|@bkv#g}1uvQX}!HoM&;uq}T9%1SaEvTyW>;hOHEM~1I2VbZ`c#Jt>tp+nC+_-@y{CqLBZGU_=1q`9H2dt< +-kUTI||k2_0qpW3w7u#T~_q?8`biSq|4Df +32}*kl!owX*R&ocq(0>s +#Uzr=i-bN7j=1vE2`MZn-hX2t~pmT)tJH$X`ra^^z{H$R*d1##VG>>+4=`b$-FHlPZ1QY-O00;o{l@> +?8)D0j%0000=0000w0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFK}UFYhh<)b1 +z?CX>MtBUtcb8c}pwG&sB(zPb)1cElQ1#SIEpQ$S*2UNK7iu&nYcQjfe2LxY9uC^kCA(#X0f0i6zMy@ +frEWC3%Utsa#wDP)h>@6aWAK2mtey7DqVP|D?FK=>WWpZU?Uu0=xbS`jtwOVa&+c*;bo?k&UC~PkjC+Xd`*xG>4-kr)F{CP3|YXrZ(#a}P+*DJ>JgcYaaG(S6M?_ixUju<8VJr`l=)WZh-r}uZbZVW97HEJzutXhz +sOkRMj($}Sr#{!m$6F3oX4d+z#hPV9;@t9i&z%ITz>oN<;(B>a(Pzj)6E%!pN&=-Fw=sAtQnbSE6SBj +L|!s(*s6Xz6Q5&IlR5{lt=WdaSY%R0_M;W1UjwxI_A^LOnLk=@Lp~0UCLryH?g<*RTl9h@bNW{4#{s> +O#P#0PqKx@z+4FKcWY8AmtDsuY}tGwi}Ilf`Q09D8i1cX_L0hS2}vIK%i3oGIUKf<#o{!wl(?lF9cxR +e>}xlx*8E?kO%V|XUeCpfRgwo17sX~{AY^=TsHRjtz#jespuX +&~%U9N>_EEe%Ux4Bas;chWEeQI^ULC`p#! +=~jWacG=9cyXEnY#9>HXDu^O96}Pehbb#l!AP|PSxM6Jh?)~kjh`qi2*T;zceEaVQXS_sgz`NkOa}S{UqlV-UKc^u%yY&*$ZgKc3S1~n*NZi)A#X-(U6tsfBk+Y7*j8 +vF8x6U_GXMwyLy1UgK5G&4%22dO-8~y90M~0-YLx6O)T4fuWT+`>JY(Op>qc7=lS^R!@l*&pz|)ENT! +k8%IC?1J#Too2w!_bC!o)+x)Kh8SiHakq)K@-N7@p$6G3p^ZIK#Iu!o?wA5^MF1KJ(YwrQyH<- +jQwq~_@1d`DIXT6#--=%gH1|gch|bM%C*cTf6^@n^sSsOuawzrDK@WK1v9icl_R!N +o41}9CMq;r532`@2_>%Mm?3a2T#vV*jYy%Xbac+7Z0+SEL3I0F=@e#1Rdgx6puOFJ(h7GuJ3A>Wtk<9 +xY$7&v-TY6q=ITui??_65$X1rHx!k$+f7T%>Wf^I!Mgid{p_()#O;h2Co@R@vDVQmvcDFFONI!6VbmL +}i^b2%n0bpUUzPu6jik=!Cm5BO35!iiWIgGmawnksg0c%;m{Z8WD$V~qv?kn0M#9U}Xfi_g~XE$7S&R +ZNH1S&!Ch+XOgb9bMD603MQ~b5hR%Zq6AW-=->=HMV~w4&zE|A7$4~{D8qzVJG2G5O@PcJGxI&qzTb1 +U$mpwF{LSB8fc+0T|#j=rb#gGwDBWHd^& +E%*F+&hZh%N=wVwBPG{`}RxXmd*VM%kOz?1rb<8jTew7;OXDfo +c=zLR@LmPDCOr%F|@_H4*Q`YjY>u97!%7UmVtq&NmsTA1NKAsv`glF)qmUz($CBUXbg4#ExNRYrU1GC +8&jE;u@S~JR6-nTF==Gzpz1xAU==+Tx2z|MLuS7vxPKFX@ZAOmv4gZ1B+y%yJdd$wfsWxOkh +oUn_6DogJz~i%+Ox%JN6ooEgZ6lLc{Q9I-3Y^b${JQW=K$0}xf9c{C5GUNj&u#)-a#!5tqM3U<_2`5y +9a3;5K(D-(}?Ccz47NS< +?OrejS)vM_hxCXUT%hZcS*VcXo$r0p9SSF2+?I}^&{%zJTB^^c*QNM0%0DWOe+Ub!@4Tpe3ap(7$V3b +e3u#-OuPv5XxN;u9An!ZvMo2JKEAO_Xvp;zd(xzMz~F@aI{fVT?*FXPvADGb4dP^u*q?v4Vl6EF_e8X +^SC1Ak-ZS!P`C$-ip-AA#QrTBUHSHy0aTrRBn}87hgV`(>0o5Oy9SUjv&$#CRc@kauixOsNbZKUNyTx +KMe5(vi0F5dX-bwr|>~Do5nQ_oiUp*pm}kmmI^=mI(1QCgUY?kiI*|SQyaORle;2u?9*KQ +Ay*6J`5}Wiw*Y`#C&3z77{Qk#4OJC@)oi93<6ESqeD_gD0#MUcO@DZntkTo&r+1hzf;mLd+bk{BVrRR +jIUypa-qupD$&2xYb%26(!2nALvc*=PuR;y?>C><<&t{-1$Bh;Z&!(}5OlcpU}@hFVw*!Esh#bV$B=D +mv&{FVpy1*FV4-Nhqj7Bb#LGqnu@j_Se%TP~YY@1b2723ZOc)QZY5gi`J5(s`_kQ{dowF_E-BopzwP= +4a8)UQ@IprKT8+jE=!0HnoKpgkHU{cizX=1lK{R&(LiU=}GlAGdqr@8PQ_JH_%(OHwwFqztfm4KI>hv +8m1f@r%*cjYSN{+9_&me_pj&mk`GIuv$*qC90xuK*_&``gsAHNP;y5-c!napnekX0(_7Jp ++c;&Bds79TyLs^>$ypE}@UkIh4|svDa|*|3|!PU6CB5I1V-T&+sn8&-oK4%8OJ&v2JTC_o>`|UqV{Em +4Q=ezb-%P>frxPpm&!7W5dn9mm$1U!H=z9*xi!%_HX_@ +6aWAK2mtey7Dv-q9VP|D?FLP;lE^v9R8f$OkxbeGx1*@Q_e5Z9c$>9ndHbtGp*|?Y3sqMYp?R6p0GHr7si>^q=@fH +2=of%S3%TBtj5kw^CJsggPq&(02U}P+f6q?Od%C;%AlLd>^Ofa+LhNYWCGnKH1oms-;jPYc~&OOg-wN +9?odY8(@(l9@2v$MCSZ{NVbQ+6qmuY4teNEnf7l>qL8NLNy82|T1`OOcA{jxAE27%>ajJQaeeIg6G&U +5J1g1#)(5P1Hnwu?81!={#R*~eukj+%IS&77Og97I=2K#)o6wDht3a?F4 +W`f5|Cdf{(492z+jNO3oLYq`Z$Rq%)DBjFaiwqpgm2@JIoLr%SYwKjA!3b0}U@J9~b9@T2Y`vMrQZEB +GlgN9zF)*lcFcJw;fhB*0nb0DRkps?*HMh`@kWl+II@LHgp=7pQsuio)0$!SL(gb7*qM0f1TF^QHnO{ +X@a0v0|Dvs6G&V4eIXq5g5=4}EnK2=YG%(1hbCDxA|mGDHImwN5gVQZ!l{n1 +2Z~uvRHa#26@R-$4y-du%+snSAVydaOTY52N8P{p;Q}^SWc`djb2{pWF^VOc-E{x`WAQHoRfo!Dse!e +{dbJ-lvCAZ#-thQR}3C|8Upu!C-%Ib@$=AKX}hBfp9RKu)F?!e*#=5LxvI^uYPZg-0pj$t6S)HFZ*}> +$>)IG^d|#g+B&%zj#!sHbVrl^)rY(8h&_B5Jq*V^P~aN)4*G+e5s2yC_Xd*=h=noM`vp2|eA~UdBU#- +Kp#R8fcr|?ZJnFx{ov_>C-E|K}FMFU{_wugCNEX<2b=U3R2kg3g-+hnzjo1*_j0nx?_wlxeLtya$NLc +r3(jN}clB?lhGJ}4`nzrOv# +E-u(Pm^EjB@>7e!4;Oc`2+0m4GHF2L5)$4*q&Wck77)ddzw%*x+HoVE4Gmi^G&Yq9Pj}hqbZ5|42)OT +l8u$O+b6T$WvzEV!mWZ`z)N0DLutUwt`KTR>RkCO|=;)J@cB(p82%12%y{Gjik@!Ao&>Zctg6E|0I_3 +smL#qxXhSX@xv%dG0KXI>Z^~c`{`>UN19&haL^lYP-XB%7wx;r^7`?ISMmDsyvED=A!eUo +#gRYwY!R~e;k(@+bm+JYM +_2$(BV%?&UBtNsVd+LDB6nE0TWMh%(^6|UDA`hXQk#YyNAMKc5i2}aNi4l12@D_Qzl}2F;GdxjT?C5_ +$8)Rm3AlRQdO#)&`V>$8U29F_g66j-6WNV$z+HNgo*8u^`a;sqlY3(heHwVMhut7s7|9Q7YEhnQmZQCe)S%j% +yv@C6o2WAX*qY`Y^0BOZhg;@oeJ&w-sL>SIZ&b;{c0Ppqt&)HYf&DPdX9WVJ5Rp)I?1c0BLrBvOF8Ln +K?l5obqJRB&%$Afn*y8c>N|{@Sj7#2e2r3xVKydxvWlEUWN->^|@TEd8%!oTv7kQ_L~V{4=)xJwa^T) +-GsL^W*tUKJxcMFrxqPMv7BND!JPv90tanX!)A?GA0S=DA(VY|EM+NHG4*$lTk?@kj&hJm;hEdX{oO; +}Bl7iOH(BLl2@*1mE0$YG6XhlBsBR~dhp|YXtgQVJ;-PJ~iO1FZewAQv;3W=YSYmNaYSY+De4+;#J=! +%~YOZaoiQu0bu_2tlQKJbZ73ssj}@(g>%8S)9S1u`j^ +~L5iyP?evnk;mV+Hk>iUAY%%VeqRPh3A^SHU~VkfyoN&QANjeigi942^syx7tTWj-$t@AT!b7p0-m`> +1I5N!J~7P%q$Pr$mc1Uy`Vv?(rBraTl41e3P-N8k-ciCq*saZxQNvX4@(Q*UeQSA?PDTJlt;b)SPeGw +_&q`soN^I>6JFj}x=#JW46UNofB70kt=F8SppzzHX4$54p~weXfh>hH=0xQ4w#fWvs$e@QuyqNCy^jjym_F#^s{N +Xz!<>1mLkJ0s49go&HmwwG#zB)w_ErCrgf@Xq#$EFw%a6AwMk}ScB<*Sfqe-MV13jtw72`$V&fh0IOb +ExTmabT!jqkk@dZc_JD9v4aR;3*7rFzcA%x*xn)m>Gm8vjomm=hwP3X92vO3!xd}dJXTr`tIzHK-(cZ +^BT>{JPHvmnU1nL10#ukAkT)(CRj|exbC+Ipi +UBBKx?e1}cA3g8vcnYCN~FjHWQ(tnCSQ;>n$ns)OqU^LZ-H!W`m=KWcVWiz1qNx;9-`BlCcn+>jXF?EpX(XTlcMVs$-8}um-d(WMpDHU7DzP)XcJyWQlB6q1-;;`6hQI1=?ba0`AA3dW&QUwaQQ#^=~3+D)T%`6r5vST8=zEYj6N1#h2&m +gW-OM}fbaNOVSPSn>}irRK4bi~&pQ?RftTBc>4E9#XrFEq^t3rq5RHw`dk5tYRht}!L69KInq?mjEd1^ayV#2%1DeMxHhmZXoW<5&7 +T%eCEy}6zfVCiFvdk?yJJd&UyvhDltPIHVpjlc)9>--+lME#a4CR@KdNnY~N_JgKB~(_V1%oaUlzG9tQ_yl*$aOLhQikfqB88*2LCXFL@g3dEXgh$UFv^bH1u +3f>&K{U2(&+Gv9xv!SZ^T~GqulfLgvz&Ym3*Elr$O;f=i%ZeUW64FI1lhQ{}zW0 +yBt1dK3{ACR09sB&IV2P|6IRS@;#kL=AcDWK&Lx}F<+aPxe6xj|YLI&Afhy-R8N-^@d-p^99A&@D}fH +GCT*kRyON@16zyRxPvOvZs}cW&NeMn8bFE2Y2WE%%jU?7%12v3aRrkM?`Td?w@pQA7 +|H4DwL1cQZy>gK=L3u1N7|qruz&r#-TDtuO9KQH000080P~d=M-Z@R<=p@P0L%dZ08Ib@0B~t=FJE?L +Ze(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvrVPk7yXJvCQb8~E8ZDDj{XkTb=b98QDZDlWCUukY +>bYEXCaCwc6!Ait15Qgu4iXZk+#nOY`1TV@Syr^#wvdPp2lT1h_yY}tvrYckrHpj`#_kEJ*`v%L~;cb +?YBkua!n>raX2TYTP3yHJfiL$uC87;KWnRADr#f)m?Numza(5Im!c&_VpWkt)6WA!|0^HG63Kt{q)q7 +k>4t574&$sw>Uo_??D*Wvqc>X$0Dm0uirru`SX_Pv&jBSp)ZEDWc4ThXgUD+9Wo>0{bYXO9Z*DGdd97FdZxcrl{oQ}X$Wi1w<6H=7DYcYJQGgbSCJ_dT3e;NP?Zs +QpyQkfCjQiL3&F-CjjssL}gG8MDn2$Ga-j4hI{_DA4idJ)}Y3Y={p~>WB*6;Uwy#u;5UXJPYTsbOLB?-Tmx{#JUJY7$oQ>AjLoh0GHQf>yX8CN@p}U&A!VXW{(EF +US0|3=t5erN|g&QpIK{c@>W#K_%R*#;E`$^>-BntENNP3$Jk5*R7s&n)WS6ae4nQ)RTa6gg*!WGZUc^ +A`7pyH^4!>hKY2s1o?p=8lSki=$jONEV}y3v3%8myy)l)`l=NlDl5;z@WzN?Qnp;QlR^zG(*gK^9{$u +z{m86ZQLdSUc$4bAnnx2cw$>{HZu7Q^5WziLtr6^oQ|}+fD7zNp#>x0&jBSG{w%Y4iZkF07gJEM9Np6q*v|Ea8-Usx;xuv9olOKM3@^DPz) +~JFCsX=2$rbH#|EqFw;H3BLlrxyk++FI~)p~+~u@kcd+F0Hs(pdUcdb8<_2E7xpKIxl9Ga&uX9OwK3KT5n(I68yQGDK8 +gvk~Jq;!SYH0MVkC__2%VMy1aT#!sAdKfDAoLf@&*Sx)|VsC9G5^ATU_XRX*>vRqhlxp9?E;k5fpwwg +B0|OeJQrB7>7Ql7jCrKaT>x!*K_=>2>LMAu|0DbOplKLcb)w2ZQ?%Sl`FS$xE%q3Jq~TtX5{y<)W5J3uoFw>|__GE2hc +{>=}h}Z%V2+rNldDAvt(lvzv@otJUzIdd$$KmB=NO_QP-h2V8529Q3SA}&a$qxWN{$ajfTk4jw* +zErHRtU?Xgkl@i&6v3$0_EfNEopI|pL`$9FzpSs8rD2HBrR>4dGMap`x2j>9j0zPx(%?Baa#EbVm^0| +&GC@V3lMn|Jxn>Y#r`Gq$ei-Bz<-xJ@n7=< +s?lvMPz7)t-~Q+0d9&%Pfnfy)MC>iF_~q>RR`XssaWlb5zUsKUR-mLEYDSOo8=P|gRFgwt?MA7dsph2 +_u&yJh=(?zswL2*D~(o!A%{|PpzT=K!Pc=io>8)$Num*P&bFi9;hEWvNl8EI5&Ub@eM$PUddFyx2*<)O=)xO+2C`R~pbGrw}PZ$P(oGVNhaRAtfY-?(<#90h4OVBaf+wYVv&Jm&V`yu_?N`9rH?a$XMTS=X?C +sK@*CwCiQZ_ets;n1O_{_fOO80qw&dB;hrFg4)GIdr=R4=LGxp? +5sq};c0RRBz0RR9t0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFLiWjY%gD5X>M +tBUtcb8c~y}?PQ)+_MfYggY9;h+mq0=(CqB@{r#=n!4omm*7aA*je +w&uTJ^ObyxvX_nP%T0_%RZzfOb}45^O*TYJ?6M&xe+2gtMa%(5a_TLGYhj8;u)CHWQJ-toZ%_=~dP1BL&58J^j|t50$CjUY5d&AggJ8xFARNp@`BZ8fG*u(-chh +?Yw19xzZ5}$c-!8XoOsk$>dn_s2`Cg-A8g0GX^yoF7qFYEYEGXD&N+z_goY(@vwKhpqh@PB#)K_O%j! +0F@0OQk5~Sg$?@<5P)h>@6aWAK2mtey7DxJZI#dh=007+#001}u003}la4%nWWo~3|axZdaadl;LbaO +9oVPk7yXJvCQb#iQMX<{=kb#!TLFJo_RZe?S1X>V>WaCwbZQE%He5PtWsI3y2|3|9!chXDfe;C0RxEK +P#O1qK9#MN5>;g(d}(O6z~$JCc$t$1Y|dku4s-yZi3$BgL-K#(~x4D|ZuT_W1{$4JhKJ~ +~2==Fd2H6lD{$8)&V2aJOhuY6!(hM{3J-vyR{$?t4$!T8vrC_EiS0Zw}`$(_%mgMux_E=PG8UhYdN)C +Nn)l*RbDa&ix74z0~b6j8$==Ns;rbH+0}gDZM_H4BwUy&baWO)*OU_B8wXkWx=oOl0V*1E>eB0@A=8= +5IKw_OS?%*tXmPv#{PnWIN4{!KuKL4qWLlBty00%g|x}Kk|3c_ba2(I4}zyk{8PF+YDaf-*tAKzFdFn +cf@fC!=7kD;mDmLY1}`0*4j(9~dgiH;-`vdIkJ;1qI`kpE6e!XkA +@QY$?J{+5D3?96Ya1V(hC4cy%L46<5Cu5^-)Q@DhM@G4U=$9%wTU2{VfU9&2k0lGRnkJ))PCXtG|RsF +6~Hv)l!Mg>xvJ%vvWp7w5wW*@WP!8)83W-7$MHZsiY!EsBJ3CA;-R~4c-jnrANVxt)P<>Wvs9G@aUuX +ICxZIO9}DzRG~KTxTJRh8k^;!KMj*R8vWA+7$pfBa*9zxs1=JO6sWTrKZDFCM=xXQNz)kJYUy`6{B_( +5TE{9D;utdB=f{Lqr)&-MZ!qTu +v>>U!|fU%K!%_LxHSu0)d6{GNgAvJ6hl%t%;$_v!aXdR7%Y&pbtF=I$Q59M26Ntzi2RruK(LA(f7^}Gg!Y4;pS2TuRF0OGDq_lp=<1@Ly=>4yl+;DFAFG +Gl^FVT6p3mAiMs5AS}agC-i&HUsHPG5>s^Dy$9$Zr|V}G)6nrsgfy75 +Bmkz82Uw5!;K=GZG9*wl{*?m&*71raFtGu@IqDkbuV1#ySEH^y0E0IRV$M0p>-Jj#OZM6tmU+MkiX)T;cQR{0aa4~K_I;xj#VGw%O0IMme +1*fM=rtSoYwSeBkTCdg*U^2AX~W3w7Z5PEj?KIm{wA!7Vh<#gEorjn#57rXxJE+^#aB%)yg=M9&`5YZ +LuXzehEy0*KT9o@4g{Y0Z7O?0%+M?X>2cYWpQ<7b963nd8JidPunmQeb2AB>Pv{01g0T0MFMGbXhNFUBzW7V)JblMM`CBT0~Ex6 +$97uhgBGT(FBIQ<&OP_DOTlZ%h{U5qpmoEAg6!xJSOC$vfxp#xuq@<#^cznSbhCuQh8Ms9LUeNqAktL)mKIoy)9725ObG-w0;RT? +e^hCiL}Yzo#ap-|Os6H=ywvm#JZn~}At~oK_5uhDNCs5KK31-@z~n6>Dc|N1j`fshmg^rzdn@4BhsU(1g{ccJhCs7sXV(UbyH!Ic#iAjth2OH~e=lOn|B93y*PyTC@CI}W+#Tph1gciB4Z?c{P)h>@6aWAK2mtey7Ds3Q;WQBe001@u001@ +s003}la4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQb#iQMX<{=kb#!TLFLGsbaBpsNWiD`em65?}!!Q +s;@BWI#y~Ky;19B^+&{HYF?KQ0Bm90jRgtShYzprEkyO2_-E*8i$^Jcdv1v(y-KS<*u^&8iHHoFSasq +1?FK8+-g5iTR~NC6NAeI^S^8`>IuBuEmHoNSbAYPUGORvSs-C}1bFQX@ +>a7uNSotKo`cI&4422e`_1QY-O00;o{l@>?P)Y~Lb3;+PcCIA340001RX>c!Jc4cm4Z*nhkWpQ<7b98 +eraA9L>VP|D?FLiQkY-wUMFLiWjY%g+UbaHtvaCx;_dvDvw5&z$xVv!&a>B@{8_s~{2HFXl@Vl;^ZM~ +5qLxKb-}CGkRWRX!rChWpt&GyC8!N#`zyJ0Vaga(8y-H}9dd-CmY8tFxUr$<%c&H=C^3oSdvnxnofzZ +WFPuGg(wjuLw>Ud|t|;5J|m&t+J`-Whu)sJ$T1&Z$w=lom(GDS<6J`&aE54)BfHYQSIR*p>KtTi9Js~ +@r|%7RN3vx$qBH^W`^NtBkH$sDas&@3%(O^9KxC;=T*gsp+K&F29Coi9rftZBXyf4vRG%ErsODPbV5( +(JlV369`m{uyM4_LS)Q|`6ucIUvqBv7c10B)*IU-?Q+S-R&pdBLHD;A0YV}sYF}z?a!79EM`4MP0l}P +nzNGJp8^paGpvjV8_3J!uFyvb{}mL>e!OPNonY8QS=y>q5TOq5n;-;CiAPiN2Y|1>Mv|7+J^ +;0Myx<6$rZm(4ht3g7C$Jv3MWy%;$W{lV@8*lqn2qq}^yyP^%Xj-+M2Xxz9fgX+>yqt7d8T);;IPdAR +{2?!WtIZhfQu&|{zeHyU&OCJe{6u6DOk=YVK@wRR`FF1Sg($350(Ok#Fop~Jg>xZ`TKD}1T_a_+m$jW +;NVd5{T>*|3N|HUoi6{^lzE=5E*#&BJg-`^rpQHAowz2z%T}B*l2d3W9GFI66W)+`mZ)W+*W +w4)#M>kTuVz7J>!-WJR-EiIT~+J-C*P=eayYY{5Ul?>$(XNJWtdQZudHg|4EW$h%GMltg)qQ?aiVAmY0B)X9-+f*qy#im!I5Hxhafq;mOF4iQB>I~Kb~!~%~ +ts-JhQZTLe$6_n?l^~!Er!2BHai=vLa^qXPKeKz)drV1}aYEQtk)kn<(MdJj;=J)Wte0!5?Vf&<<^X_ +(N-yj)mX{kz=_eeZ{hft!wKIeHH3>&?@nbJg^-vj^+v20r+Q5QA;SxBt=kUD;(w)TLFfIMy8i3s{#7~ +tdxZrKL@x0W|BqS-pLw~FTondmY_1v1JJCh1~jvUa92p!Rc08)fi!MbyO7krlnL0pd(zjVjdrW-;kXx +lxG-i8V1@b7!-W=VAbJ>Sd=M&)5ntD$^dLHLA0rJ8*eL#VqK;a=<43>;T%!WRJ`?LTXzn-I+Am74%xM +4t^N3J@m<~GMMeJ?1%Ub{Hd4<|yiFF<1(k?-Z;q1*~@u7{glutRUYF;-O4N}1_Cg)@LdWK&Y`1Kbi+c +0o3`Rnh4$RFW~pnuxC6ZKZ6G1z`B@~m>8#uI^=29iOEktS7ms0|E^V}+*AYxJ0EE1NtW^3oSalTgRFP +!?2bXrooMD(!h_pBQApqR81KxU!{_6)6-w;I?2E!4Ak}kkyPiR!TW!w@_#?l2L$&6%&Asd1#5zB2=UZ +Bal{Tl*7XY +rl4Za@TP2WaCS&>ht#b)SV1|+lF2o-Bb&C=F-1! +9W*(nR2v46ARuFcStz)haMXJ_o(ltH8x0qRdNajr?1KJO^^BsxbBfV=6sDU#_jB6gMzYnB>j%pYL`RK +1hv8GZj5zN0Am$;zlX!BnkC6as@glpwh*HcmS@Y%?XQ|47RW5A~J*n2L!RVbRje)?Rv~w4zK2k1 +=8C^3Dusd#Qckm^4m_18k7zB&H&5dwuK8$hu_oiV +jHf)GQqOG$wc+pS`Ol#4{XHFD8c^Z*%O*J+R;0hH=ZAx;Z1;p6RYYn+6M&Z7845;btN=-iVQ_k?R_hq +}59-SmWLD=mnSvNs2T5MpM&D71iW@pPQ2=u60*6m80GtCa)9NgdyFIV7RhDP<(GEhSuJEwM#&Vn25r% +(5B5NCP2nI;M8w<>2$V^yZhrLv-7VcsK0}BXY3NbGPWffXGhh9FgB2sP(d#53WdW}0avF?Z|H!#0Ls- +p3HyA+%#ZkYy#fS>N +n;XJ*5YgRHE62IIcX8~+SE96q4`TwmRL?}3N1#{5>0QaDoB@@tBB!{^(|!GK}Aej@`htI>zEA&SE?OP +PgyX0j4B*EN9?jfEqAJbv42|FVn@Z|5MUpvz;!D`J94d;;f3>S&h<&PBw7e0n^MDv1C +7p5p;Oa_mY}m|8!$LMZ9?aP+r=)KzT-+zRT(3wuBDFvIOmReb;E +n~4C=%8>_xwib&9g+|sY<`}z;04VQZ0G+}^};skJ461VXw$3M(1p~^h{hB_Nah2r%HaCJz|^Ta_1)px +63=rmum^P)dU)EFY$(`Vf*0Ueq^X?&_Vcb*%VVr&%HZdLQ=u`x8gmLUul@=jqJ_K$>nsO*4NT9|E(pE +gq5QIa`W0YeVD<>JZ<*7XWkpho9mG=4+H@1vl(}ukR6DAFl2_{M7~j#DYfwh=sV;dUhKigU)AbI&FSE +P|GtDBFg*R2zExTc8N`ph)D=T8uV=I1i-|k1aA?(^ly!GxWCSvEH-U}JK1t(1AW#zKV>D<0yA=H3jeZ +@qfK|6ZALuUX=2}nVN$j)3h)0;irdHb_-zAbwGtTtqirDd1mEItW1mDvgtB!`8K7k&#-!Y1{G6F +aG(bqtbpu>wv%^bf#ZSH$=k>VzSB?Y+;dOG@(r$Rbm03WB87)A!u^aHSv8vj^K%n=U*LMwg~8a7lQAU0%Sv1- +gN&SgS>?hp*XqAm3yXxf?7mw4B!di+~Euchp~S{k`xba8*ou1v1LsJRk~5M*&~g1s_=Jo|(**l#8i2u +mFjgB1p+NVS1*YU(7EP0wHZv#E!bFeIk;2QATe^Y`N&t6AqXC*qnu_-Fzbj=BcsSYH@n`O~Y;;ObXSdAc`3FFIN#Bd`AJjwr}$z1e&~l?+uq+HJ9r +@E{EcX!o^=GjX_b$`@7KVA~&H5jA>Jjl!uJI?w@@O_y3{-f%o|N9d*4mwJTm2&1+ds%4z-svJd`9Dxg0|XQR000O8^OY7y-RBv$f(-xwH75W7G5`PoaA|NaUv_0~WN +&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR>?X>2cZb8KHOaCyyIZExeo5&o`Uv9Wr?q?Ci`lFMG=@U9*KuxC*6Ya=l5j +oUO#CST1)1RwVYZvn09|SF2bq9N9Yhe!$dGa(s%hGJXt`jA~A`^E +p&zEVo{>ZaLCXby?2Q=d}$;GFfU9g)p5uLY})7kXq8n177tVAcw1kc4R5=&mh`7EqcckEgs%aYW+Yz= +$W>EzjN#Mm)=5GrR_nPg&1FoZCw!|=0Hl#2DM-V9#c_%`F4nM%Vakq_8-a{n;9xxJYT*xmi@!|nL?-3 +$z$&xfsZ-A=InTdo)$|I#s9V%M5NYiFeAZn%QDTHaP(w|7|BEH?07hVEs2`~L2JGM!%E-W*)x5D)0`^ +{2Df`ZvJixq0;Fc-%Fyrs#Bz*(Eav%k1$47@MX=77C@+y-x8>CUoYUY=hyyhj&vJ%FRk-YScN#gcG*P +^Nkvvo^Iun4A$wtWE}G#%^pvu#9ih)JY>%zn@wdTW?)dCwcQ3#Rm>ME2-EfHCQJVz!d#s$aOx+UjEA{ +|K&LW^#HV1DujAVE)h-cF!CIX140JIFS3HXZSDndD +5;zOcYuCYB2{}nou-J%HnTc@6dRK2Jr;{=M-ydj38^cHsu@rJJdLaESM4 +nqtq~atLwHZ9wvCGNy3m!hP?Mj9#Y}FaSqJR^{> +DEk%q~eQMu$vF>-Z5U}E9gar+5`sd{nhvE{pDEcrLLw^Es0x_!QB-=B;#CWn5YW9O|*`kitzz=O>&DD&B@r$ +oFQz<|>{4bymLr}Rg)rHCkSG!V8)UL!tcA5@7@?3u>}p%WbkCu@s6749z*u0;4WTcs*b_*#@vX^##IB +WBLlI7blSoP#o2v@qqfP(bA_itQ1kHj)BtTV`YGQpV!o>?g5%@q2a1CWiXw5T`uS!p*`Jmx(knjlFdG~EN^ugrv@>U6~eu@u3c%=k<}S{#_jf`-)0(@8!Y9LC24Lrx4Fk?&+aoWVPg-wjnEF +;Yjuq7uLvj1nka&R^T;TLLFxs~S|n_a@WZ<8Y&Z)GmBW7h&=SDq0iA*so5zg93iH(QKfvZZ_;COvfSU +t<0TBb@>{upN5xK+0$@2mI<__!(EVtHcrQ-cL6=@Yr1>M@~ +jX(z#3qrXhmA)&s@e7o&rQ~j3HP)BR;7XJ#~vLM)o^2aDm)&DIXE0a5R)i@(pljlS!y9-sxzz<~tU03 +Yaat$UxyzdMa2YA~a5pgIYqOfW2wSm`Ee7++6x%B@BRM5#nr=hDxVSA~~fqRr#q4tvdB-;dCr*dcLtS +!zwuF4)%x-W%7q@;tAXy$r^s!U)e%HcT~fM{Z+dTPaI{5M=hil2})A?et_#N6aOq}JrHjp2dKOF;wHG +bQ>Xsi1e3!+@`X?x{P=1gY6Pm6r0zo2c`Vlp-wy}uyYI{y)XzmAjD2zWAAZm3)jFLHIXSWuQt%S?Au_ +m0lJ`jC1Llob*FHKr(tpPkZ565PQNkyEO88ceU`!db&_EeWfD|z#nPKUHftb;TXMC+cRIo9w$S8|l>? +jpCs1W$Gy!EQdZ#*F|S>+l40N*H-Bl##{TX6aW$+WHjGUzc=kZl1hNMoJLx;^R#WP5yL_7RKZF<%icj +-2_Cs#Kr>XPZiBYGcs{Z!(h+10ZI|gVmNrB1P<2bYuE;I`rE6 +{$HZROZRmCV^MZb$T$v#2laW<-(Cxc}_$W-Q6G;f4@AYw{fM2RdHoM{ZpV>CeV2-5u-MI$%&2Shr)iN +{YbWycV{M`kPw_Vij0rdWM{#M)Y-))9Z{$uT;BG+Ej56pP4(i|zNHsfMn%CFKI*;J(2X`c(&*pdUd% +KAP9+gSjEQcA&={#7J$w5CUS77$g%dpeqrWH9b4g$vyCHzznPFHRe_hawxzQInNuPDCgLpkUUv3wHy-t+qv+3bM+zo@g6>wixT)YCQNpuOonpBoUhwh{>uP(UQQ!D#tA42#mysH!wIBD?yi$Ytzx`)4Ipb)!JT!GVMCH|fhB&9@ +iqKYFIuQa3XET1r)EyAs{g2kWU~p>mlQy6m6Ny@vaIZt@La>U^%5&*v8GQM4n>$1(xLF4AYwucyGCty +XSB{pv_4AZt{1&B~SpghTCW%i^tsDY~wije+!QIKIVeO`Qm222>7f=~nV_MR`cMjP89e(tK6&(rPh>O +(sI^b{%wh9NYVXCA-~-gi2;xKh^T}()p?leq0G1i?A1bD6mlzC%p1-$Ee!iIJ}R2Y@luja5ZtfYD< +#rU;!C+EMqLD_f)hHiw|X%x>JW%6A(Sn~grJ3pbSmdcADVcqx0Koi_}xOyZ}uTb8dX1ydeBAfQD0K}{ +JAq)F=KW`tq}4ysg}EXnWQx?|T7u_UmeNLSF+a8qZ{J?8(u@bCE=>kO%ez$riL>nivqaA>XES_$moD;W`Ds=rSqH7Z+*VWXv_Oj^1z&8lgz6eZ&xal^jVd4N79L7aNPPO#QLNXK{=ORl +$_bfbSPAVWBN(y)VCygWS>Fb3{6_<`#oG{5)BiGR#r}8So%flM4UrNhdYtT+$>WNx6p+Z{ +C0JN>twDgGM2W7;F1!PMHp8s*_2B2GG@SsJuE*K?cD&$Mr~V9QbR9_QfRUt_aaU;>&xYg +=Q3aH%y=$j?cV;ano-WTDq+f-@P>3j`<Tlr#bwSE7HpMDa0`iy{}z-CFKnv)f +@X)QGVVyEKVv+r@#1z^rs}VU`RgH@B0UheKDHZK^51mWOOHchBO2<~8#E1+wE||CQ9Cy}4vTr@6aWAK2mtey7Dwy~a9}zM002lO001=r003}la4%nWWo~3|a +xZdaadl;LbaO9oVPk7yXJvCQb#iQMX<{=kb#!TLFLY^bWp8zKE^v9(T5Xftwh{iWUxB$B&q*^1?;6)l +%jP<9ZO6@w6MO1&`cZ;NNJ32!3ILw0e&}!S?&5`jNS)7VJJa45OCqpX>^}SK3w_D%wu04S&AY}jqpFX +>GAnmNb#~4=BWkufvaPlIMy{AuOt!VGxE0K9xn->ii`jvj$t5#;QOUJ*+boC%5qh%LY8Qmd-Ck+S7O& +sD{qyrTi9)D+=+c5_>CEYr^h3cj$Wyn!M6l=?R?uoEgzt*@}kU^Q +IG@Q+Hfh*aEUT-N1#PP8Kh{X>OTX{asXcI-5+uT&(J}hSL@(Z#pX{4E`=IF6iIC3ah2K7bMd!q=O5vw +lr+rwH026!RH-XrDmv-Y+2VzSSbwLVpC)?wXmITofLQGWHPB5ZcH%7)G65O5+1NhwQITQG{-}W2|f4E +46As{Rs;dCT+P5NJmO)kG<@4D)s&^%hJV3?xA9~+poODvzbGoE$z0hCz9c+5o%4*Bhz0g +|L!jL!8o8fo7+bq4@uQ`7nOmZ6x@|&C4?2MhI;j6|$&IpT+X1r;fGFgY7j~y1%(%rmHFe+OxMi>9CvO*4;A1Sn8Z$2CI5;Xr-fp^TLif+iSIg@Hnz1KHW +6%Es^JC08hGHQtXdW+P5CW+YS6`x4?5sZ>}r%`FbrIas9iSr>o!A&;IcAn`ghjej``cQOafW?CG;VEf ++-;ht_qsK>$MNN}y06XA!kP(+v%0GVcYKJj#EFvM+MpO4x%CEuLaT)meEjl8}d(Qb32?<;}GRvL}KVJ +kG_vKQr$<;MX)}Lwq`CMhX9iPR*Q0{&?7PMFEU#Mas~S;Ers~E335Qe7;^&0Bl7di`<*&8DDLnAzhx2 +;y}P(?(W`2&n3L^J#6%pJ!kL8Bv*#L{OLU|Rt<7wt$>O_L#SQEF>)xHJF-<2r&{MkXFm28zUX)nV$bw +8bd!*2=^nDJny&5S?A(rIp +z7dst%^a0iDjn;qA_fB1J$l +!k>W%R5~L)t@tJik-0-tRN>%(sw-HJ4Pni;6={n<&=1hdX2#mmEPCsX^lEXwj8!M=Xz%+Eu!3ygBfr$ +=IUe1`@hl$Hc*m1xxPGe!>X`muiR(xwgn#Kw7G;L3uvN{$QZ5Z^8l>vSdgtHx!JR)8SCn0jN>~(n`xe +_Es}^CRlza+s+C~vca+`fY$7&I?Xl;mP)s(LqEZ7AfAJGzD6?Sjy|F*4_Lod4WJ_{66QqAPrOpiroMV>WXOpN!JC1;kkZn;;Ec17D$ +zg#ngyqJ$HEaC1)r=L$lohC2(sGQ{rD6%<3Fc6T^ +yd>NsnPG{X00-SgviNexC`Pg#hs0K*^nbL|;8Iu~L7cy@~LHv*Z&!yJAn+G;SjpK^}7Aip8RZT)bG!a +~sYRd(4v?`tIX9>JTA^Z&lsvIka~JQAp^RGdw2I9{b1_TTy*Be2PHVZ7>)Q-DO5Uvit&e$ouel>&gqF!AM<5&`zfvJqs>v;kQUtw~zY}a9;6X=MGOw{1-LL$R!r(|(~@rj`Hu@YMR(R)SXeamjj!6`$fpS%9SLl*K2= +$+KpL45?%XOt$z!&a!-5OaMa%~KdXN)kftX6*7|iT74?RtfpZ7o_az|Ddmi$Q-3f?2#4@p2Uw~3Ub1Y +z`Vdl5T)V}2X53}K|L!rygKI8myqO;7Ek7_(8QqI+%&}?8;0d7A946(FrCf)u%)`6&O*H!ibT(n6)B9 +oQqrx^j;ji-AMpi&}_1ozu5I+_we1G0LOghwI7Vm(-7)DTL?Djg#Ye0napUTpl5pOt&t< +zcw`f^j^W^u{ejBfRdB?j-ZqjdFNQrm63xA5K)$utz&3=j|(!tP&?ya0M(s#-AkmIFzrg+>}nrB$w*$ +=6oYp)B_>B`x1yB%8ctnbX=>*{MBIvcMtp{)S%bzno-KdI>UCd#Aqk9?5Cc8??Bp~-CH%RWGR4K``h@ +&t(J25%_Vm8ni1_28_OEcpT=+WhGz}I+!}sVqBiqWqhN71Yij|n<%4K%iax7k7c@fn64+50P_P^qNxG +)PB^<&E%2pI2~`M(eYU*P{2L@t|t=#y*a^m;@Q#ata_`>D$iIiVuYpu)a7kB;v=-5>jG;&Bq%x^b8g9 +AX=W9C_H%G{(P-N~hZSTonJPhKMgS*j^clgJ%Z_YGOh@?vKgR?zF{;Osu9TFQ>x_|4LwZazy5f{GGxO +oS;H12TJT1V!pVP1&ch +r9}SiX$+!Ca%+C&PF!-cfj#$HayIL85gngsa)ka{e?2K*;wQu<&oVY%Ki7x4GftXQgM$#-yJNGA{8o1 +`g3jUz`r?k^rj6Xk>CL?77iT)3oknYv+1W~UV5D@G&`ed?y0Z>Z=1QY-O00;o{l@>?a;^|rc2LJ%f761S-0001RX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L +>VP|D?FLiQkY-wUMFLiWjY%g_kY%XwlrC4o`+cpyZ?q5Ny5lBWHdD8$z&gf=0O_N@MpxDbL=!eC^OG} +hZgc4Pf+Kunm-^`GbD8IxlDqzeLaLbJq?~T!BGMThSt+;c>vMY9%*nBH0k<3}bTerpEt+oz-Q3CyPzy4<{%nol#!#9cD>U +yMozi_!$1fwI>$n=K~{u8WHc`u&AFZk=g!*BZe}ZI}^_5f+5Xdc%0l{{8v$E&KB6W5&K%Q7~>92O1!+ +*&|miF_EZc+1B~;p+OH0$CR!dJMkfB}D|jvg}WxN-JLx^0>)l872FBEMqrf<32){%wecZ5v@yi1(a2lSs4{W{Hsb^A@tWsfpSUUPi(FS=fLu!@-HxH_m@Bl08T +&&dkQBAd1yk~?U~bD@*6nBPIVj0c>XZE-E2DbZ%?fv~bT|WXn$pHtPhVloNAwZwE5L_&Ma?x&es|r?WNF3M +_B><9)ZtLO&Y+>UQEC59oAq7YgdzJ&%z$;eq9c|rOF!7D&PVFc!EF?E#5#A%2tee(3;BmT_bEs#|)~# +dGb!MW_KU)bn2F1kIUi7CA?^r6bO-8V3dvRntXKTglue5Klq7>WmN5Ph0bfq6fG0TR?y#K~4z~CiYE+ +?a{eDmfF`vTe98?L +3#AGvreTkpM$|q7MAf(skt|Cg$uHTs^00=<)bGKLLf8pp&shRdN@4-%<5_kh0_K|$D`CqyRzie`iSqd +zQ?ewKbS6D;*hBXj{!!NirnA_r25k1Q95MIXe3pNT{2lobWLNP(0^UK--UGxKONkz7Z38`XRZ3%B3LU +->N>+Any!ur>Lf-I@E`<0nQb{KaUn@Y!(zD?L4hblc0g56Fkzg3E06T+ufiPpAygATa0!xE)3rR=Lia +W@wBI584{#H_;NaP$TV?`(eLrE*G3W(ZuUN4{nv87&+_6#**xAn~7#aP5(GyFez)0tj)4acQ-OC$5 +T${3>WMRe3tXOpTAtfW3PDP>uKnQ@OPq)TAZ$fZ0t`9hSX2RD +)g!w)=GG%0uiIF@P5Ye%C5q{Ig)RN+wt#-&Hdj>7kPm>1B+P!4dG!*S$rn1;&sgHEN3zYi1|Fv>!5?V@=D@=P~QR$K)^&=cO>?%Y<_Szn@(-sSUq(m-p-nMyb1GQ0@otgU!14@?t8Q!tRq! +$E^-#Q6?OEwHikIy*!9ajfw!t$K5Vu@oG5t2J*vW^%TdV4Yn7r5i8!(aT5-^VgqwoHlhzYku;OGkQ*> +;?@JM0hD+!yhhP1uw~eTSo1krPsus$MeOrI-51#-waKz3bsR3BD&RBXRnX^|%bq$3HNjJo>+wAcc`z; +uu4(8~=2r%IGUp}D?1>FtjT~@fhzM}}H#?si(@_@xr#~#9uMtBUtcb8d3}{li`y^|hVT9rBE7_rn(cKVr=?2^ +Jrw#y3BhQsaUxchf+UlqrT@L7FWZWp&0*J?Jo9Geor$tqt%|R-d8G#+jgppf$>o7iA;^iJFw}KaGE=O +OYqjb~UAMjMHPkiX-AQRn=!;RJw@`<35jf1QQnq_I39wwrl=L)2o&vOx)oOr0kTRbA={|h~aZ2nbe7; +W#ZfqjI;PZXb0M*SgvETgZ4f?3g1B=i1NiL0b7DxDVINs-bd6V%Y1@7mZj{pPz%N-J16bY&sZ!Fo8zX +ie9Y$lbY9X!tC8;@rLiD(uJ*kl$FnnVJU85^N27O~OO1dWk^mD}5Hv-I` +%15t+H^pxbf*E3P^MH|cY@0Y+Ht9+sLHJq{+v9eb%H1$tfVW9D2)b9(F>awV=vnP#>tyA+nXdAn9xX1 +t00;w%Qdw^0qw6vh(JGzSTQ`ClL%19SMoFwVGl#hTvb-w1F{b!R@V@1;hhm6copEHn@WEBGYdRX85bPjZg;aj@sr3CRFD|w*Frw)ERU#DzK>pL}mhcJJ +IY{xT4qPF!5Yw^hpE$*vOl=cMto8!AA6%Vl=vRyDJ?FTN0Kdq&g0(Y2_OKmZO~2*L+-2-{;~D&fwxQb +|3cTfWf7KlO;c?=;5Q*O6LmiNH61RldyyMlhF&mD?o6}cIg8jE^Qlpih=OGO5LQr-MB8czLT=}4^T@3 +1QY-O00;o{l@>=65Bi<>0ssKV2LJ#X0001RX>c!NZ*6U1Ze(*WV{dJ6Y-Mz5Z*DGdd977#Z<{a>{_bC +K%2EMcKq6f+IS}|((gfw!wktEe7RaONLkz_G1il|KXc4NCG-Co}BdT@7VY)&478f#eCZ`ZGYXV)`2`mvnuX_&80`}9YI6N?@B}*XXt+)*nXkxW>85I +nt%4t=Ok;@uQ#73*$?%ldrXGy|J^sp2)BSwUs$HSPFnWEH{EKdh;8Hts|&*kG&Q;-dh0o}9G2cV6-;N +aufnjEa-BB8ue5@Tz8u-~5}f+#TyeQr8!bbQ|&F`PvI!5MUPkr~I(k&5G;67y236NHh4_K +Q6M9)5-94hqM(Ghjo +OpOI&=XL*&<_5=lCbAM+uh#4=5uO_HD*KIdX^Pk%1Cx^$=$SdccY{Z^k*?Q;HW_P+TV&gT_f~G|wW|! +n;BSK^_MVsC{lP_+?u!UotN{%>yxJee%UP|Mayw42+eb5^pGvdgp8l;a;MuW`@s70%G_`FVcJtb`{#Y +*ANpc%Rse}m;Jc&%P?g*MOoXqFb`4Db+4Mi;#RQgW4kawknSvY`HIl(WUm2QXAZV?{&15ir?1QY-O00 +;o{l@>=m_|e-o0{{RT2><{V0001RX>c!NZ*6U1Ze(*WW^!d^dSxzfd8JlOi`y^|z57>)K(UiL-kukHT +39HQE)Bo44*FY63OMd4sW$fs7Tn!KpiGx9npOowRn$@za6LfA^Eni{KtH3p+3D| +ol}cXyb%%ve0DUZvz(whr)1sIVHinPocRRrur!$ihjLqZQdRDlwd2FoGaOGREPT2grk}%gaVA+A`Jg&I7^xA=F^VPEf +Vs{WS?^59wHI~F>QZNAV_W>8HSs?$d+NVcN +voB>Zs}ehtWtQ-9=+-zXfTXT)@~;pMymZgMGN;fq3`%mCH;PxSJ9H|^kSF47&Zb^8w{lsT8#&3`#_V}ZHPrBaHtI!VI}G}{AICo#3?I?6*C3#cDle* +N!gW5GPb$T=7=#I~mIABEW;3IAl6imZ@cdy>W=D;6mw4~bB>p9_0{;R~O9KQH000080P~d=M;;c?ovH +x<0M-Kl02BZK0B~t=FJo_QZDDR?b1!IRY;Z1cd2Lcli`y^|zUx;EEup{KA2#U9)0S` +Q?dtpEMWvgJf!busdMFU?GAwFJi6(T^4x10jvJ9{APiVf4tBJ0b0iGs09??y%NUa@8d8X}KQY{O@#nJ +)iGj{H)PMjzDJsjekbRyZKi_ +0PKv_9sFLYe^SAX;clmy{k=y;Ndz|7f*n=qaA*&pmj@ky+s>^q=d(RJ(bJRDoi(EN2k6iq1z^aqIOqd;zy_{UbY@H_;Tfw8w+=(la-V6{vSDk(W`)bk`>gMKOc~*ZpfC +ugUTpMblJHkG_!)*L+EycrDoG{r%l-D7;fF*@lt0owoKSQ +vab`4}?-?o^!S^IhH;rlpOH)$pYc3R_Yst$-vDDmOUD@X)-)@U)>u!0?1XWzL_tO1RY+rARlDT`iYgA +FXyB8`dAS17oI9y*5xZJ{yvGR(&W~^4^RzLe91Q!NKuaXt{l~?TQYJ;rTMV$!thr|Dk{m~SH?OCPnnd +(5+RI-fk_q56*pf_fv121_-RlzIifS(JY8d|dIIjwlQE%}<33z8R7;kINdvmH?C2ozP$ULEos&7SC%{ +ellg2V-{Wzh$O(d0R +;C?v~8ZzPQ=}5848loRdZZBSdu6iL6;xYzii1Vv+xSb5Cl)e+L1RMwIRIe}NsA?MiMnP_P~V7eIf{6( +f>2B4dP#Y*#!Zn1(}>przzQHZ_V6^l$cpoM|CXJpN!~sG7+F{H@4#`1lxW{d6D!-CZ6MAURiV;!CRw> +zkoQzBXA5p#?#G7COg*AjUjt3HYd2Eh@yD6j+wP2f`=reh87!T>pUG&AKR+Wbi*FXaV||&FA +N0vAj@pU9t;Me9d2grlTT;OT;;f)Gp#RU8?B<{=ZZpHU__g)tpJSnwlk~-CN!>MW3lyO@~XMQ`(ejh5 +0aC*|D--4Qv6t5xnvzAoO!WrU8QC^V7l6Bx+Yk@=^eH#TA5?x}*?T*ej$w9W^jSeAsXdyht}n&c5lJW +MsK)>aCzT!?-Y@<}qm4i;{aO)Q(i_g*?MMwLUti%hZt@b>xs{N=|!sOD*XB6O;R*s&im}sq$u%&z5XV +eLAi(SmPT%mP6**FUVvlI}Gq!DsoVoM4Xo$RZ|H`K>(417o{ij#kn%|{GydWhH3c%hms<@)Rn#&-B@# +qDkQ!}GbFc~N>C(Am1z0^#%aD;J4MHF8OGBAXaJ;)W(cn$pxmOw*b_BaYo`hMip~TfJwx%sPq3y2mLQ +(@)xvb~5FA*1Ln+L34sco!r}E`ar<4$pPx- +SlpaIqEY~`2OmDv1(a;%f&BM_ZV<~43#`1~eZ0H-{PF9@cmJ`kf&XHZzC%UHUt~gN_l)^$POG&mA@no +7%+dqIpIwwFb=Aj77K?4dD2Cf967A-v=MUm=Mo2+tR5NN^sn6>&lL$$we3(P|DtuK=?&Ei29-o|*9?o +pBTs6$Dy>48)b@yehe9vykYrV50l=NGOU_kj2GiCG%yR`8 +|{MHf^CNI}Dd($KwqO$DUWsMUGvSY9xp!WaH+;c+*=1kDLz?#(nzPi`|#y3s>cJK(T8aj(P48cs4KO4 +yrtbmJyMZlI`y07qR4BZeTMHI(nQC~(omLsv@J!E(|P(Mbz}@s8(2|Dx?Y%qAPC;>j9n_hzkUk<4VsP +T{69G|{v?BvDocQ;n#?>2jz{b%iW +4Ijr)nhNBkJFgy6w-7_aLU!bB{!)kvp#UoFJl%1rIza_b$KC~zzy^X25uSzMw(m>3_N}LrF@V0;X}ew +7e+Qn2&LEnqZ~8c>^K3nsfk|FI+fbg`xNgI(g_+0j%$VNw4aWUUFVLZNVQAx6N&GR%b+ENI;`EvcEYt|k6E8^Cz{dV`4**cM{$Mckm1LezMVgl1Dapkjwmvv~-Hm! +Jh?rol1NYygPYz5nlrZ}J;5_w$+E5NV?!pOhTS?+doE;w`K+i+tn7GChM4nSTnVI=K +UX#lf;N3I-tue)rTFv%^iv+`==a#&*o9$0nV8DbwKmJoy;7Lp0COn +imqGyj1%x-(F=)_?g;j%&H3k)Bj)y1lhFqrX8tS58rwPB+jV{UqMJUC*cxV~qH5Tmu&5p1v(=RR*jJW +kG~t-T^XlG0&#Bvt2pA7tAh1s#;g#+2#j6rD?GR%22>z}CLcyEkPN2HsGc#K!awo^&KWL9y-)pANGN0jD5gVjTaB^ZkS4 +ha69wNLD+9(cnik;6un2?$v7|5pB0wmOGDi*RPnxUlEZ{Za?!49E36VV3~x_q_i(B|kiAL1OqKD)jOs +Mzvy6`=Qu*`sA_K+R?}C`lBaqt4KIW}Xe{HUTYlm;ysWrY11zT6rh#Eit`>h;6CSs}%=PX@Kcs(BRyE +_>xG#v9@oGZ!FjV``w^#3J!srM_YhC1KYK3(FP!7ARh}jP_d)+WsT6tdY-854ERLP(^8Y2eUFgI3yHm +6o|v6$nvi|>h1RGsT`dSa5>Puj8UVX#3%T7uG-X+1j?=&`j7>HB5xF_{es7b()@-WnhXoII9L8`H-Eu +QV9Z@>qA~U-iLG?^;gm{fPLWKf~nM$;>`T_k2vbUf^DNzhizncw`1Jyl(I%Y0oXyC)YD$9K(cx7cj$)2_@iq%{F+f>e|&&w3oFjX6z?}aibpL{&@1SmVOk*WD2YO)x+a)=&-*y3LcjsUO +y1;%oz&drc~F^Wo>AIU8~Wwt-FuV==xm!wII@x`0?up{Ok?CCBb8(V{$hse1>(pvsHa86Y*)htY4p=9 +Qjw@*euh>b=+$WFVVGWXMec)F +s*?;U``)<(7kL4l!u}!!=}jZ8^PR?3OVL%Z010;KVq;mne>Gu>6 +9N3dS2u)_5_WzIvUsCwQ$KN{!6KNH3O1sMmPJLuh6LFYJJM;82}6N`kjqxd1NrP7bQdOc2X?3va<3>~ +Bu>$a?*Z_2QyWTC&BZ<^ADB9TaUVWBK6^(vkuA7y9l +2@kzEa$>Hx-cBW$Btt5};S&2NmL>mcFYgET41YjiVgxTFNp?N&@z(u=rP72a{ACVMdaJs=+lD$Rq&S~ +DYMxyW^qj`}2u9|bFd0_uBng{6waQuarpwQct6i!JYOD5i1!!)_wyP$olmFbw^%@Z*X%#a7B$wA0_CS +VoF?3myrX{52CPLfELSJlyr({?Eqvtjwc{3u+`_+Z;B-?E$AR=qpU(u-T0r4eF$tGM8hfe9Agia&87TP$hhi7Sm6v>?Bog2+Xp!tKY++}zQAxP(YEeB{ulGw%T}VjTLb2VLn(7V=*~I5;i6DL25IQMW +ZnTY!qfXTJaWIT;7zYiG$Y&Vlf^kJO4Y26$GE^nkm$4(7JVk9M0& +=o0R`V}dmnypCbEAf&Ty~c&{0Cjxe8T)ClFLKz(RnYR=?mG`DDktXDVw$!q*sus`oC**Hje1CC>0F%m +zNa9+TG=kYRDthmmNs2O4*6#<)7d0G$tCnG*PT+3jIRiMe6*U_*Uy*wE}LZi@VM1o?_fK7cho3)TgOJ +vMU0$z-Vtlw9a09Q_0WbF{pcO}c>u?YQH%}@OJHuKBZxgX_Fi&(Xr#iv&JuEsF2W`#Pl_+HZqi|aEL% +x*sOsHNSf&B%rlF19Sei^tDa?yWvN;}Sbe +L1&{I`xVG(D_?JP^bytF598pXb^y2PYn|S0S`?S0rFUbY%hoZ_*5%2R|{Ry|ADqUQz(paAOg?U)U+| +fyyU~%oOMYYwpuIX7NsDw{RU(;7y5z5Pe$p-RcttDo+p(P0e^e8L79Ihjqccb?Oq)$h%*6c{ +qHII#aZssQ=qfT>E@j>VTrw6Ld&T23^h4-BN1IK|0I>Yl5fy0}X0WGC7{K#1|KBylE$}6ShW!3olF4_VN*gxm(C(6yp<=TQ4c`a_e+n-DQ0MVbbtW`v(l#Y}lvVzBO1~1j%!6T^2f$b +0C69q&B+NQRKtPQY~FGoCCp#UswH|;`lk$TvWbWjJ;s{r?~SBed&5@^gVUr+iJvX^h8|8*6tzXzBZ=1QY-O00;o{l@>?Y>*thL1^@v35dZ)d00 +01RX>c!NZ*6U1Ze(*Wb7f(2V`wgLd97GmZ`(E$e)q2+S_G0>M<}rEC71_vX@(WZ(qMM50iGc+5^b}QN +R^~wdqw~I&Y?)^=5BqM1K1LI&c}28NM@^KMY3$$m`1TIBfP4mGK4;ASvH1c?fY!z#!I=|ak2BS`lS7% +VMlXNw4Tkj2wC$weWaS@vZ|;kJnnV-Iw#AA>+754vJ)=kL6njP$$MV^S(U2JSBeU4jR>+_6zmuTPxtS +;smAb9`>7o>nPIBpf|i-)f3uNX>fG`2h$~D6qn#i-=Bzec3O(}SMk%Q}Ic=zEbe7A417)G*T3 +E@vtK?u+`a3hvu7p>sk~tQw96FJvQatH6RA}5V_M1Q4)|yzljS7`duOv5`oR=g`23{c`K=v`vrNzmGM +j){UQ(^el2MiKofonDO|E7HJ}+LpXs5{*ti#Zfn&wY*2WubpQZs^R1m<)Ddg?@SDGcQhogY6nOr3s80 +m4FA!3Bx5#f$7%qX7v9y$m52wURrsmTibP9>ojzRRG7?Wo<&^yj^KDv!VstLLqa(O_s%)mD@RaMb%Ej +&#R|{^RLCMAufX`%n2$aY0&R$c8VaA=2ek_wK}DReE_rLAc3Fg^3v94G#?B@S(rt1Zl+>}K2x=b9)7= +_C~av|ngu$Y)~A|hjVgyCdsfzq=x1m(0{TR5Awp&^1-WnIL*CnFi5(QVa1Tk8%!Z!TRB5K5x!~J4*Rq +|GO&!0P51miCkgGV@E3Xso{zhsMb_a3(x +}Ue9f1sYc%Q}`FmMggD +W?SA45(f^x+tg%_4KIsKGsr!(lLsSI6E`-BpWhMyd%91=Vd=S7PX_8356~QtXu4$TnW=jvkEcFBSZWC +2ss)jJVSSE}@uDjqlE`tFANc}9QbozR93ULF_FKtqrNBRLg7`79lnAJ$!v&t +L2avN`w(s$^KDZVQ3IbsOAGkHr1PU}t@-I|1i}7jUnAgdCjn)0yoNsR{<2w(Ch@J6l0;9s7J(h#uq3Y +`}JCHc}oq6n3d6cG6=W@RMuQ*kC{g)A;d4g+KG@Y*%CM>5Pm|CkUlSh=TdMQRt4Dutx?hl4z%EFpF!4>_?Uxd +(3VRrnc|~LoDzf&Hb#-pfDK%?^ogaczZrLUI+Z)~=)+N)1k1Ilg7O#m8_Ua-U8`BMCf +C%y4iN*dXBc_u%XWX!YL;18OT_DHw|JipjDK+*fV@6aWAK2mtey7DrNv&_*E!003?i000yK003}la4%zTZEaz0WOFZbXm58eaCyC0-EZ4A5P$by +LAWR+6}Hf4W8N0zqbt@nL6YsoFjz*SZPl`Blw!Lrs;&DelttG?ojx$dGjTYuDt8Lb+n= +3`(o8psW+Lax3Elm5etvm(HzSv~x7W9wEPdovF1#`IeoG}+qLCSgZ6|07n7VW}rCY8)n6;SFiXFh?1j +MqEDMjvf;>j8l+h?+v5co`|Q+!E^Y9r)<=|WTxA<=+y6(_L$K}Zg7!Sb@?IjLE;XIrjP02&3j6<84|& +=Q%IMu7klC+#)_Al8F|CxR>9-V +{>i%9Zc;;ldf}K66i-r*?&CTb$fVgJr{IE0S#G|7VX>FMPc+{|Gx$5-6eU;DEO-eS*URYC8{^wKDqgdVo^PXWlKwl31G6ip +q!orOV2y1>h(vN5*_o)L^;FY3jHR6?88MPPnQ;`E8h3Md>$rUVw`rsPme1X%M}8pR;KV +23YM^L)o3(Gmi$pkeM=rykYMOX_J!oM?8}JYg2&x +gc&u^tH_pDTrv$Jk%zZckm_$b0-c7QfpsKG`F1-;N87%UgVGFY;5iK(?(A8DNT$1*Tg7z>9Qgt$)A7< +$JVA9QGg2pp?KN&3G|u!%$URVvDz4XUhE0$S9{I59D>6z9=Rl8WyxEdW!I8N4`nt%N_qy +RPjXh}Z7f#P2rfWA4??06l*R45anD&sM3F*{1&1+2XX&Rq1kbX0Y($nE9%_3ecsa40opP9C6_Flm}%i +aHJHybUSAP|1dJWvc43&~Y@2lGWRmLM4XSXjqQ} +g-Y>z`b88~9Og7E0R#;7^t0o2NjOp98P~IrB|~*T5Vnt(_h%Pp_h+X9*Q3B7c73D=ayb2t6Mc=%@Tq{ +qqQL{Bs3V1kim|n8FF%suQ+?}%)h_m<={~9FXHp1Oo9_RAr11M;;gyCSR)ckVG$wtSmqIhtbs{dN5v~ +H+XboEX3qL}=n?K*p-+#Kg{(0(k$Znrk=2U;YAR6tZW=ipqWcO&kC6}g(g~%Y{#>`@g_J!Jcrt08#n37 +#3%wi5JbP&MdrESrN3R+$t)cEf)QqBW^D@PPW#iJn_SxI3kRRxUFPMH4ZLZpJRE@R*3=kc#vpSM7)&C +8qAun`_&r=P{A)Xcn|X6OpUN0LVQg$JaCwzhZHwbJ5dQ98F$5OJhu8G;a=tIy7D}O%UP~# +*p(yq^7As3WN#0!keMjI8QlP5Rp&Z`jDcucZ5;5U)v|NQ`gIfy^j5S{M0B!bh>O?-{E4u%Dmvl#rY^ +jX2eM{e+`SM~^h68caI>pCZ-oun3u&cfAjIJ6g6YXufv*JkZyWH=mBIM<@6gFXO>{1xGdwIIBdh6Wuk +x#Ql~5*?aGC?pB)pc0Y{osk@vtYw2+p9>>e2WP|E7R}O~1kCBCB6?ctEEKvcXz$RVCUiUYZ`6e7_ +_Hh_oL=o5U=JwRXK5ojxgenIxN3EQM!T;>n7pWaPcgco{w@jQzynNBn5wl>Q$VVa4f+r9|uUcp3H;124SZJo +e|N%8hizJL&Q-U)OY>B(L1$v4`+VrbgN33;g`g)i`IWq~xW%5Gs&Q;uRIF&Lv*y>m&7sGJwBpx=KA1P +;fh5R6Ukk`Us(Qnku6+-Azb#KWi0Jy|gb-X#<5;l`u^xIH0RV +T_{mvNZD+cL~HLu-7^_+qH%-!>|}J;?te{nobRgI^2a6e9kRWHI$4X&W@dsC9`O)hh`8+$ZZ& +CPpi-<6pDdSG|p&AH^-M(DkbUFd8v@DC-C;DIg)LSJlU|uy>sjOw`R_ +>Ax^3(?Y1PL{it|6T!gRB5P4UKVNmW{E{+0qky^&M0=VK@%fi=3kWw3`hALcE?0;_!Sy=F|VPpGe}bm +9E5KW&s=0T-^ug0{uYk8PXIe0yb*+Qn@NKfEL955w|K^f&pF4Rs5PFDfH6qbtiww1vt`g|~{j@dmjc_ +GsvSXoL9?k^7AArpP$%fR${6^5eZ6pzk$)qN3M=+sM`2vbP~LTv*(`w{C+M|ED`D?(|UdeFEqaLhlt? +(QR9r_K%f^y+=5)K&1w6^$@Ra=U-#K98c`KB!&liP!%o^@=yiC);kGw9r;wi_q=nO4fTCWacUb$^gmE +b0|XQR000O8^OY7ycz{pFGY9|x5*+{l6#xJLaA|NaV{dJ3VQyq|FL!8VWo#~Rd8Jw1kJ~m9fA?QOxF~ +GrENvfyMYO=R*~Kjo9D-gBc?bf5mMEKDSyV~NUiYuR8IqDneK_l$9&DMM8P3O#Gei0(61|H^CURcw?@ +6PJ=sk`s3Mq~xO^Zf1lBFr($682D=uU~U(JZyU7YjFDiv1oWv_FMv-_BH4FrgM!V$JJ#M-|J&@kpz@7 +5h8;v*D5*S*3roGd(%4a`xI1ex}(A-Loeglsyf5%~-9us8mbn#5_tV{Yr&QCFP23NhRcwmi#Z4)>Iz`T=5Q9ZFyT2Sf+)%3`uiV!wf}JdX0|a#Pa9rGq2x +&weIZM&IiWImh>zB_>E=Hcsm?0yg&x0?%@}G~dP)%R +{Kl4*bLvDTE{!(MTeDc0~|a;7A4-sWQ$~yf6|hFNb-85z$d?!GuzdRBsKRC<-PO(FaCoexj8|0#QJOw +Gko_x-~DsIJ>eEg$9r_k~b0u*@?*u;g!;~EMxKn8Xg5sGfg4FTcQ|4@kW}BUM@0qPYznw_jh+@2oOng +Ai|kg$o(Cw?nP1j1f5s}uszpav- +ojSKw66p?hHCFJK?iaq(}F!`N)@Zw2S%`#qaCLc%~$1@ +y}4442KykyrHzC{eyIc18##2>I5Nh8Z2Gn66&Q(G3?5Z8Dgkb(^g6hr#B{XM3LX>MM?+ +;ul;5Eq?SkRPJRm=r;}SZxD>9Kf7dRHWnCBkYzFmC0&~v7k+^HN>B-1LiWt~#a9v@vkn-L~GmnWqxz-(=hI3ZQiZkEqJa8@UFNj!Y_u?Bry +a4T0lUbD^G|rWuYVD_UbhUrhvg`S_|Og`%);?AFKR#1Q>;$yts+S0=y3^~Fzm7{<3cCxZ`I1OTLNa4E +~Vrn{2ez~XQC8`yGju1Z1kG{fqD1EZ4JZMcHMdW&K<^04KQ=O$3?OR=NnHB?!O8CYG#%?~i=!^$o~9N +`4EFoksR3KPf@YDEe3g>b26<-?D-CKzFOlV_ksoH15GPsvg(n;}7)G@ob*{pwVre6F&x$r+S37D-kzX +wqFHbz-HcO(llbMwzIRUoWl5?R3(_h66JS)Zr>uM45fi3kVbF4e-lAvns%nIUls;$|F9~7v^N7dnuYa +^rJ^$WzyeDboRXMSpNM8Gy$&g+2; +Hi-TiRh-JTrbXwRx(zSMNZy1v=0;2v3a~xU=*;Mz#ZDCF#wnMfOm!5aqxB6ud)+*?NGKQhOZdgG5e;V +aA!w(68hT5Dn&}R{^3So9Xs1gsXny}k9G>V#fFKNy^`BQdtbJ!pUs;Jg-9T)~3)kjd{8MMG}$#;#(j$ +ZunF%AmMUXS+Z-!px@*O#p~-faGqj0uleuXOMSfv(wg+jff;U-|8>X;o)-Nl>u*Vyi@Xa_v>>dM(!iI +hsj6yNI(awI$BhiJoncpWpz1ApRES92osh{?S?#Gpsmi&){Ri%YlXUj@Gc07w3LIwxK +pA|Oa+m$`g_X~J+e5~sC#nk#?rx9w=UiQTJG6A_LYPloBjUb2e$STs_dq7DwXIF0OCg9TCeSl(9sKMl +8FQ{Vj8K72)Gog(ZaG2*?ivpp4EBL-ah;u#F=P!*y@p3zwnYw@3PN8(*sIKz~eKeZ(u3P9%*(; +VIjkm&?>w|^510I-&HMK(?p}39B*!?0{x-hq9uwHPBHjWe0r6sRkRMKkF4~-pUuTN5Nv6iCjS%Tp)TM +xFRe;t!S9K|`sO9@%gUV1n@$JSKPap2uSK49!8=2&rO&#dZCU1JAGyH2WiB#ez&pkY%0{q!J|?n#5uF +;guCR0NfFH(i%O%;pHjq8wZj_dSbld>kghE{%6MYphl4VS`4XXpBJ|CL5b{Z5~LxtIJN9nL@@ck{q_OS8$6A*7W|}QEvz_tr&TOz7HCPkgB9C{N=SVJ-A7}?hG(+Yc+2)D6^o$(;7S#mW@Zne +@SnA)BcJe3Yt_pE=5cb#?IC#vELZQX%-Y?{c&?(deLNH;-upG;z(uV--9^-hae#lT88+~uZqS +5u5dP_C4~T5@;`K5%H*Z^`?L}RTm#06p`z;!~rgES~4E5JnUyZSCb%z>TjfHA?nP&LOT@Kr8w`u)%?W +TACQB1qdE+4vXmeBcdc0Ra;O2XXGp6?-XefvHyBD`|wWQ4=lglwj_hYinpXSG>xru}NX@rK^sf0j>_m +-eQ@1_g2gY5$b40h&6%&uMG_X`B8-ZCdG3ZAb{_iD{&vaZ~*Wc5~C>o$H3HTyfxF4;b>MPVo-|JSY4Q +P)h>@6aWAK2mtey7Ds#jtz(o0002r2000&M003}la4%zTZE#_9FJE72ZfSI1UoLQYl~!$U+cpsXu3vF +bP{{5aIZOJs3>nZZ?T{g`i=;(16ahnvlubk?1(LEWU_X9GQnI8t?$CU2MDp%<_wc!wIF4^^mFHkr)B+ +QE&b0v{n@=t+e5&nAN!Z|lP|^UE49bGqT3p$)m{X`aA;s^YVpSE`?mCnUc9!w&F}=_K&bbO +)EpX-H3n7cxmCvi+|8s>7GsJL#EaxwW(A2LDQXsjfN;GW11Ut@YbEiz=Z~eeKSt#kg2_UotHyZFVgO$ +q9n~HT=cfDKE3~*isW{y^y3qiS=f!Dh!9#7$b}2|>J7yEK*bY?cgk*28E!~fXEa-Jw?^ENL7Z4ckaF= +P7?RYA4G%jIFS#Z7PAgIg=GMltLM%x6xb!CPu4b3>yIa(~N2f&Yh?X|ICPL;4e!GCt*#usV1AKiS(D~ +20;vFvnu4q3+_7^S8UY0lkVpOFw9`VBPAp_RsbJkbXP;2!Fk0+4q*-6I1Mn2H%o_SBfy~Y};yXTN6%+ +9Gpx-%vDcTs9EVmyc8+lj}l5v +zt^lC+`rootGU~MrMNYSi~}Z@sT1FJ%=%1tV_~ZDl_f`7q#X6hz?zL{4T+FYs@CjPV?=-hQt-h%qCr6 +t&yllk^e!nQ~9x=j^L*8MPU9frP7?i@i9~ZRIm!ZeExX+4w)bm3po|VVL*1(_Yf%l4R@eC7jWcUx60C +j7(`GqGqS8PhxfIqU>RoZKrG$|!?JW}Y5WYsH?%-bqv%>>S~ZgJ6W|qTx55RZwSkv#`U-!}-kh9_@&C +^!@bV?Rd3v$4Io%zGnEDlHEEb2v*jX=6pI`3c +IQnt|Lv$x};O=4b!qJis>(BuaB@DXO;1ps$ZX-ygfNN3-&*`$7k5(@%{5kX0BhmHXj-ru*!3wZTcBHg +XizB{&wBo8~Dpl0h2H%n3bvu1{_|v~Hp~*HmDUg86MoRJdF55VYeTZKDHhXMu1Fj-XNm +qmNaO2nuPJ%*ky2aejS0ze{>7$QeGYGN~%L^oUQ~YEEu0=d^hy}y}V&Hg+GE7lwoCiIGDkFco<$u(UFTVqkFT+qhCmOBW5DcDXGv~K +p3&#?l%aG|BbINbWg>aJA<*=eV +PXg@U(-6E=8Io}Bd<%EHMf*eOT!yBncy5+aJ1)Yx4?J6TuT}?&XN>D=HU%kd9BEN&SYK{sn59OdMzX> +EvUg?q|*_&(K;h~*)3{bmA2AvT&Fhi)D9CM`GRC8ejHYlvI36q@JB{lQVhU$o}t#LdZ#b`7hV? +pZkW*`k07dVv_BJtLd*OFp(yG@BreH{G@6aWAK2mtey7Ds}jrI$?=001~z000;O003}la4%zTZ +E#_9FJx(BbYpLBW@%?GaCz-KYjfMkk>B+zCQ@7kZ5pwCANHb(F2$87n<<&nk+i*AGQ$FaA&C_TZ~;&f +?<)WOx_cfN00WY;y?eV!P%euEW_o)1-8~JSu<dA>7Rq_Qw6rJvxCo=YVP&E|xia^Xk=~U%q+u`W2gP*~c*Uwru466s}#?jUqP0F& +P{3jHmZJ5R-2-f(Uby@eXahgL?|+@Yjn27KB-zhO*xntLe=W9GrO;Bm+^S^_5m +pjiTxCm{8yGz!^J?7IpTAY_~MI!SZjc6nnRy$sXIIxFLiWQ5_I1%6cM#@8Vtnrp2q=*ks2939>E^wk$1=c^AsfdXYc5!e}OEx?8DyA0IG|&DvY?(`u +nZ-@_(ii{QuR@E)j1PxWmc!CWvY5+pm51IiO&4BaJq7n^sdbaw#uEh|s3Gvh;i7bg#~TtO0FENsEEzQ! +$moEXSwys|@Da|~iDm%P$wdofakFL;Xf)nlz1!sgWyB7?>@UNoR83t4zGdWs(d_#IGI`5v6XxD5;waS{fDimYAD}_FhzkV?v +6MzNJ%bj(hBIshn4CAI;;;6HCdSOz2;COn`s_A*J748Di{l95VMD5RGIzYce4 +<8oyJ20+sU{E(OPXe;81o(FR!aaabfD}so}gFO>G2%0vjmm|A!6mj^EEWUL>|!j1>V21s4T +QF4!1ih{2=_po4?NkZN*#eB4zClTQyx@x64bP;_C)QK6C31<%8ruclKc#Z9ZBXP|}%9LfrX=-dLP6E +f!bylNQGM>yh98)eZc6S!j#{0bzlvs3NxD#njdF54E%LaVuJ54R|3)-(ukhY|39O>M<)G&g}g1!FpR% +Y)}C#8{^Pw!dSc;DyGYBy +FmUH{@Jr?0+@KT41bO?3DhhF|9(7TK;@NkKu3S@jnFg6ZVO-6%`8~JP;X~ZFq%iU=Un%7|C +h8UR4HBI*&`0rQIyKXYFb;FAazZu?ku|gpAXL&AIodY3q@ha0^{ODdNp#QUqM5Ot5>&i~Vw6t(VAn#Z +GuSWec5sIV6_wl<`;dKC*Wq(}ybzIO;nyEZ|VeY%QXM&+k^?c3Fp*Ow-Yo)?9chB} +mf-eLI+X}rx`7z=_sPn`Dc>(fbT7?yF&`p>x+OY2X<^b8Ad85UNY3>2naM(iHkknh0`r_&C7$y3kgcn +UI|0$f7DQv10tMB7ktDc-^@l|=kP7*rkXr6d>_{=sxGl6c;bCw>ySrm#w?5jT_uNuQ^eH%!QvEDzInE +T5sXB6#}dN(sGbz-7f0CzRar3SBX#LALst!L#EJG1Z!k8q~A&7+6;E@Rm}Xz!Cr4u3R1mPP-x=K{nupj1yKuCVp@vDx|Lw$OH$L<=}aXK7<4zUR8RoMH80YXzX)CN(m2`J?TVJhbSX-6lZDGNLhPBOnm=KoL*%=td)jF@mz= +2`-_8C3>Sq3qxk`4HKu~{ajjKFOySVPcmps|iTJW!u)Wfj{QeG-h5uYunRMAnvu1=uD6T5 +d%oYun}u}kbz*DtU@JDpX~b +X!%XpRjW@vLxK%RJAyP&-5tlZCYfq2=6#|ilVo7lQvDg!$eJ{zhSvq;I3^cPWjIB=K^SnY=m<)V@xRn +?5HADEJnFl0)wckE}@weG_hF6oLxU2u9QQ)Y)Xcw**$*9WnY)-JP_p|eTXakAfDEe8+0pP=1I0Ww^_H +c;LEBO`j%2vt6Ju&)VB)ZR}BxMQs5cqsxL8oQ<{O@O+51<1;+j{;n@r8N@utVeq9-fnw8WlQB`~cgq~ +eMFJ~bpC0o+zw^ZMQ7_u*AGR}>IglBO}^DMhrX}dG(7+3O_=hl#J_WPlxI*ti*@R%rTUTz+|Zr0) +NMelz@%>2PfFX9lN6sttIk~CMy<6#$V1swkrbQLSUIv`v-8uBY; +e{fN?(2ksME(TXyarV!|%hn;K2_lL{+ZU2sC88?4?LwtGpL=8j~^mgE4_>pg72YftJa4Zh;d6NLz`mQfTGUbR +{m#0yzow-NI09ur||o19_a_f9b^9ewes035EVt{O|vToV4wy5L3`!5wwD?-2et*h6_*mBLr(0CzXA3_3^Y2c0mxUj+D%z>qp#6Eool>W~@3IG +xgikNgeD7gSbi*LFjNz6ysj1+6M+Zkoxgd6m!5?;$CpeHbqoG$|6-fc!DYylfFROipfH0t7qGMsz*3a +w`n^T`jrLwDKe~4We1st6E@(Fpq>FpM;H-T4-g7~1#UV9Dv}}YK1D3Vj4zQ1F|$!1=&@58^;_m +9;b~{(E?(-uS29zx(a>HjCrCP2Ky|YMi0{P(gajF{pLJM9ZyZ3zcE`6iKqxy=lssSt$#Z;>B}QB5vm_ +0$se4{d^}catVG317IhUhmHiY#%rK<>ED{>_tIOSlpIiOR~pgcae<}_6bXqlEbeqFKsg6QzD=)@3P6( +ClnR?C1Xvlc)PT$(M_;}PNeY2s8^`e(UBy$R`rWsrn&Dc|`rQTpvRN#}+i3iutSB(XG9Qv?e5(#$I1uG0dD^{BA10fug8XcgH%>>CWtwc=d7bn!z*W%@eyxo$A~YoxoQTW&%Pqgqpf8&s*N +7)vQMH6E!QTTLVEF(ds%3)2xNZep?EQ+ymXz4ib5`ew*;KnL)8K~zTyo0yjrg-r?EnC=LjT4O5PQJ8YY5Se7Siu}+ZCX$jz~ypaXcyX1l2^Ry +$Q6dJF7WITP;>+s0BmK(&yw7kfD&P>^jY76r30goay+evwNQ$ +p{d?!7|?Owty$eTt-M2&r+}*UZ&2#XiT|fpeQ39)HP6K+2Yl4^X#;G?28QoO=py{zd-Z+76(sIbWm-v +f1T78sgE(WEiJUN+5RSo?u@85rQ=oYu_J?IVKD6ISk|Cg$0~})7u9pyYaE0Oih?aEls~_*_EPwSwDe( +v3v9bUn$A~wQO~g1*dfQjgHFZJvQrbfHMSQ&3Zvq9KM5$3*FW;1An@9+wbY?G^!fl8+>4(8)ugU2ijR +POYf`BdOR6#aYG8u;=l~2UZp=1ZBd3(^QmYh9=@7WRJs7nz-htXEifCV@ie +F7!S?Dq8g|~oMt=2wLiOrUy#-=uvAdtk#Bz43$3^wHbGNHPGuBcF{PLEggQb`^zUv65VS1}r^wN}fcf +V+U_Wx+#N>xHZoPj2TEs{uO1$?S42p5CrmRGk|EXj#xyUGFeS(8?2_8YT9tb32^(Qclox@Elt0#?WL{KwD1nkK;iZ#;D#5}m+stSUhfwL%e&Wb|57~0MeJ8 +#))B#$#mx3{E=M!blI+6xZFA^&ww~@;19l7JHBeX8@9)9fY$Q+l;av(WH)qtA6&aI%jLrt>Xu|vZbN+kZ7JFd +5GM(w>lt_uSfBsY!2(v5A2Efrxd{htQAQ+tx=h~H+uhek^AnbU6Ae;DX}8viyOj5O7b+sZ_V^?_UH1Q +b+70kpY$2SGb0eZujngWUJR}-bDk(!Kk)n5)4a;i#-T9Tbc +%n_DrhK0uag0Lynqm}fKp%U>=URTkc`+{;=xx>_Z%ES$-P#R@sa&5qeednQ_e?XPg%@D#Zh$7WsFhq%y_@z;u%IvR8RYJ5KU6uPqShD9(5f&z@p+^}liar_DryKg$6wRSpk}4I&+tW#-2#LbJlA +>iW~!YH@89EP0eXtPnygO8y6mteIa`WN=TOrAyW-I +)H6o6^ACZUtO>$*$(w8zfYs8$R>gHeVgnTllIBK30{A;(U{7#W}^Be+8$2V%4vH+)k7#Mxi}07n1-02Tl +M0B~t=FKusRWo&aVUtei%X>?y-E^v8EE6UGRD99|(%gs+o%_-K)%u7kFP{_@6aWAK2mtey7Ds4KGHu}i008F!000vJ003}la4&6dWM +yn~FKKRMWq2-dd3{hpj>0euy!REkHAt)Ej>H4F@q?(e>DE;mN3lWhd*V$&REYH{@yvMa88a>_K{D>@< +AB)^+{}VkPv(+CfU|-nVP=)OOkQ=QYTNz&o2KbQN2HE%@HdU;+4sELH>%X&N97zuVCOXXF#d>i1*N1X +Ch8!-wjDhO>?`te6EdX$tYy&3+3Kil8@#Jip9YSx4B$z(6>fK1QMxDiDiQEQ0LjgS@n4ZGEGw*{eg*Q +*s+q|1EtKr}lHbYEXCaCrj&P)h>@6aWAK2mtey7Dv)CZ&hRj00 +58=000;O003}la4&CgWpZJ3X>V?GFJ^LOWqM^UaCx;?TaTkQ6n^JdSTkAyYT%)dk@C9IN~=}1ZC^TyE +C&vW6$dl6nIu#7zxUYOOae?=?ec=LzjMF%P$+pKloqwA6;Mj}sglYNw$oD7259pg1ns_%`#mrB-KT>7 +q~cXjSZ26LGkL0*>6mGg3%;Y(ajyr6g4gc+OQ{VL;yb+7T)_!SGr(%Yh3m#qw3wyXsu`+D0H=mi%-T`XFYGLSGrf*0%W(G5m-%^|p0D@*LJAk8z*TGm>^o{p{5qjA=g +j4RsOm;wor3~CQFFdu^y_gYNflD49l5eQFzNgH5U`c1J#rcDO?P0L?e&`TK+b@JN_0AdQQrSKJIO@2y4^e=8+NMGwk=9&?4;N2dc8 +lZbbIuF$q@=A}3)|kWV@!pB%P{WK*)t6)J||?|<&1uu$2Nm)*m1b?3sR$0o<-rd0nMhoPeSl^1K<%r> +t3d{*)uO0SirwrMzv#!@>fP_NYXw5_X^*S@g4-ZB_*=H@^o>JWLyF=5)mX@ +NyH&X_hIz{YPH(MpR-X&f@OVXdMVi+|SnJ`UeZ8EqAd!sl?2F7g@!D|4?;q#BsY4mOh^enfUJ^S(~~C +rp%W>2uG*#|A +rP?q};xbtpUe;|h_aDrNTStcpxadwCB#?8%b^>mD>qqRS(e`mkyK%3VU)S4o$qc|d?lDdR3umlu&p8# +%BHV=2QY-`7G?DvZsOcab-}#)hOy=Y4U+CU?o}jSD4&jD8&GR|S8q2x8HP(1@Kh68VZ_SU!_H +m1_g|j>-Zbtd78NR=vlkEI$4nY3={?#too8qj}tfcX!!h0 +{=j@Fq!99KE5N&cG4h~*U>-qEc2^RPNpV1Hf3w!Z$uQjdI@#E3{C|WS@gu#{HzsPF(&H650#2vww96T +}tjWb0lA?n6Tj}4V)Bf}P^)FCM0|XQR000O8^OY7yTxrr7fB*mh6afGL6951JaA|Naa%FKZUtei%X>? +y-E^v8ejzJ2Z);5XvABzZ8z0{)25AOpXu}4a?zK2zdq#Vhd|MU+^{1#@_#0ciYINpAD_+- +e*9&Y~~M8O9KQH000080P~d=N8H>qutp020LCQ%022TJ0B~t=FLGsZFLGsZUuJ1+WiD`ets4Dr+s5^G +{S^mi1;th2(w_!s5C$}HHV;VbCLS`tahVf&vTmkG_KviyHvQlC-hCfGTz9C@#^T+*ckla)Iy*aCd|*H +IT(ASHJ4trDVx*-)^7?LZ2D^)$XbvRLcYW6jmgj^Y+D3GQZe>&T9n1CeVqw-BX}<|(zsY^Y9^HYqL;T +EOZh4#K53DX5kxBlT9hwIwvtCpc-`cy>c|s-8%ejW12e)v*Ovl8IR(PAm#aj&THAxsbG#u6*6)zL?coU*LS>fAax@SwBkRryru`wv +)wKZWuxy{Eb<&E0R?TyO`;@}i{QHCcCq;Q`k&|T&hroFa7M7KXbvq9u@uRV%YE0iU-2LL6$Oy4lNBDh +NEfd!-@QA3e?0-U{PF8&nST2s`}3cY6tMsM>gw{t_4%9p^6L8H^8H7oWI^ELsRU?{n4laeS`GJD$ve8 +O*k~i3NcvjR-B=b5d}h +A~y&w0COJ!)yr$wb+G*>5ED!fP^l9o%LW7|vEisWC5Tv1jT`x>lGVWMAoM8A)8nby}C?#938N +#4VykT^A617YfrFIHU(+nOfu8747x}!~>o|n%($@EQUlOtTj6q20MabkW(I(UD4v6-m$mpWCZMm1_&+ +%zXN@Mb_&6j@P@ZXutvW6=6@&)v1`#eBjWWWfi^W{SG@hG4-N>l8Ugr=9qB|5S}~aur0@5&>;;I92{2 +AtJC#2zzd*z55qWAe`-K0##uHZg>M!3}-Uycjtz+%)q#Uf{`qb*YvyANTY{IHja^O-i^_?ZSB=_ueY( +z<@xa;xQnw-Um5<@`Z*Hdj*xw2-=uHbdUgzL%i&J_5M|GIJxV*W0IDs-T5?8=UZ8n~`PbfnhR;@6ju<{&KE-Lx2saGK|53C@&mZNoqQ^z9MvoZB|GCLDs$8<*#cMw{ +Kfph|V7=43St0@M5M-M?a4_z8b{u{a8gA*1Mg&_M111%{8qa6VJMM(flZKHNy=BO~+mg<;FX*&}n)zP +=ct|SJOP8mAYVh%7M6eeh&lkx1HK42ywY`0@Yr?620=&`b#%y=u6Hvrj59h61W>XhD@uoK*xkxLck?2 +Xe{$$_3!bpR3ppcUEn9pcu(OZj9u&1l&`Mf`v9tFURFpWqkhf0A-lrvUW|+XM%WdeA!T7}AklOY#9sf +VW^Nwq`+0OImgNroV&a+6!Q^Q1w4@qS(QZA&Kl;tod1)YK>qUg2z?NE^$dKQ}Z}7nTfmwY3q76ZG{=h +CKh!ShNW%Kt5Wx2!o*Z?U<$lpRMhJk26wZX>k@2m)R*W0guZ99mnj{bC%zzG3@r5IW>7%Bq-jXHenFXU|l3Lq1 +I8PV>Q(YEbu$4GAk{wG%lM;>15-oFT0ceo~p=DvDJgS-8gB4&E%dH_qHX^wN2`dVCga&DkKdI3 +5-$)iZDjd7M*R_rC1n*DR>!A|@Z$vLHxWmggleI%wO`rK6P_Ja-#I56IC+w19_z +4sNdE&(LOcu8r>Sc0aJM)pWv-6Q))1#(werPC$5^c7yN3YS9@UBrG!?7+D{yw5|9Fg8aj*(8aGp1{lK +CA-s!Yzb$)9ZY=+plbct!QH3+qN$eYw`U#oX1m9N^%8JlETSsO;m>m4euW9myKuN6T*GE=We|Lyn +H8s(7Pm=ALyr-MExsWij&*wy8`z>hZG~KhUoR*PfouM|Wbd^O6%RB4kt{jYUn-b0KN;R&F0B%RP+^7@ +1OgZ@^Qh#h13Y3Q2q-uA7;;^goaEQ8`tR2%4DRx4Qlwdq~26tnA#*^hqG~;77aE*6HcMOK#@;3;@^Q< +nHldxkk#8dAlsCSfq-Jlu8zJQ;b_^rtDAzzKe4zwA6;5ORn! +TDQ+T-}6$o3c~2=}irh9tke_|LoZHQ^nE%N~3ZnxmQ*46ECF###buD(-QNh*hwJ2C`rS3}!F5!uFmJn +sN1|S|wFefRbD{;t{y8-8EBl=qx&}Izwxu{?1`?oe%Z)nQkTi^}%}>`!!K{*I=lXYVJ5p1m>2NrYc5& +qBm#RBbN}QCsC&3irum}d49^IycjZQP0+^-J$g-)T+3*t%j;u^(&H$kWXf +Ka->kWz+wH;77;GZ{HJ#BZqu-ZTB$6E3y3_^4TKtaxtRwQ_e|&naNP4^uS$iY5u$Igdf1-yZSk<7Ywn +rqxR3$UHYX%WU32aOrSHx((9QbRjbGIYx|ZIGvW{BHpg0$uJaVv|~ngEm98W97OAnw`EmbDo~Lzs0Wybl@`wM7O>!cKVthtvbA=^2kzcBV&SSNa}Wm +ieAlt+6~a5M2an$al2ppi)!=^6~8N+v!%>=_^8VGBGhi>&2{hTw`W|mR{0k3WHSZGe(H6b@~2e+at#? +ktfV&9GjEcNsZy_5-@M@6YC;JL0f}HjS-O69ymBcvua=dXLjOcNXZfLQnG5dA_sYw4&Tho|3qMk#{(5 +965XIl;a!Agq}PqD1g|l04o^W$1B>|=oRD_F12&6114GH@grEl~2X6&?;7zY5+p)LWHzGIQ^X$70dtu +~y7&8s@~Q7JhU|ni$^+UfzuG#1$8Q#@_5PBFGbNKcXzd5Zh|@oZ0CXVh +@oOk`Uyr!WJ1I?`-M}>H(~=qSDCCD0cV?Yeu^tkp><4^{-+iVTZOmVX!l>tTePofKMw@?QDqujYuZ@? +J`O9>?j?c3&atXG`K$1Pbg7qKIh-G#f<7;1r^i@eX#0F7QR1#IvuhP1an09GOSEqD%?qg%ikHye$1kW +G$&@~Ks+Qq7M)ZBX!j$fW$^PF50aXmS<6&LsX~YE{{c`-0|XQR000O8^OY7y8ZA@;-zfk9Sf~I1761S +MaA|Naa%FKZa%FK}X>N0LVQg$JaCzlD{g>Oualh-YK<|11m?NQ&CT`z3jN@8Tsux?)ldQPu-5CbSZM(J~lX5Y%^=@PZ|NGG+@x +E?vZmQ-+{@D)lSI^|HVY3^nTK)B)ii~XAt*crUyf6C(V5#pvRs8d#HTG#$4I=^?a{O2JYq=?#8&>pfJ +37S@-Qcoq*3}LF&bDP$=Uv$ktd~VzGPZg{Z$w*N)#b$>hpC;eEdj0& +5-@VgCSM7aMx8+K8awv9vJx$=BVr&ZlvzaFNFaAYephVd(HwcoZMS)@;maH4Awox6<9wqR+YKF0_>k> +b`==&DB@g62P@N(F7SdXo~!vRenO*HVjU6ujZi>fKQhiTI98l;(G*Q{7y+*SR!D{I!=O_MjT-W1PYeE +s6v7sWSUzWu|Cx5dj>U%z<${(@ffyF$@^;r1t +Ewj~$ssOkM(-r3u@KD;)d*nZ8~h94EpN*kq%3xGQ`A*+D;nLFw~V*evzjK9!&^cN#jsm+eG3E$^?FvW +ijjR7X?CW`OQ`sgeiZ~`v8(D8?;`_*_eS4t*eE;ARzQW&!M5>Gldl-iE1wOCrnd|Ub@i%wQ+5CH9bdn +0HNhhEYFM#mEa0s!*s~w;|1gW98?vyXmp6cccjjWbTdKK&pZYy53Hb#(SI`?m3Sfx{%wKXG{m{!?j9x +q^%8FR_zPjYW|StX?C*{x}8Jwq-+s^8q}Sm@AUy +97ha|tf~=L(fnlz-JPoLst4DJC|eE%tQ=7?*>$UOWb<$PodKq3IhW!!d}!SR@=u@>QBSaH(LeFI+BuLfEI&5~t=G29)HzJTeC4;>o}Fnqp##Q8IKtK6 +6tzVjiZiB-++0j@_m!&V6n9sadn>sf@a`VY5|96uG3f7pdI4L~9Nhl43Gp-@Erd}N}`op8V*tsxszUa +5KVm%ly=w`7!YU)dE3W8R^#@t0i=DHnMO{Kx*l=@>roANEHnSj;7DI*sGrQ8jD6eVdE}pVQ>q4IpCE) +~g{Ip?fxwJg<{T7iA4 +ygPj##J|M-2PcF1!)9&h(0c}&>v1GwmlPqBtfHmdGSHNYLZI8f2P1)0A%f?N+%AFopD^}J8??t%J$O} +2aT8}0Ms24#{(WF1&yffRC5WxtMaHs6=_-I(`mEWCVpVJP6ZdFjNmdQDNg^IX$#{787rY3e(W}z?>No`yqUmKY5AYkx0PFP3`@-9Tbv$vSmFO+p;4Fi0u+;mAiT@K)Q?V +vGnZSm;G%x0%gzUtb|3BTt7&`@N4AUstn41q&rE;r~t{c?_qWM;s=RWunB8)gtsL^i-848DuAXy3Ml( +=K!%m2DBfPAjx1npriNmd!EZxEv_wI#9uckj3=A4~?|R7ikR$S&{ux5JlIuv$3KSr@4lztU4V5tFOaI +*0mJ3(UHw(xxFdbTIb84BBMlw7UKD0ss@eVoCQg!G0qe +bG6l7>%CPQIcI4dja^pjz-1S&ClWZ>r@c*;Y535%;6g7`3V~H8xmic!XwABTWZDOb09#)Gk~=93X5A@ +85o%o89>+UO+NCnoMYkI7^btZNn5-sRvx#o~fv&v7BGa6>F?8JL(PM2ZcgkjocSDq517CyP-oOx%i%QPkhC7%kDrj|ISz{g2rs +uOOSBqJnHCzLkV7y`7hcAESfP&^9g!uCl3kUbCXTEWWs0Q(E_jyWH8it7apZUe(<%=+{yzses2x2Mu5 +TllkN4l9TWbF2rM4mCuJd*Tq-Dc=-nM8UxT@lgrCi@f5T8#8$mk|ZXi3B$H2m*-tsSKO@rQWS|%FhR| +gDL&h~?p>Sxo@IYF$i-eJs*)H3=pm$pbTGZ3k!^7`MKeor6s=I$Np}r)Y?TJpGJ8xk?` +ZLnO`EH(Gyx<-$ClN)V%m=8kB$Q+%&PYvrJiclz_aXu1It)md)QtrTW0Lk-N3}z<>ey%Ut0!|P>!eTnLvjv`mCL|q +Lkeq270yjo9#AN;RkN(s5~n0f5R;!R`(acI5*-7%hj+_#+hracl!a%fx(65OaY}397Sbu4i3<=tRl%H^A|^#r6W=YHk0l|1Gv*Zx!4OS&&9r6uE +SzO%;_+rnV`5qC3*H-3}Q9`AdaYX^om$j~<|#zFawK$FL%5t)HNK!*nxnq~!RY!e~#RO +rlB{2fDuPSU)}}G%M`-bIoV3R{HPnxERL9QS3EVeZCPGP)?JtL9X3(FcZYAg;+4f;Ys6c?v2^|=16Z-e?j}p$4`_%m2hXb^Cz~4ZqLZVx_I)#i{yZ% +M*d`yvB*WWB7{LO#ZP1QxEq}-Cbp|Z&{5ZC1`)kC4QSP6>?6?l1Jyt?vvD%f6pYl^;jV8Cct4dh7WPS +lbxYRbb3zCYt4PtFEI}S($yC}6lIuDZvkgbO{xo5(o1wgU88nOfEk3cUN0;C+DT%IP!7`z7go~4{2la +JW041Hc#ACSZ2Kq79l0ITqvd@_zL-`=k9cb3lRGc4e=tGZblaJ37^n+e9BlaHM{xkdV>KuOkQ531XHU +>E!BRBjc6VZVI!@87(*NL~$Gv4I&{5VucA{zasUsY4P_UHu}-HaE2OEq>|^XbnS$C~UVDvoP%`JjN;u +tpj{)Zc1ijWT@KQOMFzwGf3{VV8Ie?c7toSXn222V3LE)1Es$uCp3prUqL9amliND +lOIVcys*lFf9FmOXH+gt}~OtrsXv@*P42RN&G1u`t_M~jildciWW1#Ojau%eZ7)4M<45A +c}qgofRF@B(z~b;w$}&ayROx`9f^+K=- +T{-ZSTIspy2xT=pFqPA8Wgq*;8bu3@g9%$Pwn>2S)5Gw^i4xDq7*2!nu3KbKvQcnCx^(uEbNr^w<$k} +!EzVxffbBSiiowyoj!?FD&FZ>XeFQK&?qXYg~7xF@-=!RitfSfjJZS&Z+CL?x)qLaBEBeIy-r3&q*V7!)k)Dt~--4gVo+@$R%9Wy}k55qf6-aL$(wt0rXMO$ha<~9gOX2s%5*ft#Y7?z4`Mq!nmcg@s4n1jiS&|RdeG}ba&;?oHf`)H +arX%P)$+V55tI347^7dndwbZ!Z5F_1us(vIBunSMCJR?<9h%;>05sEAd!TckQeOYY?vqsiI%_KC<1;r +-Ybng*^{ZWNa8f`iF+xnyT^5v3?i}hOrexI+~0L54a>gjMkTr66sn00m!luRx=GbQoBO*L-@boSy!mr +cq!>@$3Fa=rI3Bk>fZqJ!_XQpeaR50X1NbaJ)F_r)412poqGcc0az`s3w7uC9jWz`RI%pe`9u41Ipx~ +YZ;FH;`X=fN(I9sl7PHb3e8|A&w6_d+UeoO5tr^$B=&7A3&bi!kdV)Km8KCZc>6ke^i9jEA!Dxr0J(* +*Q)!RK+|N(WZ51r86|R71p6HpV^y4NVh-hi5}mHix(G +;Y&s*z_%?N0vInxfU&#d$U|k_>S$pDDaI^VYJEiW8g*SLLJ#OQ(G2xLIeeMJunPX>swzX;RLGD|%yD@f-WZ7=FfUcrucdVYv^F7aB{OkMQ#|y96u$-qI?Vy^wss(5}7;!@ +lJLGKJXK=o3=Od3D6)tN|w^)F7zRBf@IIwhb9SoaH3fqr>B2Jy+m-fW_) +M%EXEyn>K7WNLrR?|b|@q?R*ESkO3|!1==+k)JR|OLEWfG$ybHU5A6g*jqfQTCOq+gk>4wMeU`;-w9J +cfDi$w-o~UXZla8!P5MSoJuze;L^VS715I{wcS0Va+>(jo1AH-p_+5^mAIo`!oe6Z|CdKFr)=V-j+;A1rqSwRxKWhV)M3tPw|;|YxgyGbNro)``^BMfc1a)0ZjwwuG@mPG`gyQhJrB}1MP` +5+Hw&js;>mJ8Yxyo=q7!;v%&*xIN3V}8}B%F!^PvrH=v2`7P!AX?jE}GG0gYlZdccjfA!h3JUku)qu3 +!Fc*yar8+_iPdc`A6u~ylDXoy{>E!&FU)oBX$z=N+<-!{PjK>1*d_(6M;!zYfiKUwQV5hbjYMMZp`i@ +gE0$bBYB+yCu*cvKC1%%O1U3*Cb$w}YWB9}lE9pCiV-hgR@8YE9vDntWLgZL%_{Yuo_s-@tzvpetIFB +G^gQohK<4O%p-W^2LyTf=()~hVhE5S!I`D;yH{n4oX0g#VRaj$j{T{{*e7IT3GY^`zUq5nr +HXS68H3Oo+$DDFVUkhu>W2yI6On9m6Fgs%9#5$L3MK)Q0z~RY5OG9wquh)QI+u!iY@od0?Wm +4Hp*IoAr(niEpNGpwe3h}#_u`z(mK$PU$b(kK|d@TC~IUg`$52%@(a=X53K{v|XX@z98_J@FR52QA&vvopB-Bs_jlgokui0Z%M-%L@~>Wm}_jlbAie1C5leG8!RFTbg<(?($^~ +Bq?nKX8h#v{WSJ!FOHR+}7iG%HdtAtlIR&Q_KHUhjTH7_yi +pMsu$=_F&%5TfY44kpm`^L>=d~H`o=_i^geLTHkION5X3g{Jqq?-DK(0ZEfv})u-i;%=n4W7JzdV02O +->f&3J>62Bxn6e^eBfpfxN}N@lSV4a{E#y1oy~?IDHJgv5p;M+6@rZpfoD3$g0GfOaQYs2Jy}A1XL_E +7+KwF+*8##z4|hM0W0TayoGdx)xm_qKA?3p4#kHc=IzNepxmYJ8vw{i0Ft}{g{8i&6U0`M5iglg0J&E +iq(AMpm9sT57q`rKB9?Wz8{2}?5BA&8Ieqn8C0`*K&q}qj-1R-MERX;>D|_Hdv7LIvi1m8|!Yb%xATO +>_{v`c_OaMIyq^pY8=f;s;Q%k!yK0o|m_VISm5SADWE!l1+3v;xb1snS0zJH4&( +_rkfHqT5#?5ZfxZ`7Ck_cfInwd-_X +pGqjZd3~z7|-&ysMaEnq3fTQ2R*%vjeB^tq5^xbnwn?5+3G|QA{o5x6=jHxs20ovmS2o`u6zm{1-4Gn(J3b8ponr>-aCsUX(qISMQ^fCb7^EQk`bvE7Q +<$RU|t4NV#0N!1mv2HPPw7>BY~ij?rP3GNtx?%IZFI`M2`r!3DsUldAVA}Xi6ZEzFKaUR1wsS_-j6X7 +~MQY_#hQ(Ih(XMG64ZR%exY_B83~`QU|8B@%WoL%2580XiJvTY~f?-3?Xdu3cn2@+s_K3T+DQGq9ntI +IZ=Fi*5*C0+j5nKMBu>p{Vgbz1Zr3-^>xbF4Y+xm=9?xbyTf)+myP*qijcd&jgu>H50)>% +{C^qroYGkp1g{?E=#_HpvN-MT#(M%MY2P`bkc}+yTH)^Z}uy`cja4Z8p9S^#Teh<>Vi%g5S> ++tx7K61K59v5Le~N2)>!{16n&_4a-O6Z2K=*XEmJFgR?wQgi#aZNk%XLV3;{_;?O!N`mf?+)Z{SG=qQ +Hc-dP>q53X2vQm2oM<1j$%BJ{B@ul?l(pE_bV3#g>G??U+nSL5!ZH%U!I)vYXUu02-aO>B@erkTp2_s +i>TvNC`)qlYA{ZlqGtfsvX;R?0E~#tRhfnpLQ9CaRyOM8wi%H93G^p%qh{4Spq8=Hy7a%e0)NG8~&%qqaa5ja%o0Z54xLJedrd?om +7(lJzE>YKVs>vEGqDP!`M98w$0dqIPTUmdtnB%CwmC;h^6l!bq_%wLy<1D|0|+&aAK3$d +=LNmM(@{XfWSR%)81Q}8l?-FC10Uk;v#C|9^-(x2O09OjVEELQDJEtx12~E1~S>zDpS%--)o56U*l_PNp^P`#|fo@T +bsXyJA)v2vnaoil60ihwCf?u}6Q`DbLizTnb(pjZ32B&D997IA +FCiI}AhB4TPbXUTVEy(1l4Kmv-}4oAT-aChnSVMbvlRdp40^ +b{f6j$;77X8S#WmBy&Z0P?%hi2l)79IzU_afDg&s7NG +k8ASe1HeU2VPq&`YA6CZ=mCtDR)X%#%sr$wMoE8x)b%)GvbY!BGLK!Pka{a1iSORE#PErJ3$^&vichs +&!01Pc2-H#1(CElo8dERwh9-bNp+LO`0hWibDbs(V?vmoeaDH$!x&>d+l?FTeis+ZWIM-UByk?*Z&*z +nWV-!5^7@AXVxAZZcsvhQK+gz$0e`HpB^lsTmflj}rKalmx!)qYxqrch6Y@`Bjqhp<}b6lf({>1@2p- +?Lmgc5c5P$v8-9y6fkXtuuApPE)j`KhN65@4Dxs-V;+fRqgX;#CH==fP`UK76zDGnz)wCreepc`&2N& +YpP?r6r2Xe#|2kHmA6LWVB^=n)3N$ovtIiUc0nt$rUY|Ug@3}8AF8|6bJHZ0Rv8M3!#lxTR**AYW0s6 +iP1pW;L#0=wHSq43`)@ElNWBPcN=RrPOgiqkmI-Rj6D%TSKHKi(?_uLC0iFb))Km6o=mJs ++n1RpWrC~5TjOovxA|e^-dLh9>G{6QKn1IxbgR1bM671@TM#A@F9NXY_+KBYJA9KNU514)gP^UEvJ7XkI;z!1cKf}SAlu^t3ZiiDtbYuQ^@<-8#Ovy@~KCeciuKyV~?O;W{sCu +mkl@SNG(U>I9+0j5t94OB_aRZF0F^AIXk%*(tc*=ukJsy(XV5T0nsSk6M&{T-O(V~^5b{Sxemxk)%&~ +q4qQ%Haa&~+$@iqpk8Kep#A8%&boC09{kC^4Fm0xyu*lZQnFGJEn5MQqcvKu=Y$ih$=tBly|D1Y*kmX +7CfwTu001W!GUWEGDLz94zIl+g?_(sXFEVxjf%JKkGjac#o~~F?Q4kd(-oKf%i6`uh)-02b~j5!#ylll!I1C4K)v6iq_%2}`vlA9^yy@N*pgw-Y +ryJ?JqcHU5ZSgjg_H^#^X;Gt-*?g95WOah3e7;%Ob=2l%1Po{bPUhRef-$npway@T=elf4a5l%(>?3D +^MCg!lLcPq*bgogEFfJMe>Zp1eFEqT^U5~dRSQToC(n)CcXiZ6T)X8Q3_>PcF`I+*e2s62f~WB{537p +Y?}a~5{!?jS20@mn53CrxAO$||2ngs!czL^>MA(ZY{hr!oF=$`4=C1vSZRR@V3B!!X-5Xb=(7!aaq%k +QihndJI64q6bggy=y34Fv=EqfE0y_Kv-sMw6;wIPZ|Q#XLx4;@S-eWrWAvfe2#8iKnIs~A6K~;Vs&-f +{Kj+lTih2VYVqVSynpF(@udQVJ97ma-_sZO(Px!+tyVjM)m5VOkS;7%2`y$pOM(gV$F#qvOtVt^q2|+m0)WyL9u;Q-G{>A%%GrJk?vfDfNT* +w^d}4qqC@Z)rHZ{1zyX&H9CwrGC6Y@>r?D>5Y>~&zLgTZ0L4IkpQQnLQRYygutx}JP_Hyo;dR-%r^Fs#HpCp2Rb}MCPa +P6hx{1i{%e~9*a#fV3ay1b`KjWjdH1}KD}aillY?>0Tnh6s1D{xL(K7x#25)Y2v&;vu5Gv>Tp^eVCCG +8$XE;n#Zx$e33LpI&a#PEKdNk#{Ubf*738`c4h%oQu{@ow0}(_a%x&N8;GEoS`vrlXByCAAYkhlhtrp +@U!cn%5H3zLr?lwD7gaCqFlTV+7nMFtp)w9mt0hrs{x!O)M#HU;~0*v2IAC5S_I=nfljUAD<=Ix|d*| +;;lH0dz{+eeqN%2V&%rR4$AWj1y#BaU?b{)v%S3ior*MY7RY&Nre6!3nNC13?%S@ffEU#V?!!5B?S>s +yYxIVCd}J@Nhw3Dz)74LQ+x&MZwHs*%N5q+s% +(^108J_--+gIGdt-ZdE^W3ZCGZiDagKnNy0Ii}p?{j}S*@ZUkmhnPk+4BYMfKi@l`?Ye3%xw>eT}s_- +ZOMS<%}xqglA8pz7;&XqoDGtKHzp#%x0~6_!m%PbC>6gQwI;2Per^DH*1_YLn2h5 +ac`!qQ)J7CL6G-8>Rq3=M`=GPuAppAvlglU9F1f~WW>Z#lSkAl~D|xQEX_t}XpUWRG&6Fg)Aj}qBJB; +h<1Lh7F6Kzh=J1j%Dvx{;`mVh91H%*@8&j4BDQZNNsNs0K#+XR>8vFu7<;8Hz5>qmL#cw*74Prs+EbJ +-Uc*u;O$u2%UkC;vze3$Y7VB4S5V0M*QI`gYf4A_tVZ)ci+@6t2U;3%W41* +!6XW8JsTo+Q0+JWXcpL=#lpt*`-b?yA;g3d;wHTC*XyO#QUK%R{VkhFK5rL5mJ_pVM=_NdsCi2r??SiK1$xd{W`ZA@7WFe&^hS~PcE;%IQ_+S_Qjju;ClG&<@djsU!P +Cr_<{}|$u}nxO^PH_b8wW^9wV=a?kvJHb!I>sC45+#hYFA^gcqx7{5tq##u2Cq@|4cI>$T!{(DBHe(c +fgbK=OiQNMs%-c;MzbA1UZ@3-Q&$@q(Yd%%$r{=Np*%mfDnuql$LccU&uBD-O{HomxwNyXEWGIH#*!k=a{nl +;_>4}U2gFIzw6oEDe&I;%NEqd{&G?Nbo~oclb;JeeZgNUSotOTR|@LawIW#h!IRUOXyXf)hF}?vPLo% +7OFVgSW%_y@d_{s4uSM6@3m%ATjKAdzWy{wF5hCZX=acN}^78wu>+AEYYhte|MIBPPMhLtvnzm3q+uF +R->b3m#Y$Di@DH^(fFvp*4&vwCBCH+*6jtS2)zF1YK#tnY1P=EXdgwORozUmfMd3YI7Z?vSH?0 +HBWw|W>+yiP$F7Pkn4Vo(nJnk&-HF_nj0+?3LTRDMQTa-ygvuM%v(VjnY*t7gD@Ew5)bV}B_#qS!qN0oQr}IFZc*2r021g|MJ)4Q>+>ca_Wpoy!^{wIjV7IknBPx +P2@KwScpY&A~XqS!v&t&av(Ug&6x|7JwF@hjF(f~SnKlPu5n2Wn66Xg>B01zX2%TP9%|J1j9$BQ#Jri +zGl06I@8E^qO<0Usg~21_iZ*VSMy<70DP`~qxa3b?y`zo=az-rJO~tL}#6ywqPeITa;or>-`~&qDKlS +IKlVTp*mXBCYBB>?kadys8lnUkD=Mvk9=~&`XjVtoF7h5(Am@)>Y7cbqO&17HZXX0jRoN%*)Ufdvxk> +Z*wnIBZ1M>vNKl}8`QT&ChO5Ao-4?S~as^H_Brw* +V-lf+r&#(N_anN7my+`bmK6y~Z@9+il45|J+WdfzT6s$lL)TK};;EA6A%)eHQB@*F$}r4%uN43O8&FF +F1QY-O00;o{l@>=`7|$3%8vp<_YXATe0001RX>c!cWpOWZWpQ6~WpplZdCfg*ljAmW-}hG_Gc}QPrQy +b@e41o@-do#sTe)*w=S|jCds93}ge2ZjB#$6R)?M9yPj>?#@uW0%QVGj0k4T`=Xf*l_c-J*Ymgl>nA3 +BletUR_&*E7D6O*Ql)SHIu9*n*aEj(sR}C*rljYD=dEewM?+)GgmW=kRVdbrC;p +MeEFN`Jt9QuPTmjzv;TBTeIK5K>sB=32)w2o#4e;HxkAA4V!tsE@j`9n*m{c*Yw{uLtU)d_nmktn?e3 +&D68V@vZGNfq+n|JZ(gcF3}$-FKfuJxP8>zuPhDVyYMKJ!RFtx<_*u^$e)Rw_A0*DB7i%VJiR)jKFu} +U%j=U=WDya3!gPZBaGw{p0fWdQkJ2iaSj>E&BZ{EDYKB8lfX63WJ=zmA=mU&+DBXHgdnr$mCC9~!vm( +AwSz;UaGH)kopR4nkDyMFQ39d-b +CQR5@(2U0K0=U?-H@OilkIbm%OUXcoLa_XpZ&S_W+@!Jt3m_`Rx{lUcxfb`tD3$ewNBD>myJASp=QV_ +6GA$AZpqzZr@wVIb(d<@KTm@!oYXt?JAUye=x$6Y(F~ea8!ICdDe78FVjd(eWN$unI`VnjPzg`o1rZ0 +uVx`67{wOL9T~CmHh!Jrl*Lrg=sTh6eZG`1JOWC^F7c@V|r?asxaLT{Dp=U00zX%2G^Fx+MHR@AT(e{ +5JS9!jR*=2Fe}VhBMwOF3TRb>kbe;{c@W3g5+#{ri=si&K$p%zbEshvM;IuWodu+Idf_Fl+5(6G^tor +XMij_$I+WW3HZvd!Anunx{2!Dw;c8jP!l4=InPiCJD0z4(1p~GJ;n-G0eNm9AC-@nTw3-G+QIP|+^AQ7gjW~&}d1xA!2c;Jt*gKGcHE<^|rzi3 +!p2PowMs=x>nQ;Pr_d)*fb%bivOjIEt#2?5|#NKD6%xRX9Q9j}O#3=H5w2a0x06j9;hS=Qh(4(LdSUM +(rhE0i&%)Xb)&oKY@h?FMNv3r9rn)-T;@hJE*GN=KIh0XG +V6cp7c1A)Q)p%YFZY|fi(#ff$eJ;*AsE7mk(~Z3pCJ&~mCF~S8EBeZ?Dz0{*DP1FO=0oC>&!Ll9C^Pz +2nlW@Ic`gf(T(%=3t2tNx0al`a@G#>S!U`FqQB$|t-$~SA5uw4*=^My#t&A%v?cfWEm#X8;;xo^@cx9 +EfGBiB(DF!k^9zh2#l79*cTGJ5$2JH|XP7xGNGJ3dNmRf&B?mP}57l&*V06LSs9{-qhRxi9IsN#t8=` +1vqtA3F;hEbcNliet+;ZR=YU1kO_r`#6S4gW9d>+8m=f}u^4-5n==xzzlbajum71*TN=}s5G~qbO1JWEd +jK1m{1XQph*H%g^9higI@41hVU82GC+mz7OdLI02|hrvCXI=&3Q-BN@{dPQ$uL8dn>(1l14)H{Fc1-6 +Fk1Hq^2^4lF?zYyR=HFrYU3gp1Z6UtYi!A_85uZ~=H$v}WuJXKw?bKE0ejwfl3~S;rNZb7WAqj1exI5 +S$+91?;RCw~0WCBliyKdHyTWypETGKBzuhKU;-I!ue_3kn#~*)uaQO_^E8H9m%>1t6EkHc-x-Yj%??K +xmKU?sCNnq!1Ko1p2%#&E)HYk+`11wCA;pBObJO-jyq6=Ks7O>G>2L=SPgFn=QO9YnXVqE)0=FZi@`O +%q~+t7H~RoqRc=QL0)RQSq{z(Q{ +_f4X#-2s)4etl#B1&Q+KrCFK8Ex2tAt`qQ@W#kJL_2=~r=?9~zabzhQE_i8!E5la!xl;b!Uy$-H(y&- +;ac0j-KLZ3gm%^sSOoAQ8HG^q@6`v^P&C?`lNKD0MufPZN0kT-#=kwXn@Gsxs2^>~6j52ODhhY)qZcz +?hHX4!Eea%j=|vwc;XF2{UoI<4MMk~g$c60wOD8yyH@n>W><2krhO|-~%gXiB^Bl~@Fl34Bggk^Jqq@ +NVmUXx#GaXZQjb^s{S)i0(LzIMimn3!jaZxSio#)LE*W0g~F5WOjTZwLY8XM-!;7sw~+-}9@`3q1HGY8TZw +CeGT#km3@tWvsIbPY00+yj-iZ$FGyrIsp<^g&ih(<76v!pFyvB8av0+#pQ~vw}Lc;k)%i272dfQN#7pA)F_?}YNcF&{*Y0{DwigEh +d96dI0qoDZo-T5I{Pw^9Icwi$E40_r~BU^|gYVOFYa)AB2IFrM65iAN3rw!0?=}Bti8qzj%`r`|rdXy +LKhG06>7|sG=xC&8HPG(Tx5IURqEWU0A9Yr4(at|(5jVhBZjlcxOdneb#4v%-;DpaNTfI4*)ppCNXyI +T3gK_;`?h10o3iD}~(v|<86JmK_Kpq5H%0zR?x#}oJIEnKH+{yklNy+II6e6reri2-Gmx^0h--#1*qy~sC&_At0D*= +O^~pA?Zjo`(|QVbSQXJAmr?&boX=Li*GYCIL;SFqIt&n!B`iSA0qdO2Zr}WSJP}9Z7% +_T1qzIiMp3aXO9??@s_>kbyH*H1;v9l&h$#&lYX~ni61w7``n3L1Qd8?+h?#0fL%kZY>W2Mp@YBqeG@ +hSW!Z8Gk?ny99j?&x`#kk|x>oflDo^G=re;F(zwH_%pu%LD4boEy{@Q8cb})PYArO(eYZ&;k;HJb%L_ +Me(VPM_&q7-M++phq%R&@P2HRV*nRHc)T*LjXwE+shIQFN3aPMHuXq)R!59ejK#R_lfQB85|4D5H@X8 +a|o$sReC~cG)s$7AU!?6A(v6I$XC(_{62VwwbqGNukx{;yt-pC^a#yHO4U+3??XVXSZ!I>L*UwG6K)Px_77jwQ%vqy_W9J;4ws +#H^_;tzU_EbDR_9d_y~jAd{-O&1FgXU=2F(x(lm#&z-THz3R@LcohPfZtJkQtEl$!hwqi%9`g +P2i@-CWtI2EB%Z5kyAf&wvm!rT|dDz=!>iAMx(DU?KtV8tjgSW*}M(v$^jn;u}4U_>2m9A`F%Rs4u}jGQ9y*|6dbDT89$xL)Sf)Bt{Wkvnz3PCQA0<1mk;;x^?d2%l!JwLI5zvEu3v^IvSe5u +r@d%ZYxhc9pH(yFwOx5knM0-Eq8QsJV%<+^1=LyUey#)RxUnmZ +iN8Gf>k*e7A|&$u25y$q3cxW+^W?kN0(26*5EAtpsYoRDa4E-0*_D(T_tHrdXkf{55`h$tZo7$ik4c9 +>&EN5X6Uizm&$J?hO5u4#Df~;?mU)_8rQKM^jfJo;J%oIS&vbDOcKK4p&~#+Vh5qjMZymjzH4L)8(jg +^*l9|?wdAlVz9xcOdTlDe>_Ie{+F~Tc>2StTPh1+trm*#QPSo5L8ET6dJ_dXYA`{mdJ|o|#vC1@DuF2 +G9EqA%L$yc`Q>C)9+o`-;&UC-%}EyjjyiFuRzvA%vn)eD^&L8rfl@_i%dM9-Arjz1 +Ah-B}_%VVTlNYz7xV;dRljD)sc~OnH{@bGucF7lrWl7Y9Md;nZQLN1S+7jj8;AbYLqHuBQ6p?(NM2>b +TuRurrJJ&FOBUL2;CxlbQpN%gjgC2k4J{~zHjae*mv?09~=aM}O#zkI>bIm^E) +3Gc9CQQF$T(8bw?482mv*1~tjz>Uwd3%*u~pcU>}NIs;(63e6FlGvgRpB4o_e=>xWFn>z8Dhq+KhGPU +SW!kl%wR-MopCOVGmMmGS&`a4_u`$@tPd7Nl8ostiM#HkQ~em@GyxY +!sWkOrMj+xs!lTXuWlVYhw<LWwI$8qpPJ^q{Hh*xK@frR$51FFqt$R{#x2~=8?pN3qs8+H$yHbs +Wl~gLLkmjN8q2!=O5=mWbSF7Xr-r*Rh(FHIvlvauzF}xrjJqk<*q+Y-0Z`oI0;S9;bIZM3CU_4E1 +4scMZR44*&r-Ptnt>V{fb*6JX(u^77t#UCU-J9)p=%n&6sK9XBmEZ&M9^;bAYSIiJ_jBo(!<3!+1spp +bmKe@?fS_xak;Eiyw7az?4Fw()<>Ppna`E +TO7RHJgG8j+F+0hXUL+ws1sK_x{FL66sergfuU_SekCN{}kIeUcxk~Moc>@8BPwdW(zvVowesh%E +wV2Wc1FK^zb)$jzq=n$W+FlN9k6@NlJdQVxZ;b=^DiwjL+X2vieNQmUnWMsdz8^GXn<0iC|-z0TC)q$ +ys|Hjs!*##SE;B4oSgy8=-PmvPCvDC8AVxD&=sbKxIFN71pq*6I`m4g?(Rv4Ps7pVP^`5!bJHVZ0#%! +DzKP*&1xSijzYPpVA`e~a9h#o*QId-=c7co?2`%M9!gz04Akm%EiGtW2deFb#x~*=#=FX_Eyp5lEOv@ +O+7G-dM6n`7%x=cw-nzkRXHFM0P!Nf>_^fMwYa7%tv_B#UKpLyF{jl3q31n3o-+!45XnsI{gw^6?9?8S&Uf9*m=7~E}xO_p=WE|2f9|@FtB24rNOS4Y=EX@uXg{egCE! +ELS+Ma-ZJXnUAZq+*dMBN*{Xl?d8WyvBKmZD&`j$x_Gr6PJ-4>%K30uSV6D>JO{Rc|7dH0Jqv?zozZ*H +_nJknpBU!?fBqlu+#*nxw_p5A@&xLYaoz|;(y8XLNX5y25~yEQ{@_^4j5np8*9rf5Uz%{^^JdQCWd}2*u2oCy9=+b2`f+NendLHga +MI|vtq>c?JGK(A7meWHEGZBsx%m^Z^vaq2y2N|h|RE{2{C?{{3inEP~ZW}^V5Q4v0g+&qZ+Sk?Pq-jQ +LeoU@~iNUhg5b~ieP2+i0qy|k}%P)uGlbWCz)%Iz>*8lnWe8eN1i6q9iCYcO4YYr^J1Gq6LwdY=8g0QV_D@h4LxQus@ +)W(>F~RRJ>*C!a_y?dvOdspSf$3F49tmphtByRYU33uuckirRw+{ukD})sD+MrjW6Xaq;nyyBjgs;k1 +knmvn;cYpj}9TM@|meToX+?X9}r&yeL{{@0=4o-a($|U4T|mqRO2#9afdvMfkA>sxG~4=sIv-f#h>k7 +lyJ&pJoK5b@Eh8u1n`JJqTJH_85O=+w&Ih6U0O7pnkhe+0#APbT`T*rqtbP&zOqUHSc4nJ9#AIqgD1^ +nj3^^PHTOyHQxEm!4*I7dM^|TdSnaCSPM=8K6IY2l(;1OnkFMvS-a4bqWcEcb{fJ0<`}b7`Gof-F~Pg +4RF(+XU8SJv=84*RjSLtyj&pQ~UQLIJP?lPI1Gxhu1;tQN$z=Rons;5X;ZYlO>gZk!+}ts@NH2RBv~U +Q|VBY}!rvEvBa|{}qKSeBYGizwO3dgggihK0Qw%%WH!fzbT>K~l>q>-m>Yj4@C16!`8y%<ZFeIU4x!t}LE(S%h-2w{~*+sJ3JUD^Okth$>8d4=GkEccdd(YuTq9jh71l2=463KJ@& +W&l6Jd&zv2Qw&ERfHdVsSKfeExW<6%Drzk{(C1MAGvr8uTqC!`aJ$L?AW)wW1CHj#CzVCwLJFJ1mc5c +y6Vq0tq*KVKK%IhZ$Eu_za{p)!ZVeYgR0qdp1stpH(UxGX#6U;(1vy$#m_$|CDpWjFuWUg=IUq^14dL +oZ3)*^Cu`bmNyD|NrdP!TJu(CLMyd_`G9)ctL(q10%e(27BbsOxQC369SCMi4m&6$bl>v +dL-bieS4G*Z_iuuciMsW66mNC*R0$mxhlssz%F-KniQz1s7Ak8B_i=bOd-u2xcO+wXd^xjbR`$9%vYG +cdJA+$K8V|EO&~z8^_IxNXx=cw#4}e?AWY!<)jBXn&SkG8V$@=Jy>A{llfWe^fY2-ww9gu-vX;Nh*NW +Mjx284y(!}W4$*{D!014~u-BL#U2U7whK|rEDAHhaXdS@9GOMggh;{uWtD5diSgGr?LoI~;i*TkVI;7 +XLi +N|F;9cvdXqWg{;_F|kY_kZ|Ab~}=l{W&94G_yL8PzIG))dWYXn0dD9J*>dH=1`&FTY#@o=h)GHCE;wp +Qhe4yVbfet*f|nLEI{fF3GXf)FtBnTj(|O)d~XgvfXtlfghc7%)AFYF=>w^wxnZFLm-EDXZ$u*kON>9q_gmh6SG~Y()F#C%2x&OE}nP61-bHxop&7*YfvB-s5s~M$# +x=l(P1dW&50v;k-J6qOyAjq%lE)++FU9PcHn!nKzCYBWFwz)qfJps1 +2y#_oqYYdAnk9Gi+l~;&<$+od8JWMuE)$$b_rWdQn+I6rJ#e66(F$X>gaR&4D0Xg<_VV%4^u9Fcp&I8 +;*Y!5Djx*o$_eTZ4>1ck0tpoBQ89y@hlvZ%dEtMxevAjLP+wE|zo#OLYCp-Ybyh-~;VLHS_5EGgBIzGoFfSq4nU@qA$%oW&s!LmSmhDozaVkp!Z7b^>q +wEJJG`ggB2({XS3yX(#9vwI|)Ch%s7wB1ZNn6^6Y0NYX;qHe!dmOUr4qkIY_i6naGM_sZ?A()&j)LGw +dpDq@mkDc-I@_OCGvPEDN@;EAFzjptDT7GP@Tdk)B>R18*ZMSO;9F&(Z7=2HEoX)Zp)24=qT(%WlTF$ +S%%{mmjD9E`#Cm<`o-!#_NKeD&M?1LB?A)g$l2@A8>;1022Jbll-{`(WZ0Z@!MR_bdcqSIB-wR +)T0bpkJS;zc$u=|ffr>}S%K(~ZE(Z;A9x24p{v2xBs;JCi45bHW=wyjtcx`gAMxcnq3UaOgOionWsuN +l1|5y_iGu$kzpgj<&R+Oo5K_;yxfgjKHHs`WiDOwj2jYHJ*!)?X +=<8XlqD{-5+mGVg6A67FU@+2awr~&i^p^XiBJrgokc-HV($zEsERiQc&}oU@3p=n*Q0b7LdDv{&#$Yk +b}=wX-_D_}n+oE{?y%-gT#hV*WrnrgNjI^U3=1o;3Rl|1R~YBx5^kP?ly8O_ne<}wQSH#WL +8`1ZhbNysk;02f|6NQGs|Mo3W59H;@gb*(r+HQZE3q#RzNjze?9ZlI5NqL50rWIq@?c%n4+!cLykaij4D_FISBdmNH|R3Am=X!PelJ~=b{rD@^2@@1Y$JtAAIKkUct!Oz^G#9O0{0hZ@6b$d%M>WVsF?3|bGvgGbuC0Rt-%x0nO +ao`}o3nCUELM+p?Ck2LjH->#U`({U_FgS*)%3j7cc={JShk^=SFAq*L$9E$cTOX4Sh= +%vhLWpgzgEl4PI>vcc%{%F7{Ay5PV~U5}YT;OLW(`$+2G}P%8}knt1y%+pY|@x{a|H;Qs?qO9KQH000 +080P~d=M?@=AP_Q2W0KRAd02KfL0B~t=FLiWjY;!MPUukY>bYEXCaCz-LYjfL1lHc_!Ci3|J+7u)?$! +1F%*>P+or#i=SS@L-|wgQ8|kVFIm2mtEg+8=-Ym?r>AN;Y?OA5Mua5}4`f>FMW8_juk^D-p-@b+>M09 +E*HaS4}69Sz8tBPR9IwYfC*(tFn{VU6If96WKInrN0zaniSH0TP*T&p}#ifMb+w0b=BtAbMgLb*@ +^1^)UlFocy&+4X1WotUOH|ArPH1ph!{5h}b>((5nSLbykuTxofc~!Q0ipM2DFNy>o9yLwX*v4tK0-S` +MGY~_@T@|-oGXsOInc09(u-sv+o@Q$vWfB8R5a_d1meW&GJ|KAdDE?dbmi +q#*w1lU#fzevCB>AWT{Q?UlZAv|tE9Pro;c6x*2H2GU&=D88jS~_88@=6)(wzu&?*A*N2}^m8ocweUU +#GIbc;9tcrtw7$ga78`3SSv@EzD@j?E7Ud+L){y2bZ5ootU!MAC}Wu7R${CtI>;VWV{ka^`$P#x`G5To)^(JwRzvqlU>qgtBVgVTVQ{S3eDeAfo1eaW^XBC3+0jeyxz`bArWOl^zm!c2Vj7%pZE +c}`k_~W@QdAK%eMQg0m>43CC(!KspPx9;p?MfYK!<4d`3a&Bb+gaGWb5bSH-lC{J8E&YETF~N^S7gL7 +M~f6{+%??csO0?&>Q2i=%Myl_+xB=46-;WF#?o@cp%E^w}c*#k?)U;!`f9G(;@d6nP6sfSI{WauOk!@$bQ>H~iLCCg*C7an;04lD9HM%?Dq2L{#0d#8Yvk4Z+z>4QlvN(kwtRKYDa +=g`Xyjx1k&UfGS%zB^XIHKs*YWC$NbS1P8J5#}E6%tEpHi2vL?5R@>X#RU6@h2sHq_ZN*jIEkT~d(b3 +6^WFrjO-*vZY| +mwS7AQ*o7mwx8$MGCTZwZ*M}BV>=eY0!>A}06i{aiHNm_KO|rg6@Kg*MVlLY-#jI#8KIjGY&HO +|YmG!g`?3*576jSM|Nrp4Ka4!B07>jsQy2VD`mKs#DN0NBoVx7@&(#*f$K!nBDl2#>d^aIHsqU{zSz*w1eV`fc8n9& +mvGn1>M5olbMzr`IMqm8CIwIz#Ul|5cv~tC0#!tQBKnBzydb{mRi>#4F+rQdQkaFneqaT({y;w`1sxL +V2N0}Sj3yckY6WHOiDN;_h{Hqi#1(deOE5AJ-HcTd=rQ8qo3@iHS;BL`H=K~i0y9gsvFd}MrUnGiD_I +xaE&Xw-*bf%C=~`q%oDp;dT7YCcHWO}TJsDsfL;*CxFCQROaC=S;&RrEo(G{@2fS-F9fIhwm>_ +YyKFTnH&ln7i+RMeuH!x};lnRXSZKUgk=L~0M3@Z!R2EyiJz;gkhJp3>h>V5}~k=mjkS|9z#WfkL=M@ +B}_{l(R&c)03CidE2#!FHF}ocj!@y#~RuQMCb(eIV>kGNqWE(bs#igr&V=LYOT18VAxw$L9V^!e&=0%89Z7|4lB2h$uK+)Zm+gU +i^BO#2@Yr&|c&!)8JRKu}=3Q4n!?3_Z-k9Ee~DjL0EE-3S;Fvw89t2L(~r0HIC(P;83@+m;<}Q+!|j*@C6!wdNqpBS+kaR +qfLI4J8UU84y(E#&9OnGaO7q#jH0^>#$edu&S3{#7I%(9ByfA&IY_?;7^X(`88)WP5?F8e1tLJ}Jwg8 +imJ=3+R$j+*)<**8B*T~@0hg~Kzno+NxEqZmsH%b>0od5?TQn?VwEqSQCTxNaza%@K&jWPuqGPS&{9T +(6|58}%P|XDywd+|J>;MdGs3lgzayE9t8SY3aNWgpaRXi2@;J1rM^lM0)htdB0r|(J5xcx3QjP}$A6> +Ak9yv@+^iy^F05Swrr=^q&go?mB%q_)_LKImY2u*21J_}*GhLSlWwx1W#?Tu%X=YzXMk8AwoDuWN|x$ +fq{WT|Q^+rp$fb_J$gW20kEAF@UmOA*nU?Fatf3b+jya96Z$hH%P`%95qe!re3)0R)r-7{bq`Q6Rb#r +ni|`Rqy}HSX~}P5mp#YWlV755RSFE1KnSZgN4j}n6(S*WGJr{!AQsC|e4Bju<>~pOXHO^3PS-QNKgMvB+!J+C7Se!z$--#b`$^PRs2da%L1sLK_~2}ak>#xbrlUa*A@cER`3pFe)I3;{1tAyF3$3`2VDJt +8=BSSo@dzI7iUs0l<~BSAL*5H#fhjB_))_T&}<{HfS?-lSFeOCH@7zb7KlotO%P$W7)^}jx8Esm|;Q@eBeegB +zs-9x{30i~x)naMl?kVoYG}7$a&`XAc{GX#)R|wcZok!R*7(adbbPSzfcilF-?J{ZPZdw_nMSF-UuBW_SsJ+sJc?&ot2Q*XA2xXoo;Gy7F;En;GO-=5 +CP`*sGHDGs#+aQ*P#X^yF*qFn354XVvoCW|+OksI?#1i+~dm=DKMYF%jEgWx1UUxk&{8fHox5{*zshH +vJ9cuk*J{NeR2z0A70Z^`K?+*n>=U+tr044^4wmM{rWSQ|cr8=avQ)FP+_`}Xu2j{%GX5Qj+{rX_%D{ +ptwAfwM8_?$Yd3RuZfUJa+JTTFPGd`Qu9M+!93rfORVY%lXvy1V(utGd7q-HtZH#jI)?m{`WC1}@-;I +xNA1m;x2^!dX042#A-a5H=%mrCvge^J~44n +uxsg_3--3H@OaDwLzL~)V@M|wGO;21ZG2VeRQ6E +uvJzgm(vpBg$;zZsYgf+X`_%s6D5DAGPJu9BP9478EVJuRvz;Y}gdNl-i?f39VWIu>)E{@8TAc>-<-jnbC1g^pCyiBh@Ws1B%2Mtgwv=ML-u=YHsG?lo9=nCS8BA;n})mxb!;)bP1s6g*-W +ng!110Dt?LK}R&Ngub=!pshLfmKUA&1Y6QpPjrsIS}&%-DNs_$|UC~p;FNON(qV`UsiMRLsNa0g*S(yfmHgGTy3@zX5v;-bL6uMx<#fQ}N;4V-V;TX;hq?2b)~v&bJLoFk(C>CckFvK;HjpFY@} +($u7LRM_#7II+JDz+Ix;<+B13-YTn(8nBR67=kG)mKm}YO%gZBrtF@Z_(Bn~i9LMHf{n0=U_20zc=&#xM0Q~OOVaA5I9qW4l^@wR0#5Scz +-tt-7yCZR*4q)C4!zi*pm~FklR7BDTq*qc~?1V4cvZI(s+h@ctMNlXDLK5O;w5y0lAUwAA{ncXK~gYL)NH8Rb605HG +uYbl!*QS^nS2Uq0)md2^>WZ>mtJ=nkvg^TcLG!NQuVi!{`M9*iVf8A?;}v1T-yf=v5iG-w>Ppx^6qo_ +q^BIw0xdFuORyH-8Y;RZR(ianfnAP&}^)1AnZva0gv!Js?2&`osItnXXy9orI0ZGu@7MY#rn}B8f7z_ ++hE*N2MwB~9NPg4OY7P@Qsin46yZqOe>!!>t+l{NYvAJEJ8M*M$MvFm>3Y<@Z|BO2INIqT{#C4Jq6hId=9NyF}rK1WR3Y%uLhC4e&L!T4}Hh4_i7}<;UQTfx^)dWhSyVZGeLg}jF +`l%(gn@rD$f9~>j`hjz=NgC7t0QwFq#mRFB8nZ0@JE9d-Ryl8B=P_?iKC0RB2blKfXVHefo1acMa`ee +@8_>^R(=Wu@^K<)sDRa&RM6v_7SPtH9SJ +{oSZh*)eB>YS9tRLlN#x#ooBEc^%ZVl>J7$GS67G&=EQ2_!2QP+{c7 +(C-K{tC$C@qV=|Ae^un#pV*!Ig#y`w4unj$a>PktkPCT7IlWbL(|ACHCCy{5t +@SUOw4!u%flBRDC}&tlas?>mDe1iq)wJ&rxfq7r#VO!AtghQXZJ}%`ZUooYKHlWC2Px18vLgS_u^PuI +fWiKGchw9hNNwB%sCgFm29I;)GbUb-tViCsoIu;IRHT5)NwbM%S)L}jIO8j`9?0*Mba?ZE4i9URa63y +Zv5gQV#T#3U$0tWPqa6sHN2`6kT6rY*iNE*ywN0Wi=@iVvgMO>ZV;_FCH#E+1YE@A9B^@ +bc7UrAxw^q?PxUX1h5t)m{poC^XCN?-`x^R67>Dt$~aM|*hE+;4@4m!)$sg^4;qE$J0IIAfDTej +lo-oTlzx|{o`H-_%j)j$+8$sHn^Gv!!`qxVLL}uA`;>Pj=)Bbq1fD)4aBe?{!pcg;u%bcZ_wevq8ah@ +so4L^Xdfz!p^kj+?Pw5u;0mv+H0B%9rKpmn*(GJNON!*#XghaMT@-Wr_UOkDpR(krx|_Xfe}8|R96TV +NzL6SctVwNYl&PSrhtMscLaps4tcp-cD?LU^$x%ofp_qyv`$^_1TInMQU6CR*#89+rs~w({ATyCe(_mp#ar57^|7NRm0Adz19+}N^j +k;qD}+ZOVZHQyKn=1B3<%xbRlusm_$p~|lf(~9f)`0iJGJU83B%D9@)70BQdQqv(FJQqrUoe+$xKEj@ +`&+3aXHjCPeeWUfppT)eZbo5P9CT={`T-m^ffHBY;nh`l^_;6AWmjflbBr7nLe;IA=fdBtnT4heDEm2 +azUO3O_{$_xQ`X+vQvT+4$Q0D^9z_hprkgJV#dtweVp6Qw~x^ajL<7^h8Y@ojO#`Q9%^`9)cLP^FJSZ +gzDqBQ=ML}15{?tvM;wrTjd#z0{RO0V4AvYs7h;AI@-Hsq9l8Qap_+;;DhIz#$H6}kr_~ +B&scF_V-Mympz2@M$sj_t{X|HJmgs`n;n$L5}R{-MxCS4_3jr%FLiMjg|9P74#79|j+=sly|6@fHsWl~o&PZ)s%J4tsjjD9_i{K~!zqbFQYl}aQY>(#34 +#A;AWn%=Dwg3B~1eHFPR`m@|ubTZDVo=JEe`nOdoi;`ex4e3wmxDa1TVjEGc>Puf-tE}`NlyKPKjy{v +YWDxA505h5_u$PXJEMD2sv0Nm=r$AQpkXAT+hnSm${p=JhAtSgw&eHnAiH>tO~2M>)-ouP(OV~ +Z8>^2N9mmEwTXCb~`eJJ6;kQ-$b?5>bd>uEFujSFLo${O8$#K227^8@G1Yu(8qn+6Osn@$CsDJg2Pom +p`yG^sfaLaw*rhNsN0KAKZU%~Lu+pT`vPzdH?_W!z6KBZ@vHT#Nfa{BZpDpN{&lfU(fxP#P&FKMT1rBumk&$!*G8%81;uEHPOgLhX9<>P@TS6parj?nB# +I;XpL(N_pOP_OmjW{pzXpd%hOLHO+8D5+;Gxa1g%gcTxKE;m&#jfOP0*wFwgVV|08G2f_~WuT-kUncWE;ZlD*Z=KI2oo%QK26U +!aWk5ir^oH%sms`#-3cF_e<0Je}@O@1@2*!SfOfK5$xW&JdElgM06#RthN?pUo>4JFq${`+(jr%^tCU +I59j1QjZ-jZgBg>4{I5Kdjn;!xkL_VVcacRx{msYG({!_!-q^LZsPT8Vn$p*X=Dp>V=*{sP&Ztr94t|B+(oV(pTa~k~o`V|L_Lo?x-tv;25Pg7%9%^X +M>fOb5(lN@*XkBMXCqu8r$fgS7+{2!{=st<*>Q31-hfd4WvzI6D&gf0ftTt8jIOJbGhoYpwpDChuh*| +VJ!@HvATW!WR3pAJst}A1obwF5*O+4yuRO$2$CEqAGn@ptETHV*+3l9&EqV2Oaso%riJ*Xj4Fk*0Ynu +M*w$zU4fi?M<5SJbF0R=fswQd&@`%VUyQzo~ciAhz;O>MfwYRyS8vPQ3@fHdNCKbH+7TW +ARz%#y>v2d$34}1iT0Y18;$|B0!ICz_lF|%2-aU;GPsV +U40nU>+7a;)TqfBlV#AfX8!f-j2oN3K^s8}WweNZ4)y+%ubf&9>kT0$0LQnK?S%8#kcG#hHMJOY~-8eI}#CsAHUt(@4E@C9qHrG`JI*`DnR3wSdv|h0g0gAe1g^^t(%?$4qv +AJcv47z*Y)1k5j%sm}j%9``kxbT>-?3k*Hzj2e_5ZK&&$HgKr2+v%pL3GKW2~y91yd`@|A%nm4eId|o +P__6D^fJ67`pc05#=(vq8zHusZA+Ij;=QbN(2nOFe31?~=dXC#z`?>KVcJ~6Om(T!cXciy^iwPzQ_cQ +tofjEJ0_Kxqa<>T7zT+j@aL>2fPT#-v1Hhmhl>QxD@0+A{s&UW+w(8amRXRwVU`;p55n@CDUQnsoo1| +%JE3d9^yj;XM&dc0hOhv$*;Ggf!T1X1&3R>#|$L4nS<|#9H@8+q&@{ewM>RJq}S~es0&QX{xUIUkpaD +xNH^p6PKfU!=ysy^=2MVh18g?Pt`Lmp_m@kT8(m|4Zs4oI=WC97o<>f6qtCw2Xf8gWXw8H0+|TIv_31 +(pXi`9eK#hJ;s<^9DU}`>l@{G}dx{OGH~rnYGF!L|SYI`U5P^j=uB|hIEZHU& +790VSzoCI@~y*6MVaV7g)ukzV$yRLE9YgY>x-j}74vR|mp0W93|69W{rR1^nF7!!D~?070%5^S+(j=! +DyJQ%s`<-nhe#9ueL1eJLEu!F7c&3L$@nSBgzNu0#d7yO1Vx@G^h;=5mU6s$)i@(%!^(d);{Lf_9AEM +-wtHn1SpWHWK}+Zy6HB?B;Zy6u)Od8IxSj{IrstEIEY-hsMH-x`AyJQR4ZMQ&gdo(uhonHVqdE9o-i6 +#%6CoRkh~xGWIAsO0t1Fu5j1-qGcZD$@qNA6VkXxp6rHHwY}4PKP(o@oEj(wdS&BA~$0dnbkU_@__@f +?7F%=*xg;gFl!Y0)$Xk7xcj4=sAju+(f)q)wR!|Zeei1ko39NKH`y(`2zg+(;;c&PADGY_&G%m +i>V*?$QhR)hZW8?RFJW}(hGG3;a33EP +_Id^PhSHpl7aDWLknOeWI*_`x}Ds_3W4Oa1Gj8PI4cwBDbmk``Y9>s)VJAFOx$D^&tR=T^yOmGcE-Zh +0WHxUCz10g9u;+pQW~$IZNbC4-{iGB8e{#akgrIpF1gT~!sWcHOWV+%H0OtHNt^f}DwH`}kg(8WzIU< +fmhW4ND?lcrM9e(k<6j$#oQ1LMN{jAXV{5S?w~xi_P&tY1-96Z{tl +IsAOX3QTkr|al(I*y=Q6#2hqEsk5?e>_fNj$V&F>QBU#lN$@qKdU?7E8FR&mh +$9llQ79yncFh7g8q;w`v5F(+ID}6_5h+54QuwiAj`>`xCEp8~zLN`CGrL0`q8cGp>F$S%>yw*@eyvvX +*oefEMUG3|33EWT251=2DQk9W1YQv;fp6{@XaF|GzE1#ZLO^LXVS4wz44Dh2xJ1JcfFUCh!E +G)g*25Te6QnrWdJ*^wh=K8#Nwl2sK!1JJKe;BJaHa7QoS=`8L^7p#FqUL2G+MI!Td#j{a_L;&^tzW$_ +xARrd*A(*Ics4P9kux9u|R33np4yufe7{^L8kzWr$9U~K_6uUu@g6tNXG&5$Z$cv>CnM-7&+gXHUU$m +228T;06jL^vu!xbpIPh4sr!^l#f&^L^KC($4R%skIr_<19GCyM5wg*?@pWOH9;0#O~iTU6 +*5+e?)1|O1lMSmAJcHJo(^y834ps9I2cxfLbXL5USeQ|T$F>V^gfve8~e8B=w5=$?)(!j5F_IK*X%+_ +#e=I~LPaJdmL$Va9$%#cc^6DoVAv+D>_*~WKvAR^4&Ny8a4<;-~CjD!!4YgiQuSj}dwAf)Sgnp5yNb% +G)7^hznTKzq1aC;d0Ug9g59ktAbVsUu8AFdys#vav&-DoFY%IXWViMMiO4qKbed +!{L=1(H2iQ8)?~d~aAl5Kgb#J3n>KZ>~IEFQ9`YL6)dQ3z(XT=n19Aq27?oVA}y*hhpvoWZF~iMnZ~_(hUd;_G8)hlT32mw{PD3^6q`(p>MxDXxdbU^Wzd4>WP+1H}9$^#Jf%1PM+;|H0)HHSdq%;@%0W3XRm4G!xPv{0>)eWg0MIFeldgy*+S7kDQ9kqH( +D!sFFceDalVd8qQJF~a|r}54p05Eb|WX2$@eP7IU=3`@rw5DApP0%fcfpJov^DXRnQf{%H(pTS{<@IK(gpii1?8~YGy^9`6d9IfZw7# +}F7fupt^j4iVm0jTHiYe-OWfn00998xwjbE2y{QTjojb1PeuIB`koq4YXsa45h)x>S&JcA^&Cu`|)BV +P~D=4{(%E)~t^#oY%+jq(%cMGZ9;JI{-aYoS<&T-2wqMZshS(c+~QH66_`}X=jFu3Dx~oZ=2 +{=uO$aZtLSqm-SJZfneJ#J|csdw;LGZc_&6?1IqegY$KJ6~53PGyS?#A@{ZuX%Mdm7h?d6Ideq(vH!KRi!VqWyoKST|2deZ3* +e!|yKBg9*io`h=BZuVPcRq#tZIdpFl-7aun@oOF~noXeW-&}$|W@a)5yaNl3cL@(Mer9kzOS1l#H3ASi0K}7a?tjJZzhIZoho{>eaF4&1JaNmN +218D2~t{U`~WkZ3D%VMA+92saN1i`9Hf=&qQoby4~jXc4g|dnR2nCD~A5b#a;g^e=Ka(Rx&75NqJv0! +7qb6v*qgoEt*EGXvl_cZ>htp?Cu(8l>2{y*{y?j(&LCuahE<0N+#U%7;uUyM|*iGsFVoGXk@$e%L93v +NIKVGz!9+`vj}314t?wklSP$~Wv!NNc}5Sk?M}LPb9HrdUA&Yo0_ku+B40P8@8fzZsv9b*ceZ2JH^pj +wRa*HTSV5!U3-N^906twCZgX#3qK$PVhnqlX9h0C9o9ek&z|19-@&OhtTsc{gCRu1K{#rqy^So7jY_9 +CaT$`hPOA6Q$Jf_l46a{7rw_zS56H2^@OMZ=Zc^PP&pJ^kT~k`eX&A$6aKZjJcwz)w)HhcFr0dQQTAP +{t9%GmRz2PTCo!QgRX>$26iaS21iRG+(43rNcF*u!vzKB>f=%c5gbwf`{<4_ +ap89%p(qZT16DEIf6MT^f^olfTs(7Uzj?`APjbE>Zn!x?lGj*CL%Y7m+)(rd#Fhj{pA`{})Uz4g2f-> +p5OVLSpAjH0$1F$z6S9B}+c2nU{xfNowM9R6Z#PnO}0fbZMdL9Y(&{`p6yjJIzgeIFWTSSuLWO6Io%t +Zt(u<6n>yF$669K$eaFO9Fqf( +yV<($B5Tc0J#4V245MJ_blX%vZqleVLksK53fP)h>@6aWAK2mtey7DvqtO)dZe001Bb000sI003}la4 +&UqX>4;ZVs&Y3WG--drBuOg+b|5h`zyHgFb8n`0mHJxu*)tz73firZK`1_OM)b)$%_8_DA`WzpzUEZ0 +z?wY$Hym9%G(}m$e}SUp4(*%RqMo44w`GXqZ66O`iwv-lLiWqsOFRt)O2(qKNg*BJGl +1)79YW^V{YI9!K2jaCSaecX|R<;KnRwD!YS~*1lY?1CgS8ToO{Q5T%m3`1UIs{!u!%p +;=dLh@*>Q7KoGF7q0y_2goxm`GB(Wi&&r)buAafy}r$LG;Yc2bK<;W#mXwzt1Y<0_&AAOS7AMv7V(U= +WeX~=Ps>F=TXsdx8c6L&2(=!+wE1J|8AfwyjAGGHPO@opY_cry^}_#o+L_tYr{EcTr5Y=qw~|~Ek?{E +zYGR8-(TP0^^1S|v8k2yy^Pth79x+f5WGs+gs3hIwo7=vW&9Zb9J2~JE*=9swiO(t9{4qg%>p5Zwi=} +wT)9X&A6+G6Wfw}UWgXwEa#6rvP)h>@6aWAK2mtey7Dv9ThG^dc003wR000;O003}la4&UqX>4;ZWMy +!2Wn*DV>WaCyB|O>5gg5WVYH3@QN`TpxOBLtO|>4uOyaH_$^VVr7k_EvsFzv$E@d-`SPqSh7rdC= +~{4cV^za`BWUo(GAolZxw>8gacVOsz&VyoH0u3lK%m<$XEdd9bhl4=4%3xnbtv$jm52S(r8*mG2<21) +R3k{>spIx>Jg1~tWHL?4%6-&Mg6@pWyyHMae$AaXsZMfJj>?x)yMZvob>;T>j?O1Sn+7E!P@LFzt?Q} +anPSdS;8~woL|mGZvlV$H^8@d&zrliH!t^3kKbSoKjyeEXC41!>v!;dD8}daU*Mt3B;0F!`HmX`wdrow9-+GmuYF{)2vU#)+PL7R6ZFD)KC{ +~XnN?3lD*pLv*4=420$79-DjGADL~RyIpS+^Z)_XDL%ymI%2|)lgxRpYw19&QV=ytTQujICZy;KS+p> +s|b>wqbE25|y)GGIfL1ckBC$YwRt?XlOxNUchA58*C}z4Ga(#*1j;=cVEr@ULlYV+fgXOJV#gge&i`7 +S1tzg_et}$)U(SV};K7`5mKqtDeTNUiv`2L~@6+7Ztdyj;=Fi=hL>I=3p;0Zzktgk!Tte76kbUk*Se8 +2Hc_H+&T}#t4lJ$K2yLe>MTj=AY4OyGJw}`MKOokOK0-q2Q4f~!5+@LfVzTa2(}wojx&V2LwlH@Y5eW +{J^8Y77JYqu*MvyfhO@xIGE{BYm&tb0w8ZhA=f)?@JGt9zo;JsvE8L;-ZPsV};y$7YoDYp$*O)tQOJ2 +~t_8oi}*!m9xlm=Q(wDQ=8VAF>@L1V%}V=FZLY8fWOGNI-PMZ-qExOB%0_tLlGSh7>>!Dvp%HX|N?08mQ<1QY-O00;o{l +@>?xL+!w%0RRAl0{{RQ0001RX>c!fbZKmJFJ@_MWpjCRbY*QWaCvP~!EW0y488j+-r7S`ATxFz;M1^S +!+`bB0Xqh&Ovl=6(V(Qd`TNnb(ll^&Fl6$*NAihooLC|_RPKDMClmXs>V!v3ZmKPh8bQe)DIONUA-T4 +ys+Ky~p6tIh$g?NeE!X?c74+QVM~9ivvcHSy%`?GZHYY@0d5ArMx{hpgnp9PAr$HAm30n$bzd(FZo9S +*C@Hd4B6G9qEliHkC(9&6}b)s4nk@g)zg=q#m^&f=nZQthV`Y!V?KkpfA5MO@`e^SgUA4L)52u3 +Iuf~3T;RdhFyd1is-i%bn{SQz}0|XQR000O8^OY7yVN$wcvjhMD{tN&B6aWAKaA|Nab#!TLb1!UfXJ= +_{XD)DgjaFN4+cp$_*RLR)hf1wS6y4h}5AzatGvGRa9UvHrK%gbc=0=eMNhNWA{SGgZC|g;p7t7?ieC +K@UqDsjc<$2YbR?$31tZt+-h#a)!t)aR9pCsYDkiyVc!`Y!b;qrK7;&|~FpNJ?qRk}NuI!TN=|B@hh! +kIZKN=mCtUkln8w07q!rKB1OmTg_1^IjYg9qA^O4WVHTE@a&h(>gxEd8ifLu+z5p!aCj+iKT>k#kH+R)lXh9EOwD2f$#@vqz +ulfuL4+@b~ANr;TaEC^4t=o&Lo0ytugf#^rj{e9pLhu4}2a-=FLX@$IkwUCOoUVO +?thS_Z9ewQ8fC@7(q6Dv;Wg>eqCx0(VTYUxL^HBAfbN_3#XEG<#xB0oE0R;s32gB^`%&FnoBnw21L@W +}5QA$?dNK@6`yrGuq8dKZbmo1>2zSSmQt8 +m-+0(DPZU8uX}2yXNRmz`k=}eOK-<)s$Cr@K{JyW&`>zANIM0z_d#@fDk27Wl#o-b98{*J61e01j4pp +J9fIf_tp+)U`(N+Rj!=l+;I9#IiAGOIV_>NuEN4ou}rGYX80e;MEbSAwNE-jGxYwNjSPK2oIxkV!nUy +NAs`=2W8H9O?6FQCR7(f%Ps3}VwO0y7kh{LiUleK5_wHQ>BJ8a_ZfKb@(M0qFQ(ZWmX_E$3!2A`2=Y2 +cly*YD=cdPyCAzyAb0Z}j!?Du7KYqi)nTJ8brPP=ltL3dD%21Q6^?st3OY|PaSdVpDn1f`|!dmaJdFe2P2Jh9`6>V7l$qOy`)zQ8#iGvCFv+ +U@Rl^AQ(){-Dlm`tGu9KCS$?+-=v}KmSkt@6~2={}@|%a&MGtIu-NN(5N{SB{O**%3C`I7Is2M1u@AF +o>a|}UJDW*)|TB86C~Kj>SC`7$ojCBFhC#VBNIP=N+XeM0IpB6<)zPw6N&J4B~yfQvl~ntheAO@PE|? +(Z7-+6hN}KdAg@W(E`;ZO2`8XD9Df7?j{NpfeIc(Kn>vsiefqe+BhcfS=<*%GcNqQ72xLUnMvY#>oGHBAyas0 +7QbD;J>5*9Y22c2(@g($aq=!cIy`!L5+9$wn=)NWNj8+IL&r;@ZOJo`%Z-ZCimVj}X~@&5&{K8`HWt# +LZ5gEPA$+-r{DRK2kT)ul1tj+|IX6}-33@adU7Vb~K#PuE#m9%2C-IBdm+XKAi!p3oEaA +7@84}C_4WauQ$Y}~ufj_6Ja8RGGxLgW0ylm&S58OgX)MwDOyn$u`|#?BN^nOy*b2VpE_hEv|IuzJ1Oo +Sv1y9aRA`++xav5~&^X1%2z$Xfg&9f~R3CF=-{>A%ViO@bt}z)(WHho@XVv_ld99)A{N1sCA*?OK?U` +S+OoelMz#vlv;zdF_m6N*)w)%F)s>AaJJF{6{->|uheasI4?3+TRZs!1F#C7a*FdoTINMK@YScm2t5J +jk&T@l!M=AA+*;4+B^;*jWV&5h*Dt8fbJIZL^Khs=)s`u&t@s|+=HOD7+vcI*np>sKK^RN}^wfSZ@m6 +ih=Fd#s@a#L5Odo}U|53?YZR-7cm-3miSFrxhh2+9SWt8)KU4&SVC2ER%J=r0t>GIpyv>i7aM3AjxAC&cFC5 +Tj8lz%Y)Ji3T({jW!W#JJ)Up9DNI%YM4QEhA%JhW$RwPFEK2QfiB_A4l-Yz^)4TG=@ZVCnb}r2y-fDT +yG2852GZXQXLrZgo}FLUSm@a_7q@8If$J~AbH`uXfSRzGpn<{?w_q8!8-#U2VDdc1=)z9URQ38eJ*wj +E$GMi-+8Y}4ko`2iu40M4H1t*P9RxuIRdZy|T(YttO76ahGFAaO6S=SsDdrmfEkP!0rsh?R8LB}g6JQ +0Bz!kuK#GDC)B?g^_U;-FOoD|Y&BRxE^0zqiw3r6I(PFDq?Pl_?)x02*sWJk+_8gCJCX>Np!W7+fb1LbQQ!ptRbqTNWryyHr}eZrarJ<7v04p +>EBhNORYU+LzKMQmw*C2Uw56g3g5mIzBcl3DhGL9uq@v7S7dvv&VH^sGumi1$85(4&fs}Z-rmA8%<{)M`}H^c^ZU>4&k&M&VfM`S+;rXTckep +xZ&T3=5Z2FKY4BbQ{m`wrmfdK177X&a%4t)OZ52|`eQxM)y46OM@Px5(sk5Pu(OA5L$WKJTm>33;OKsuuZ=)-gI;SF|8UR~_ojRF4H;&-#Iz&mvI~@+xt~x1 +>~!pdkf~a^zQ>nJq-eM)!Sv)S@`BolpVAeH+9^Ch)JK>4$D=JsfhS4wlzw>ejo5+ub!Gb!)$cVC!2;S +fEQa8tDjj1lO>K7zIb$NW)o~N(>yQ`_ZKe)`(zxrN!;{M?_o7mNHN#UmKMJ2dI`UD8%hA +0})&9$m$avnJ@!%8-r-!hfseSv=h+!*=JT=nSgWb_|UO9KQH000080P~d=N1-nT+Zzc00CpMx01p5F0 +B~t=FLiWjY;!MlX)bVi#aT^{+c*-v`&SSS8f|5?$|Q3O(7+~{>~3RcvxDtkvi3^&WQDz$$hJhV|-(E(>bvYzZdm+u}VHlE45lI;sfb~aauP +vJ+Ma`7F)Shyh#hgubkc8{{8mTea|+@-ajZ$JI~@6UI`>(0r>rnj +{=d+yd&{w8J;MWeS{skTXSD`>w;D90W7&`Yl$g{rg}Y<)U;SF}cNjj*=Z@LupeH#xgir4f5l+Tiyy3w +NSvh3W17Y=B*({w1H}sVT!M+e)QGzvW%{xmY-Je7j)yT=JsSjW&GG7cbZ^+F7P+M6a%efvHRwqhU(P7 +3B6JC~-S!b0$^UbQQsNceGCIKawazh@j}!tM*Tdg?K7O>)1#C2Y3c^(zfh|ebP!S77K)$t*vN8>DI}u +b=h!hSFI5+$cQRuHE)^?FCVg?MyOJIBW@^c+&MD{7qx6e&X!4LnftA>gSaIDn>|1BS1#7##h{_zTmB@T8EGe{I>*4K`gg!yQu+9on!rt9|xV>dakisvPHB) +-nI5yB%H(*RWPpm5^Jt=+K|t1Qc(UHa^zuX96wxM7X7ZgoymyW>_^==$w|i4j^uGAJnH1{1d?kbf +ChyZ^}xR-o`xs%D+M8Hi|}qGIKx6Z$vR}lL7N9V&WVr?ArXK*aV7>lDyz9FB`8WeQaZ%Aht(8hMo}i~ +eV7`Kq6dVA0QFp^&kVrgo0e)d_?i{o6|qVlWq~h&jQ#^VGXh?X?LrPl8!1CI8rgK*n> +E3G&g`d?NNkWxu+;XOdl**dr*z$l_k|1F~~v(5l459HG)6-G!azYIP%OQCqr;ojeHPnCo6OfR(8gsYG +zQhLmwG$7rez6EBCVDrVn<+3dz19)z=o0Lf-rGDz|_q)PGVG`a{k(9hD$T(MQA^g_XT7-sAz1Aj3cqu +fEpgCMm;4KzMK82BTgV?ACd(EOq1pn>yr@fA_|}tE4S~UeGhxvDTKvSi}ZkGB^rLjUxA)gVk;Ra3+e$~Bez>3K37R +orwkU*!qdcHmU^6%_$Qjx2j(xp0ahPVX}~Atj7OO_M)2y`BSD=C1x7q^`d#!%?7#R@%^?F6go3o +ePY|&I-zI-^)w`?F=N`3m=k?-W4hGUY(rdc3pPx3AnjQM&rC1F;lWXnB;vZ6O?Zq8y*L0n7Qr;!Y-4} +;q(&23&Ryv4``VK>s@TW?&D#cE=GZ_ZPPdX&1ey;}z$Or=sPP|g#Z29c4zUytA@+@P`=YA=Z+a89F0N +LK{gMPe-=72O^M1oN@Dfa?bu7p8r0BWgk#^$-yGDjl241>EO2r*K5PwE|CkD~#nDY1oMKNXr3ZOd +lAQE`T|<_xXylnu5>|3O~o9`)f2|HYP+;>3kL*72m>@>>nZy^eQVo_Q=Ko^yGJc6_M0%eKfcHFUs0S^75<1b*A4rz_;FfC +qHRm8Sw3g*Yxb&FM2IY3+2tk6(GMJs8#n^Ytxne9)p;}Uf?e4qyXxiEuA195?#pyh5tBx`oT;1FqwT1 +@J`p3Nn{IcM0+e|=t*Dq&+)8B^D3G%HGa`pE^iL;q=rvIr23527yr(widtEw|5{WUaidW$JA?EHgX*G)I+;r|b(y$#R$oUFVwJiO;~CY%}cCc95R7p8`E7m`YNOh-CjTUY7M`K +QCUu)JDeGNUef!QFT#{HI)g#_jP%b)GJupU2=kyd1S?> +Zxmg`FCa<2uC{WFAGDvTn1UQ%+8dG_zouY|3guf$FhkNRk>@;nX{GAo9$ +q?hu_lFZ1>(fp7Q^CI!rOiLpbDY?E5cY +zIj7l!dXXTM!tvuG!@k*Z*+DoU;L88g*(t8{sGb~agRwP8uJtjbD@Bw=!cZx~+~l~<)m?C;6MjSH;{< +$vUAwUWik|5V05nRQjld}4ubGHJFsKLD(9J!cD^-d5WrlX}il;7nqw#a63S7&D)+;g8;wT8KH|bxTkZaVJe_W|PS +zNf1WDF4>3aE;Z9Ro32Ee7@a0s{8>pYHliq}A7LtTNobhq*cHRXA89N~l7er5>j*K;xiRdw)LdKPL~8 +MeNXyxC!VaLWU~hc@IG;Y#kV)6Di6In>SrZDf#IN-V|1bX1_+^&mmcDldqJt|lu>_IJLY7Gq8IdpDCi +r>8ex;oNy>iJfY-b%brfz5%xKLA?z~ln2$(R8te<}zU9c^X +Y$L}xBM!$k!)Gla0Hgat&;qQnpoMWQ`M93#AiMe=l8(X +r;P#B&JW>re#-yXc9C>o?t@?Y5!edPL% +3#QQ30mj8;FdMbo_hXV2fY^m9C0D$1c&l<_u?Eb}S7!h$P&DekSrR350$H=P0fNi9=sw$_mLCh#9q)B<$4#;yv3~gn*!VQ40xcuA@K=_K +z%`A@N>1dn|X>ka6chn46Jq;HjX`uhg#P}5dp=1$_0%|V>uKHy*Cy4O5LtCG|*8((TBMSi{19<>#7+B +D-tU-+vI80<8G5k1J7EbEAIkdt-MRYnyfE#K^(JtvL&ea}ld-hNZ9t>&DhzBhKv%18SJZ>6Z;Vv!co( +9)TLWJF-aSTI_xXHaxVR<+K!+_0$ye&xPtW927lWZq+j-}J7CEf+kdf*ZJ5jcd#?Q(VSzdjP8S(Iy8! +)I4P=GBDDPNLCddvnZfoKOCW>lFm8ufDq7<5L)Skq4QTG +2S$7zd~otzU6zpT8fHoknLeea-W-kCw#;ZRi)T+6&}!_zU`eLIAF?Qyw}Pe5fB$`{@=WMq-$rxitmHB +eTm}>vvZPlLVc%5|9E@p4gF8k6k~548v~=PGel5U=jHv{B^yHg=JtHyi*9R-=jerz5V|$Jf4tSnbsmP +wYmFu$Hn&%f6kp8c$MVzY5#rCk}7f=&j5JYo<5NjcnninSLP~C~u3JM_|L?8F7RS|p#n20;R+2+84*M +IP0r7-7V3xEUaW_%0+j5q8I=w0OE;t8bccV}@g!LsmUU`@_bj4)W7Bw<_>cVtH=MZ-5Vmv(Oy3S%9Pp +!SxE9y4J|SrDWeWaANH5rcN*2Pi7`MXq>e$&pY+&q-Gx=wW~a-Xo2)+6>~OxrEsNR+T>>x3F3e*&D5u +ZaX=^3=Ck`&2{^6-Vi3K(i&VxNaFine`HYn!q85V6IdLmipJ=POWLu%y>M_pfmkNsIt*W-BZ^wi@$4E +XF^X@XrMxa`KjA{+DHV4 +H10!A)=I{at5eFRE-Nl(qf#`3`LLS@0GkEeA+f?ehv^3LlwVR7n%2ogi49RZj*doug*q{#`bgM|=DrR +$v8_QIc)K=xpXXdPxyJL=p5gNM*V>|i3rkXj9wZ2FSWMwsp3WOuQP$c1Q!;7dZVLq&K0s<5-8qsULEv +z`Yd-odtQ^+hvyNVW<&oCie8Is>a(LruXJ3j8p~HbbdFbBArpi4^l}zZ;Mb3%2MzW-%6htkU66W)d~N8l*bp_QA?FGGe>y_dm0iQiy&~ +^}q}kL(X5bZN2?{4yz$u&Vr!>lQkkE1ono*=svmYbD3cJl|L~6z^ofY@qJ)H$KsRhJxpI2gZ7^8#dIr +unG*8(Hw;z_s0f2ScClvY)02oOq%C1gvH^#;^ +%HZ#U+2yM`F_8rfGe(<(J?|~D;O!A8$g5cKmIK=GD7Dow67_T}-aL0~1Fx#t#A+(Bd%lVd9A1JZCY9v +7f_nw;&>aBonX;#axgRNq7O^{v+w^q)?1@ThWh^ut!9s +1rxIW&_(%CY;KwhX|l$8xP=Y?Kq-oWM&j`<}8vkjQik}qWw&6@q00&(>Zou2MplQQJchndphI_b5=ri +P&%hbX8PJEhbR^ocv|KQt{0O~Zq<9NAxSDUu4v;@xleL^9*6ur##MMf!ZL7$7Rb>ycW>h<)^?yi6pkR +Kxy*NNW*XAeDX+BuSNcI>gsIXS?&M<6t`Eo4n!%b@_g2j+fU8u +d}lYmo~VoWKnFd>d$_)A|2M5;2x64I{W1KoH^Lg#>`m+)fzT?IZ{Girdo@uz9argOtwetxu9TUFM)`8 +&2YW_32D;MVo&e9v5Q8bXqUrDi`2zfVi}R6sl;t0py%ptvgHw8z)plpmf>y@gQG@8b|e80O6kf40QlW +qR{F}|G0q+##NgGy@G*TBfjpC$m{0NXDN#;Df!A=QX+l)c#yk}3UUDy5i4%j7z{RIg%BAOx1|aM)o+1 +%e&+|~U}5UgAZ8SHr$fudmU_sZPmL@vh4}pPlW(7Vrf%LR@Va<5LVoV^*Pq;BW@1|fODXi{8rl!bh7% +ZlP|u*;hEM~t#5X`Yyki^gJgp_#Zuh0Np|2+%dP0kOSQ$a5uRT3`k1v3ezN3asgeghf`?zQnYndB&ogElaRp*b*JK%VqUURf&axj0+k9brr86 +ieya2?VNGsbqlyse~FAn@b7!omUjoCzqLqDysR@U5)tS_mMbM$&~uBZMKq<@QGxQMcVffy~mw$JsoOh +k~^z1z~BwlI}~BN5qTG8v0>qcP4Ij}HX?R?B7Yno9ecKs)^6Nq-x_^LrJyvmlzqqj;ZMQuIGH!Cwxd; +Z#?98_7Sgrc14wWc4K#f2Rn%f8F4AU2NOCnD&80=ce&JsC4AF+?m!;vum6e9Z?Jvj6*l%C~u0nY01k@ +9OJ+jP#(En!1Zr$11?N`f;(s5%aXa?>rX<19Y~(r0dy0u_+OlBcYq#prOgeC_EEb24^T@31QY-O00;o +{l@>?qnThqw1poj`5dZ)Y0001RX>c!gV{+WpR;2m84>)zkcUXqC{Pst$r~thv)j8i*h9^LTTQbR&h#+s2ZsZVfR{=t>LuWZ#MmTDG +vuxAKX@Iw=%qHa#3=(SA4U%Ab)=R<>M{+jl+E*G!eCtM2k~W$w#h}R+Xi=Pa38)-x&3DyCLw)QKRn4X +=5n})BQ2+Uhq@O8$;e(ns-V`)iLNF0qy#`jg`=dCTWc*wWC*+QJlvl6S^tc6A+tXBz;T=LRiM+Z?3eE +^;=mRCCia6lgGN0EE`of1vQd_2Aj}8jeG|$DidD+rR6=n8sggx6!&7mib6ymlICcr8@zGtb#lToQY +Z(N<+=dJjST(ewQ`){EDdqIQ8o4;fSl=NULevfO9%m#01|($-o8}EZ+`KFUTKHrjRxHaYtS!KP2DBlVn%~Gb1R4G$t0EC`C +FJ8PD*6&VT4JddIT8lg_j8spAbr+xo`URI6*GANq;lO#7FBTOF$OfFc`jS)+8Lq=%+i8dpgv8qhqtU2 +y($)=2A410>@*^O1f_VwHLqK)7Vx5aP7AmW=qd^-g_P`;)YOpqCb?+}C3`wO@JT>Lhgj-i$Mp>hguJB +FNS8YvGSyjx&W-!$~zl%wF%y!PYc*0=u(}g@zZ8F)K-LI_Fe3YI;Aj)#4L9grRy8#vYC`?-PsK7YdER +G@Gk5o3O*(7Zzt*?1z_CS!(AMEq~=O_R;qq8YY$Ya^nrS*7_Nsi +_F2s`q-$r1sB;-E5E#5g3DD#Szz!_B)R;S$I#_}gWiAdqvCB)pNn6FEDNXcW8P#{gRjj~nZ{2{5{hH` +wz_y~%9T%jKCKo4LEdKiR!LRnN-hgx4sEy;HHUH0vP~e=!r+Mx=Kw^qo& +5vDm1x3g;E~k{`GkSRJ0el$qznEnS%G5r3!quzKrj%_k1QGi!cygkwVFy%L +pH~(rR?#|B6v@6xPbYa=k9|NR%Vz+M*R*2LB7ubhv~V2MLKTGjm{W#IbltMgCrpC(dA-{w{84Z#lJz8 +Lka(<6-ddV={dICh7Y<|;TnYzGJIJ_hAysM5WutJ=a@(2Yvn$%e+rML4E(W^0(*-4)9!+|zR{sUv8`# +wX{5(bFgpD +(dJ)JO9KQH000080P~d=N7IP3k3R_j0Jt3h01f~E0B~t=FLq;dFK20VE^v938C{R#w(;G+g1E&(@~tf +26>T3}ERgh?^a=z`kxSbL#}H_VvY3@bg{16V6#4I+At{Oauy=1Cyc9K@8P4~Naw#g3Bzdb_$&!Tdsu5 +BXdQ_rpHB0RCYUTDzaXRt()IDleH90R?_bgQ0P+hE6IihWN6DMa@XF|q`KgX3gGZnY8Ecvk`)KIAyp^ +Dh;#5}+KxMaVzOlc2++woXvH7`|nAmgej=}UraMnqOxGLPIj?EzsKk^eBMxTrsgT1!!`Rx2O^=eZ`2B +ZlK{9|79>8i;!Xcu){u4N +e$a^YJAmR7#pDwt98}&@wk^c($qzILwtusPvLK~1Ft2K&(9NUuz3Wym&_IBGXm71p|i%%7;SuEsfYge +hLK(|(co79RB<+J_x$3Oq+!-sW`j_1hXu74iH6p@~dX +hepI_2Q`*EUly|3xi*NL8|}`eQsxG<~u;hO44~s7*3_{?l)7wdX9|dn#rUoTa=mBZmv@}*hf}-58`zE(q|$Gxwt;{EHXjjmpLN`O6L2$kp~36eGsZCIbHD)AVELZ4y?gi +WyJs803uc@OgM{K*$QMHGE(${nv&_HyQI5SEd5~?LK#YJ`kr#vC`nl`+Fqn;DdAZg{44m*+2n^|@*$ +0qOz&l&{-2*=<^92_~aTu4T`o1-CM5M{NZn!ypY5qeTRHjo@SN?NBFQ!4rb2G24gB!}d-#q3Opl~UXv +`H4Zv0i=-rm(SmRBqBF!iw4dj1yp*DSs?Zq@7EpQ#=}vQkVZimxeD>>o+nvOP)?Wx9bfkJUd+4rHcl5*X0NNX7tGG7iwyewN_C5)ro8sl?P<6(Z9j6s9ttL$%J!B_jjPY +zyEX@d9SK3J_i8{?Uq~h(BKOI8?0|6LJcnM#MvKqiefzh0lV +K|-Ds29 +B#_tc7B?aj91FVp0rm1nS=@`V%up=*zQ$(mG`uj*jguEEV^+AfZCXO23`Y=3$x1Ca_f=2#&xc4b}zPg +1PwP>Hex}9DJxeb?5j{)K&rK?U7`PoHh^`ioaMi_3jyW)zu$+7A2=;}&9D- +*>~unjO}~lnR5F%FmirMQKrwHv0jtHv%fkoDJq| +8rhsMdo)xryO3P!W9q|zUGD-E=guOrc&I4sD@p5V$vSd`}i-t)c#JOFN2JWo~AmCEO_YbcqTxeNzsf) +91Y1;^CU*;-_Z_QaU~&O-<>aa?VLbL(`u0fFOET$l_;2?0layQ#1oW-|s1Ohj+QP-mP@Nh8ItEY+Pfk +=q#e%|L10S?<6n}Qyh<|$4I`WFUia(qb~TeAQIH;6i(F&zpCRep% +~in(SL#FzDK+Ty@b18`(QVs6$GfW7^9u->!sb?R&CHOzP9A39Le1~gtxDFc}q0|S|{r{-;0CY}8)j!L +1w-PrL!IJI9pi;Fezp-QY95J0tN@E+pNWE43(%`5IHBSwlS<4VbIa?UDTZrymrgnkPnrRx$ZaA(TeEJAB%jh=Jb&2nGrgC{^sX+hEYt&jm$Iy +5Nv?ZP8q^to;rgYYeG+0JDQR11)4`?=3GwxT-&)8ie`B_1(qJ52s#h4#pd+;0#zV +AP0Sa8-3)f2S{-Ultor(yy9vI-7aAlyHblSUoDPV=Hzs6;+N=Gt3# +JF+^5KxJwvilVfXl};6o;e>}N8EGMI)y%gy!S!lX3rnM27~hV9$|XZCg_8F;7SXVy<-#zmc1FAi@&KI +c?{_)i=gaTMcv^?y)H0|XQR000O8^OY7y7@M0oj|Bh#ZW90i6aWAKaA|Nac4KodZDn#}b#iH8Y%Xwlw +ODP7+%^#YzQ01f^st?HP1BDD3x$xflBPv#TE)_o@M9yDA@seLb!%AKjW?TqzLsUlMd^l8yD!6zO~GsC#)@q=1?p~ileC7{+NsXDZfg2 +DZK$bYqK-x}Hj19IK@dJ;@)uK@OYueuqhvkGyfvY| +>dwb^XYE2hZKxtEm8{ATCEG!^s+fr&sYtEtxHcc!vdaaxB{Y|-6@zz@YiQ&5$G9p_xRsl?4G*2vV&X0 +;Too7Y*zj(~DULfjvtmRFTAjrXbhZ>=l$WvJoV*2)1)Ym^m)J)*0jW_1yRV;KlZ(SyX_&CSi*$1ZmjB +fpdumF7mO&xCf95KLmE{mhv*Tv#20GSDz+!~Cb2DcFuQ8lLa_g*E6#nNj-o=koB3 +Htm=b|F^Vy0Kx=kNWrN1G7jm2Tj(ZR%sS{*v@oz +8e(LD6PL~BBtnJ_?rmT}-LZEH*+_&1e@5L84qO!z8c%Q=V$)xEkD8F9BrS8waAxM86uIa*+k8EXs)|G +0mvlvMH5`FHZ3Wf*3=XzjsWe-|4hI^xYc*?7xXy>L-9nJ2O1c5g +}M8nZE|Xmr@{79a3HUI(scAhQg~$RHcZI2&a)L`O{JGT~6N7jmh!z)C(f=2NayltQk%ViIBzol>9!>|JBRNugB?E@%R!21Aoz7+ +T_4(w8Fw5_&Bp`v6yh%T037<*TyBrl+Nliqu>%!i6=K0Jpfo86D1?#pU!!vDWUuHRv_iwL=wz`-k&G{ +*Y`Buc8P25{5Z^-6b!-$9@i~rc{C$kE)j41=jFBGDsw)0+NQWqqS4ACi&x15=`D0-rSJyto+ibAE1Ob +&=>O%I^)UZEyh(hh!z>nd1gYlf0pF;ii)hdlIKo{t>$`0e<%7?$@f59&cD)ED#M3gPiR*rsIRdvE#l$H246eY13wG$P*5ggMhKjxW8#H|R&!w +_=YmRE&tF)rJdX{Te^545AWX}E%-z==DZ(3!r@~Pzt-haY9+Mqj|(Z?9yCOH=R`IBOHrwW&67TAf`TN +F-edB#Tq0Hw;{g}1`T=3NlYFGW@{J}?8@kQ+H(p~^CCl>7i!Z}*HvtO?HJ7`5ZMhnF7&^>wuW;jji}Z +qNqm9b72ZlIc4+5Pa$BrSvZu^kiEb_6&XXS|J>E_(gg(6TVYjtF*$?XuKf5nm`kZ%aeryF7l}hG$!a) +Z{aowm)vlkmUz&;_iP^gXUYx7?+Z&3^vfGV>WaCy~QZI9cy5&rI9!R}%q>DJa}uPE9W+1#~ht_YA`i?qEK@VbI*(YDUA@g8=D*shx77qX5@`%4lK(yt!f3&GFBdrjZiFK$);)*&-C}n#Ee(Xc3ak4` +?Znwli-ud26-LJW15|KT{I$<<#T#yPF$v~sH$>hxgT>OIm;!}!x?>d)|Yj`pDppnvflSottu;Nr^G=C +&Zn#><*~|NfREY@NK+%RU4pD@mBDCFcv^QH;p3G3z=bTE`dw2i(NvR3CQo(te5f)IHxryaz-iNUb2ye +2k0Tg-xQZA5yjtESS5cy=1wVz9@ZnG@#fuqC!cL?dqg89s3$j<` +V`F(gUjqWQk~?D1{wMyFtN^O=gGJJHFmGtsmM +=W`@nZoJTxdM5Op!i%}U47yZL$zcvsAI~kR+A}v+Hp|ds!=UgID>5g%9 +7bPi#lYA=Gj`mND9)R;>#{r+{cX@$I;%n82mpQwU5xeOacBG)6W2-FxZq?-$AuagQYIS#GU?`c*Fadz*<+2Hvf)Yb5#&|u`=$nrNn4;EGu +sh+axkm>6jQ7SxTzF3;AQ&etAYjQ7Bb4QO6b-2w`dDzO%9@yT++3ir&|;$(fk{Wp$uT-YeRIUM2!2T8 +jCAnS(;Gz+!bMtKyfO#U-bj>^)JQD4({_9iqMRExPJ9mn-)dxv_D%V7DV2;z6lR}m=YC*C!(|--IF@^ +kLXan+F&ShRg5@>-}W=WO=h|T+9Mv(Wo?jr&3^h~Cq#4Fc(G1WqS^|6G@gbG3PQKk{8@lQ@yGX +bz}c!I_+n3u*kgWKvmCCv^*-NnwgWVqAve5GFj4#_;I!xDiL)sEv4IG4w@tyArHWxLSf* +XUDT?a$qx7FTS+gno%04@^RhJ{cwJzBzxHe_GLSB<0^Hgwb0{FFy +?@hp?V%O;niTieM5 +*o!%UN_ljj{t^!YO0+xIg@{Y5eE8>^d8Yb-`dF3dWgWtt~uQ*1oMpH>Cc1RHTwWX7Z_NY7 +6h55X)y&Z2}g1hv^qbYk{$D^skgE$xWk7aEIqzpgzU)i8rZPeLn3G|8oNJWf+{N{+(0D&JAgK;5mtRW +LX_L?9%m0Byguy!_Qqn{LkhbL8#rc*C>iERxl|XoBBFlYZeXD2Oxh1d?$v(Dytwp8exShCN~}`wLi?|q8*>BcLaW@U@}=}Y`lK@;t6ub7_qdVi}7ll6@UOHOm- +C@Z*mo8jQDtF4@r_>B)IjR!ExB_%!SEA7d8Re+4$)i#Qb^9O)_fw#2;#i>8hd??}cbYFA^2O4dj;R{P +WyxmS9JG<9iI0N;x}zUks_R$Z&H?x-bI`y!qz&Pz|x#YpM19aobTtCZn0jNKcLA&r8Sye#onqlPAU4#;qv&V1u|1u)59~hubwC3O{cL +O6K3$7Cn$6Hq7yBppe5PlOPY66(!DFvPtjS>{>3f62^;XZL5?xmQ;N?wk1>7;<=f{Nxtq`d~v)I%ErP +O`q#d6|84bBBEjXrUc$puHyl&=EF9?xe~zQwaj1Inla9P$%XZNM=vSwt1R!kL{SZ}D@lMj(AY!@vE$E!oG`EFpy*EfcRvF*Bx#x-v3C*2uuONbMv`Ts +?6r%oL+T);F#3h1Q)YGUoN2`&hatjDOYZf>X;w?@jibs)BEykVL&H2MP-9Eui>4APgm)Ekj}b(4P~hSx&W54Tva12lWW`(vu1@^bGZetXbxQM=-o0T*!g<@60QmqY4#f@)H; +Q~Lu=YuKUkz#1FxT2NVc%o;`PA#bi*268n>T2%#Y2We>#%lQv3s<(flyF`=rc{*0bUU +cOsnjaxu9Q3NNM`C8|`(0`q;W%aEN#CjpJ49Y%xa$jzp3X$w*Gu%*I6_q+hQR;Bn;!})6-lr^c{vn<8 +xZan9?7Pys?3UrCEbmj>G!bl@Icc(-dz9Dpi9Ny-}TAe$GL2kevIp3MirWTg^nAAHVBj*Z9LII-R_;fp|x{Pv +$IirD#;msI5ycMLri9p>oC=WYj*ok>B3PYgq7L*3#bkruVkNAL2NT^YE>hR`&3fnEy&`5zRzIPkG_XF%W3c +fhj8`iO6RvH);gAM+}5|`7_-i7(~f>=8Cdog8CasI7e_PbJHmDeIP+yR06hZ$03!eZ0B~t=EjKPPE;24;X>)WfX>Mk3FGNLCLsCglR7p=xE^>2pm6E|u!! +Qhn?|F(y+>n~wD+WSCpxr7o&Ma+B8j&VZ;uh`gaoUbDG=a!1vH#EZ9|sfIX0u^z-vK{V$LgL(Xnfy;Y +oTQ~9b!nOl;Mb-cSTUmyVAz#Vn`4RJ(w0m1l3{(t#6X>QA=>rDujfx8Da#7qQl#+_;3w +S_1KEBJ-IHNicTJ54$<8&`@Y?!UPeHK?&n?5lX2o$d&a~hX@b88E6Rn1+ipqJLNQ3um39K;3Iu6@no< +YYF<&>t5i>qf-IDokWoweE~NqZKGL9h?%x#BK<;O~P55rO^)|3GKbMFcGGg({GI?;-D +Mt0BJl3(QjCu1KYfb+Bj6wdTDnq}u1j0wR_Pj;0hUl%KzZJZpZ!E4oO5W#82ms +6sO8t_~p<_V{D%lE9kh)+N}2m+%TO)465QmFZloxZE1a!t3PZfOSs`&p3~m&G*BCs0cR1QY-O00;p1l +@>=C)Al7Q0000)0000a0001RX>ct!E-@}LE@WwQbS-IaW^XTLZgg^aUvO_}Zgg`lba-@&PR`FO&d*7W +FHSDXEGQ|C>(4j9~H0ssKh1pojc0001 +RX>ct!E-@}LE@WwQbS-IaW^XTTWprU=VRT_GYIARHtyEoa6EP6{E0&*%M4dJ%REh+mP$VK18j-xA>g3 +wni|L(h{E;+@^546AzK9g@a1uP_GCSTG?|OH~;VFTQ#@WcHY{&gJt(+Aak~B>Z1@{wFs&eRoFRlgr;H +#8;oQ_7`c;UBR3gbq6|C({-Y?3Mw`^S!3S?J3ZFr+dKYiOK@5IJ(8MIj0o<OD_EFT%) +eQ*cTH*)SblGG^df@vz#I#en1)D08DjqdN6^u`KF=AhTUVQpKn=fa#-$aOs@5yF=S4`YWtIN4fkiJ6y +vB==Ow6V8MiIVn4{0L}NRP1HxS)#*ka1h}St&?oax&!=L`d1E!<&G* +rk~#%q_f`QD$_E_>S#vB;;h>x*;WC5WfP#^Ro(T8akxCOju)WfX>Mk3FK} +XVE^2dcZmU+xERHWq%}GrxPF1o}C@CsU)lpDN&n$^AOD!tS%+CV~Dw$iPBqk>(E7bx3P)h>@6aWAK2m +tt%7DvY)m%;`B000C4001EX003}la4k13F)lJLWNCABEop9MZ!dIja9?a?c4cfXba-?t$SmLj08mQ<1 +QY-O00;p1l@>>bGkct!E-@}LE@WwQbS-IaW^XT7NJT|V3(rVR&Cv}@Eh^5; +&$Ci6)HC36Pt8j$N-W7QvQkJ&$t*63F9)en&@j+5GSM^8FELh0KEqQ02}}S0B~t=EjKPPE;24;X>) +WfX>Mk3FHJ>MK}11RL6ue8Zqq;zec!JbiH8D`*S!FhOj8IAm#A$TH7Pu{8+&T6u)WJ(Qu6oA+HTT>2% +0=OGv~~GW-rl+OgIsJM`NX`6FB7iY$Pg7KugV*;$wcm581?5l`xA0rUk-yG46xGR8 +rEy-ASkFJ^MtN;{u2fzkr?}XKOtH4)>T)<`=eT%KCbJ2ku#4L+NXVph-pSH}Mdx)$!UEZpP-DP|?E@rJc)3)lCV#5%=58?5quitR +E9h^xsE`dS+`Cu-8<_NZQ?OqG^t08G@qdk_ZK0wwt;FUyQzl<*pnqRx$|s?fg+QRkkz74Tgz>FaP;Jb +$+{<9J8L(XM#DYZga*cOP$dWDF}^VrY;EQ`73k3r57b%+N-ke>)=*aA+MFVb}P}OGEMjO>wgmq<9Y)P +|)kaUI*OUM6QM#UY_<2_`&|G=g@3wq;^5u(vF_Rs#N-OD~^R5)9dvZ3+sNjc~RKO@EHqh1)jByUK3Qy0Iw`UQGE$ +evRBt8>aj$G4bLHA3XFgdz)25&QL#x490+^yy<(hMS}!JkVTrSg#>+8)>WhnW#|TJ*YSj%|7*8{5g0& +L2=q0|XQR000O8_>~q%jg!*R`zZhbR96518UO$QaA|NYH!d+QGA?9kb960fZf0*UQbj{gQbe_U$&#bW +66LfWlWRA$z#*VesAQ!3N!93tGq{kTU2P1^h~$4RSnaGd` +%%dSsc7{mW}NvLfqcx}hA3B=QTyVKO$0#%1~ANLbfK3Rmay6HGpgg=upXq$(0+r-~!9x_7 +}q#qyuHKBwL#9@O&s7BK`qu+^!G17p!yP6GlbF?f?_>u!qr0b&?#Ux!;vK!QuFP)`JT^u=?G84iLxw! +t%?YZick3`WLKIU-6cbCpF9~x;Wbtb!AP;?xB|0^UD}Ex_GHULX>542cZNA{e>0OQ&rUN>j=+|EuOpu +>L2_2!U+QsAV>Rb}9(g- +81a?1~y1rK);0}VZzb7lLf^dF8iSYFRBehwgJ{B_xJTnp08S4Xvb8)tAY?J{)K+0Z1qdSx!(Z6Ae+IQ +a{2v;uwm$(!X=dg9k4l6*<`(Qp-J`J&^CgE3!4aNFujM@&z(Z5}x2^$o~1~-0%%7Wum%G2l_@#%^+6R +}pJDi1+IS^3$}QbnKeYNbfxCht%b{`;Z&!5zll@#`Rb1>^CNJ>Z9o(9b7LG}tO23GLJ#A>8PJ0oa3+$ +~&kgH)>iI)`_15J=(GnjoxQ6Z!5F-DEaUNk6)ZJH0 +kY5Z)n#V4d<24pj`q8^lagk*uE&|ayseoE0R2E$nk>0@=NPYxN8#f5LuzwvWv@MJT_RVe@vW{}#F1}3 +ns}@MQ><5kAPSc%(Ce7FCa`4`CI*|^-VB`|7R;;Mj-m+oBVeDty6$?KE#{Pk*r +Dk_{CKp^u_loKc@U{?qQ`;**~;3V)-vICFtvHyn@LKy%fqfny|1hTC-I<F8fI!`k5r3@PYCRwlc!wjFnNhQ-5Yu48n+UVC108n=MZ6iwcl~4w +oz>9Q#aGYG;-yten!y8J2-z}>)Yh7U0{OjpYiC#5=I*K0j +Xz%AvLN#!Cqhd}@c0gS;%e4@Fb-=PqN{|5ZWmlx=HC;$^^I_h*8DD%OyI|ge4!JHHcX)NVtTjFDaGThYocldLRMH?~psCdgZLG2Mcwk;OcWXS#Tg-)i3;pA>_?T!G2B+KuT+ +3|{&crG>Lz-k@CzaNEsp1TIOvGW8w@71bi3Wnv-w;G;5l)@kG#?nUoBz5p|j`!iQC?_dZge?yRjW0&?r>c2W9tm2_oV||4_aBf7*l}B>&5*24-bg!4xMq4L?TO?C8e}{q? +@*Dgu2d8e4uCJ!WxP2u!gwUDmULe7RZT$z*!#3{wkJ;@N)`D{v>Gv(n?Qn?voxgvcn^U`t4sx{|485^ +qkhmxy@G$gPIE5C`d!^s_rN5?9d82nI^}DJ0@umN2NsU%z42%2_Y)3LAS8`D2s6)IntMLh2g-BfVYTu +%4wZ$w1|K0Qd&G9s|^S%Q3o*iSvn+#e*>O9M$!#WqNyN}>#GA|XB?oaYn!Y|9g*dZA5yOsMlO&11f|B +2_eOzoUsC^=`gd~;Q7XUaMbgsborEYqH{r$X6#Dq&Clj(U&ieqGd^Te@FOlk6VOfq=N~p}l!ZR{k)!C8U9I1Ct-KMx6N$e1)v9{F*(AT)1g1WCYfl?qog=Wf3oV446UD+&P- +F9AkFb}GO9b$#tH}o@R;W+p;Zr~2?vwV0hLS_^aVSl<=un2nhN9>-WZO%)CjmDJG(Hctq0&6?U-vsgI +739~*?>f6R5K?6HBeoSrcR(wbAgz6t!^i+VJ%sg?U7RZz?0dC{cQ8m1_}8#Mba(whPlyBz$`{49kOIN +n2#K&`(;IfWLR?%L^L3E#-~#PS( +c2{(Q>DD&2e-!QR8`KgjPADAhaDnwrI&viu}oZseKMDAEL8b&6fjE8Z0c!Z#e8 +*6a69v&vPAIQ$N9JX*_iRl!p|52P`UqknPmo~#I@Pa)kjT0v44n>jyaM#SBRtKoGdvV&2DAj>wXcQUL +Ht1GeLL~Av@UX>+a1MW>c8bX2A#3L(c@?oj9F_qixdN!{bK0QBqq2{z2yf-ex!;i#NPc6x0Y_g^TXwI +F)Tj!K8SHr(r_V8PYpBY{tkp^R>QeU1^$~Dd_)H!I^^N7mA$_f_paFHR3Ml!vHMR^*c%aI?(@Pds0kN +BJ;B_2qkdzzZLEk*(qN9S%b@NR2Gem}OASk}k2>sjM%PS6nCXVKr6h!S7k +@v2r;k%Bb=B?Go&ei}hV=p#^HM%EHI<88yIb@g3DhVvUCl#Ufsl_Y1f! +HG~4uZ@kO#Tt9E>Zulz1d+o&uu8M$<7L^|2036q-QL`F<+|jvF??k>tcM*P^-Dw9C-%Q6p3}xE;uM*D ++{o^_C__H!!6cvgNJWhg)Sh);-L8HAMbAxMNCoqjSpZmsy|DgBDoA=R1N)iy6>a|FnV7$~*pj)P4AP+ +OK99LZ1?*f&CoZo0uGV(DG>* +y0K}UJyPz1%lk}X$Q|(>xqks~ld`3(>O+LxW6~LBWfi~+uA!zzIisO}LryaYRgUk;*?0(WdI-~*+mSf +=E_#1q|M=xor?IAZrAq?oU@L=>^kYc(<82DYC2(W<@|b23ER5!0cXqskAmUR3{so^V?hwx9t8dCz2=> +hzeR3^;mWY$FNg(bp3`Wyd=YE-X{vr +X7e+0__*}Q0HOwhK(B$*|SFeI9E6hdH(*gw+-eR-PTJ_aSL-zRX@X2IE0;gc=8|-Hwc=Z$YVm_cW +rfT}`0;~by>=pGrFOI7NaY9<{n5!i|il>>6cLHY~uRMQW7OtPHQq!*k4@0xgJXkz(gh-wNTG +X>?}8;bw41f2 +Otv-2%Z}^=8g>j0+wg~VnnD^al6ln_Y?YG`v-3E*3w4nRhss(th;kar0pC=lGd)3b ++--T<^dkoToB6+5bn@e1^v(kwTuY4)NjCSBelb!Zn!8rsV$)e&f$$OezH?IHcWs;{ +DJ_D{AwGtq5I^R3GQ#vp=_X?rNw`?m1eAYr>$=K8?gnq~It5Ni2YkcN!yb7e1dp#Fk<&Kz-v4>7@6mn +5ZfWZaJ6XzzqwESj~_io@<9M8Y~^Yt}M0j?>Og-(pJ4nk0-fZ=1yLXX@O8mU8+PP*9gohVXsQ}yts=D +rJ4T^Rn|F#Z3w@IP?$?rU|4)Dil4xQ2bCQ=e$6IP@mbgwdo?F2p^i;#hPYOAF&Il5c_hyEO4+@W!+Vz +8S@BMQ`{XV`)eSu*0IeD4K!2I7I~>80Waa^!3VAn#UR6` +lV^{{ie@zn9uX!(fl*6Oq^r4w=jqupVX$$eqN*gv!uXSB0*V$p~+jQWLI}&~ +G=zYx)KEJ*8$_G!u7p+)K6z{Aeqsq%-wwhvfaV^AKZiTk01}&_6o^OtYzjtbWL*f)4HNuMQtEhzKe&9 +IIDLj`BpB;(2RD+j2lma3P3o +6?Y={4Glv@N0k3Co-5sp>Y|hIsS>>%2}o!N_#wMqb<}6}a)RZ1XMa9F+TcnY +=8oBm#F3YGDE4jadZmcNs!!5S>h0+5`L2jl0Hc7-xX@aH0deP#d9^>IKE`2$Du`@8BUHbGVdA^A^~&` +0toH%AB|bQ!kT`r(LLjpV(Uo-%hn}6T>IqTZp1A7!aOHb+vpe-(@qbCvj79O$FqDO-MkbEO*f +#nuMji|;MGfj7$w@N_FRsk`eDDlgV~iNO*{NT{TaRU+xcK?Fg#JRa`} +K-QZ$C*IK1P@$ +Uu#3{Y&J+0E69$9YN7K@FT +cm0U*LUPY^v<5hrbPN<~3-`uUiUG@s6b1lo1GPKNZM%jigD2`i_AVPu^h|3Vw&bl;2Fg0u``5-g`*bM +(ZHxGa4)!Eao11zN{yDPMZtzIAcsQJSQJ|E21|UnY(dX#hcf-UOj$v8+#2p3xEo%T$nw(bpAQNdt!|a +DQn%DI&IY~S{PeikK87X-wX6t?9UtdCRqU?*IeTLcq>dYDdaLShCEw2t95blU?^_uN6kW(^Ce=LFs|X`f@mb}Ens3Cc{2y-!=^?c>V1tidF=e^zJDn}= +OsCr&LvPAzM!S@q=aaUW_cG^o6eeH=qhL`3RHLP#~Cs7U5GSY9Y2rFe1&aQn{T0#!QSgffUZ$(+I3c` +`&jXDe-J$FMs$tSkcCb^&rZBs^e3|CzE&8XK)`I6?BiHDJnsDiB@xPk8-OAqhgL2O84~w2nKdNd=9&P +BZ$SNetUjK`Fz$Ypb931<9xMyMt(qW~VCHQAMAul6(xL5{fHuGN*Iv-phDfE${WuFXW%q) +oV%3g@Fq6#jTy$$_`RgoJWR37WjNk*Guw{oJ*u4n~n&dl@$qr-$6I8+uAqsUL_>lNM6$;3lG6oxd;VdTbg#f=Ga}moU&fWoPIy+c^}&H3{?b(?r`G +WaKBLft>W*tNEepBJR&DrrzPuE2sA2+V8Q@6=)s&jDeZY(yT}W*ih0mzg}f~c5=Fj+-hf|cSHEEbq(`>RLKQRRO@p?(Ih30(K +Sd4rb_Ki=f4+tFSvD{eu&CO2^BZGF$@I+RNR2B${5^6$hXbgo<9>r1mOxlr$>6&3J3zCzH_uM4|J~gL +`cJ1tV2WCdXKSoD5aZNS*W^)K8%G$5oWZGrM4v$7<=C$_=TNpPyHd2JkIHu>Vh6%+Jf(I4%k2fa_)_l +ts&VFTwaH1UP7U3yd&Z7{I{%w@I$lIdCYs{j%aLdI)d%r`Ihh07J;tiRCjV{b23Pw8f8WxxPvL^eM9> +faKFWhw~5HDXly*|>=?-i@F$h?i3K_@k3~CkSk^5gjTvqL+Y7jbOcZ|Kk@*Mu>+_(jNh8RB8bfkS?}> +`0_Jv72D;twev>ql6qHPgU)s(^74uRhraWCj!r0o=0WY=ZA0(IiEcnbUzlCx!ak?I=kFzUt~t=f0m;k +;~>21R^l!}regl3;F0u~c<%YT90G10I|Fb{rB|Q&LD0lT^6OSa31DO?yGex9jh(%>8v{b#J+MW-{5al +5WxWwa=lnOFIn#FxOey>f~{-iQ9TA(SG+X+&>dMo47&v<#yq1yq*|a(Ft+tYhiBhS9=rjlDWvN#~zU$ +>OsqC>jSsn${LvZF8F<-^3oWKwtv5xnyjzE3LIoYjLB>7S|VHG*h6*{Nnnt9^zhaYkxq$wZS#HX+mQG +r*OuwL5BcqOqi_ZQaO-4S2wqCSN;Kky9()L=?&SSg?iWTy8}3Ze&s_1xWPg8#{%eejP?(~O`vD)V07; +R~IfF{j@fqCHl*k`3RHaK+qWRMLaeVl{BYSomo*n;>+RisZ(;{Fjt{IK*8&HlHRHEKWILau|e1u{>>(aX5z&-%84SijEv*MM2&iuQ;Wgj2%LJ8*#rQ{ +ls@i$r?VTN(LkRx!pXIZ`VY?N~jG=q&t$Ve=T9V9r9w664ZMu;x~MCuqozeND52WPtxi`rB7m=od~8p +Q8UYlW}IqC11gnt=W@>gmi*bL^mFfzArQ5ytrJnlIxc9iT5)_-?N3i|B0)`uD*5(%`M$ob7v8k2f1X;J< +qt>6%_J9!JK%fk~&!W-Da&np2dx;e{G8qX_0ZKGg;iO2`Tb7)woPW>d94&>v-O`X!ww3FJGgs-Vs|}@ +y9%)pM73w*s+N&Tt<6Df+YSy4)7p1NKm0bkb%$moR2Ws1vY;g{T+h8x0`;;mUnM~`HJ=K2`i7~ayej2 +tf@oa;59s+#-bjX$u428P!>KHTjSX#{V&Nr4b7^Fpt@sRH#yZF6@U_R3prJ0WfYC_AQTgGaStswv-f9 +Yes6gFmTj2chIVj{;NGHAXabdU7#h>jZcV~5K*}4BLeM6_bQVmvEr{a|LCN-X=r0}fmQr4Ua> +J#=9@hMx+wWqf=1QrSi{8WV4MupxHm`bIkZ0x%CWZv8u)E&G92?k?X;S+?~BX8`AMf*7}KfTopXH#92 +Zua&^iZldvg)+eRJmD*gg%;w5qJuT@tZz6R-VMcIU4D)wJO^_D^Vg#oiaKd1Qa_ +kuH)ShP8nripdO|Z?__WlG*(~oVw|7vpo^3r!ol)e<$V?Bv#6{Es7b*69{bejQ@Yoj$`RS4HDi`)gM+ +Xe~!7h>TD)@gDIGgWnIpe@|C>-ziP1Q<#i3`|=_;cu2HxzqD=+!x>R@o^emaL=HnZ_Dl(U9yj`9J8q +2q*IN1_=<8XP8uk{+qC}HT!U(1TT5;>eEOVY&O|FZ>%^{Y}h}8Q5r{6Pv5H82lB;J;JM9>O9*I7B6Gl +PSG=B1d?MkyF6EU$hhC~E%j*|^n0fM+u6LeV4<+BSh4XO7yDE@qWkvBr>a-s2mrd+?M!1pVvfY7C +N$@rlf^l`@stbr|ep +eqn2650VDw#_2({GCIAP|`0c{1#W`Di+d6=Jh%ym +$IRx%;HO?a}Fiq0Pn`+w1**`YoI7H;90TM%Sz8^Z#CbGM+XHgP49OOJz!Rt)&4d5RhmQd4uS_ttD#@` +PweI^^bEkk(7mwo=AVWb($#(gc*-Cp+0>lU*1EO~jHfMY<3Jw~Y4YE#4g4hG-P{QQQ>e_jss-}`!7$# +)aVGe%cPJOOTT!O6Bq7R7l?p-6`O)hH+V_9#w`_PmOY{j2SM@@+*|^%vc%9&D%HL@*8*CCZ4+{ +2=uR_=_ljYO;Q)|xoO|d`;*ePr>lE3X*m#(460bYO#yib>MUps)be*I@_yL-d$K4Ei{ObP3hjN7J$DSM|=Sg +Aaf%L~9>9(32+`;g_tK6SdPeYY%wf*gNp=lFjTn7E7Cb%wOd*w>Z=-DO??ehf(Rc3Q++UAtA6(;14Lf +>~pzi0dVKQBz@tdh*uKi$oGC{=S4%q2w7nQP$A(lr36M1!$n>hOK%KgRdpRKU}$7lNfov#{-@@=82F6|DBr29t>h=4W?G&NuwINuk +*38N)NT#Oxs{Cmsqmuvo}5zU>LE3IVrLDe0B!N8EXk;w(iP%r26GfCX;$`#mRcr^CAKVRU#{!ni@s0# +xpNI&#bP0dx6bCj5J?~!{Pxy8g?Spu;=a!$5}a$=qlHT3a1o^~Yl@7=0TydPg)U;v#0So@B@km@XiZh +0y2IzKU4tMU+ePSU#vw(1>!zTpCb{-AL9%-0uA=?;G4BwM(t-15rDh|N=qj+_D0W^;wEd}-BitQ{hj-l6YD=KqE6%jB$HXFpe +?e&~3UR_VyDAUJpLHW$@e1u!gA!)ABft3y*iCF36_l^=|s1Mq6YGdApR>m!z|m`84U?l4>q+(?bwY}z +*5rL`&uIXYWn0pG9Q|0~_6D6Gkyvfz}Z=5>g|oB`TcHtFYf9|04@^W;Ia=o!j1wtT)cV!sw%l{`ZP +Kni2tT1pO;!M0r5F-cAv-=?O$D#KJ*^riDJ-*rvmRr$eorePs(j1qt+&Q7z+GSMju{FEjnxr^}vsL>i +c}HRBe>b-6%d1>e{lzJ^Coi=msG}+@ttGQFp;txs4w`9CpI!LjG9B_m=KO85zu(>TW%wql3T?tZj`L- +IbQWF|^K;Vby_ek3BpNUh9^nI_T^0AZIo;1R^$YR2Wl@B0>xK|>DUA@82em_!$*z$J51z~`5jl>f&#` +c9=?__N_yyeR$)BaxFU+V5!w>JIa3-M|1^dRJCb;e;mXIPgiI0wFN%$%7nRs0_%DYW$ZtP$L0pIYRXJ +%dtK~%7EE~pNwLvwqfs>oPW;cE!qt~dR}*SGdoH=c68p6ea;bLZg~So+*KDPC=&9tEE41pR9BVR(t`( +8^9Ug@n_whE*-VLInq`T=3wye;!}>DQ12l7U_p5kj`;E1})*L5p*&&1>U<0&Ga6?MZ81qXS!l}5{U(; +M0W&?y-!{rx}E=e%w$!%ecdFh<@8Q0$UNPqp0xs5A&o$xCLnn}dOAQxtYSP<2KtVd)YI#(!=A_&^0Gf +m3s&;-a*N<_NJ4zoHceb~a6%qf>+FVHPVP{Oct_jn*H7~|tfaq{#G6Dgf@(nYM-yn1fIFA7yx-(Ryg% +M87Ye4x_jfQ!zC*rWp|uz{k{$IR%qc=^UK(+Gk$@+&rxBRTq!D!JtNH-bgZR`V=s)&t+%NaP&t>9QqE +Zq7dbu&;z8cne)}%{{4q=0~Do_k1NlRpQC7-t_KH@!9%cqN9M%37TtvX_;=Vvv62OdCFoGGVZbj +~(O087h>2>NKi|yr*O`v59ud@g!qI7zokJzJt{BszjJC4fg-af`e@3nX?7M46z$&-6U4yDopR0 +Sa#)Tgx8Y-_)2i>62^}WhdU)I!}9PAv!15r0;jF%9_@)3qIi6W~X%&+9@0 +=7R(v~-ur5uh?K|@n-tjwRHia$1xvk5G4tDS$j$xpzKck=Gnu#DG!5IS;-%LKmLInZg9Oi>R#1pPC#o +&fX|oRG8sypxBbAHlv_w;kS40?r-9B)oVjl~zZSOc^Werqbm1QbQYPCnMnGl3SpHeoF8kXJx)J#nfXl +)sw5+!iVLS9PaHMMHHFp@4*43TIxO?JgYC}CbM@iPX4@4@)w@lG(q~|Bp}-dTqZ<0e>jW8xny)HA_cEWDmRMTRlX*;uUoqe|+tmhfG5rGMP`qwldOYr`jx^TqS}KJ +X{LTGE-kzM=PL+-XXur$iL7wX%x6a_&R<4tvkETmBr7uK&Cbk06}SBFKkJKx3%`X!|FMPu6A>?=}Zj! +;3(tkIm~z@gd^(RK`t!nIiUeYf~)vw-rO_c09R;py|bc|GSJIAocNi19{!j9RypwPq%B#nN{b>6aAOT +c-`=iE)xg~mCDSw7JH8>x`SE#O<7YATMDyI${cvhH^i4>+oG%j>F8quN&aCcz_#88bE-{wUtfhW+O{} +Yo`sD?PPpCNkuu6;gq08y!E02tq8EDvVE~Z{BWtgET(vME)7}x7qjD)<~o{0PhrwluPeBPLRJtEc|q^ +6(M%c|wGKKrNRd2twUN=A_C@}=|SW7McoSdH~du70BRqxZ$@IUZIxkp!P#GflgjRofbdz6G`07>R0h- +I+*{Rw+3QoF@z>hyWEWte|~LqLdHdxsCn(h@p3g>0>MdMvNJ1T02p)XRX +hJX{tdd-vUQ%iNV_=_~z9XPg?8L7SV-%8`eaYVzRy6^`d^{-_wutdQr;K%v$$MK_WAcN_2%>aVxrWPM +%zgf0OcVr*kAvkV?ifimP=%%nI?pmjc!JUukY>bYEXCaCuNm0Rj{ +Q6aWAK2mtey7Dr1-q-8S!002k=000jF0000000000005+c!wmocaA|NaUteuuX>MO%E^v8JO928D0~7 +!N00;o{l@>>yz1OOy3jhFlDF6Tx00000000000001_fg=w90B~t=FJfVHWn*t`ZDDR?E^v8JO928D0~ +7!N00;o{l@>?ZFvLBk3;+P(C;$Kv00000000000001_f%zH$0B~t=FJfVHWpH6~b7gWaaCuNm0Rj{Q6 +aWAK2mtey7DrVyt(^l9003<{000pH0000000000005+c&L;o>aA|NaV{K$_aCB*JZgVbhc~DCM0u%!j +000080P~d=M*_3X#M2@G0Kj|z01p5F00000000000HlEcH~;`}X>c!OZ+C8NZ((FEaCuNm0Rj{Q6aWA +K2mtey7Dw4?P5ssZ008L(000pH0000000000005+c09yb6aA|NaWq4y{aCB*JZgVbhc~DCM0u%!j000 +080P~d=M}lBlphYnN0Oz^@01N;C00000000000HlEhT>t=ZX>c!TZe(S6E^v8JO928D0~7!N00;o{l@ +>=!`MGmE3IG7~82|tf00000000000001_fpm@l0B~t=FKlmPVRUJ4ZgVbhc~DCM0u%!j000080P~d=N +AFROtn~!|080@701*HH00000000000HlH5m;eB9X>c!aWpFeyHFRNTb1rasP)h*<6ay3h000O8^OY7y ++pKr?eEc!hXk}$=E^v8JO928D0~7!N00;o{l@>>tv|7 +Pq1ONcc2><{W00000000000001_fo{YA0B~t=FJE?LZe(wAFJE72ZfSI1UoLQYP)h*<6ay3h000O8^O +Y7yhqJe*GdlnPD>nfE7ytkO0000000000q=5#>003}la4%nWWo~3|axZCcVPs@-Wpi^baCuNm0Rj{Q6 +aWAK2mtey7Dr$n2aRR{000F8000;O0000000000005+cZv+7VaA|NaUv_0~WN&gWa%C-cWo~3|axQRr +P)h*<6ay3h000O8^OY7yA$zc!Jc4cm4Z*n +hlX?QMhc~DCM0u%!j000080P~d=M|TE-#sUEV05k#s03rYY00000000000HlE+Edc;c!Jc4cm4Z* +nhRZDDe2WpZq3VlQ7`X>MtBUtcb8c~DCM0u%!j000080P~d=M=lfGq{amR0E-U*03iSX00000000000 +HlFpE&%{=X>c!Jc4cm4Z*nhRZDDe2WpZq3VlQoBa%*LBb1rasP)h*<6ay3h000O8^OY7yocgHmt^fc4 +E&%`lBme*a0000000000q=9EN0RV7ma4%nWWo~3|axY_HV`yb#Z*FvQZ)`7LUukY>bYEXCaCuNm0Rj{ +Q6aWAK2mtey7Dw@rbX@ra003kV001KZ0000000000005+cS2Y0uaA|NaUv_0~WN&gWV_{=xWn*t{baH +QOFJWY1aCBvIE^v8JO928D0~7!N00;o{l@>=5s>bjv0RR9N0{{Ra00000000000001_fsr}^0B~t=FJ +E?LZe(wAFJob2Xk}w>Zgg^QY%gPBV`ybAaCuNm0Rj{Q6aWAK2mtey7DvLpK6;V>001`u001HY000000 +0000005+c{5t^vaA|NaUv_0~WN&gWV_{=xWn*t{baHQOFJo_QaA9;VaCuNm0Rj{Q6aWAK2mtey7DvlK +7a~Fo004|9001Tc0000000000005+c&O8ACaA|NaUv_0~WN&gWV_{=xWn*t{baHQOFJo_RbaHQOY-Ms +TaCuNm0Rj{Q6aWAK2mtey7Dqt>BlV#J004Lh001Wd0000000000005+cR7n8>v9aWsL1polm4*&or000000000000 +01_fjUhA0B~t=FJE?LZe(wAFJob2Xk}w>Zgg^QY%geKb#iHQbZKLAE^v8JO928D0~7!N00;o{l@><~C +W4j62LJ#q7ytkz00000000000001_fi6=40B~t=FJE?LZe(wAFJob2Xk}w>Zgg^QY%g>y9aj9y0001S0RR9i00000000000001_fi+ +wK0B~t=FJE?LZe(wAFJob2Xk}w>Zgg^QY%gPBV`yb_FJE72ZfSI1UoLQYP)h*<6ay3h000O8^OY7y!K +ViQTLl0B%nbklEdT%j0000000000q=89Y0RV7ma4%nWWo~3|axY_HV`yb#Z*FvQZ)`7PVPj}zb1!CTY +-L|#VPj}zE^v8JO928D0~7!N00;o{l@>?Sh{jZ=0RRBa0{{Rn00000000000001_f$w4g0B~t=FJE?L +Ze(wAFJob2Xk}w>Zgg^QY%gPBV`yb_FLGsMX>(s=VPj}zE^v8JO928D0~7!N00;o{l@>=YN2j8v0002 +t0000W00000000000001_f#GBU0B~t=FJE?LZe(wAFJo_PZ*pO6VJ}}_X>MtBUtcb8c~DCM0u%!j000 +080P~d=N0+05?KA@b000R902}}S00000000000HlG&WdQ(iX>c!Jc4cm4Z*nhVZ)|UJVQpbAVQzD2E^ +v8JO928D0~7!N00;o{l@>?-akwnw2><{tBme*-00000000000001_fi!6W0B~t=FJE?LZe(wAFJo_PZ +*pO6VJ~5Bb7^#McWG`jGA?j=P)h*<6ay3h000O8^OY7y?qbWv3IYHCJq7>(A^-pY0000000000q=8s- +0RV7ma4%nWWo~3|axY_VY;SU5ZDB8IZfSIBVQgu0WiD`eP)h*<6ay3h000O8^OY7yv#FkMF9iSq0Tci +L9RL6T0000000000q=BM!0RV7ma4%nWWo~3|axY_VY;SU5ZDB8WX>KzzE^v8JO928D0~7!N00;o{l@> +>ovL_)c1pokK761Sr00000000000001_fed>A0B~t=FJE?LZe(wAFJo_PZ*pO6VJ~-SZggdGZ7y(mP) +h*<6ay3h000O8^OY7ygBg4GT>$_9MFIc-9{>OV0000000000q=9sR0RV7ma4%nWWo~3|axY|Qb98KJV +lQ7`X>MtBUtcb8c~DCM0u%!j000080P~d=N4dg6YELQv0MwoU0384T00000000000HlEqf&l<c!J +c4cm4Z*nhWX>)XJX<{#9Z*6d4bS`jtP)h*<6ay3h000O8^OY7y&X<4#el7q2bie=r9{>OV000000000 +0q=A^M0RV7ma4%nWWo~3|axY|Qb98KJVlQN2bYWs)b7d}Yc~DCM0u%!j000080P~d=N8$#~TnQBb0Ps +-&02}}S00000000000HlFa+W`P@X>c!Jc4cm4Z*nhWX>)XJX<{#FZe(S6E^v8JO928D0~7!N00;o{l@ +>>zUvLR8G5`Rp!~g&v00000000000001_ftK(A0B~t=FJE?LZe(wAFJx(RbZlv2FKlmPVRUbDb1rasP +)h*<6ay3h000O8^OY7yp$jBOV0000000000q=5n>0swGna4%nWWo~3|axY|Qb98KJ +VlQoBZfRy^b963nc~DCM0u%!j000080P~d=M?Dd)0*wa%0E!p@03HAU00000000000HlF`G6Dc_X>c! +Jc4cm4Z*nhWX>)XJX<{#JVRCC_a&sc!Jc4cm4Z*nhWX>)XJX<{#JWprU=VRT_GaCuNm0Rj{Q6aWAK2mtey7DsQxo_Tr;00 +4I>001BW0000000000005+c@Ld7`aA|NaUv_0~WN&gWWNCABY-wUIa%FRGb#h~6b1rasP)h*<6ay3h0 +00O8^OY7ymRfBkJP`l@XEy)<9smFU0000000000q=Beu0swGna4%nWWo~3|axY|Qb98KJVlQ)Ja%pgM +b1rasP)h*<6ay3h000O8^OY7y;{G(?r>Xz|09*k88vpc +!Jc4cm4Z*nhWX>)XJX<{#QHZ(3}cx6ya0Rj{Q6aWAK2mtey7Ds=j6_hMF002J8000{R000000000000 +5+cj@|=C7H%S}82|vETmS$b0 +0000000000001_f%6vx0B~t=FJE?LZe(wAFJx(RbZlv2FLq^eb7^mGE^v8JO928D0~7!N00;o{l@>>S +MSulFrT_o{P5}TL00000000000001_f!i?z0B~t=FJE?LZe(wAFJx(RbZlv2FLyICE@gOSP)h*<6ay3 +h000O8^OY7y)W-_X6}12W0B`{S8vpc!Jc4cm4Z*nhWX> +)XJX<{#TXk}$=E^v8JO928D0~7!N00;o{l@>=M?`QnO0000I0RR9g00000000000001_f!(qN0B~t=F +JE?LZe(wAFJx(RbZlv2FJEF|V{344a&#|WUukY>bYEXCaCuNm0Rj{Q6aWAK2mtey7Dum&FJ;aF007Ga +001Qb0000000000005+c=d%R>aA|NaUv_0~WN&gWWNCABY-wUIUt(cnYjAIJbT4gbb7L-Wc~DCM0u%! +j000080P~d=M>MI?%19gl05W6%04D$d00000000000HlHVwFLlhX>c!Jc4cm4Z*nhWX>)XJX<{#5Vqs +%zaBp&SFLP*hbZKlZaCuNm0Rj{Q6aWAK2mtey7DsOu0Il``0021(001ih0000000000005+ch0+B8aA +|NaUv_0~WN&gWWNCABY-wUIUt(cnYjAIJbT4yxb7OCAW@%?GV`gViO928D0~7!N00;o{l@>=4KS&_x9 +smGNX#fB!00000000000001_fyC4W0B~t=FJE?LZe(wAFJx(RbZlv2FJEF|V{344a&#|qd2?fLZf0p` +E^v8JO928D0~7!N00;o{l@>>#LpWPwSpWdjX#oHz00000000000001_f%NkQ0B~t=FJE?LZe(wAFJx( +RbZlv2FJEF|V{344a&#|rVRB|^Y-KKRc~DCM0u%!j000080P~d=N2Z$lEQ$dD0LlUY03ZMW00000000 +000HlGPO$GpPX>c!Jc4cm4Z*nhabZu-kY-wUIUtei%X>?y-E^v8JO928D0~7!N00;o{l@>>jmU58HNd +N#@Qvm=W00000000000001_fn`qy0B~t=FJE?LZe(wAFKBdaY&C3YVlQKFZgX^DZgg`laCuNm0Rj{Q6 +aWAK2mtey7Dokc9IXFD003jk0RSTa0000000000005+caG3@GaA|NaUv_0~WN&gWXmo9CHEd~OFKBda +Y&CFUa&u*JE^v8JO928D0~7!N00;o{l@>=j&nXNA6aWClKmY(B00000000000001_fw0~N0B~t=FJE? +LZe(wAFKBdaY&C3YVlQcEVRU79ZEP-Zc~DCM0u%!j000080P~d=N1bYj3DX_`0I_=j03!eZ00000000 +000HlHQ@&*8KX>c!Jc4cm4Z*nhabZu-kY-wUIX>M?JbaQlaWnpbDaCuNm0Rj{Q6aWAK2mtey7Dve{3; +RYC008_%001EX0000000000005+c2NDMWaA|NaUv_0~WN&gWXmo9CHEd~OFLPmTX>@6NWpXZXc~DCM0 +u%!j000080P~d=M^Yzq>c!Jc4cm4Z*nhabZu-kY-wUI +bZ={AZfSaDaxQRrP)h*<6ay3h000O8^OY7y9v<;00002000000000e0000000000000 +1_fpkd+0B~t=FJE?LZe(wAFKBdaY&C3YVlQTCY;MtBUtcb8c~DCM0u%!j000080P~d=M< +Rgx#FYR503HDV03`qb00000000000HlGuNe2LMX>c!Jc4cm4Z*nhabZu-kY-wUIW@&76WpZ;bUt(c%W +iD`eP)h*<6ay3h000O8^OY7ye-4mNAOQdXZ~_1THUIzs0000000000q=A%52LNzsa4%nWWo~3|axZ9f +ZEQ7cX<{#CX>4?5a&s?XY;b5{Vr6t`V_|GzbaZlQVs&(7b1rasP)h*<6ay3h000O8^OY7y6?b_$xB>t +Gx(WaQGXMYp0000000000q=5)b2LNzsa4%nWWo~3|axZ9fZEQ7cX<{#CX>4?5a&s?fZfa#?bYE>{bYW +j(Xkl`5WpplZc~DCM0u%!j000080P~d=M-Z9Hz@P&F0B{fh03-ka00000000000HlEtPX_>SX>c!Jc4 +cm4Z*nhabZu-kY-wUIW@&76WpZ;bY-w(EE^v8JO928D0~7!N00;o{l@>?QlWz#g1^@sADF6U0000000 +00000001_f%8%a0B~t=FJE?LZe(wAFKBdaY&C3YVlQTCY;wzKp|Jn}0AK+C04V?f00000000000HlEiS_c4dX>c!Jc4cm4Z*nhabZu-kY-wUIW@&7 +6WpZ;bb75|2bZL5JaxQRrP)h*<6ay3h000O8^OY7yW3^fp&;bAdb_4(bDgXcg0000000000q=Eig2LN +zsa4%nWWo~3|axZ9fZEQ7cX<{#CX>4?5a&s?tXlZn1b8ul}WiD`eP)h*<6ay3h000O8^OY7y0x`qn5C +H%H>Hz=%D*ylh0000000000q=6P)2LNzsa4%nWWo~3|axZ9fZEQ7cX<{#PWpZg@Y-xIBaxY(BX>MtBU +tcb8c~DCM0u%!j000080P~d=NB8lKOLh$a05>uK05Jdn00000000000HlF$UIzehX>c!Jc4cm4Z*nha +bZu-kY-wUIb7gXAVQgu7WpXcQbZu;NWpZg@Y-xIBaxQRrP)h*<6ay3h000O8^OY7y000000ssI20000 +0EdT%j0000000000q=7VS2LNzsa4%nWWo~3|axZ9fZEQ7cX<{#Qa%E*?y-E^v +8JO928D0~7!N00;o{l@>?jTwf3x0ssJg1^@sk00000000000001_fq`rX0B~t=FJE?LZe(wAFKBdaY& +C3YVlQ-ZWo2PxVQ_S1a&s?pVR$ZZc~DCM0u%!j000080P~d=N1#lH<>CYY08I@504)Fj00000000000 +HlH8ZU+ExX>c!Jc4cm4Z*nhabZu-kY-wUIbaG{7Vs&Y3WMy)5FJE72ZfSI1UoLQYP)h*<6ay3h000O8 +^OY7yy9}waLk<7{k2L@QDgXcg0000000000q=61}2LNzsa4%nWWo~3|axZ9fZEQ7cX<{#Qa%E*=b!lv +5WpZ;bUt(c%WiD`eP)h*<6ay3h000O8^OY7yVJa~kmj?g<6(IlsC;$Ke0000000000q=A`&2LNzsa4% +nWWo~3|axZ9fZEQ7cX<{#Qa%E*=b!lv5WpZ;bWN&RQaCuNm0Rj{Q6aWAK2mtey7Dr&udnW`6002!f00 +1fg0000000000005+cc8Ui8aA|NaUv_0~WN&gWXmo9CHEd~OFLZKcWny({Y-D9}b1!9da%E*MaCuNm0 +Rj{Q6aWAK2mtey7DtnxCHo}}007T6001ul0000000000005+c!juO9aA|NaUv_0~WN&gWXmo9CHEd~O +FLZKcWny({Y-D9}b1!9da%E*-Y>zHhndQ1^@tt761S&000000000 +00001_fi$8A0B~t=FJE?LZe(wAFKBdaY&C3YVlQ-ZWo36^Y-?q5b1z?CX>MtBUtcb8c~DCM0u%!j000 +080P~d=N6o`DuL1@D0A?Ei04V?f00000000000HlEgsRsaXX>c!Jc4cm4Z*nhabZu-kY-wUIbaG{7cV +TR6WpZ;bUt(c%WiD`eP)h*<6ay3h000O8^OY7yov#Vw`2hd`jRgPzCjbBd0000000000q=8MZ2LNzsa +4%nWWo~3|axZ9fZEQ7cX<{#Qa%E+AVQgzc!Jc4cm4Z*nhabZu-kY-wUIbaG{7cVTR6WpZ;bWpr|7WiD`eP)h* +<6ay3h000O8^OY7yEf}!Z!2$pP<_G`)FaQ7m0000000000q=C4$2LNzsa4%nWWo~3|axZ9fZEQ7cX<{ +#Qa%E+AVQgz)XPWnpbDaCuNm0Rj{Q6aWAK2mtey7DqE4*c~Yb003wg001oj0000000 +000005+c$GHapaA|NaUv_0~WN&gWXmo9CHEd~OFLZKcWp`n0Yh`kCFKl>iY-MzEWo0gKc~DCM0u%!j0 +00080P~d=M|C+zP`m;F0R9L704o3h00000000000HlFCzy|c!Jc4cm4Z*nhabZu-kY-wUIbaG{7 +cVTR6WpZ;baCK~KWN&RQaCuNm0Rj{Q6aWAK2mtey7DuU7-Kd5D007hg001Qb0000000000005+cK*I+ +BaA|NaUv_0~WN&gWXmo9CHEd~OFLZKgWiMY}X>MtBUtcb8c~DCM0u%!j000080P~d=NAzNalYIdI0G| +T@03rYY00000000000HlEl#0LOyX>c!Jc4cm4Z*nhabZu-kY-wUIbaH8BFJEF|b7d}Yc~DCM0u%!j00 +0080P~d=Mc!Jc4cm4Z*nhabZu-kY-wUIbaH8BF +JxhKa%p8QaCuNm0Rj{Q6aWAK2mtey7Dr1@Zq6M7008d>0018V0000000000005+ct;YudaA|NaUv_0~ +WN&gWXmo9CHEd~OFLZKgWiN1fE^v8JO928D0~7!N00;o{l@>?!f28$T3IG7gBLDy(00000000000001 +_fd|S50B~t=FJE?LZe(wAFKlmPYi4O|WiMY}X>MtBUtcb8c~DCM0u%!j000080P~d=M?w%8Hy;B409g +tE03-ka00000000000HlGP)CT}?X>c!Jc4cm4Z*nheZ)0m_X>4ULY-w(5Y;R+0W@&6?E^v8JO928D0~ +7!N00;o{l@>?dx-=4S0{{RT3;+Nn00000000000001_f&SMA0B~t=FJE?LZe(wAFKlmPYi4O|WiM@OW +NC72Z)0m_X>4UKaCuNm0Rj{Q6aWAK2mtey7DuGbAQDCh002!G001KZ0000000000005+cvD*g#aA|Na +Uv_0~WN&gWY;R+0W@&6?FK}sOY;R+0W@&6?E^v8JO928D0~7!N00;o{l@>?mQhD|d1pok~6#xJx0000 +0000000001_fjHy`0B~t=FJE?LZe(wAFKlmPYi4O|WiNAaY-x05Y;R+0W@&6?E^v8JO928D0~7!N00; +o{l@>==Q$=h%0{{Ru3IG5n00000000000001_fs5$}0B~t=FJE?LZe(wAFKlmPYi4O|WiNAiZER_7Yi +w_0Yi4O|WiD`eP)h*<6ay3h000O8^OY7yh-{tOM*;uMmPUteKjZ*_EEUoLQYP)h*<6ay3h000O8^OY7ySk>pY`~d&}iUR-uApigX00000 +00000q=A#~2LNzsa4%nWWo~3|axZXUV{2h&X>MmPUtei%X>?y-E^v8JO928D0~7!N00;o{l@>>5N4=Y +{0ssKz1ONaa00000000000001_fzI&<0B~t=FJE?LZe(wAFK}UFYhh<;Zf7rFV{dJ6VRSBVc~DCM0u% +!j000080P~d=N3N1NwN(ND01*cO03-ka00000000000HlGu^alWNX>c!Jc4cm4Z*nhiVPk7yXK8L{FJ +E(Xa&=>Lb#i5ME^v8JO928D0~7!N00;o{l@>>gf||7z82|vUZ2$lx00000000000001_fm8Pf0B~t=F +JE?LZe(wAFK}UFYhh<;Zf7rZaAjj@W@%+|b1rasP)h*<6ay3h000O8^OY7y=mr%YMh*Y~tu6onAOHXW +0000000000q=Bgr2mo+ta4%nWWo~3|axZXUV{2h&X>MmPc4cyNX>V>WaCuNm0Rj{Q6aWAK2mtey7Dt# +=rN?M+0082j0RSZc0000000000005+cEguK~aA|NaUv_0~WN&gWaBF8@a%FRGb#h~6b1z?CX>MtBUtc +b8c~DCM0u%!j000080P~d=NBUZEjFJQZ0M82m03ZMW00000000000HlG~j|c#8X>c!Jc4cm4Z*nhia& +KpHWpi^cUtei%X>?y-E^v8JO928D0~7!N00;o{l@><>ChsIh1ONb&3IG5b00000000000001_fvA)S0 +B~t=FJE?LZe(wAFK}{iXL4n8b1!0HaxQRrP)h*<6ay3h000O8^OY7yE=aa)B?ABe`2_#~9{>OV00000 +00000q=6@y2mo+ta4%nWWo~3|axZXlZ)b94b8|0aZ*^{TWpXZXc~DCM0u%!j000080P~d=M;w`>M+gJ +}08R@403QGV00000000000HlG5oCpALX>c!Jc4cm4Z*nhia&KpHWpi^cXk~10WpZ;aaCuNm0Rj{Q6aW +AK2mtey7DtLR+g|Fa%FRKFLQ8dZf +<3AE^v8JO928D0~7!N00;o{l@>=vjs?i30{{R;2LJ#d00000000000001_feEAt0B~t=FJE?LZe(wAF +LGsZb!BsOb1z?CX>MtBUtcb8c~DCM0u%!j000080P~d=M^Wr;Om`6g0IER%03ZMW00000000000HlHK +rw9OWX>c!Jc4cm4Z*nhkWpQ<7b98erVPs)&bY*gLE^v8JO928D0~7!N00;o{l@>?Jp62K~1poji6#xJ +m00000000000001_fugwx0B~t=FJE?LZe(wAFLGsZb!BsOb1z|VX)bViP)h*<6ay3h000O8^OY7yDP{ +LPeh2^niW&d_8~^|S0000000000q=6Q{2mo+ta4%nWWo~3|axZdaadl;LbaO9Zb#!PhaCuNm0Rj{Q6a +WAK2mtey7Dv-iT7FD<0szvq1OOiZ0000000000005+c&c_GbaAj>!O928D0~7!N00;o{l@>>>F)xm00RRAH0ssIV00000000000001_fmcBb0B~t=FJE?LZe(wA +FLGsZb!BsOb1!3Ma&&VpaCuNm0Rj{Q6aWAK2mtey7DrUx#oRCg006xO0015U0000000000005+c_(BT ++aA|NaUv_0~WN&gWa%FLKWpi|MFJo_QaA9;VaCuNm0Rj{Q6aWAK2mtey7DvoU5zOBb001XL0018V000 +0000000005+cWJL=AaA|NaUv_0~WN&gWa%FLKWpi|MFJo_SYiVV3E^v8JO928D0~7!N00;o{l@>?R9v +nbq0{{Tk2><{h00000000000001_fq+;G0B~t=FJE?LZe(wAFLGsZb!BsOb1!9hV`Xr3X>V?GE^v8JO +928D0~7!N00;o{l@>=AcKy7I0RR9r0{{RW00000000000001_fh1fD0B~t=FJE?LZe(wAFLGsZb!BsO +b1!IbZ)Rk%}aA|NaUv_0 +~WN&gWa%FLKWpi|MFKusRWo&aUaCuNm0Rj{Q6aWAK2mtey7Ds(S{wRtX006pP001BW0000000000005 ++c41Ws%aA|NaUv_0~WN&gWa%FLKWpi|MFLPycb7^mGb1rasP)h*<6ay3h000O8^OY7yDw@gOxD{O+0034~0012T0000000000005+csG|!2aA|NaUv_0 +~WN&gWa%FLKWpi|MFLiWjY;!Jfc~DCM0u%!j000080P~d=M~^A$P06qW!04V?f00000000000Hl +FHzY73xX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJE72ZfSI1UoLQYP)h*<6ay3h000O8^OY7yac +oNbjRF7w4+Q`KF#rGn0000000000q=CA>3jlCwa4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=W +My?y-E^v8JO928D0~7!N00;o{l@>>FoWC)5kpKXqLID6V00000000000001_ftJDx0B~t= +FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoMX=gQNa%FKYaCuNm0Rj{Q6aWAK2mtey7DxV +o83Y>x005K*001)p0000000000005+cTvQAIaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB +?;bT49QXEktgZ(?O~E^v8JO928D0~7!N00;o{l@>>NvR7F%1ONcY2><{y00000000000001_fyh@30B +~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoNXkl_>Wprg@bS`jtP)h*<6ay3h000O8^ +OY7y_>jT?4haAN3M2pkIRF3v0000000000q=8Ia3;=Lxa4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQ +V`yP=WMy=iiKU-(1ONcf4gdf<000000000 +00001_fw5%_0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoNXkl`5Wprn9Z*_2Ra&K +Z~axQRrP)h*<6ay3h000O8^OY7y_!;PfTLS<9ZU+DWHUIzs0000000000q=9~F3;=Lxa4%nWWo~3|ax +Zdaadl;LbaO9oVPk7yXJvCQV`yP=WMyZfA3JVRU6}VPj}%Ze=cTc~DCM0u%!j000080P~d=Mc!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FJo_QaA9;VaCuNm0Rj{Q6aWAK2mt +ey7DxP5z|Xb<001`y001%o0000000000005+c1a%AmaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1 +!3PVRB?;bT4CXZgX^DZgg`laCuNm0Rj{Q6aWAK2mtey7DuZFCdNzy008y|001-q0000000000005+c3 +U~|vaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4CYIW#$Na&KZ~axQRrP)h*<6ay3h +000O8^OY7yrY+JraRdMWa|{3gG5`Po0000000000q=Be=3;=Lxa4%nWWo~3|axZdaadl;LbaO9oVPk7 +yXJvCQV`yP=WMyBaV~IqP +)h*<6ay3h000O8^OY7yEuuJ783O=IwcGX@0{{S#1^@sx00000000000001_fg5WL0B~t=FJE?LZe(wAFL +GsZb!BsOb1!gVV{2h&WpgiMXkl_>WppoRVlp!^GH`NlVr6nJaCuNm0Rj{Q6aWAK2mtey7DwZfttM*{0 +01vE001=r0000000000005+ch;9u4aA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4RS +Vsd47aB^>AWpXZXc~DCM0u%!j000080P~d=N0+af4!%|Z0Mobt05AXm00000000000HlFNfeip~X>c! +Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FKTIXW^!e5E^v8JO928D0~7!N00;o{l@>=Eh2+ +Rf6952|O8@{b00000000000001_fl}BF0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&WpgiMXkl_>Wp +poUaAR(CcrI{xP)h*<6ay3h000O8^OY7yNKy%m3=04N@G$@YI{*Lx0000000000q=D+|4FGUya4%nWW +o~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyc!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D +?FJow7a%5$6FKl6MXJdJCX>4q1V{LC_Wo#~Rc~DCM0u%!j000080P~d=M-d@I9c2js08}vm05<>t000 +00000000HlGW0}cRiX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FKl6MXJ>L{WovD3WM +ynFaCuNm0Rj{Q6aWAK2mtey7DpeVdkUTj001^D001}u0000000000005+cUJVWaaA|NaUv_0~WN&gWa +%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4dSZf9s^Vsd47ZEs{{Y%XwlP)h*<6ay3h000O8^OY7yP`8?X +#|i)d_%HwfI{*Lx0000000000q=8Zw4ghdza4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMy< +OY+-I^XmxI9VRC6X>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FKl6MXLM*`X>D(0Wo#~Rc~DCM0u +%!j000080P~d=N9CHTnR^BR0B{rl05t#r00000000000HlGdEe-&1X>c!Jc4cm4Z*nhkWpQ<7b98era +A9L>VP|D?FJow7a%5$6FKl6SX>Kuaa&KZ~axQRrP)h*<6ay3h000O8^OY7yrJQkdodf^?#0&rcH~;_u +0000000000q=9)f4ghdza4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=WMyP6Z*_2Ra&KZ~axQRrP)h*<6ay3h000O8^OY7y@# +SZlObh@3hD-neF8}}l0000000000q=6ef4ghdza4%nWWo~3|axZdaadl;LbaO9oVPk7yXJvCQV`yP=W +Myc!J +c4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FLPpJXkl`5Wpr?IZ(?O~E^v8JO928D0~7!N00;o +{l@>>&+~vO{1ONcr3;+N)00000000000001_frL;F0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpg +iMXkl_>WppodVqa&L8TaB^>AWpXZXc~DCM0u%!j000080P~d=N0(vnR{aD30JIJO05bpp0000000 +0000HlHbR1N@eX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FJow7a%5$6FLP>Xb8vERVr6nJaCuNm0 +Rj{Q6aWAK2mtey7Dug|Hab@a006ie0024w0000000000005+cOj-^AaA|NaUv_0~WN&gWa%FLKWpi|M +FK}UFYhh<)b1!3PVRB?;bT4&oX?A6Db75>`Wprg@bZ>GlaCuNm0Rj{Q6aWAK2mtey7Dr$EAZs23003M +H001)p0000000000005+c`(X|MaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!3PVRB?;bT4&uW;k +$iZ(?O~E^v8JO928D0~7!N00;o{l@>>Mw-zsg0{{RA2mk;v00000000000001_fof(B0B~t=FJE?LZe +(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvaUukY>bYEXCaCuNm0Rj{Q6aWAK2mtey7DpLEEQieu0 +07n~001=r0000000000005+cJ8BL9aA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR9b +Z)|L3V{~b6ZgVbhc~DCM0u%!j000080P~d=M^e;8_>~I)05c;105bpp00000000000HlFicMbq>X>c! +Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFJo_RZe?S1X>V>WaCuNm0Rj{Q6aWAK2mtey7Dq +?CMmX~z003`x001`t0000000000005+cL4yteaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY; +0*_GcRLrZf<2`bZKvHaBpvHE^v8JO928D0~7!N00;o{l@>=HHY}u+1pojR5dZ))00000000000001_f +r+FJ0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvgcw=R7bZKvHb1rasP)h*<6ay3h +000O8^OY7y^G0R)1qT2C$rbc!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFJ@_MWpHnEbS`jtP)h*<6ay3h00 +0O8^OY7yTdH&$HVXg%z9awuGynhq0000000000q=8Ab4ghdza4%nWWo~3|axZdaadl;LbaO9oVPk7yX +JvCQb#iQMX<{=kaBpvHZDDRaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR&wadl;LbS`jtP)h*<6ay3 +h000O8^OY7yLjoE44-x<;00002000000000v000000000000 +01_f&JPJ0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyveZ*FvQX<{#5UukY>bYEXCa +CuNm0Rj{Q6aWAK2mtey7Dou9o6na8005g20021v0000000000005+cR@)8$aA|NaUv_0~WN&gWa%FLK +Wpi|MFK}UFYhh<)b1!vrY;0*_GcRLrZgg^KVlQrVY;ACFZ)`4bc~DCM0u%!j000080P~d=M?z6Cg>?) +70B$4z06G8w00000000000HlFL;SKc!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFJo +_RbaH88FK~HpaAj_Db8Iefc~DCM0u%!j000080P~d=N59k!AU^;A07?J=06G8w00000000000HlEt?h +XKOX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFK}UFYhh<)b1z?CX>MtBUtcb8c~DCM0 +u%!j000080P~d=M@GS>XYdLD0OukA06qW!00000000000HlGa?hXKOX>c!Jc4cm4Z*nhkWpQ<7b98er +aA9L>VP|D?FLiQkY-wUMFK}UFYhh<)b1!dlWMy(?WM5=yV{|TXc~DCM0u%!j000080P~d=N7Gmyv0M% +S0BkJ)05t#r00000000000HlHR`3?YZX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFK} +UFYhh<)b1!pgcrI{xP)h*<6ay3h000O8^OY7y5U^VP|D?FLQHjUu|J@V`yJ!Z*z2RVQpnEU +tei%X>?y-E^v8JO928D0~7!N00;o{l@>>>)SMdx1^@uU4gdgD00000000000001_f$Iqm0B~t=FJE?L +Ze(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvrVPk7yXJvCQb8~E8ZDDj{XkTb=b98QDZDlWCX>D+ +9Wo>0{bYXO9Z*DGdc~DCM0u%!j000080P~d=N4%-@gaZKp0OkPz05$*s00000000000HlFo5Dx%wX>c +!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?FLiQkY-wUMFLiWjY%gD5X>MtBUtcb8c~DCM0u%!j000080P +~d=NBVU-R15_G0No4#05|{u00000000000HlGq5f1=xX>c!Jc4cm4Z*nhkWpQ<7b98eraA9L>VP|D?F +LiQkY-wUMFLiWjY%gPPZf<2`bZKvHE^v8JO928D0~7!N00;o{l@>>>sw2I}0ssIh2mk;z0000000000 +0001_ff^SN0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvwbZKlaa%FLKWpi{caCuN +m0Rj{Q6aWAK2mtey7Ds3Q;WQBe001@u001@s0000000000005+cG#U>8aA|NaUv_0~WN&gWa%FLKWpi +|MFK}UFYhh<)b1!vrY;0*_GcR>?X>2cYWpi+EZgXWWaCuNm0Rj{Q6aWAK2mtey7Dv$3+ayp7006`$00 +1)p0000000000005+cnHvuPaA|NaUv_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR>?X>2cYW +pr|RE^v8JO928D0~7!N00;o{l@>?c=NYzw4FCW&CjbC400000000000001_fjTG;0B~t=FJE?LZe(wA +FLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvwbZKlab8~E8E^v8JO928D0~7!N00;o{l@>?r3UFXL3jhE +}B>(_500000000000001_febbe0B~t=FJE?LZe(wAFLGsZb!BsOb1!gVV{2h&Wpgiea%^mAVlyvwbZK +labZKp6Z*_DoaCuNm0Rj{Q6aWAK2mtey7DwCS=~@2=007Ju001!n0000000000005+cnL!T#aA|NaUv +_0~WN&gWa%FLKWpi|MFK}UFYhh<)b1!vrY;0*_GcR>?X>2cba%?Vec~DCM0u%!j000080P~d=N8pYFH +H-oP0M`cq02lxO00000000000HlHENe=*UX>c!NZ*6U1Ze(*WUtei%X>?y-E^v8JO928D0~7!N00;o{ +l@>=65Bi<>0ssKV2LJ#X00000000000001_fvHRn0B~t=FJo_QZDDR?b1!3WZE$R5bZKvHE^v8JO928 +D0~7!N00;o{l@>=m_|e-o0{{RT2><{V00000000000001_f!R+F0B~t=FJo_QZDDR?b1!CcWo3G0E^v +8JO928D0~7!N00;o{l@>=H7SNrl0RRBj0{{RN00000000000001_fkRUd0B~t=FJo_QZDDR?b1!IRY; +Z1cc~DCM0u%!j000080P~d=M*}W(qBjlz07E$d02crN00000000000HlE*RSy7gX>c!NZ*6U1Ze(*WX +>N0LVQg$JaCuNm0Rj{Q6aWAK2mtey7DsW9lMpZm002`Q000yK0000000000005+ci(?M}aA|NaV{dJ3 +VQyq|FKlUZbS`jtP)h*<6ay3h000O8^OY7y+3V+&R|Wt8{1E^E761SM0000000000q=D^f4*+m!a4%z +TZEaz0WOFZbWnpq-XfAMhP)h*<6ay3h000O8^OY7yQi;$;AqD^dZW90i6aWAK0000000000q=9&G4*+ +m!a4%zTZEaz0WOFZbXm58eaCuNm0Rj{Q6aWAK2mtey7Duaz89&ei002Y_000>P0000000000005+c%X +bd|aA|NaV{dJ3VQyq|FLiEdZgX^DY-}!Yc~DCM0u%!j000080P~d=M|glw#xn>201_Pl02KfL000000 +00000HlG^dk+9`X>c!NZ*6U1Ze(*WcW7m0Y%XwlP)h*<6ay3h000O8^OY7yd;YCslm!3)N(}%2761SM +0000000000q=7hu4*+m!a4%zTZE#_9FJE72ZfSI1UoLQYP)h*<6ay3h000O8^OY7yf}*9DO%(tDI9dP +z7ytkO0000000000q=5j64*+m!a4%zTZE#_9FJx(BbYpLBW@%?GaCuNm0Rj{Q6aWAK2mtey7DuWYXS_ +iG002h-000&M0000000000005+cgP#uoaA|NaZEs{{Y;!MPUukY>bYEXCaCuNm0Rj{Q6aWAK2mtey7D +s4KGHu}i008F!000vJ0000000000005+c_@55|aA|NaZEs{{Y;!MZZe(S6E^v8JO928D0~7!N00;o{l +@><;00002000000000Q00000000000001_feN7y0B~t=FK=*Va$$67Z*FrhUtei%X>?y-E^v8JO928D +0~7!N00;o{l@>?RF>h651ONb#4*&od00000000000001_fkdGX0B~t=FK=*Va$$67Z*FrhW^!d^dSxz +fc~DCM0u%!j000080P~d=M_g&r8Grx)02BcL022TJ00000000000HlH5r4ImbX>c!cWpOWGUukY>bYE +XCaCuNm0Rj{Q6aWAK2mtey7DwFNGq6Sr0071%000vJ0000000000005+ckERa*aA|Naa%FKZa%FK}W@ +&6?E^v8JO928D0~7!N00;o{l@>=DEmQ*EDF6Uir~m*K00000000000001_fd;Y<0B~t=FLGsZFLGsZU +ukZ0bYX04E^v8JO928D0~7!N00;o{l@>=`7|$3%8vp<_YXATe00000000000001_ff?Kn0B~t=FLGsZ +FLGsZUvp)2E^v8JO928D0~7!N00;o{l@>?2NHhpv2mk=z8vpc!fbZKmJFJE72ZfSI1UoLQYP)h*<6ay3h000O8^OY7y^O&Vq2nqlI)gu4^6aWAK0000000000q= +5n;5CCv#a4&UqX>4;ZVQ_F{X>xNeaCuNm0Rj{Q6aWAK2mtey7DvqtO)dZe001Bb000sI00000000000 +05+cJSq?XaA|Nab#!TLb1!0bX>4RJaCuNm0Rj{Q6aWAK2mtey7Dv9ThG^dc003wR000;O0000000000 +005+cY%CA}aA|Nab#!TLb1!6NaB^j1VRUJ4ZZ2?nP)h*<6ay3h000O8^OY7y@4;ZW@&6?b9r-gWo<5Sc~DCM0u%!j000080P~d=M`2RBVzUGQ0R9 +XB02BZK00000000000HlFhF%ST7X>c!fbZKmJFKlmTXK8L{E^v8JO928D0~7!N00;o{l@>>}`!?~B1^ +@uF6#xJg00000000000001_fj>470B~t=FLiWjY;!Mfb#!E5bY)~NaCuNm0Rj{Q6aWAK2mtey7Du5k1 +=|}5004Fx000jF0000000000005+c13eG`aA|Nab#!TLb1!viE^v8JO928D0~7!N00;o{l@>=oql8pZ +4FCY}EdT%$00000000000001_flEdZ0B~t=FLq;dFJE72ZfSI1UoLQYP)h*<6ay3h000O8^OY7y>zRr +5%LM=cOA!D75dZ)H0000000000q=C&-5CCv#a4&Xab1!0HdSPL5E^v8JO928D0~7!N00;o{l@>?Sh_s +JC2><}N9RL6h00000000000001_fyY@80B~t=FLq;dFK20VE^v8JO928D0~7!N00;o{l@>=Bo0~X~1p +okU6951d00000000000001_fihzd0B~t=FLq;dFKuOVV|8+AVQemNc~DCM0u%!j000080P~d=M?<@N5 +j_k50OTkD02KfL00000000000HlHQXb=E!X>c!gV{~q% +{ba)VbpZeXJp%v$BLDyZ0000000000q=92~5CCv#a4k13F)lJLWNCABEop9MZ!bheQ$tcoP*h1zPA+n +DbWlqH0u%!j000080Qi*_M;X)hB`N>_07L))03-ka00000000000HlE#cMt$@X>ct!E-@}LE@WwQbS- +IaW^XTLZgg^aUvO_}Zgg`lba-@7O928D0~7!N00;p1l@>>(4j9~H0ssKh1pojc00000000000001_fr +WPv0B~t=EjKPPE;24;X>)WfX>Mk3FKuOXVPs)+VJ>QOZ*EXa0Rj{Q6aWAK2mtt%7DuH%DV{F?001rk0 +00~S0000000000005+cCwdS7aA|NYH!d+QGA?9kb960fZf0*UaAI;UYIARHP)h*<6ay3h000O8_>~q% +#~+u%1^@s61ONa4ApigX0000000000q=Arn5CCv#a4k13F)lJLWNCABEop9MZ!dIja9?a?c4cfXba-@ +7O928D0~7!N00;p1l@>>bGk)WfX>M +k3FIPxKMNCjj0Rj{Q6aWAK2mtt%7DsNd4e99u006xQ000~S0000000000005+cYkLp?aA|NYH!d+QGA +?9kb960fZf0*UO+{2eL_t(RP)h*<6ay3h000O8_>~q%jg!*R`zZhbR96518UO$Q0000000000q=Alp5 +CCv#a4k13F)lJLWNCABEop9MZ!c0sLr+pfP)h{{00000>;UWlXG{P9!Ke@b000 +""" + + +if __name__ == "__main__": + main() diff --git a/asdctool/src/main/resources/es-resources/index_ops.py b/asdctool/src/main/resources/es-resources/index_ops.py new file mode 100644 index 0000000000..d1f3bb0021 --- /dev/null +++ b/asdctool/src/main/resources/es-resources/index_ops.py @@ -0,0 +1,151 @@ +import itertools +import string +import json +from datetime import datetime +from elasticsearch import Elasticsearch +import elasticsearch +import elasticsearch.helpers +from elasticsearch.client import IndicesClient, CatClient +import sys, os, getopt +from file_utils import readFileToJson +from config_properties import getGlobalVar + + + +def createIndex(client, indexName, createBody): + try: + print "start createIndex" + if (client == None): + client = Elasticsearch(['localhost']) + esIndexClient = IndicesClient(client) + res = deleteIndex(client, indexName) + if (res != 0): + print "operation failed" + return 2 + create_res=elasticsearch.client.IndicesClient.create(esIndexClient, index=indexName, body=createBody) + print "create index response: ", create_res + if (create_res['acknowledged'] != True): + print "failed to create index" + return 1 + else: + print "index ",indexName, " created successfully" + return 0 + except Exception, error: + print "An exception was thrown!" + print str(error) + return 2 + + +def deleteIndex(client, indexName): + try: + print "start deleteIndex" + if (client == None): + client = Elasticsearch(['localhost']) + esIndexClient = IndicesClient(client) + isExists=elasticsearch.client.IndicesClient.exists(esIndexClient, indexName) + if ( isExists == True ): + delete_res=elasticsearch.client.IndicesClient.delete(esIndexClient, index=indexName) + if (delete_res['acknowledged'] != True): + print "failed to delete index" + return 1 + else: + print "index ",indexName, " deleted" + return 0 + else: + print "index not found - assume already deleted" + return 0 + except Exception, error: + print "An exception was thrown!" + print str(error) + return 2 + +def copyIndex(client, fromIndex, toIndex): + try: + print "start copyIndex" + if (client == None): + client = Elasticsearch(['localhost']) + client.indices.refresh(index=fromIndex) + count=client.search(fromIndex, search_type='count') + print "original index count: ",count + docNum, docErrors = elasticsearch.helpers.reindex(client, fromIndex, toIndex) + print "copy result: ", docNum, docErrors + if (docNum != count['hits']['total']): + print "Failed to copy all documents. expected: ", count['hits']['total'], " actual: ", docNum + return 1 + # if (len(docErrors) != 0): + # print "copy returned with errors" + # print docErrors + # return 1 + return 0 + except Exception, error: + print "An exception was thrown!" + print str(error) + return 2 + + +def usage(): + print 'USAGE: ', sys.argv[0], '-o -n -a

JA=nv$40_xjP; +9&)Z{j>aoK80~PKIC8iPzL$KJdr=-UzS70<*&Ic@&`OSKFD*&=WLJPKg0jdojaF9KK6t%QG_z=*s+80 +kLBaksZ%TuzWw%FW=0;dPCy-I@c8lL?8CZ&`GFAg4eJhuIe73O;~(=7>OaMNxPD#UWyXJC{sZi +#A%BMd`uchb-4HAPQBhI7u^i)v{2w}Wh<^O>#}x9Mg3iq9Fs47|$Nv5M*@wLE+qaL^m6In=G8|>VHUP +^T))UMl5qB*(m6_XpHUifjMC^Mln$$;G-4mfu +#3`uAVcqeP}*|~r7KQTdiCnn)qjS6XzLvx@-KgKUdZ1+Q%|rSV0oGGHKpTDQX2ayq(904d2q);N{4_9 +*`HHdf0fd-qm+hkbu3NX7XOznUBa@wJR%~ZCzORElmYVL23e37EJw&=OLAbkW13?gVY$KbkL@mu*%(6 +;f&cMeav8>)p!81Qbp*&T6v~bHBl?B`sDQB{-xj;2rN#4slA{(;hI-%&cLn$iT6;R{ipq0Eew>+^nIpRrBqy_MJJ0iWQJ)85n*?oY2((E(K!)y{c-soUf|mI2*|Vpk{6im){rnC2f%O;r1353SKA>5a0r`h^k5>FGmA< +)PBz<-MDEbn}um)tnUkbFJvp|NKz{k`xTn4#5qYQF=#x`m2UP$+yl=ej#ApJF)q5khxj$Z{w2T^!GB80(2|T;S~ +xeBE=ko?Zwql;7Hm<;&CHfe;Djxlt1%jF;24D7>DkHByJ`t|h9 +H{YbF7s;P)$P!~P`8U8NnGqy=D+U}%lEO*jX=F#-Y>=^o3rk2`4hDSh +#r69v1kO6RWwEErZg`T^ZhG>le&3?G9GtUiMb*e1 +#Kc`dX_t1YAH-^?-e36Nn0$gm7#D28%WVA3&0u}#uC=@=i>w%q+$>MJz<@i_($cb1Q&Vf99cB6O(n~MVi4!N%DO0Ab-pbXfaVmZXV5aZZo*U@9IA^-LCz`A*jI>tP%V_<#8HtE^C1Z4k~*cOF_40ydWP~H=I9|LH?S{f*+PCnKrh +qht|xdpA^SH|IBp^?4RFU6iYWgF_(UMa09Ksc=0&o_ifKVtXj2-78Mo!zH;SCx^(H%i+A6BH_gn-Lo2CNq-C-R1JG?xYEAg~|Ca*us9))kzOz;Ptnp^k)khqAQr1Mx3^jcN2}=YKFT)ZMjav-z8cAA +a~c@;PJ14EAB2mSyPIuOFR1e?H3x>@(!K9a#?K7x|axd~s}m5bFch5v&i*>pS+@&SMW8Ka)Q>|Auu7% +RiK*|F6As500w31f9zyB?PMq8AIva7tR0%Mc_AnXWtdclG!&>TaV3E~AR!QF2;tENgaNc# +-sbKuVq$mqh7^HndD#@H?buY1Nv&;DYNrv4prFmD!|CsH_MYWt&5M{$|MAS6oZQ`e@A;kI`JLbEd+y! +9`t|ECuuf;roT=*S>hwG?2I#;4{`*x?QIY5AAXK-FDIK!?=B$f#!s2S(d(@adAFlgI;6{-N{%C?c$#v8m7E|hJI*~^`+%s?Dr-Ue+@J +ilk+tA9dpBH%!9$?m@{+{SOORnV}W+*V>o(dK>FSJ9}`OrG$;7?_&*$j%TbXn+OucRYP|~&Sg*)C^s^ +2`9uJNn?V5gf{!{csJpaQOu$}lX=s)BDdxY(T$HbiQo_R3&UFLyfbUwNkJti@Q#x-QjBTc)eAK4v9&i +j*hw=Uv)led7+j1gHEIl3u6LbuEncJ*r`Ogn|wXMXj6T-4>PHFjBF7*qiTS|(3Vo%B@0%_*f2QB>|DO2!(?#dA4V!Ie_}q7STyo02|I(w>%1cV ++U5sIDn6fq9 +1E9;s>KZ(Lpcb_^#Y7Yfez9VeH2;kr_PcwecUcHRGb1N8q5(cvNKv&W66o4qC`fA0AFH>F+|oqJyN=8 +N1I%oMy4oC|z~oH)7IH*P4^@xhR=-cgE7_>s-g(W7wC(fl`{AhS$Vjlb^cL6W^!M|d7A6VIuYkj3IdX=jQ@}T>7?|n$z +^8int|;}$=coH0|{H+sutDmF#pSD*N~h3|ulYD#j>?w59LEp$ZEd{)doGSPNIpL$bmJNy-UjA6ADxoFok1?!`H38n~? +jOHm_3G6X>(;GX;>KQ~fxHR4ppah&Yl=8{A2<{FP~;Je32bAdgD=$;$Lh~ElxiBZJa*i|z7zXT#DWts +VCMf!V~)nVz>3Iek{dVjNM0O#1#CiNTu%RMAAL~wHNz#3S-4 +89xBziA$S#e)t@`L?Is6bU`>FJfE70Qr^k6faqDQXTetkPw$`j!Qz80)iNObm3yAID3AzVf-01$3diA +FT8Ydt>-Rk7m54zR_IMY@KCtK&xK+*Cj{mz&A)_;1he-odv4)OWjIEx#*gHMBDM(1C)HO2x~w@GNIcd +$lR`HcRf|E*iM`kr~_nL@B3{Bh_oakbeu2p#YOeZ+SZ@Z0E`TWg{(d34EIpZXskyRNRTqOq~D96s#Wu +|w-U^e(m!{f{ib4`h+P-I&vRmoBI)moCbhNRY>}sd21qp#HHbYBIxpd#B{g?ZXHvJbC7XCdaCr9U9!KO<~OV#6#Kd$3DXfnFM=t|}X-dyi~Q@s{ +gs(!g~s@@A=3w_WZmmH5L*u}1GXf7mYO$jo*s99x#q;VF?QVSt(4od?|I+{{D +uGYE&j)4utf64`T6-e{|XJumoL|RM;{oB#K?fjAscxRJMn2*S=nNd5P`230|_Q=LyCDr8kxd*--{3e%+43bL+*I<3P +aRlZ7y})(Q0x!_p=uGH5b?Vd(&(JUmz5cgt+vW=d0)-~#W}cy8@#4j5!h{KG_Uzf3Hk0==_z>qIH%4E +uFR`tyjkkf_HH5x(|MZFe*|>4z67EM%9-EKO0b5wGV1dS%Sr?p3fd?kXi@yw}g5NG<*nb;+$NNvrVYz +b>*rTedDy;Jy!Fh20%!-v&@0|#`j7~M$D$zY1Z>|6IwKg +RwdON`g};H*7^OF{!O2F5}D>DaMjW}o12`;L!)C^=B{47!hbZf$Kv{;miwws>Osli?PgH5oU|%K92iz +x7)_O>M~O8rAFBTk2rX?7E-bjbG=9)x`I&+{Sae-hSy6dzjkacOs9|nwpx91cSkkL`S{%?6c24dFarg +UV0}S4qugfR6hUw^ZIi+=Z;V)ly6zq$w(xk=hN6Q=2_PCMfdgKX=l!yAT#hcS+ysn7N*Fk!gH5!G5y2MI*gf6gFVsdCl{^_@+K41Gd*ChtqcO!NWVs +T%k@3n<=szWIUVu{#BA`7dBO&nJ*Y4J*Q;A+ez +@{;I_cbsX}e*fCyxX;aCUx0sN7qs32lVksYv89y5_1Wrj*LlrPVyGXN>i%z-`A7E9^~fo6`OrfTX`Z5 +|najVv98_%^X6XH&2Wr2oUVZU7u7AN?fAZu>?W>vnIOuJBF6IM$>ZXPNvE^?0=X^8&W=|6L!cNjZ_J} +xvd!v`d_OEkakDi8Z?gKBtiWn0%n|u=25@%z(+uPfFT}!D?4o@8?)sy5@&j8h&lkC(x`FxZo+2i$&({ +Fp?jccR$g$#Yf`_@Lwcd<7I@V2!i55JPZ5${^N!;_vK(@wl;ZH#lKSHEZNOU{{I{g$<4Po}TB+F!n?Y +_+$xysV-+E3Kxg;=bzQ5`Vd`dSZELaaCn?*UI6e{oG!>5A3Pv3yeHUtS}<_#Z8(DqUGx=3nfuj(_R?`hi-xlwa7K>G`u~6csuDd~rN-$NXkDNo_0G9Bd694|W7QgWk~iP)WEpyg9r(+#Eh0J{Rr`cZYkzVOI}MsOHs?hmXa1L(i%M;Jsmw4?TB_py +Q1CEYtf#l#~y2svr}xZJ>E{YGwfVD&n~cw?1grTz09t)8|=;YPJ6d)+0AyVecV26pR+scPP@zQwy)Ve +wnx8M($f8>SYB(qm2PENxmKQ4U=>*ltrBaQRckd^o2{MJZZZ4KR;zW~I&Gb^I;>8s%j&kSSv{5~Fg7q +QkP`3)#s|^^8G+nDUZ5aQ6j&H233LW}0x7|aU{P?l=F#ckIpI@RuqWsVjSYJ>0|XQR000O8^OY7yf29?aEI9xGKFI(88vp#p2 +)17GvcLW61pomMl;q6p?%i|!Byu+i6bgkxp{h_QY;J4@`}OL+DXtc65bckGSGzA?ZNs161!s#qIKFQe +brqb}^Y%7v^5DCAU1e!o)Kv^MPxCx@f4G0}@$?{W@7f@(vS9z{J;=N6@h58gnp>vMXkR5Rn(RGUe;GvMRl +cq)Lrg(({9+sT-?cwq7pp6I~o>(A8DIieEyh8U-X=x0TDRlil*%3+jS0QpXO_+ud4jDZqFy&M0J3h%dX-n>V9~ZKKxQ1=Ez4##qpt#< +wA7d%-n+B2<9EPmW!{YG$Eo~G?*(nbs +d`*iZ2hG!fs({{E<7PV-rbP4_3&zrWG7qhg@Wr_b?tiFR`A8l+PCj!nB#gg$=-oB@2QIcTwB!NhUyXyWgIDoxFu +hCx!OQfgi;&9U^l$R3{0>I23PheSgEY7-+F+3u%{`1$9o*)@<+>=d0G_T_LA{0V!1$TmRS!HbD&$h2!y*?r{2NY(f!Glu2kp&XzD5*#WC2`h)C^2}{pBv6kA5LQuLc1@p +%M0)ndJT9De{QPF_NB|y3RYG8P`2!Mx9FB^E+zN0INsu92n;0;NL$1_8*uhVU&@)6;v^p(HJG!!V8`X +qc=z)&mcQ}8@>4l=$g?~Z{is5q%`>?@+@fUK;W!~6{B8XEodN(F@%D|NqSBZ`t|Cy!>W=LH`QyG(?Sz +~2P^#!u*&i|$+bLbI!PCa(cT7iA76uPOgj9c5%8FSVjr5x)Z`Vx~WYe%-g%@M|a#M +vD47JI{x@@8D$GXbt$r66pq>M?P117xg&V%Jsnk9)m!PYWtO+7~R`SI*!c!9GAzrHd`Km%3XQbnAH;l +-Xc{IF=6=;9|YMQ#_`46yDDCDc5JNjS@`*AfW}NC&%XImY#WWpqm7hV}QJ1d&GzStqofH^M`kem|f+g +fQK`pmsr~gkQh@ViNB4#GXU|B`k0r{;~nJIj!(CxF$!&^P2TuE^=2RUg8 +9!sr{KVS?Ys67Yoo8PJOqWId-RjX<>lb-;-rEpP(=kK}x$$;x>_txuV +xei7SNwMGB4*qp0;tGg&}|a@{3|_00y161dOk1i##9bDmT2G6X$7LAxPyucVPbf9z-;6YIA~1?Q3{<0}9rtFHaP{39<^bW$}mG83lRN0|T>{$s}lw?jak&EU0gCT5Mr +9H1}8tH0N8Gp`c~u-dSXhNxZ68k%ixwfcIPPOM!9V1>kA7fU1N#B-i>9uKAnp(t@2B3DF1Qk +pY`?zUZ7yIBj`2iI1za^|Fusvpdn5;vd_{Q%!Va`zlqF?Z-{x5YBZ2E=jt+x_UrunAquiaR&=&oYyt~ +51g38cOu(V-RkWoASL{YB2HPOmgYwWsmm{8~7WllC{%MnuF_=Q=^)e4bjpuEM{r6#fk0P1!)W>$y$(& +`eX>a|GdU!r&dl26@;(3Ng)bQgm6+t_yQ)Z; +U+Vr3BCkW@E@sgspcd<8A~e^LSkUqJ(HsHd1m*LAxz=r1?kcF#V0DTH|PumQGpIUfeyVqU3OhTp1jE$ +0iqK)V_u`C{dy97X{kNHo+J@2VWyK4FkmnpZ_!V{gk8Jn!@^c!$isCz-~M0WNHx5{AkSdcYf%EF8Tv* +3?eys5IG6(`pi}EIon52YDD$gyc8}Bn1B^A3v`vwv2v&?uNQ!C%loK+-qWn&~Rt*T~3y!gM3omPIuq3 +L-ZC)XDM0ha`SL6ndB{A`d{%WZ*WDkyMbuV&qg)rC{%!Q?h9Cd?+e;nLkIa$SDka{XDi;1)zBCP3I`A +M;u$Yla?Oz2T0`emj1D0LA*Q@>}(DWHJd^ctCtio4pSAqA!1T05Bc9Bu&>A-|4x$H6XRG+Pn>bZ*v|J ++sI3BhtpVTE}NAUdA)h70g9^wu<$0YkchmTNazItTGSGO{gH`UWGX__FPnBt^p_@Y(m|n_Qy|NPalX@`-1n|LL%}S7E +yqB1vDz^f;b|2N3e}#D^F~{B|AWe!kNg@Vi`dZ4uspL#|DdWu2` +{{VS_y@YRw91X)^j)GU4-YfBGXQqM?rA8i=;q6k;$LU+c&tQ4k(FJ~OQ^3Q!Kge|eni_N6#FA}O72Bu +n^Bob?ApIX+%V?}`8;?1;cW2&?nyop6Ovy$MlsOxe#)Mk +#H#-PR2$k7$3QOW-DFXWzYmi5@e>(N1PZkl<}*tbpzXGy>g8mC);NI{*Y!pERc5S*likPFxMI5@OrjTEZtY8x@ +yF2o|>;sSZn7?GSe3fT!6)D5d$F!=-YNWy3dn7@ly4XIKCKz0H7$Q!T|?zt?Yz^l@zy{Ko87FNGev*^ +Lco*JEuo)K4sxDW!pupQJnE=66g+x!`di()Xp?E^ilM$8( +>A=bcHI0Hx_@!>~f5B!I4W#(IccT>+@;Q623(hJE@Ej4M!{94|!B1XU%=mtgFd)X(@77Hp`c2h4DB0H +CSZpCeKK=m|Jf2lAD29SvR<>cI}(bv83B5zXG6ylCxOg1W8cy0CUjaE>KD&Gf+xe12f$^15Z*7M3TYT +V?dR-!^JTRdWfJ#8L^L6H&o^5X<^_h&IV>9h%%!Yn0jY92uo-Vr$4_Z!vJfeG?j9S07$8cpA)&|(Kcw +sz|`jwF!AreY+!#8fLWr@fj+RS5f;v3juH*wYEU7!3acqdmjO_!Opw*NsKVBR$s7j@>tEI|i>R($wGi +ADTqZ#K!Pf5UHF`cZEb6anKV|_K9K#xrVnhzIHOoK~OT>s~4>f5Z_OWi|deknkZR!2Tq9CyEK?u(<*e +Ks)sT(MkQA>l8T|DHdIq|~AvS0P&8Fb}YY!0Z&L)e&_s!Yy^@ph~V7Eo>|SoDncJi_OV+f9&AJvHC+Q +B8y7q_teO-P_Z2Q0%cOp~!-VobDbG1uIRf;KPq(iTYyjTECJo^{Z~8%<9#>bP>>G0rQh~Qb5_{FJ#qC +uwi@VV4NhZWJDvdc~@xBfo1@bY8z!1G9N6uGgwv8xbcsXA;uEa*%c+=JBs;8B4Ln>ZmpV9{-)uy(e;qydRsNazoapR +pd8%ZDy!Gc=pUnx*-t!PI#*t1&dxH7%rv$fhfCrWc>Topq(p#^PWH+t1)(@Vn2G&&m(W6ENl6^)G5N+_ +_2~hYAQj~^Mw1j`A}lvY!-Lk|yx-Tk^apkR{s;Q$=t|s4ifZfdz@gv`m+m8LZs^b1y(^UGmOu{nb}rjf36#pW#D9( +EMf05wEQy!%tjg(T+KhCbo+Hv&=tN5s-?4(+u~it7aHYW|0h#H?UzlyI;(m{h9sRUg}V@XEiO9rhU(Y +{;+J2!?e7{ro8nBtwoKjX_xv8#>;zR3Y>lSMV6I-63RrTB=)77>U3Dgui_vfQc9UZ-r()$#bmwM-2?2|OkMnIQwCDfuhQFV|O5c! +Efg!KPiexQ7#f!LHfN8^`zfR3)-m8$*M@9-OzbjEYt4O=EuzJ!sa9m!7{qB7O$#+jav)rPk1-B3te=* +qpr}6Y#L*E7wx5z+!AJ)#FgTHhXPX5b +il;L?#V7>`{QgsN^v6EY`T<%TWN56WmTv6grAo7GdrAP97KM5nhB3Fo5EMN@3@(e-_4u03n0+cCU9_N +A$Qa0Rz)q&Q^4TFe +{hB=-51M)Sej_7DXd@%!WXPac>;A-=f}Nja38eJM7VvT)kMqW8ak=d;`?MZyp6xQke=qs9s1=lK=x{gadNGQod*|^5e%pGWZlsSZQ)ga7`DlWb-b8rZzWWJK=-~3`%>Xb!8`rn^`-78jj!q9 +o)@c+o0F|9_Gdh$bxdy%FiW;$ir4|p>TIG~HMLt}5B&cO+<8JIUBuQ@qK|?>h=s$nb&S!X7arCAQvTv +&RNQ3*O&jU}7?D_DNBf}I;)2-D~;l-1}a`dee#U&rqqore3uPazO_Cm`?qRLEyU7HTJn3h1skDVv&Ab +v3kUJh-K{ava1FohrNj#^Glny6(0NJ?Mr^Vj^=yOH!aaoztYZB&=14;{GHh34w)x8Xpi{cK6haX7l@P +f$}&ct{WMsv7!)Kk2HMbYzNZnQlg9U&&}dbpOjpQ9fdeVQ@q_Qni`N?2i<2aLDm4o#zL`8wi{ZaTw!K +%tD7{#F!|7!!DSmK#901&`O-^#23PV$g8$-Yzp0%VJr~|x(b9Uq+@{+V +mn8ciRTbX1)&CA2Wqun9%5sHKY6wX`imD)CI--3mZs(J1`Sa0IU&!I40jc+!J2{Qyz<>sqwVaGL{B`C ++F*YD;b2EQ#RhC77ucr9@kG99Rm1TJJaU^B;a-4*B7SUU=hB%)XXV9bT%6xvy5WysH+P#18G_j-JJ`v +&50OH)$iH@E<5j6bxP5K@5GX(`N9NxF?`(JL+}~hMOGn$6C=txWTY)i2;I;oVOuu@#krVOct_(0JI4e +B@1P5(+VeytgMVh)WY&msF)i$3ShXKah|rDn9(z|)wQ4;Qj>m +zao9;CJ0di>$88~d=C8v~`T8OVJ20NCrqDM(zT&n7ZHq>NlnRb!1wOn2FUV^=<>~mCgfWgu-?3a}=)#3C3JDbv_&#+IN@t9y_fpql*fgAz$ugF)-SMDk3%mM`J<_I9Ym3 +&42`b?X^Nqt9sT_lF-ik{W?|>zmc#K}=YOTpZnBRi?Jj6-Cg=;O>hOhLLyUwsVQt3U8(}1VCTM0dZmU7G*MW2WE{~Y*Jg~7=d`(o0nVD+f +VTi{9w1jU?G)>p9D-g4ZqR+>>q{5=V1u4OoTq&CFQ(e*)Jlv4G3Ak9ll5COH+-nVZz(nQ4el=M|QRd# +IR%(XfVS+_3<(yyeDHxxFR?l4(n#DY3#Wv&qXVz++vih=7#o~djeT`oi-k5&sz3W+`m_~JI8rC?zW0? +y6?gaDtag%u5hZjI^&qZlra;ltckleWJDKiw{cbifw9gO*MQk57*N4bz%^eEZ=bdHeC(1QTZ+9(}YO1 +z|Kzw}0B*{+Hz9MTD8|@Mm(NA8vukzWr1yp#v7b*uHo%Vq5-jv~m0&XYYT-HhdWm7}BDikKZG++vhwCf{d66+33^w;U$l6U?iX+srri)f_n;U2$kGI$;Eo_|+p1k%eey_Y +;_oT?1Iz+d +0|w2#odjFGnUa&NKvt7ZXqbJEt=~p+!TWv{G1AWgdcz6uh#y&Vy%Xx9|g2*8RH4pKTD{5@(O6Py6|%= +eI$O^NvznJ~&g2?1+H(>*-(4#Rw~oFw>v0MA30OV3$O4f3$KY+uH!+5sLOcSmrRlGFC@Goxu|yn%SI5 +$0AT_GvDDe$`+ai$855SZS-HT|6G>Z!_#leV6_J=>O<}+C2!y?qtVNFcf`Hk<0051MX84ao$71XD@+b +*_5?Y_p|oU>)u7{W$k$Sq+lU!Z0-N7aO>@8Zg7fgXI1edki$VK+c3oyc_SY$wiAs0Exdy@hy)eC`m?| +y8bZEJt-NN(+>>SDnV6xAP^H)kIU|LHVd_Qlk=mOLxB5F!zf8K8^g +`PVK*WhpHtcrjo39j))^tr!+<#+6ML|Vp4PIAhB@!u`=}Ra4399S&Qf<=64h9Bk^J5L_@2pHQwvdKtP +e$%3kiF0a-ImVqF%(dtDB1_*^{zI5N9-G)_%@;5Fl_iUw-*d|ME|9@Lh4 +oLqcX`ZS4PVN;4A7wY6wLtf?k~1?P#5O>RfaM4}n#1cmrnP;MJas05`raM43 +<6gdX!S#Us9K;_hH78fS9YaZsPC{0^unAiNlbYa=4_-wF4+o%( +<#(*U%%bv+D>aEZ^dbE(Z^{AzdR*+8A68jQ&W{*c5ZKPfh5^>26Gx$`kmGNs@RdW#g4VO!&033KL-lDsP +2d3Sk&otX}`8?hkS37SHaQVu3iPjDlETEpaw6wJyhlF>#@NgK6LDmWl*rcQv7x^;Qad&x3H1=G4=i-^ +kYBF{_tywi7B>FCE+aMDgaAZD=HA(SgXJPXvO0%gz|2UDenh9Fq;vUe^J6ApWlw3Hz`mvT?VJXc}1`! +_jx8NkyWz4&nskFvwpAq;*@FRGnw6d>r67xYFSzW7Hv$v{GS*DI4fo?liLm9@WWiW?wS=w>*j$O4%J* +7cm3nF8qnRW;%^*h_=nOXDHbv~yr*mI8Bz}xQN2fjfSO;C1lLsN +$k>xJ5;dE;rlE&=owSdSGHcEBTUzkqhLvaW68xYBKvR#l!4p!?+7?;J4SYKj>lS?IO9lx?G+}zl(MAv +U*HZ@%jbyuDQ`3>!Vc16e1jqN$Nt-rs`GPH4Z9Zn8hF|fYCq{oJ>3UaM0?3C?*as{Iixfz?GS{rr@DY+*aSttn78Y{m$8x$QBvJxu$oK@Pwh>JIIe26JENhH2~F$Q>YQ4Bzkx9Y&dHLCigZsSIjN_s`$LeZO$eVm+Tm>}HHb$(B~VZ +W`Ffp+X6mDZf2#~2e%ohEX5*5y|Gcoh|$ZB18>2AJS8)rP*s-Pz{Z8vUhmP-#Tjso_cWuJG#}mQ?;Im +b*@#IolH=d4^1S>P?&M=>uX;KT +tjn2`D^|_<+06T*0y9M@=P*6Tdnxc4nM+k25X>C{V5v-0RmJGzd2bgP0z;0$syhzetzB+?kTTg-E_xZ +f$Ue(*&C(3lS)h#ur3kOAgX*|=AoTu`q!j~}Cz6Yj`DWl~a$cJ3HNC!gN}Jr>zr9U@gKc`$b;JkNo|&1AQ=NxK=gSupdh +44dMo!QO%ZzynjQC7@W4hGM4jHv%>s>8EWI#pxY*c$vSikS>epKj!zIz^=Xu^ +_=$(Qi7Zdfwn3tf%okKL>9#eQ@0<+TThn8-S%LzYQ4(@^>@LPRX#by)VzH-7EH;N%5Mi>`(Zs1KJKIs +4+Bnb>oL>aIXy`Ivx@l)edbzRlBmC|{+(t|2QTW7WXMC6|Agjh@){5Di +RGmHfs@r*Q>a7{j3=2}o4m3)VuH_6E2Lg+b7OLXzyQ|bPqyh)x_-1|}b7TyFRYPu8$iwQ&bOHF%kkl +6X5a>_RCl^d{1bD1L25BM>l`0>avS`nF6(Wqa8c!uJ1SStHYPVqSD;4doh``+n1(KdB;g%__?D(k+ZL +v7*?#@@~jbn~{jE>?L~q;cI`?clGSv$XkZT0MXD&lE%kpvrp%3~w8$mn%?3LEBGssAe~dt1Q1u=qL?s +oK1I)Io4uwU~Afy^)0#v9es^}*pJLvtRG%A>1tuG0Nu-u5EAvsQQe3RIOF9}h!v$Kz?PZc$t|7b`br+ +Ulod=mjI5*qdjL4li@ddaY-oQ*swcBsN$O{yy^og<2remMcQhpwMfSt7{;6Sk&WDp%+a?E&>`>p>y`oEZS+Z%SQQm6`a8|n%M*8hOFg4W!J=Fs})r07CfB(1loo9yGa +fdq(=fMwHl*6e5yc5*%Wlu;kw)llZA8;FUVkEj6niRNjw +^PfJ*Y8HP$=dfFQo=hLyO4lO_3yVDM_M1Ugs2i2D-ME;>{Mc)t0nPH$D07x%M=w@~-aa~wJwm*f&(=I +s++Po~x|hYITTjBQ;C18=!Ox-VWtz<#b@;a!Ds$dO$YdzG3#3oYFu=p^+ppp8zmiICm{cP#eFxnI9>4 +_Bw&R^rzlJ^4BRsD{^NfhP3%SAo--412S%FT3-A~1eQfR}UtDoS{CH%Qvlo$l{_GJIv;r9p0!Jp3#K4 +MHFU*#P`>GCSBAuUV?}_vSWE+mb@&^%3`c}i +Jo>BEj$z5skY)d*;dv2~>q?8+J7Xflytbp3O%`9y7BDUrdk+ +YJ_=lq_VqK+Sub(Jg92~s35ivg)ltZej$g*IT*r&(~pBjgUK1w?)XY1c}8(V{{k_DISE26)tTevV?a$ +lg@1?P;#=#LObZz{d*+*`wWz1V<%3OL4mODZp4ukQy5UyfrN0%kgC7GHB{YOrlR5p)Kf#6*m3%O%5{AK%G0Sp3a{*UsG +qm=={*7ql^*>U^r#!FFXUK}Hs`y?>}&HHGyGuA+uROWefiHXzxuK}myU)R38)!gzb)_v7?i1F2aqJ5x +~Y;v_tT;j==+cjyo&GG3$x6ZxWmM0RLwvt2Bn+AoJ?;|_YV&-sTo4WZOUzQ!jyT+H?ZNx=n_L$i`IdH +Swv~EUo*n;ej19ZXYUDv1|Ymj^po^LpOADE_1q04WAD8RvA792f>R6VLb0RZVE!`5mp=~ +53Xw*^KXSdHNC-qN8Qfi8|r0cIS#7-uSmVsHfX?fl2f>}|`!GWaA^L1Iep;c^JzPb$?mV#3OmH|W;b7X*d<3LcB#GHp;f{PgkgjP*fW?f!^=KH#4}gyZlG{yz@8c-LcD* +WN!|%S8nw&8Lrl{CM=IkKtfsDA=nvX*t=&6yA6E?d9%nf9HbVDeVIlDEZ{|L_+BNT&Rr0Gi4Zn*&PfN +O3}^5fb2Jek!AcP(mRs`ToUW3w>Co +Da|a#_49biGWCi}QlBxnm(QIDGs?qd4tB(=@(qxNEu +Iu7JWO}W>pw~p5=uvOgQz*laJCI9CdQmLkX*`)JU0ZvQKwmOy81*O2u-$9LU$kZOEzTU_~s01Jtp~Kp +XH2uRlt!dI{!q!gYC378hrj`7 +Ce8B%I?iW9u1@l>rP3AHy~jw2{WnsX%i_@k8x)1a?)qt^zG*8M58)Hn>TOv=)aCUn?&2LDf3M2rd@e^ +dyoEm&@#|jFHkawwwaT32%o>(d;VeX`6(;_^yZ3gBhp12xGxA4w3cXSF`DPC- +~j+0&ntL*Y$@eif_N4>`scYPXk?E#uj2CGN;SRu7-Zw+)aK+8d33c7;AH~t=tueDYhKju&Fv{Z_-2QRsZ?J?Li!2+P}Z0IlaMEe`|pxJyg&NJJ@;!%JeTg=jY>}FV45lw|>Dt{NUG%4#0=Q(+_XYpvlvNGq?I* +rhobQV(a|ZU(SD~mj6K~YbdS&cXH(=_^mT4^ifZId}(?>RdVDNU49*GZIJ~2xn8v|$MEMB{`vCP*vNC +`?V?Jb;I@q)zLg6g6f*f8z7L)^d(bW56M>!rdh~2->sheGgkI`MRa%1Ru!1aoS90;K8{DjerAf!%hU2 +mjbpD)TvdwNH8L>{6s9ySEnh_|@aAWoUeFWzC-d%0GKA8XujL-X(P^K2F>HLNH{Df%KW$k>N +8`7;bUO;wJ{}t1HX9g`exrptYuIntq*;?@#VjqQN1Z?_k^pX2b|8s!ml-z<`;B*Naok&obzAL&63gX7v&scDVMi_rL)XVOR`a`|dnfH@m +0FEa#l#q(ZCckwVA2tBhx~+fGHv*%-yETwX!P{!vCm8e0ITuJ~^0jC{4K88Z#i1~WEGX$eZFhf1ME}6tSAIs4z>IUln+XN7y +*oVmFC~!3*yNS&%0();HBmxir>E~JKfqnvzai~AV7FKCojYw=i;~p!gaY6d>P`M5?dXa!-aj}wgC+Uj +KOLSNeEWoH?5+Rt=;OgK1)$VzldcjTk_i8i6HO9l^AD&SRS7oogM8 +Ty-$GbH?O|@3@jwMCl>J^GJsy96Ru#LqhlBauHfegMO$xl2tmYT3xs(xTcq +kRY&RzMkl9G-GZscPo7MU-Kgz~QrroRiFu-n~6dPCp(FOl!Nd(- +71jXqW^6C-_muGCmoc4hr%9l;|J9amm*?IZO%rgyTQ7HfT&EjSp_2fOXd(^hgOoEY>HMeb(k(En2k>W +io@tKxG*^x8JQ*p73vrN->^g&g$DLl2ZKi-6vp$Z~t`CN2{ykUS_I3q*_~R;XBUe5`B}3+^&%=`{_ywX#bS0n2lPp`rJ +9IeOTc;dBhns={Q(eY`rsz1uP8ylvGT?Lj(g*93_=WJOJX~Q+{SnZ9`4S%=U5cRsb(zQV)R|dGy9(%G)Ump*NnQP;VL_cOG%vSwhZ)b?JScdljR=nSNx@|K0sh0mfSL;SZSL-K1BEjiAVA3@|{Xfq0>0ww(T_#*B{$O{ +V?Q)14+73Nk*KM2R6y3dBUMLp&bRTnjn`T`gb$DNh1r2Ex*EbwD>~4brhFGh)Xai=) +JoA3$Le#XMCv1;hg#6g#b<1`Wvp!2`{8-R45?V&$}UDI$b@16*`ldQ)f5J0wr(Ea%dlG}_Bwu)&eK1C +c)xveyf3r*uo*@+EGl;tG!snvaWs3cE;csMY1b8+1ktN;@K4H`)r7LlUh`7g{%VgiWP;oB$cHje(zBj +Q2|&zB?(YE2vfW^rr@+R@P4sG)FSa$WqQK{UX9L0MpMaJJKR|x142i{bOsIbmTeAqjKoq@#HVIB`)Bp +b$A}|5Y8bAo&Mt94yS&Fb47hD?I2oc8ch5y5^sh|eag}3019)&hR()1@20z+V+&k}VyTiYs +bb#u9QIn81k4R4zndPgfxYS;Rxiy;E~%wS2d-J5P2^4SxIyKYq(p&{-}}MLkBf&YTI|)8TorZVK<>;^%(&#wF?Ok!Bp +GOxK-FzGwrl=ixOl7wm$b)k_%|xhm6pj)HZWZ4-@SeT9$7g9?e^AS5tjFuoM;`=h-Xj4_R%i#DarIob +7yQo@?Apj)2f)zk#-%#bqc*`8@1fQD3OZ;|AC>!RG^>1t&=o~N-R7tuGTU)q8kb)$J{7GTQKGWbqbXdy(N4~sAct;Zq{(i$8N!qxB4_Jsu{0@@I}2CJ}xn%COAp6c}E +cuVT}pQO(b~hYt-o{T-~4Dnf~Dn!5|T5w^?K`*-SzO-021a3mwN_BRdh*eQ%6;N%uI2O1ij|4#)cfPr +9IFR8;FxG*zGrzTUNGZu8g +9hg8yA{A-Eo1mr_p`GrB4z;=Zh^)v-8m1j(s6BbG?@Aa%rfhR4F{A6T9tUn02V>NYB|pSw3GamPj;@V +6h_&m1#0Ww5q|cf?xC2I1^c+@`+4AVMN|EPt3UH`_iX5)GKHWSV;LidIqy@s(GU__N_h}Ty6q-U2>*8 +u-x+*Ma&hq`Sa*q0Ls&Ro*WbuP@_K}2{s#}IMmfhkMpVqFmy7yDdbDee|;>nWd|Ct+eeiLj!I()Ewcb4r +loBRGWCpV^r+5uV1wB{yk?GEbvg6A5K+@y|B|KLf<7tP5f~Z7l5Eb*z=|c%5NXzNYZlYp`=O!rry(XP +cw9tWpWX(p`EmG(L9qCL;cC0p#jYnw9h|C5gM$~f>ktg#h2On6n$qo*Awao6|HJECQp0FaS)S%os|Eg + +>OwgGW5NjAyTsXPs(a;u^a^zQ9ZR&gdH+eTVg9Vpy7-;dl~Z@|29+b|HT;N!7koH&J$vUi}96fIGv7F +Bbe)J@~8mHZ80MU$R8DYB^6-c*^5^Y!!<_JPwD7P>3-n)-_oQq?c{`>`H*ntG*Sy+W0?EO9KQH00008 +0P~d=M;R7wBCHtz0H0g{03HAU0B~t=FJE?LZe(wAFJx(RbZlv2FLq^eb7^mGE^v9>JZpE`wvylVD-b( +5Bx8z^WT$DgvD4nH+nYVD>l3HlyDKTW6a~p_B$6d5*>2tZ_MI63B*2Gk_i=mAx{XcZF&GR6^TL4ptoy +Xff_NTA%OTt3i|*%G(%J9qvo~>alZMO7oY`+2Ht6*SUHEmx-d}Qdev@Cu5xa;N`IVn?_Eo%z=6)W=kq +135IA`CyeRFztaq8vQIrF1Ad-L7d`*&~u_Wk?s-d$iJwCn8c?RDO+lNDd{D5u^mUNE06R{T1gtvK8AG +=ow=j%C3mG-F8`Z^JniY?35SbGC?6c7A%^J^cJLw=)m3JPl`?oOgqGod8S(gX3p>?MHbSXfQoOpcAeM +&MICmp-{c1ywh2v@tS!85R>HyKUz-nn}lbb&UEUpR?{gvW+Uq?PS^e_{F%>x5JOll(+a=!bC^PExgA# +iSl{raAKYjiL_u@o3pod^xhiVz@O>nyRN!=)rg4fLmpq>enp%@i2Pe-{n1-Z+2i4zDnLV9G{+dsxPN& +leR(_VT7O3_Q{%XVN(HRmNK;HM4VaDKpKVqA*n_2`97XVu(0JnfIf!guxM;_!7)|@ZcbQ(rsKAqYbUo +Bjg$twK85^pLN2d0tXKM!9M+o?24{4~dU^_NQFCF6Ehwgp5uEO(fNQI`8rz-?;pvU~#!TWh!Ck!aws6 +V~e#C`-6Cd{aNnI6I5;g8%tkP|<>SAL>F?!NLgkM7Eg`bu6a@K85uQK2A$cmjlH)u!1&NxM0YyRO_%u +$KtKpszmEOR7+$6KZ@d<(GalDpQN;zo}?Cg!i>>$w5I&0Vv(w&h&8AoE}E6(;rS+w%mq6Zu;jZwT*O< +4lYnpz0+_%}4yVCb<$pZNuUau)wvVP^Y)h00H_?uPw5w0VoXMTkxGz`(G_*I +{tlgVU*}q@rs`9s@WOwZhgri9TO|W=lYl+!PSPY?`D%1`-D~IPLP|yg_~_>A^G4Dh0Vz8m6F?qFKxo# +N$~UaXBqeu0S#J|J^C=t+{uCS*b+dZ&AJK3cz$4yJ^1ZBeQXu1wM9*YYKMo&av(kf(9=HJ0>F| +`#BlY5v9adBc5~`D#TD@LIK_GYQqbCZWewTNU(e<~+qx`pSu$i>*xf;?ZLO2WHYY}#SI3QwK(YmhR}J +J{%}waX?ahr=_i47zW;e)${$`cCOf#j9PuR(^SAzTWFdQE>H-A(N{;R%&TD3hWG}=KXuflpGvo>k8(l +jadN0#s)T-*Q$NGMF{SJm}iHpN<55OQ~TYur@2B>~8yFkjz=7i?x^+;BdW`c;FmOyf<02&_HvXj@f8i +KCBY%TaIAZ2f%XHwt0w;H}~-5CD!?b2Oy`piLKS9v)?39&Wi*{b3eISph0o!DP|so#?ZaLk}kAOathd +!*nCEwnl+MObmz8sp#ls$tuik%e9<|0i$TD0W(K2)BWhh1N +*dYd@WmkM_Z?xb3?tZdbvG)*G&cr?$hK+4&c_tbKl=K~F4K%6ijZ=;}aX)CrgZzjPQ1{hle1!O6(&74 +-Hj&$pf1=Q2l4`~=Db=u$$dY_xsoXx;_BSSs(SH(WHxwrJh-~*gAySfa6%N96S;3wt63<=zlhJ)+ZA#bRV}|Y%R=DVOoW1<5DTg6+M +szlv(9!1SwWLG<+s=sD&D&w9GIvVXHTjx6P?6c1}V;2WWntr*hpFHGsI07Y&*wLyN#hiAG|zG{V~jqJ +^Y*LSoM@DbnIsH0YIflOM2YM!a0lI^i1#BApX+tI0x=b}gO?zxIQCD#xmOJQ)~~%8}48#E^;Zn4!_wm +$AB{6tp8MNKJ2{0b7k)s39sHHJvGEAzJ>i5tPEqB@6743RB?Q1A{A>2(D!R!r%(og9>GQsnGw=3%mU5 +0{}2RhaLRRh`^Kd&yNRm&QH&ej(XD{PTyU;{qAh~?zHCjZeQEr^geRvkMe*W+xBl~x4~^1I9LuY_?_l +iYC&&1i9r|2F8Ds@+Xq27ut$FP=P$eeJDyJv9qr9|4M4~@?+_glo=kCauo||K%5~QYP5BxXOy8<*!;1 +~p7M>;tt71wGRC{ +#Oy>W)6m!dWQW^CSjC0YFfRY1OGZM7HQEuu4+RPdplaCWIt%Kw11^_;MmycdPjzy$kOltDphX@2DS_jQ2Aw9_23$~~5w@s;-vwlR +)&L7i)nXHhfXxU?OI7o)k=?KuIga{j+-9noeKaD$ecu2<$%z1l;%OKtJ(Hnbf5PyLEr^$?pMdw|GJhL +~^9mekwu4;>a(m6@VG06xb>p(xCWjFM5X-QkXjcdyOb(mX;H20SJP2^)DlS$?XC%27X7g|f^Jy?kXxc +!jzFawYt(Zs69*yePbLr9SLL^q6gITSXMr?PfBP6c46@f3y!S+>*amHbZ&>!Gk8MAfKGFXHW0Fx!O`~ +5}E(`s~xSQKl4d#cM>hiuM7>?z9!>!{mzN*+LRtImF}6b&_EDF{DXu2T-HAP~Oj^XnL7Qin(J70@gG$ +o!l<9x%Rh3asiA@(k)hMSa^^Q!)0wfi=uY?`qIS?n#RX44tJ_k)+5Y7T8kVlfsm8HGwW!M=D;DlP<|z +GK^iq$VKR`U5?0zMpv-bM +(N8y{r3gAA`ml-0I+X214Fi8H+f_kU&Ka|HJzqR59?!>lF{$+U>Ky$5%iL@Cw27VZdI>M<%-mu|dFqO +g58r$KfjPFfpiRfYw2+g!!^;yPuUAOKW~uDfEM!nT!^n+kgU +24hOBXw8c|e|P%s^qcAXFTcJZ2QarsBnhn<{tEC{O21)8TNCHE9kz*K{piNdr8i2G(#NJyS0$K1ZewB +i5+SEzMeS>s-N+Fr=#{7TwV3CPe7z}j&NVX2O%0tQ{wSs6H5kx1Dn)~D>gbnlJ;rX(D!nm8;q@pYixf +!SAkx%Xq5Ru=SXdE(f6|E@9XnZ)q@|~8>4$Avi&bt_j_Op+(x`c*gEhgO=v7Oj>R7MhKUuZYHdW`Rvk +(MJdSg|O#8it&0oKpK{P~Zt=cc5M%mC#baUEfeLz$`W$P%@y>)xs%t8v@J}@ +a|hcFfcnSt!tc8#3?hc()8^@2Rlb`j0j6zA?ATR0QNPIq0+e!z-5dTAw(7sOz@(&gE%5QqsG=KaTkH` +Y^H=%p+5jFx(c6PNxK7(RDB0zjL~6d#5Jpl#|GxmxJm7Z2XRtEt0LTHu;(stI&svLPL8#f)u>)$G_s; +b^wlvdOB-{6A{NA&_hTGJ_6VhGD0EJUY;Sg()aZ#!U`p>|mH^tR(RTT7LfcpW4{2LOX#Wb@n)}P7Z=D +PNjW9jgi7Ef-ujNR{1d$v +Y2Pkw*_+ksUk!;j2*T@>sh4uYp^?u7L?cX)jZxQbDkj|{7Fm@Hg3T(4L1hZA+->WfpY +71~!&%gQd&FQzNXYbJ;w5hkPot;=C@1Q$*Y&qZ(;;*J33{9+Kur7-zK(dK~JgWgqtq&t_Vvpwzf=aEP +H||$~?lbQUV^KZ$XlqNUMLC&xAS59 +UB*Yq0MUN(Msm-^opdJVg7IN~-!2Oko<~36dqZO+>#Q1c&i86FA(YvireuJon`)TljphWyWoC@%>j{z5 +T~McFTv+@RK)%9dodQIq%Dv*2sOj=h&n1WEZO!&^FPPPbn3_rJpuI`!qb5GP!M9IDnufD?i{YT&?&LU +Bwn?eSvl7qTZ*PF^Lj56pN{gIXOc%opJHQlHEMXXZ!bn+uNjI!?6v{LWb=0fUPpMj*aDjfs1w&0 +>uxCS97aDunW@cl1R~8!wHKM4YCkSfz&r-puGj)i8D5%pipOMImcYVc#|`{7$*CQsBo5xsqV +{LV#$2=ANb45cs_-d4!Cx%U0G=vVQs))JK8SN;}q(uBHJuPg|v{ctah*}T9mO_N)ImLtM!&649n_DS= +5wDygb>K#t_&qhqXf`s8AVTmlD%B1Z?_wjtduu<-{G|wPNx(&IeK$48{1zIT8%q>BMm9nf;c`#X%p156wh)r6 +Yas{<#*2F?G$b~~Kx7*{ST5{;AlvJhgc-^{5JzeQ?aDl>I1{D_txGpuh+Y(evuvl`9Ef28AYO4Lmf@C +{uD6Wu3F^IFu$y?JB9~?paYhtkWU@RYv_p@34N-LjCc~I)6@Em)y7$JSRsjTx*A&}A64x$SJP4(K*N;<(39F%yqk}fz0bmVo%hD=t#m1iict1CZD)5h1y`H|q}e5Q{zEg9n+#0ys)>ApsO&1}UUj63>A8Hw;cpk|1 +D~@RZDvAIQ=YDpH!_4En0d;%i&w>f2ZH~s>F+~&(95I=3e>^ZJ10tmhQ|zXPFZvi*fOikx;Y~K^d418 +~#Y+)*=wtnhmkk5U;V|7(Jibm}YlD0B(cb_YMng7$L4EJgrH5JHg;8F5y-zZiq%w&2Y4Tc3(HVQM<+K +{XZhHuG+m~4pux@FlA8T7%tIm3({%~TzDg02Y2de-=Q0AdX8(n0zY$7mnVWB~dXW^W8`C@@NYPiUFzs +O~KpgRt|-gB?_a!*1>6+|gc*^s?>!R${1knO+%Dxu4q_juMjAY$6DAC2cu`@EU|Z1yY=n<9#fvq5%>_ +nh{C82%nEBt7-^Jaz#xH_798g?T9pm0+_^xhh@*s)M8F%zoiL|7;hwh^bg3$#~0G{gcW*LQb}bwa(7Y +ESCFAaXkrlGQ2d=zjR|W+cabnrZO&KWI&7XpSL8oCJNJ*zgwg{ +giK0U6{yF9#?a}Qfu$zRopJTdV%m_)Da8=zs-ndJ<=a%|wlj_|u=EDX81`=aAg^;^r5R%nmYC=yGLkg +iZZyJR<-HP@!mpyX;yr^WQ7P-X43SHuX43GCkCZ9^&!cy6ZfoM4L`(E1b$!!a)EX%M@zo#{P=^Y++`! +5EALD>+?L`y8MHcnOR*2Z;)OmDll-5M)muSRJ{bH?lhkSY}OA@5~_uGg@F&OsA8(A-2F_A!A(FX{nNI(>G8U%g4MK>rD6zdIuQUGBa@+(0XNxh(%BA*6*X7{|$cFTRB0KmMJaBsV +YKng&x4o)f?D_A{y{}BaU#`coyJ#}$1OwDbz_S26_+*eGb8YdfyW~Vi;%&Get>S@;GQ-kfkPsdQ=3r2 ++llB99KGje+D#?Lc3(63Wu9G-vq?tLxxiPuRc2e&ZATabew1}(HOy|+$B%T%PWMv*3l0d`ER3S>f+C0 +D~J>*5Z@>* +N_#%r?@!^STH%u?=uY~xmg%J)mLHC9AW)X0*Zhe57DX!oX_O3M-E&`xke*0X2@RCy3m`|6JMp>`If7V +`IHWjs6^LKPMt{wQ%)dFy7T&0Sw*5#Pb{uKW}~5NKO(${V_%wDb?*h=?BLtxKGrWV=6xA?#)?s<&vbWo1@2v;-7o6jQ6&9+ar!OjpQfv-WSNXT{ZBicK-qUu ++xNOJi;JZ2+?^n+?YN6dmr&a~J}wLfp{C1I10}T7{EK;%mrd0UNAkPKEf)TrgZS9_1!mw|$$ +aNT(8=++7J&#pen!+|hJ;hd=x5zv&YlR(Y$OzPm$*m?Zr&5lW}ecOKG5Jri +IOT$D2TGwhg!>&=Qj1X8(TSo_dNF;PLKQE5F0Km_-sC;WmC%e77oBaw)g19Dc}xy+I +B^lA<2KYi$GWGMq2KL>IXJF1N}-J^pBeoPTEDVYe$S;F{gV!T`WD2aW1M#l+xuzH%G|2o9KE0~qTc!C +QJ9u1Z&%?bJj5{$Pme3thP5wl;XOg4SoWr+r6;qxfJtY@^0}i^j_$D=AKft5!f^Sj!?xccFt)3qbnfd +O8W0-4B~nf1EM_CId+2QbZSXI3_!Pe`)G!bI(>vd1@*7&3i;Tw;co^v8cQ4o?+lgyEyI4BU79JS-idL{qu)?CI%U3O&snm`*45EV_Q7jOQ4`t9jO>ByJS3h=hgeOifRxb^#Lt; +bo#&yMqdc^GC1C#F7n>D;)c3Gb?J97+NYfyNS+5{-3ey3lm1V(qSZv?hW%6q`^~9a-|Dj%50mr5cSV( +%vaQ5N#tLNghGHid-dcj423JHLHI(ZWDcs;;Tq~!JEE|BR`=>fKBsDVuUr5&i?^WO9KQH000080P~d= +M}9?s1w^I*002$_02=@R0B~t=FJE?LZe(wAFJx(RbZlv2FLyICE@gOS?7e?{RK>Y4e)d;#l5BDoNHF} +45G)$h=n_j@f(v9rRDz2!yF>`+EynFim4D8-kxm5(K;x22mL{S4;#ey +2!RA)U@qQqo@kn??>IcGNk_1^pWeE)d=dHJyCoSAuM=9!u2dFFX$o|)9#{xE0ZIL-<`P2;%zoc_{PL##DUW+D>y1nIo0hzB>1~1UuP<8Hbl=@gcmAO0dw1S@?|ov?zuZ;SB;8x|{dcT%!F_A)x ++*s}yVxjWU(VX!pAMSOr+#-7|DW?;!kZ30b^f31{j2js?EU2VU%~tA*q@vqV6c|+|HbzSo8z8=z`q-Cm%+mUzlhNb_-*Dm8)stasW%K|{<9e@xN1svViLb#$u4-D}^gZ}yZG|>-x5E46HgKe9%7~jIeLKb61zad1O$ZH$*9GQ5icc$WL((oiL +7W)apTluMF5m!G2zW88#0NR8Tg?JUJ3u-ks~TcZaO+7cP})vwA4L6G@eIk$JSWWwdmLU(vWG)M=QJ&# +f$#|+L3*j_T8`6Wz4R_k)8tnRgC?zjL$qp!oNv&^Opfcqf=LbUcWU9PA+K=2);;XzyvwL;=Q#OQJ0Lj +e1&ktDE?zQ|WVqTyJbXzsTvvtN^j=oMo@Ov2kahT|SpJk&NcjEEL1bte^1(iLyED9y=QAHXIN?A#az{-PBKx)vHE@$_^aM) +9PNI$0ZwTyb#<=?mKG!_DuU-c6eMlDNf_e3bM-nF)|9+yP(;tB>-~>x!qJK&8NW=juo5OVt+EYx7}6{ +j`Hs)DIQC1~`&FXT&uqJQ4|Phc+qFNiV$}qdg}}JpDl%)L0L|kLoyJ)pRNdM!-gXb#{r=TO#$8oW9@e +90&qAKvmQAs-R7NdMQ-Iitn5h89Wx)1Lb?^`SYw_!j<#2RV&oIM&fwkFeEg(#)z5KuK4=TRg2>3!=fT +k6!G-cuVzE*BYj#yJ`A~h85cAMO;8_D3-8qmmN4=R4M=vaU>*V_GbB?L>C|bB(bm|V>vS5;3UZKRGNV +Pep5B{mJ&AHkC&yQnw&G(PR?Nd_IW@musVttX70kg(j)g0W9p2zNcy00qvud@1*$@rI+U3o~j&+g^3R +TU{NZ=jT)UnXi*6qdZ$WEmkS6|O^ih52Sat8Vt+-E~TMwP34kT}QhrA;m**nCASo<+*$0$6ZBd)EtzY +iK`=Ox#+We;l(t3)!H|uk^$KeNRs;Wr_c$C-&=!Yw4f##3d~8em&6?`14pd7q2W{iF21$Pz`kfa3SWH +?e+WpFo=Fl1f;YA2c*Ggejva~_%4({016ljVheX+_d=tJbSUUAFXFA~--UX)z}+lZj4j{Jis?Ith(NS +MXXnE(Aj_cNNrgM==3d+bK(#Q)>dbHz4{}1-$2CH4Pm`0=#fd@QOHbrrw}Mcz1K5!E9wURdosrN067) +-~j_ptfkZZl%$v4V3Os|(Nbw(QH`O^d32{$L~hS8Rp?!_=-07kh7a?`waR5b>55#Q2ELK4UhNp|XvX=skni~({I|z|7HIqj$;OuHt>T;5D +*iA|3It`i(l(ORl#@=!kS|0up*5n+hCvUlu>kB%@w4BWq?JZ}s#moh+LrtetGx;Lb=g+Wgg_y0rHXQ0 +dk5y!FC4)YHkPjrzBb}8phIK}q$6co}&oP##_Y96gqtYf}ruzEuUVJx}KZY-H0<<0bULPF>`Bpf`Fv>dX8F`qvyUc>w7Q!t072R6|C0rvH#Bup`kh%`nf+TN4w$=YK55TYI4P;e7XbT;~YFV`dtKxs1E>yWM>l +&%x@pUNR-dlzmHP?IGo6M$eBxTXE_TYr`iScZ)3SjDx#iralzrRr_UQeWN1?%o8Z-*FdsO4wbbvxutV +|m#yvO-Ycz`q^j`WHWR2lm+a{_Nu6Eg8(pu7W910&D&H9DlKL9U9U=%611#`T6g8^b^l76Y@C*dKx*7#x8{npO8 +=#2iA*i(;BX#K*&5CBK!U=d;W4FKHDZ@uN1BtX*IM$0BPbN +d7&=RtR0a%tuD#lbTZW>x#Gms1so?%2;iHpm;n_cUodXLD$ +VaG4JVZ5WAZ60e7nvy-AwmS;<)lm@t+WwuYDJ@(cKWGWNL5gfT}$U+}h=v34*=^vPaYHvu#GA;DcR4i&(L5?bV7=sW&|J4YxJoNn;Ol76halir +^viTnX!NWTFfZ`=ysha?0TsHJi!AeHvQlXDNFcxW6*VnwX1VZ&nMvCy3;h6eB0Y`IyvB3<4MkRhgDlG +R5iR0+?kOhg6UV|mo3@JP)d|i6}T985Vxt@*p`TTMP*33zT^hzirIF)X^6eyNq`g5iP0R>n|Otk3%_BTVTjVE-3DI|W(sNA|+0U(K(j|AGMY-^ZYs0FtSq(<9>fI}aePO%e9(05>td5kP2#nBtn`^otxaS7NklU9S;Am*iV +xFLu1<%$@>{)1#YUw=g#9^PU(BY&Ye-;xhnTR-MZrdF|s+%yExGp<#|3DJZDKJD;nRu8QXFVt4V!V8C +2(E{?w740m> +ZMAxuXiQXyE8cKMLzJUTd7?#bV9seDco?X^L$s+vl5gKa>JjsR@jEBv83f3V7K2WkgvjC>^Wq^c0?9y +K%W>BrRpnBdy}3KbbZVkN1vLWfrf?O&q&Kj%8u1ZJPBc}V!tixA=0u0x$sO41))&2g7+v6|+anv*3T! +PIei^AKt7ON0Q*)zIIxQf}_&#Az=8X>WBNb-lkKi$n*(fQqV_B!(Zcl7ni_eoS^9+h`^+muG0>3LxI3 +kJ_N@dQbqaN*SRK$Vp9HWAY?Rj$Q5onLF}z^^AIOaCpAgUlWaFZ^KRCFvOWEw<3i{%4UMw +=#7oG5&7gJTnCP6m;A&Ply-dKq243V6KSrpf_97B5i9ruajzpUt<4{k+q+N)j{*;a>m9;A4^MJ$8vx0_&$>XJf-)m$3VV1jE)cBI#f{}sv>fnPW +1kW2O3|*p7Kj!&(RB`RQFGI+dk8*(?hk}*(ut+hoQPmZ{{*E>jG%k|l +kY0*O0yG>s~9;63p5{V^nR%<)D=@ea*#xwCFcnmDIn}oLKSnbx(QHj5_u0OFGgAGX{B}<}~gVA#~s3| +=8F{~4`D`H`_mO`!fv)L6GV2;jlK(>^wL#MN+n +~GDx%+W76h>vEgWO^ti1H#o7{&D)(Lxp%vWl@*tB6H{wgkjaJpC5W(5lrS5P&AVNR!Xok+h%`&#zAbV;FZT=qj5_{FlQ{NCUd($6n<-_+s|v9TbVBygoD#Y}@~}y?$-`#pudMx6qy0XE*`^r^>eqYWKXQy-c-wkGFZk +uRG?-BH>F3$$N`C^MIdQdepvo?bbA9x4z}`oa^!;m4hn#x_F2`jt(s!_de@j!xlB&sQpL(ectO~htGT +_x{=Wt474Sg6J`XQ7n*Ys+r{qxLHWX%;vYQ7{}Z*DGB?G|%c5rF(>5FPW;-Ii2y={)Vi!A6;)z5~Vj= +$Dps1Lcazs2NE%I%kruq%==R&HRt`4_}81Lj&byhd`Z^a(up^$)^>pg~!!vWU~rA0SO>@8y_qKOdY#!vkms6a;X!^;J}npC|)0Hy>I^Kbm7e@$_zlqRX!}BC@CtBZ4 +M+B{taADQ0@w;&MTzGGfXmIj9K!zr;opLXF+8Be(#wDnW3(MmPM|u;#;5hoRCjJ=!OmaYgGLX4!4R1;`2nfO!D +B9$^Alw!V4^L?*%uW-$kp8rvC}imNyItAGMBnFLicT%FCCq;nUh1g%~=7fYz$^+X<9eV-b%`jj$Eqth +-(umvYBUj=jh3s|md+lkSN-7H6oP!Bxw@Rx3G^Jl@~RRB>05PotnnzRvX2&V;dR{nHa^wSJt%|tzf2T +}peNir+fK=y^LXIdb`<~LV6BdcPxaW==bRG?)Aj6loE(5}L|XeJWbh;(7?bM-Y%ZyjC-b#I(V-Yhv3J +!6xjj%Ad9NNQbb=fJ?OSF`2LB4D#N=$28|w4BUu9xq26Ub-p=<(R#-T89S^kjjxFubyQj2WvUZRnsb1 +g@vtm*tM;iRuYAVvV!Jiv+R1__EC9jcr5Zve)BjZ4?{BdTfjl>-I<>Q7U|JiXeg=xN?pHFmsINdR12< +3$@7auTsxAJcZ#KQvPqmFCpU_h&~3J~w7cAffe_4w?1!K4;egf1~ +T5(Dp7whwtC|C*1T3bqQ^gAuQ~R$jMsa$3H_eVyjGxgth^k%xI2yYqhvYriJ2_GR+n*1^Yk1l! +$TOz(b)*AT*w2*yW1`jBrJ8e&rPoJ=&^1%k#gkDY(N9%eRV;Q5A?C**yv;jCYw2RdN4C!J&4Iqq?0Gfoq3pS;zrSnQ^U +%}(mO3_BC#T2Ob+1YCnyzR4=!@^Uh2D^?GG3WQAJ=BXtql80%iqQ+ewXG*<@AbDw}v^(`2RE!3?gTBh +Zagoezq19%oB+Ae^jBac>wxE1<{4q>2!J4W%D)blAG5yii<0IO0Zisro7Gc4b#tEY#bY|0+!-3n +MEwL?MUU)=IrsY?ScAw7ADp`18z_z>|P&zh(%YaKfzUzUiEvyxwHW15t7TKmG!?|F>z_&alt4Gvg*vY +ohkAxP8tUl&|jW{f^-o#d5=0N4Tu6k&pK}p)S#@kyUvN@TkmF)15|fqHLpxlR!^31aik_Fnu8P_r>$m +OAYt8-pOIE0K&U_fp}zAt>srG#Rw +ax}=W$ja&Ui|QV%m*EO1Kw4fKtMU7pZYT48!GQdXfurB&pAAVTQI>pWAT3Fa#>6(deaD;qcWAt#-b#f +_{|HG&HY3Z8~rX%y_<_nf_T{F!Eh6`x%RnS{Zh&RpPy08HJ%~opS{ +Xm6s#u@p$7dao@Ch5w`LdSi;CI4txma4*-dJ5Tc3t7)Q%dBh~&*=1MoFOB_4>;uHu$ +W7hS}kum?Q>}j1=N??Nfob$D=_Tg2i(?1T@J(0hwG?PJ49B%L`IdGlk&M?adr4c;Qke4$+rA({L6%&>beGACxb*i(>|=jmn{qIxh7 +2msqN&-Vt$P>)1Zn{vYZF#+0F@Mon0Ot7F|%r9Qo|9Xmx$L;i~YQ4dIo~I!F#+EI(l7q{9Idwqg-aZ~ +ZREy?|qkfi)0N_pJFbnm)K52b~#%Vy%MKt%t+L0A#;*rnD7bFT|^AFddP6Mf3 +kgjQ;;7Y8|ALMQg_^w57i39Dp$iD)2-PacLw=To&WV+W_Z$8L#AUOQafmggB6XbbcS^Lp^n-aEu#le> +{mrV;=sT?m%%?F~rN**rW{I)aVUcD+N7c)TIWBP(7Bt7yeW~NSF9&2 +Su}PW;&D7(5vPs^VLj0y$_QvUK98kK*pfd%eA!94h{2#^_I!=VV?EU8JNgS(=jv$OVO@NtLdQiIC`Mb +HYkWL!YxMkCg{5HY)PhD&4fWg<1kh4Ua(T>RID^GZ4P$b!)Ql6Zdt&M%(G8GXxEeYcm^MPEDJ^{_awL +f9T?AYuNB0=7xxU(>AUoZ_@_sqVPJNWT?wXOs0Z(E$F!7rP +ZLx{rn7$2GiuOhfno|1Bla3e5m6OU_*D}L(M*bP2Gu)xThC+*Q+BAX0Krd-LyJV4e9kIOBDdV3)V!lCz60W=`Q(;0N=XQl-}Tak!N^EZD~ni0DGvhMI>lW>8}sa8+l2<5#bCyO7l<$rF^s4Tov1i{Euewc&}F0orcu9wyf*ib_hCmQRlXsfeIGIs{)QQporztmDr(-vo-{@f;~_`YB1)be +PgFC1W=lX&<~|*Ewb!R9wqY&(5}2=k^zhLgfKCjm1w5emVsvi-F-9ky)1?8rtKiO@R)#GkN%|^g +?PlGzG>{Lh0pkAgVzw||9~uy^_vw&Y+2K+B17lGb1j8pe%$$4*_G8~HwQ5R+n&qR%{*I(O05v@qLBZR +(ifv|ZMP&=?!S%3zLl{hfZrp_3`11isWebRHNt9$&#ZU?G0bzhuv-ME39-5Tzru-?A3+&h +XP-Ck&3O0*6b?Z`DeZ@V3i0a1s=9=jef(%Hb01PAr$c^OdF{IkVxr>kJz;__ot}{af>oCN|v2%%XG7q +i4$Mn2(g9yFtJU0DkS=KqbC+y@~_(ZeT789MS`&EWn2JUAY1wI8ugeu?yJ%WPJq!a$>GrahQGJqEYcq +4Cl##w-a`jBt517x7emIwqpzaA9}6~{HCRLs7 +hyRl1V{2SU|>jFuy8r3S(l*~FX}vxBSU7K2Fkqa1JI_7t(c*2*@~GCfH7M6K}yym>^=Y(JchoZ_0=fV +efxVpbaMyr;r~WYk=0B_?57At{|6{PsG$31eU;KRlpoq +z;>)j^Gy8VLU^zwqkfe3V~ZcFY&?cOV&TXDN1!dgB`m2*bEAp_!$3B1ex=bqO-20k)W +CaDq-)PrJ+==p0+*~I~=ka>wWh+$UIw!QP1wc@DZkoro$3Y3o)FaC0>0THhb~q>o532KLikuJmFbo?{81KjVRH>jKVK+qi3N#sb58^2KvzwgxaQaPoCGSL>tqr1FXO)FQ- +`QyNTD--QG>U^Q>U6+U_e1j1I&4ir>}O5O}wj+_bfLIEZ3*LtZtwOS{=95?}y2M{fvpFUfjS`OT;?Zq +ZT+^^GdKM6RBOh5;a!A~d8)g9bc)#AUz{kWXbuNBN?`ikqc2xgEbE^tOV?2FsC+xTJhnw-2?jfJ4e8l2uhzWnFvHQpuAa_hv +pac*1Y#iqc@}vE80F`Uy3Utlk#K}JT=~ue3a+G)+FkTsH<0+TaIH0nOxCtZD&TS`)YW>dRK`>P6!(b6 +K^qhXWydfVfww`~c)pi*^QTJzy-pvkN?RT9MC%8^a1@wgxu$4NPdJl5}0paILZnS`zp-Gd&9$eCjdrs +mx6|f`}iFy^ON2}wRhhjdAUYRSldAe59yD5`+dfE%sF_6bwOJ|!<6ypqKBc6O!a7M}-dfQjd*M!F+GB +vYZbHmRnp96d@AHnDFNrq2Dtd=x57=MM1;~ui)D3|QgSZ5^hp8y6TDicH$=mrjY@?Wv=Qag?_mhe_v@d05Ngb2MdDP1J~23 +=S3~bU=@xV8mujju_3yRL<4>Bz@yaUelMbN`JAy3b<(^?BPpQJf&_Cdi8NLAmCi17y%Sf6{uk8gCB1N +t~(M~U8-)>i*l#5=Y)0XNylj)O6ZflX4A2iq2E~AfBa@>rAK +yXM+GojXw8or%Z$AbajM_(DNZh5-8^5!8i%jhQ+JvC+`bFW^J@~*>m0`f&?l^r?odvtL>j3G3ndMz}g +Isk1Td9GZh&WAx$RIV81lLcCZ~U#;d@nz^ARi2HFi9vcN7!)>bpZ)*F +Do(~J$I=pD_=KH%kr$jjM`mo-mMik%ynPdg64H}JYUoyd6I!Fatj8|X`vG5c+d*%@G97|#^|Xrr=Z%kXG+f7r1;@d3d=-k45rsPBD&7(6a*qn=R!u@6& +(3p~;Z79?>@IJaGley{KouSh|x(o_!*e}d5c@XzKtLzU-%Y5|uOv6vF)JLzZ +Fq&}c>TauFc&XvtU!#7~$t*I(^Aw7xLBz=R%xIdaqtNu8E#Rf7Ikf1r6BfU}1(M@;QPtfg#yVF|vVcPR7@$s7PwtHu15 +W-VKMq0^E}GCOLt_9YoMb*8JKPs(5kkHa`=x^w8l3g&*sqOAbG2oNgwID`kQfb7%)lBu`djg2&`whj{ +@PhusWJ{$mOq!8*xfe1Z_i)}Y|298K`Ql9hmxF#jnoW#v5P@{2~YHK&HTX{}`b +P_^@ZG!bDWc^Jpadx?4pp9E1P>`}@e5u+AG?CLN|Mx_}cA=n;_wn)>AdB~rfzITLV;YqlIcAn4W*GUz +UPd|na&*`gT|X7iE6L^AV5LQ@kQ&TRJcQFK5K$ZE_BhN2m6*exa}GT|OD_cQPZ7{WB%lev(_)@=AOi^~&#Y!O5>5 +w$K>?AL_$gY!48Ndlm8%nGxZi)AmYmOjj2pv=AWoaf9|$2lN-N)Wl1r={W~*}LC?ouCnS5Bzh_Lyd +SDt_uVn`pe8_SN%WE-Xxh1*$4aceL1zz@hwg0V!+mFSE9z{CpAMIS)hH0H3Lyz%7HHH*7txa$RH3ti32A9^;_oX%z&A}@bCY`{m&MzDAWa@8XFoJH6kKx>4Jx +mIu(S5|a+f_BUz)1x%Ok&EP;Uucd +lrWwgC^~O=cRK>y#~{hL4@OC{XHV#|il2~d8#v*Mr^ClPu(Ly{Y +==r~*SAvQD>_fI8X<~;OMxR*l(eExbj4nDk^C1mUq2TkP6capBG|^XtW(ok8|{Po^$ +1Fa0(Ntib(D`b;acZ1pRFt8O%97xOx*buMYf+!5DO|U#aCX%bbMu2aPCL(C`SAPED4uz0+W4i!*SjjN +jcidAM1O+Lff@C4J}Ua|MmpepIBJJT9a2eJWZ#vZ)Wna?$;78A37>!IwOg%u+?X6l3l)o +M~yzw%OXtr*ihQxm#O@%u!Jhfu4*$9U*oLBK2hBG +0I`m?rSO_0}))+<}qfMkINF2lg8J65n&lLlkstGwbE9$>N2!Kt`q`>L^lcOdzWo9oD!SF{my8}TY2=; +C?Pr7UMxNE3EM$r<7Kh?nlTML&FPs;W}o2GGo^jttO*zG6G{GAkHMerzfp3@XDTC{Q7u%S94L`*2=`X +j<%}Cjg*6EM}Nk_RoUW#eVt&b`?Q=y;9MK>wcQ}x?V!9>h#g4Aw$djiu&+!lQ=zSs--vJaiw|%H}`Jv +)q3gJTT;6ti$PVeoNk%VNryC60PTnYE6v1DPW}!Tw;cvFP0XUJU$J^sOe@0*=^6%wpKLztP3`I2_?Oh +7g;heeDF}4n1#&k;jPLz(2QEe+1=qteDI4u)TqKnx;fE^i{$KGzLf(oFzw&UWp?4aLME$50vTg$mD>DN$_wR54yA%{aVg|-Bsfg +>kc=VeJ5RqE-b>fc#Hw=P3DK+vNj=+I2gr+Op+Q~J7uXgUL9veE$O8&D&&v`QhmMOC!hwhvfM?JF^u}qKBP~^P +X@vn|fdojZvsWd2Ad?__W~Z6M9>WZdL>@ac#IIU`upk^Y)2IWR&f`9R`4oe;CrwUm%!IbhEtD*ZG(_r#(A=!84LA4GYEk|;6AK;SCSE0t^bv!pSWLq5%2qh$uc(-6SD@pcj4(L^)4T_TPx^i&Pzj1DXA6o +VR?PJF9g0%vNzt#p%qY8Z@<&i=j?M0N|^_4fs$26=(J=fow;Kca~#-5IeiLqVjg@~DZ^UWGPgW)Gg?~ +4oZxp3pdB|eg1f`@Ax-*Dxy=E?ykQ!2XcC>%w^3aD(j&3kNgwJVujvYEx)7%IvQvP6$C6Nt{IAQ3T~w +A)(%){{z;6Q{M~jd2DGevu8 +-|sJWZZLDcQ5T0vy_H+Iz5_0&5nECK{46hpoKjry!6v0`k9c>hZ%TnBpA>kk3$+e=y7oFOb#!|I3ZeF +YP1&OamYQElGqE7Ir1lXw1|tU#aY#25xut?7klMAjV|j>S^i(Wg_eKfL$-|6uTBEoKrUmk929#}cO`e +L7NxGAc=Ce|bn5&r{H}oC6!Xvqw*Yz`LcT$}i_ngFKRxef&Z*#_M6dRZwN#l(|MDiPk$4FYeGNVdm$*Y0 +&!l3A9TCx_zBrp_HHn5jhd~mZ1Yv{>0`jT{N?Qja6+JE@GY+{9NhL63CUIu#UH!Nk#j-;#$out--zC? +5oAEiETKru3Ci=paGR#0cCcwIaB70Icw^aE*mVwvijDM5evD0JN1Ow9V=m&3LyV1o(eOx!#YqYe%UZe +2{eI4BmY6Qt3-Ez;gkyHJ+=~LeU#NB0TUt+d?Egh1>mFD7>qL%iW^DTFsuWql=q^$$d7NPA)Gakxyn8 +kHLb1jsAd7mMwT<4?-bS2=_Iu~_N(F=+6OHE5?Y<2M%hb!&JF!r;5F#8wUKCw}5J~mMrN8*p(iYXsg> +Go+%JjgaYuA{G=Vz3aiXTYOD{j;F{SCB;O~Nb7DqZvSrmcRIuzEK!h{muBcd9fy5Tk=gHut~gc9)`fEpiiiCy;=^KN$J`YY+8%;l4qC#VUhK#AUZdB9whe5N*DMBsE`$(XpW52od+NnkIB +7YyI-y@9$Pj#k?I)UrZQn;vtfW==kzc<$5-a;*s&=6bO>7;5m3riigHTflHUC5=(^h(C;$;{W!|;$M0 +$fiY^1$rZ4H2S9$;4`CSOqpxn&c0f5$2z1oDYJ=!n%JxtEE#Pwg|O+2dM;}VUvz;a*}^2rrZn58WJ%D1q6A21CQ2A~e^3F6Dv&7YJ(HQQY1+5e1Crr7x&+9qKCu +&T#Ji5XIjR**f+*HJQ2G*eXElvEWYO#{Fdu^Xfp(nG`@4*F7`*DB(75PK8b_6`l$5`+i>+YSgX{+zqM +0|YLMv~cECR#j&)hn!yG6Ri*Oca=(cUgdgQSzLOd9v9^o(}uCLlNCpfkgavbT%5cSHT<&AsBR^5!1BX +Yu$o8wjI4BQ2&C>4gAx57g*$c=S?jw2uv_jm}7|A9qaJ@FX!9Mxo=r>67PuQ1<(K#5M!J;E_+^p3&#LC9dfOtc +rt51xnb5Y$C_F262-z)Jvbe|s1^wNha83W<=6w3zr#ca%J!<>hNeel1tB-#R2%_{b=SvOPRMWTdcc;9*Cz~dS~2dsro%Icffr5TgeyDqP&Y*)D11_7WSFG)}knD5#V(c@#+?146 +lPFQFUC98}V|I*}A49z2}dYf9d|JXhQN>MgbI$mt*EOy37&}1L(B>?8`2Rva3#Oef~NW{sDS7y +PKEJuI0Ffln>{{=f|#PN8750oQG(}9(I1rLA!37at!0t0u?zAXwMUyt2ru++(j>=3QRjP`~1!mD9Ro^pC +GIFLFLOo<0Yk^#e9g!8x-yCTI!(+qr`l`f-d&QTY0=KY}FC|3QEI(ccK<9ckuClpL{ix`sFKuB7nbSZmsx{Jwd=Z{wGY76V@g>X +wjBKT5;&r@58tjha-^uFuW`A{SL%&@KFrE8Am!Y+A}+TH2 +?nFL9sNbfc9@b&xPK3dYEl6!2UB-XFYX|(c!>hnQ>QyR#+zW3CZwl{|@IDFeK6v- +RyC2^D@J_-z3GX3z4~4C`HpW@{EXh=FXxQjO@OuY-6k|O6s?}YwhY`ck-+Jqf7{Kv@9)a#i!G^_ahQg +c6hm0{O9vOq&^QU(YLA^`XV!ea!Lr)Lg!`hn~lQa65l;D_n?_pztzz^R6-)-=F27Vn?mKjId7hB}dS? +`@v%~aX; +7u_f;$h3sVe`ZHO8~tST>*ZYSIJ>!C{^G|o%M{T}G*dCWzREo4VWwmo+Nz?Z*E11x0#+Vkva&tFI4-} +)Up5W6j+XRL&bZnEuF2wgdhh|=E!0NIAB#w#c?K|Q6vWKrElD9j4O{Pe-!v5Asw!-iHI!fu&V{tLtjv +AJzN7>Lhf60K*ohPR|UajV{mV@M_-kpoBoCCx#g^3_A)ShCnU5 +bq$KM{K{M!L^n@78RDa#;}sC|xq3-x9cD+qGJSMC?%$C3Dz>%6juk(N3gxa>K*9U?5N?g^WbU$6>%{5 +umbIKXnZAb6>(;X4az*s+XV`H$`ur=nnq#LkUrikwEJJ@>xpS?L*0U>GM;*{%OBM$JdTI=FOTDoxp8z +2SRZy#ViA-}vd$nkBMq>N%&i>f`vFwRAhs5@ev9g6anDqPD1dUhkPxgE1o)2-K2UHmnRkm1_ExfYD9{ +t#n6Af>1JpJ_3FW@0Lm@omjqV9^=^!ZdZCzKW+_dyV=0*M-tUnF>fYr1l+OiJn0-+UoX1grWiZh!lrBVlTHIlGw&L +f@<@#SiQOcg!26k?VPJ6Vcb~_*jBz&&7k4A26}V2<^l7U`&*K><5%otc!M+3R9;moiE3ij(e- +2ndyFYC>brO-3K=cDXtK{s9q21?bRl|5JYZGU+so^yunl>prTKFx@@@DEOQ$;W+PZ``AOKEyz6v;{EA +bR}K`~u_#nWTGP|Q7DrHa%O{x7dSHfjmX)WBqy3(wCNo{y-|Wj!4&^B|G0bWMTMOp9H~4WHp3k?1tzH +eNRjoaX6~J9)Xe#|kAhB}g1_i!VZ_3yyvtk5XqSi|pY=j<8Y*1>N3Au4zx(bN}kMrq-B_l?pSm>%gE$O5G*wY+Lk*7JtU(nZw+D5})|C@;ft7DBf +TGe5QTA*nBa!x$kyK#>uKUx3t_9*xe8;pi&OCn#Q;Lskc1%;^vDCLa&)T4WX4{5TXv!1Q$Dr^pw_LdS +)+Du{dmub~2#Am>i+mS?cPdqAH%uS@G5TuvWiCg=%v2HfD1F{CO`q4SBCZu>26AFK-0l8Qa-xaUCCI< +pY^46+T_kULF62vj6IP@Z!j#e$2hyJkWA$Rd8%Z1%SAD#g3aA}~eBNn5j{kt|u{XjJT;$q?;UDNCt9B +52O-SW-B-y}k6D8xj(F0&+w%2&_VsFzxMghcN9Ejd5)n?Qx8o(}=&Z8xfy^akbie7fej0fNba`WM_3I +?w%C2p3`&H(w}24dhPzS2cuQKs|Qy>=<^Vl-l`rOJWqW%v&L=5(wo95Gn&W46sPv3&H111Gn^4GxVG9 +6W!HR|X$DrAy3ZNyJic@b}>u%iQ-W&V)_%io4H%=)0_w8sP!p!H8Uj(h9Kv)ZM| +YKu$KmgAaa=|n$G_N59n^Fa>X26)=)fDY7 +XoBwno!n$+yjad8$RBTfj{oLCmLgEU_jGsCA`G4IZKMv9=P@VMuIiCP(J55_szl1ncxD`FyQVrhmq{aU}>D&>n +ba-^n!KC?HqxaZxgZ{dJ4h{q1mBc)NvP(L8=HppQOQwW$IkaK%@g<0b!5iTX=!9)&#{%p4o3X!pf|^Lk`O4G^ +vn$iK|wKOrC+vcK{i6I{BjHOJScqqfy~;e;Q9w-XdCVmQ-|p#1lMd%!KY|r-HE{2dS|Ky^TucO~cC*I +L|>P^x@~yElC75DneNJW +uq%ZT1k{&Cj-PItDxWcLvCC&HQvOc7EVd!WUP`VWpzl4KmJ9#-tRWW$7TDb|i1+ir_1cZrO*v#tyIC{ +gBxe^6M3#A}7&p#xNtUdPn3iE2OdMEbcl$^mL0<$hSAGB_4`>W_Q-(TU{to*i1zSp?Q#v@U#!gvwG2K76!)MFO`ymDG&Ja#ps0*P>(49H#1eIG_< +)cYZ!Rr5nhoNxedJ=lnjwgrYkEfBo=&&vNafZddmz`lWlh+0o6mOM&iEtATE)l&-O=7!L#kC(Duh{j$5QWhBxPxGhku6g0}!K?3uTGqaYk +OC_LX%^giI(BQPNl#zO9iWC_o=@otC@@=!hzSqm3+63dEy2H-i__z5>BJs% +PuUJ8s+A*a#fu0H;Q#FX9Hqo%h|PJVawT#Lg+7iszK;hp6Em{*IH@(A|n!HzCMPD +r}dJRi+$sD*rkj0{TwYaxVx?s8P0|Ck${EM<=*5jL*!8BMaWzl;DBpaVMa2*3y};PsY5+c_)#fd(mO=N$BtV +s~B=_KY*)XP3-&S@G^#=)cLJMFHMhOQJ&Cv$%H)_@he&VWoaUMPjM2Z}E_BOdEf6DjY)Y_tHrDX%w!wav3RIGq+gGD%!t%8>bNED$LccER1MkZk!mZ+=Pn?EO(J;ZzLfkC!9ff{Zq*p>7c}XTe`bh(Qdt;vQZmk5r +a`=A))O9TuB%vi<87Zl*lq)luKr!fD5xf;>GT_Rvu&borZn^&t`j^2>@JxQ-ji&ma}(D-_xVmDEZ6T_ +m&J@PPDSZaQ|pa1=-7DIvY%QE7Du<1J^Kmu2({j>*M7xZdTokHIZX#wq7u1Cz-n5DaUyw)Pl*2hm=qo +@|e!2+Fs-mU@(nUqtgJy{(^yEj#{r)=KhM^Nz_eV#sww%Jnxn +Y@n*RZfa(zd*Ok&3V?a%8n!3X3}1OWjI(zXH(RGcXem{NlfXA?Xgf-;CkA4L +31svx`ozJmc+mvx5l%GuKP&|g?CoSM-5N{kt11MNV;aLF)Zy@6jBS +u;tg-P@12+*X^(XE$kwuU0>#|$2mk8*>59ciAyP7edlXUQ?i?9`0jOA!a7go!ef$%FbInYe%|NGvBVW +n9XT4oj!?DMn+$DHPe7fyv^Pgf;xpTfP2TYR1107A;jC(+Pu|mCuxK$*{0KZO>b(z8v52qn_3trn^EX?{OU30H<9@=Pou*Q^>b|j2o(t9~=%Jw3ep$jO@JLdf#YA7}MWRp5ys-tKZEmIm>(t7 +sl3zwXgg(dZN}b)X8_QrQ@C-_pK3rF-6LE>q2$iUITpb*vhl=z;WS(Pe)-GWMml#^dFIb6oX(makQ%2 +7&dx~zMgKNnHTh)}L}1TrO!uUpf=(~* +W^wg|P469+cBTWg;nlW`S)2nM-HA1<|C#mxmIC|86hh(tZ&a~$(VaF@S3ZnJYWPNO@m4oi+3e;v!0#y +hrfzX_SHN!_{C>05t>2-sY#FW)fRUhhl3-E!ePB1xzu+m#x3qd!TpB~){%z_Y35k>U)SH+O$Ivq7bCu|GB|jY}Qa6|=nb&$teyzV+>A$Dp!0z?ZF_@qcr3Gy*x${}BIZS`WMXe^{DKgTK{}$J{c4LyWwg*v +a<5Ht{Z-ag1i60r#CW9DQv!4ABwh@DiTKj0MtX9HRl{e#tdf`D2sV>7}<$yyzIsU!w4fDHSiD-TUfd)Dmlg>M?Wa9M)Py!K?uZoRLpphkbqUMtj3 +}Ym*eM=|ux*A7rLy}UID=s(P?SS=dnG|sF!wU>E{!!Ct<9!*~W+YggHIv}RYM0e4VLOVVExfc}tUo0a+nuP6pAfSb?e2tZ!z^&_fCeb?2EL| +$>b2_`^Vd&{7`dKk#%*tMDpAyEJ4ZvG97DqQ-0iE3FVx1&}Zp3<6p=JY5@$z8qa<9VD>CG1aPiA<`Wq +2SqAg;<;eZqrh&ZBjSH(%s+jMHJ-ZxiN_Jf%{Yn>c00zrTc}ITuNDCj?twMw$WLT`&4coCnXS1ao9gj{f*Im`_a96bsYvVYs=`W;D&r;Hd{XI(`Ll*PR +!?*~mV{j&hx~o&z?!vfO2@?n|yqRDv8qhP-sGEh*8y6y7jn>0%><_?Q#~eu(t6hc2FB0~RvwUdz|Jr* +KfGDf4fBdp3u3%ZBSx$;e;WEH5Gt96I0xAfKqN2GV%AhElFyqo!1p`VNHT||}X_`yfZsk&`3GSM?q?M +_an${qelp7^^|L1d`=NSeBv%bCW`+NUy51hI8x$8OSp1Yp=+MzmV{6=duC#PiiqTt;EMBoZWW2Y( +NsyZ(51B+wM7AVZ8~;KKQegrMuipS&B;?%KCz`{vxDQ*SjkuS;g1~uQFjyWc@0WWwbpjgniRpE<)XA3vz8jP+|s~n!-h>9+JfeN^D8T;Le8I$Wc|v-R4&0*mM}~{c0<(6<5*pKUam!gb|PbU!u+Bj +M6Qnkmga675YYHd{wEdk)#Q?BlglWZAkuK;KS$wd89reF^c~BmU +l(q|d7N5&|}Xh@YqwBPDI|82hJB2ql^K#BS*3zk12(8`*g;$=`p!blcCw&2q3VjEF}(nbL$RfqTYq5H;u0SftTZ;&E{B$P4X(% +ib?Y%=+!nWtFb+Y*+*;bEZ{=t8K@VCSTwD5Ld4vJ40&ix5(ckQ9|BM3Axu +v=*s5$6LRq?S}qbgy16EyJ)3J1+Pt}TLT}uX&^42Lfn~JVCw*m-2M$V2u-iK+%Ri09HIfyh18H1UIa| +#KxKF>!Mx&$9D|0< +4J4)+jQ{o*4784K#jaMwxm$bn-6dp@h4&n^u|UBcI=@N$8*fWmW8?aLZR?im)V`Ed7Y^W{4991r`NOF +2NS;r4V%=2=eSEJ3>BABXsB|$jUq~}NAQJOe4R_v50$5oy7w_Z?=L2^b0_1P$NLn5b +AoN+`+Pjac9n^&;`jowG{HN-We@6V;tca1QUJ2)}*9qikQ_O!)U+DdSS6Yl=(jMXS?=63Am-nYY%qNg +}s7FYh&oVPm++nbw}TD#fe#4R4p13$a|v+X!`G?Q6r+i^XW-1pjc!*n}R(Uh1>PDmgP_-1PsFs3AV!Sp%w?y5R{W++SqCH&; +!}tiR7t~AMlfub;wm8KB`lZA5>6fOv*U>Mvmi0?e{LN}UfBt&xrr2-{zst_yxA;x*TP1#vi{C5a_muc +uCw>p(28oq#(NEf9pz9%iJLVz3J&(z6=?!`EyX8iWe(A@ixW(3Z({jjbQ=5_vc7el1@w-#}uEp +=Or|CD%_=Q)|>ZTaYk8u07Wb29>7%d})*SzVH_9v~d3i_W-b@e|YElK~QcGmyE8Ty}r;=7*4UQe`;v_ +EgWENOp0F4kL|=soVlfhq?F%1=Z4v#E~u$FEG*{%jQ59|SMoBy=jUx|hG3#OG8qRHH&VJU$v +b$}o$caXg9@~V*XNUVW5lST$y=`Q5$ueZ>RrD*=JtrM&o^UK&b5U?*173=`*Me3aIMV<+uEri1g`@fK ++6Wzbv){zk?BWm#E(i$Tir<-s%TFmfqHhU*=!c#K-uA{`MOSWO^zK#skvkX*fegIXN5OByVW(DU^$nc +QG`D!~4b1P5Esft{>@MC16#2S0g*piS3G<7=(FA*6F=oWAw_YV1P?IYfryFL~-QTA!vhL_(MR)WA7HF!{Em +_bV`3l|9N})Rv?L)~12##f(To<4<8s`#A#Om_TaU|%A#EX_Hs-A +;lmoGv|N*+6agaqA$YH3?dtVx>LxD#m+F-L|xsEGCIR(D+0OjZ +b9tl8QF6AF)=^`iM}nbG@1$g#%Kf4R`YD*#)_17jOP->@kGj&CXX!taa +N-O!-RPc%>1BI5Tky}|Yw_f%W-bbpWTne|MLQx^C6>B0uVXevH_nJ`rxKHX)(Q>T|nSK?G*1B3+Pg0F +YE17>lB!5ay-nJDTwV!A({kDp6h7iTI&8@x_4@jNTB$d=F4YWTglnt=+5khbA4c~w`wyhY4*_Is>b>V +>25+a!WiK|NSLfg|zvbtNl*hDTB?Ix+Ev~4>E+Pl|H{cPb@(Xd%3+m?xr>E!Gbn-Kh34YAS!uNHN%zk +UBN(n5UkJW;T-effsfg0liWk)6Ht3g>QH5nx2|$^3N{JqzcHj4L`zHCm#Gi&9kR5)n7bnjXBcnSnAvm +WO46Zedx{mAWh|+=|vnsCruW^}uZGRqS%L +-r=s)=sKpDIa6g_Pwyor*86!Avk)92xNotEbtT9oNL?c9dT?xeQgP|@5z>M}-XQ7o>`HO6v!o*ND*L` +sVMt4E4U(^Tz#cN|1BG^G@y0F^>)nZyu2gs?PP$s*mN@Aezo$Lc=o^=`ZxmQMvf^I*EAt#H6mQQ{R)! +o$r`X~>#Q{FXPiBrZwh%ZZ+Hg0s?dLkDOG~RY+QJYux2TodChqt9#Nr)e@r-Ezi^ArOXr@_lk6l%RMY +nn4j1A`l#pRV2AA55NL;KG*r}d{=OD^r~cAFIDQ%4wk4p}QczxC7hYf+wr^QSgp>*~O-rL@CAf(l;Wb`@S$5UCAQZpQ-ea>>fNL#tQyIA_BTi;y1 +2^Z^DuiNk`_(?*8GBG~oeA{2WU%)qa+;u(4XW~Rq(Fsh5KPNtFKQ*bDy~R`Vt$<>8A9N$l?3PzL!Z^h-Nibxa5ha^^@L$A5(+#SNt_UF_ua}0kCM +@+D%@~jr@5Mn7zH=$6tlLOKc;!2L^sm3+?Oa3Qn=exQD~cW+-5yZ=?5_SBT3yX7nxZj#C8W0e()%nbxx9mLxpELl$}w^Yc~WZ$qpSoxa#h__^2GubG`&$&NQ?CYd)|~^SV?zC=qu*cu|CW+xEh< +`DOOT7M;A)Jk2ZLg&@KkKPvpF@ngbI0)EEgCue>MhB5uDhl@Y6=xp0*K5Ox+aHHk~@#n{Q_p@FrJnLm +?Z`&Stvh0GZ#j~XC{22FGYgOTCH%p_rZ6o?we;YY`hwb?FlZ89H{f-8f4z?XFJPSXUh*;}yWfh1+DY^ +HzRy|Ta6s&B@?@>{0U4>7c152?myin+W=Q%1WRa_t4-yX+ATZ~M6?s4kvpa3Q#nSO`9tXw +Oit&y$XkcCq*;+ApD>AffUVU&vUS$?NCQ=kOW9IVSEhY-|7F3GszXiKl)46Sq52F>0=|I=sBv`P(C`M +aEa!cP7yio{;&%M_*6ZdYbM|9H(#>D|)#mNg$rG{aF4OD*EtS}a@ +^U&9?Io^~&bxP!7HKB+=2uIm|A>*I-TW%3PlV}dZi&EG`?I|LD)0NvYc4*2%J(#0_7dO5ZpHvPagry$M_ndvvmPsirW%*9+Fvbp+%vGW7 +zz||kkdp=evr#OF5)=DXyV1prupv1%en5h9Tl#&-MGOG0gitwv=Tr~y9BvUZo4!1UVvB +bSXS8SCUZ}g=5!Fiu3F3x?XC8bq!q>Gl$!p^bcdw62rCoMMs^;9lIYpKPGReWxn@pTa)CHz1vpfLPom +oQ*V%!UCP3On?`##yK;Ov}&{VsD`RdlWG`dGn!*9v<|J*7K_5{HR(?Thx87UOcui?#u+15X-1 +vED=J&hNJ^t?<{j)7;af^Fk{6e}IX=Bo{=_djM?x$|C9#v=AdK-E9l-owV0Rcb5v){Gru@C%McY>Nz- +Jko}^#McYRTXrb9#bhUnT72208XkQ?yNw(dhOYtf$L$h|I@JxQ$g~k?hMWgvIO8rW9BZ2|cuVfFSekF +Sh`jy561JTtap{q$Ir|dN9YO=GatI3{9T}}4v9P*fe?k5}F&op#D`8o49q7>(gPr75RtBUtoVr)msF5 +vw2HqQCwH=aM$dw#xmto2gi883@34H?T_EiG*Kmb95a)qQ@xdyMrmz9De4G{I30efq{&uMZ!SJbK4Rm +;w78_S-+mwp|Hu@7y*bK$*Q(68)@~N0dYL>U1C9p!spWo_-Y1%dPCbea*^7ls9e4n8UTP;(7%un>A-S +dlikxPKBxN_Ul>rQrOdeNtn&;KM2#?{;e=u+rJd1kNpr#t$nX}RoP30>1+Q$nBDB_gxTG`R+wu03Sny +Oi-p}NL%GtNF*mi0uc3b)jfWgcV9)`v +=0h7}mFhbt$YXg>?n2&kO5nSmy~V_Ho$fWI7HOn40N07GSclLLX)yE3D{p?L&q2fT*wv$~aTN9wIz&) +Pdb!SaFn>y^FA(g7rROJq@e3u;PqiyN9sag~9?mHa1=q^b4yvbl{w@Rtoxs^@^ZhSgQp6!YZ!S`#@Mx ++wE@&D~>v~uM}2%6l;GzLq-|58`(>Q2R`Am&lc9!u;vM?53Cb~6-&$Z(ZZ^Nb+EAd!rE6@yTKYFthj; +B?k}urSi1@{f%S9qSV`?3tZW&=~Wb_b6Ry0nq&zvl-?sYeMjFMd@NiHoN18^&KgUeA_7$L+ogGh!MH`SLID1$CwIhS>c$n4D)vN>@c*FRXIS)yev3QIjpqOagg&nv;BuUOtp5+_aKd@~$%<||z|jJj+K($Ih>F;NO2hD +cvvf9nqEf?{zDXmPx^*1z)%(CI*jIS=|#8D;jaDO5EgDm6Qm|#MULEAjy8{198aZ +6+141u|-#nm~TFZgTLad13$HQO?7Jk#gfq|(K*AneZHYv=y=wQ}wzHo6H=@$#v9XA_Wjc_HAJpiWJ9=Od7Fp0k9KY&c~6RT9IV(T +62hg^u@Od`zYyPiP-4{W=C=4y7*6pU%!`>a5HN0R#Bkc{^w*!~0Rb!8Cyyq +a?<{}mcEN8LzXJ4(`nx*lfyWd`#93Aeo*S51WBl$G$&24Hc8}W>dmAL!v=z+;%F{>zdzMAyvbC`!JSC +h82=T39JnpB`s9_k`rPC9g&<8sn7Yh5gDaDND{CdCO`b*?7GrGPlYdy;G6=}RM^#ig^GCEzNYTo-BTjOv- +-kPm*3MjY-S&g&Z{-v>aCZD@0xN9NkJ)Y7DIyNlNw?!Fa2(*S_FH*zm5b9u6n@Y?O-waVQ$?t{Ba9P +e0oU+Iz4g{3Y#u5TA7GWtB}O1MxmKM(>G>D2Y@*i2|yoo2&nkK}QXTz4b=U6lUT!ZO#2xe7jaMxTuf! +kR0D{XD-9mnaik*xl%VB4ufss5*heBXG3pDpaB!N>!q$RX1roAsx%A+zcKZ-F)g@RI$?vgPEm?i4ZeJ +H_!dqc|VpoFEP;;@7-*lB_5c}YQ8Dr{YN&cfM=Jc=bmhA=}MS&BFqZ+xEOxOZDjavnyc&ghCO84LAKq +7)7ECVgX>7(KEr8C6Kwh7xvtm0vXza*d2zL??*VaiWt^{fv%NU|(b@!8aa}*N-J2y|KO=7gOZ9E-CfU +xo9UVztyz?_e)c=h~O;egMf&_v|1k(wgBzTEnJ;7muiv+Ic8S^2~5X2IUA;=<_O|Xz)1;Gad`w4Cm-1 +R+U9SM387zpAB#t>Kt9w&H#U?agX0y_cwfzl^15hM_dBCrq?5iBHliQr9wjRXe?z9G0m(46LBJ_KC|0 +tliA1{0(bJWB8k!RrJ&3BDotiNL*_u?Gmc5NHTY1hE9e2qqF(2yhk0a|EvtY$y1F;2gmff<`nqxc7p@ +zwgiA%G0#2CibJz#7d`{*pOFDY|Jo|!>`vzCf25#>DEY2&-3538VVD&ehfj*Hv|V6i_FfAo}O+=$ju& +a&dXygljX7TESu#rGyU~ssVsy37*lZ*n@%vE{wNq5%7(B$tOwIO+5MT8#j$9S-%vJy#jr>=kVOfX{`5 +PT+@dK&APbyv9X!%Q?=hNWa!g}twnJt89`dpyGCGAqks7M4z!nwg3qm;QjSN~G0-H5 +KL%N_!wnq(A2{l5ZkmHh}f5$A`+AV#Tuv5u!eSJcEf&HBk{LTzgQs2*Suhp)*+ynJR*8`n3|LfMdMKF +^+8DY^rce6X|A(uoH=zJhG+GZ=OhH9PxYxxujAWx#XM0CeT|Jg#hJKMG7@(!9QL2q)@zc_NW{#o7|fc +CzSLNE|q@A3xBhmr;2j3iuB>HqI|POuJFsDzYIqVDaD@T6CmrJh0N8)g{;2P@ne}!Dsr97vHvid0h_ZNTI|O#iR +QOYNLe1;10|)RlB=>LGZVE##q_Xh$cCJ_j}3?BJ~=4Y$@uwNv@rIerKs$so!sQ@mSh;iq;gpF2-Cg?= +Yc2qne5TjW>m)Ly5FGLUMI)Z^sPd%B3J61`K7aLE<#3KmkF)LOhy#!v1&OHqx3bxH*k}!{oB5okO&vMm#9ePN(y@XtB^V@`jrclf8oRsB!1|NnvK)-s*=-z@-zmK{bk}tecZsrsIgb?<6+iyO+>$44^X4yjYT=@PKmE+J&pp3*$qO$oUG~!Q6)&$`wR ++7fudaRV^*7#p>+N^ez5Cw#>o;uN^udQ8ZQio=<87s7+js2TwR_LrefvK-@ae%rhmU-A^w{TLe0lt<6 +DLo7{mr+h&z$}4-1+Z+u$Nz`xcK8wmnwh$4?XPHy+_YpYX5*hO^{Zn4>lM>Lc_vMDdWbcn$spsOrJD4BQq; +IXG(6K#X5D`^cjzi95s4O^4Ny`|21>g?EL>}`v0f%|Bv|}(K|9Kx=-JJF|qyQ;s*>&7&JI>$k1U)!$& ++K@xNjJ|0nqGLBpnIa*KFB+1+LPb53?#nd~Xs7dY9UaAWM8fsi5d=(rO +ycB#C9F)A3e5HJ5IPzBVRq|BwK{_d7cAG2aJ`xUn1hzHrSm{8BJSVp#F{;lJs~w8#5DMk|9xvuBHE|L +JZqDy1f)*)1B_AbiB|Rk_B|griG-PHP@`P}t($ifPPmcWnY +gX2#lhU(Nv!^9mQY`7&!hL9-Id|Z=N#^mEn5?wy+)Uw-MEQ_kTuPoLV!S1NsyQJ$$C@MDq<1M97EdXr +OfdJ(o}R>pQpsR-y6(DkHzCQG4L>BkXIV2c$l3`1)FXQ{w??dytG9b}bhHPaAT`xj1XSr0hBx+PI<-0 +}p)n2LRHDi796NC=J&aAynNE)wA}1W3N50uP7g{vi_IQKc{{{RHN|Sqosph3 +L6s&lzr{b#Y_T|bvph>Gp`L2Z$w(hBg;0Ei9}!x=C;6FkbL;o3!FxO*ZZWHJq?)3#<{|5@o%6an@n(Y +ALaa%*sK#ffnpN3pN@&dGv6dyZ_0iLFs6t6GB#u$|%*+(B5!a9`k%n%OV7;7Fehio?Z~LX<_vR6o_SQ +?p)rZVOKD+x=A@#9S=fuQb^eT1PN*Lje9r^(m~1NVU-_77`Ipx5-*%trw(-ZPZtuUZZKd;cE?*Y-b9$A88U$zP;3#MEFqr-$A?pI=7bKA$r4?aS?_?A!Zq$i02~PfWeNe +^kls@o&B8_W2)JRoj1W9sfmZYWVo+>W29k@T!T~&pLv#X! +3(6BNG**w4x|BHTQIgmc_e8Vv7@x*k(zu_EbHT=uxb$(kn7gcHkzyRAOcOpGDVJXG#XAt+KHCbe#9S)QC +(f-`HmPMQ_JBh&zT}pQ*#A2A#QQmDXB7-D1{#2rxTe{O1aF=qU2$wSx$T~i_FN*Q{MVV4;~O5r;OC2T +@o$1^dCc%CH9L;ib#kN9zHd+OYz8mKjxKSP; +5W$X$@UDJ~TdP-1Jqm4?0DV)CNQsuW?L!U3zV)iw|v|OTQY +`b(LgYj9U)F;m@T&?9`0Pm#J64ULma!N_Q3AgO|=(qj(t|U@g@r55@AQVQH;sv)R-)qQe+D0&jVka4!J4Lhy(OFZ|bF;I6fFw)Q6twbCD%Fr|M@?fVMD497ID1v9s|n^@A!J$OCB!J}r;+oJ^zoBrOv`R< +V~8O$ggnm3vzRk6k&Va`w2+Ox=bo5hHs`RXtO(1EaK0&G{Qk|yIZ#umbn<&H+;Gt8y;ZEtv_-5z!F=HLatVni}OP>sD-bA3*+nSa}V`#=c6S) +mGOG1^1)S|Oe2c}6S80%WIQiE{R%DBZv#uIvirNmKRNfKn7lIrhL|9Sp@@L+$$fbUJ4-)*}s3h$*YBb +Z`Jnk@P8u0O8Jtjb|9SpTJdh`RTd&BDn`}a7guOVpaueqf;BZ6eb8u`L^f{ig*+e#*%6`q9{ +O*mh*d6cHbo9cTo2KQug<0Eb&6&nZk2tll@8ehW!6*_=f!dCm$| +9t)`jSoxuP0=a2SFxYl{xQpn$+akU=n(U< +g41K^%dJpgVzzpox2pjQh~LH-RSsBdGeq#3~8w1jh;X5_~|gnqVP80YL^qD#0j%Ap~&*Q3N3b8iMWwz +69+FS`#!UsQ#SNBsfKI_;V@zPBK3rSWEB>K@mX?!6x$#ns( +&HT8UBADi)*ta@gzd@GqRuaV3-%THsAH#5yH5awD6U$*MRDpdpN&bcX>CfVF@hv6e+b0dX6wDR1_cI^ +C0`^u3Gr$75;VH-pP>Om*QoKUgk6O&E^+#3Gq@o!H5%9#IbDdutNJNF*1S*IUDeZBM3Q-%a;YZID9{2 +}Da&kzbfgx(thrR{c+(^uMd1rNv5-=k3jtorA<%_Hr}a})EeZZsWf$;4cx0CTRn()7eBTw}ri737Zb* +au`H-eEG~ZzmJ;GzwIJ!tfyzb1}6`-E>^UPKJKC*RZH*r2!GÐ2vK@_V)9k +29{S@lNSilRq8`lP{$&y=Pn(;SU@*v|DnxF4F%N`AhGVKj*eXP^!WW_*EbJ^;>$o27iJ7W7SU{s6KEF +Y2f|l;88IYpgM!nr+1Gn`&vJ=^uQq^Ar1WTJpR_4yDv#|Qk*5``Fn9dtGEM)D8xLl%d`5m7yR{70P$Y ++>7msf-#j3~0?7ShLt3+@Z +DaY{E^SMjoXzs7h|;!kp1-XknIvIy{!dqvHzmYa;-}#|Khi*%Y)4V}u^5obl13BN2%x9N$ +-8OP)GRxN$|Z5W`-WGmdRqoWpiM)t?<+HJNq$n6vKNIrHDmS@=%Qg7 +$M3a*(r8pK=y?jI;hHI2-gWXL$re&vG{M2hPTy=4{+W&gRUS!%9j@*rG*?*z?an&z3A%!j>*w%2upc! +Pcx8GEvBS(&~W57#DERW2DE@JZ{|&|ej^dY7{7V%7np6B@xvtQrk?8Xu9h<_i&??LgyDgI!JKc3=GrTB9x{t} +A+3dLVf@wZd_LlplM#jkLR?7NL#YTpQM?@v}=+?DsXWzbkJ1Hqd#gI4s$B-o|D%tNL1nApWC +Hu$5M@GknQ}WS~5#hZflDi{7=gu7;l>KAkO%bsXkx`KpA9(fb?&lYlT!Un6e5~^HxzDFfa?hSp3cej5 +RCVf$_>_KZY)p7;^8I(W^&x)>&`l1|C7I%fM<8-!Z1R0~-`!U77dZNMR1uOfj`Wl7X?^$I{X<0nKM~+ +T72-!m!8Zc_t?$0Szl>Vk!^nZ+Cx=JG4~UJ8j!kZd1lszvX>)J$=FQv3AqV)!i-*#0S1Uj=*Z}{?==h +k}*!bx94z&W1f7gda`n}_$Vx!}u;`=<%?jAV+{2%JpBaTVwM~W;It|f;cfXqLUzP~Y^SR5Z68!w0uIV +k)m{F9^nO+X=*(rDMG&)s+5O#vMK$=XKAre4vM!2t4qpiduxLVJgQq?d=6zNI=kHY%RD+^2&e;{HCec +!V1wA_CmJJk;UI@yYQq(K43tigd+9YI;ZZa(8JuK=uHyVxl4({>j0;yqh#~acR|$Fa(P6vEd|0HU1I0 +Aa!69H_y9b$TPAx$+AWh8Cm0>oZLHNps{6R4=q_ElaYE%R89WLkq9!-*uu533I37cB(AZn#vlA40W&p +g)pB5RWPG@hWQ{TB^rfetcdOv|2;yUmlQ+_j65iyl3yd_z)b^I-htiKCL5ztGGSu;QN}pI06Je<1&0= +dm@pZg8FU_y=DhNMK1BueVXFQi*57axBD`4Su#&fqHrzqpO!Gi~j@yKj*U&q+v)#+huZhACZoEyp3KN +ii_y)c{U_R^Sw+PQvTayIO&G-jAi=5xu9X7bLUQW@Zdo)HaK_oTXy#BS$6K+IaX0o!7g6B$bR|xk{BCYy?T}X{`>E2(RI$=rS~H@oZ8u5 +4^l^`qmGX1<-+mQ(aoTa?kVc%USX~HdgjkRW`p=%HiaK$i})$_EJSrXMxR5S?ZWO9UrX^ +#6hD^YkEHlhDE<=^e;LJpkK*s6_%;39KjV~t#wq_>$0_aPHlSU*c4Dcvt)g3(=U%P6y&h^o@9iG!)U_*xZROpemtQYG*1qGz-Fn^Mv{x$%(6U8~2iiZ_xm +&MhO}jlHJE&CM9`5Do*}NOYdFZZ|E!z3CdAL_IPtT@JJUp5|*Aa~sK~%SGXYb%qwsbUd0uMRY|BmOcs4;;rwou&Dp+g5 +S6@X9Tx-@ChgjyDHfGcrI91TM)h1iCnaQyFj+~jnd|4~5s0bkKQLi|8GE5puX +qqk3ar+p3HBrT)A?I=B4LOojUdIo;`bPE-o&9At52XWSV^Bbg(4_eE2i`Ls_F^zN<@@E}h5(uUg(=T% +VC6M}}+ZA^Uw_e);87G>_)nwr%4-{O|*({*-_5#TQth;@^JzEvNZ6hdQ +`7A#nhK;vrQhV4OqZQ8U6EGa2@Bp@IFyz_~Qit2`R|1AEOFJI;~mRZ!PQ>P%};erbnF7VRQQU{+89Xi +Cn`syozCzX%D9rn|wPxF%}Pl|WYqyUY1gh?`Y<>#M&t|Ga+L2255`|UUW%P+rN{`~XLKm6{y@4ltHen +mK<^J%JYL4?Bs#Qn4Q(|8JbIRN-802&lPnJ57K6*?5V0(EIofN*vImAM0)-2s0E{~bGa%%gJbNHS3b8 +n$oWF7StZoH%hpl);%ZXT&>jM4g~IEX<=vj|xEDKzYDKxuNbL&L^LIBJf8UQvK&BhnqKVa_5KMZ;*R6 +{HYEH{2BbOUAxAq8xr!b*Xz4Ljsd{`(@#I;n>TOfROXz<%%Tp1|0s`r`}PR{?tAy{6?NtK@#De{8qfw +n-cV0aM!;?3Pn?@ia2|e;bIm@^d+owKs+{*M<$Umd&R;*z`PFOJj#6D||7Y<3_~VZk`TF_>(HMRKwU; +OlK?Cpw&%syFgR%hbu%qn1`Q{q|u!HB|H}HiVfEM5l{-canUgSLL3(ifSac(@sx$XexfqRLDot!^RG< +4a@dB=}9UvP@^>gwvHe+GYQ>m3066;R4Tfxl8uP!Aw4N#AhZ_c-T~pA-K<1C@dH6V3yOhO93+zgEq8+ +7ZsxA3IbNcZC1->(?R6^8y0{JCZCEfd(pvTWA3;kR#w&A06O3c#blH+(7=(?$Vr1AT*Hh?|)LFq4zP) +!w6Rc(GWy(lXG0cKm91@zFVX^ai{oGpTU*(AM#KA5eL*Q6GhI!SCj?h3bLWlfjSO3gWRKDC?@I!p2Rb +p49Mw_K@HOW#L_;*uu3%z>e2zZh +g{dCL!kw-4mtYvzbF3llWp8C}l#2$_b2Z#j=6ocev`RG&eET%UWQO`;N_}h;f`D@dOhN+?aYUKs~YtT1s +VmXYX>+~plE9zF_w#~+f;!R|r3m<=U4#jl0Sy@QD73&0eXTMsgCF`^j2ZBJR1nNJ&JO195)E$=4Qq*p +ElaZbl}qJ!)Yz00otac7dZj+gV~nmJ*N;Ei3q}47216H=g#xIrz#F&$cZC+T{b=touR*(sz6yOCo{t~ +X^ACxJ4YLh=-Ap5YlW3@0pP!{RX;EebpEtQTpPL@Z3nxVK{M0CJvp&MV`SP%!!Fi0)Qyyb9gg>?SLjD +P#1;874!30jg8}$KrD`kQ<-g$hC{ueYt{&&m`<6DV_4~T~Kvxo+&3#iYaVWmvN5}AgDpkY#P{=`J0Au +Wo}PK_2c;6a;Ya2jI-?W$k?(Pp3z!#D!4cI{gJ#v5;NjEfX-E|c5Uliz>;ogaQFg_jlT_?9_D1J#B1i +H3LN`iwT|WosB;mK(+w=Y;cTvP}G`j0kQc8XhMa9wQoN5e<0ijxoj@t-t*N{v-=R{zvCMorK1+_^_bHn-bIVS!z(XfDMc#>!+COMj87Pp6rHYvh +sjPZU&{p~;SSLEMlGcH&Tvjq*#^7Th$0uyzr?i{PW=g +XaMJH{BO&-3N_T<5v%_y_o-?ECfWhjQSrz4n?Idtoe7Qc}XFPMzwY;dXS~u1xTtO^-|>a#M&SR&Wwg;W>*2>&fxws_H4XNZD-j~+d=X=!O$si~tBpaJbEGVYzkh!*M%cA$myieG4qQ=2id-q>0s +0_&nCD9TQrOR%if>n89_N=g!dI<3&~@WT)DY15{OazLM?z6t{ +)khTj{0OvsT+z3IYN5?xk7u4vQySK2q&o9?o@vv@F%+GX|>vp#KR)g=dD|}3L3y4tQ%7O5HzHur0}@7 +I3ZiBSFaZMgV*3W?7$oK0PPRlF*b$#V62ULfI5IWfppOZ6Ye)DogyC}9}|`P%AGrLx{lEKG`>^(k+1X +kN8u{~^F`o8Wy@)7fnCL-K2Ujck~bj(=%c`6C62P5h;|e_Mf?BWd++hL-+o*4f$zNYj)(_d6QAtVwvD +Dfawg%vo!oE}IrJWPs=pEAH;jMK{!@KifOph4n7{?)jXFzmD#j9-nVF((rMfQqH?%d7Z$%DK4^S^rCX +f@90or8e@eu4t7iEOUz8q_eD_mV&|19nf{FU)P@w*5#DD7f>bb#MzgQ)Ko^90Bg`r3Nd^acJX8)Xauy$<9a +vIL%^4lTxJ{y)$6TKGH5KiY`8eQaG?U}BAZ)TmMX`RAV(^6kub1rQFh1X;&B`T*dr=tpQ=yX-%}UEuF +L|E0cX0pt>W5a>|W`_X=&twVq0Ob2+oapOk*!V515c~WAKf&FBzjM +FnJce-|+uW{904r9k5b;45!h<&83)w>330f4~X?*(1UzGP-@CPnbzl8i#|6Qcazivm1vgWDi?@%^yLp +dlqIg}aNBIpvJg90tUo$~lA?aXcQcV7Qd=2EvS6O8XM{=qx+asbE{%-y?pi*^@0Kz)V01Ao*5lE>A5B +klr!=k-r&CmicPpaFd+#xH39AP4A=(078zm~(>nCraLg+P!=D!d3 +ygRo=@K@F?z-Q11StmKVNn->%l@*=!y}2r>oGO(U|ipwYTNeE?uN{=>(0>SJK#a5{-fJ4 +TC>HM;dQjns83ilVL3sdOoAPmV4|n=ZAjgJbb6f|EJsJe?PV1t0>PZXMMV|*F;%Am&g1!2`*Ecdz9ME +kB~5QrqDM+&jtMo*2J+E`}q~l5C3vUy50_GryqOlv6N??d1e@Jz}N}%2lS6<*U=ZDt;Sdu;}rP8j%TF +3MqdaW5A>Z_(}sQrYx2;s{Zamy1JE2ai{=ZHl=(g8xyTpeXz)at^I+WM{6Js!$Pbdf54y7TmGv!M)Os +$}kq42#^WKNLdmg|O^j|-oKfzxu946K=7szXX<9_5k`GTZ3O*|{x7~5uqu*AkeNghp_{UjST37!L +T=1-u^%JY6O6###E?wYrey)uJ#ut}eK)4jAQM_C&bQcR^Q#HBGFIEAohSap+f|n-DrKIsaLyeMDY;o# +Zj}K<)C!n5?9vBxUK+rNdAcG2h4d9CQO0@Brp#tI~zu5c(>ttG*$xZ7-Mg3#b#&k3d&gV2*O|0FQGU4 +c)D?{G)C?`skxs)c#LW^aGd|U~UJVpzQ%KuGqig`=3q_dIGFZuano;S3A`S=$UM?o-AL+0gsSJ%6AmO +sq3}tzcN2VJ;a#bSEU}^tW$6T2m+LlSe06tGE5f7<=Z-nORRf@kA#0@YGXJiFOa|F8V&S|Bwan1G0#`opnw>ojt +~XJo^RJi8}I_5#i94-7bIhDOl&gnl5;Z`4!bg$69(_U6@ifD2rW-5_sjgWBk&0U)0E>rA8iKoIL{B*W +3S7`mRd;!-fqz6CNHe)?J~SPESwgPd@pinBM^>r7cj}N|X1^AAET-|FAGZ>;+KdapjCY{Jm#$c +*VI>oHsE32@4AgG?`2@K*#Lav$MyI8@ETTR`bb|CyRC91q&94wF_nL1D?YK|CPOs;78p)84uE=aG#NE +-FE!fqeqXSRPV(+5Pd!LGSDs2IE#-QIa1Kw&{}idvQheRWp5=VkA2U#|G=O4kGyI8aRItStQ*I~#EA7 +*;4o#%6v2122a1kFkpX25S&;|oC#o|tGA58L=g}AmA9iET|3`DG4&W8>e&NK46L&+$gEji0Lx*yd1@v +pwFFW)F;JYG+${rELq`vAm;^)68t>rX7|B*?bZ2ZyFL0RKR8W`Jw-&o6q3}P)EdJWVMXFUSS0PO;JIzvwx`&g=_o|~pEqw_%F8dmJWQE$qnv@mgb5S4pPwHeFkpbdO-xl!5+>`Q#_z +4ve=<~?_ix5yuPqWvi>ES!Y&uqKZ_A8ihF3!_Jm7CL6s3xvf39w=+P7%xMof^j?1u=G#l?a06G8kX~# +1p1@g++5K%V6UpOu88siuR%B3H!?1pjK@4*Kt84HWGR+CG%?x^?Rye?Jm0N|>~M@>d^xYvT +PE0rl&T+P4Ou>JA0rr(J4&dkgrZZ+4x(-F3uc64X6^JK|Kikjw1O9(IMS}`XF?vQ` +v``YXnF~+$}bFde$NNHd$j=2}+ewg=R-l?Z~C&n-sQvq+ZTX-;s!FcigXQzlXoS%vt(wYv|5in;1|4> +fogOoj}n;(xB<1LK$FxJCZ6JuS>H{M)YBGSN|qaWdc@*6Q?gwS)N4Fexe?|hkWEC?0zNsQewZpXX#z>W;+^m#q`y{#oN4V{Q<;0sNzWL9|=Y$zlJ1(wE|ScXk-Ra +Qdj=C+1Ma=_3CtO8G-T4;DN{JB_mZX8TJ1-eY~m{?BF8`}6%Dy^8o7l=vTi{IM9TDf@BI +Zez@a@<4m)j0^1O%bn#P;g#}N_9P)K^pnUR{SoE~NE_`k_5JzI@zG8LZ=?fWKvx8s&}U;k32`ycM&G@ +2=gwMj@yu@gW`s8ZbCZGH29z+3W$=Q#3v0|&DsOSx6HZ)n!3mt=4d<=7GMuZ4lLK(tnj6C@oOr`oYwk +>~mRcvAwB{j)REcxe8p$D5;*_<i_&zw0fV}@#aW=2+CXh&;qmLYHaL~~|JUXRT5@wwS~*=d#@DgJK9sPT%JBGDrs#1kma;1< +eH~gDHn5ULT>uh^bGR^bDqP~**jWXNJogonWvgFR2ldU?U<4mlQlJavN^Y-%9e7J1+=l$<{M<;xm>Y0bSnffku2Xz;)xyRBu;*uC7)$@_)ep7yrQllLMX&cs*caz@dOs0lx%z1$GGx4ICS24tyeTY2b%}Uj&{Hyd3DI@zM +0u1Zl!G{WXthk~LE_`I;il4$WDOTTo=sprGkNuLZpq^kLA!pbJ4vtJ99uPS&o|ey8oJi_(3m`%UMg@1 +|d)PYNC#oEDrJ{8X^Jp}C=h;bB8BLxiEfA;FMgm};13c;4`?VT)m>;h5osp~B#6>}ecg9BH%~XBuBM4 +hR_%k`}TzmSf}*GK64>!;{f>)+RJ(Vy0P1wRmc($K=#-Pqsww(*GZvhk +)-6A~4Y6_Ot^FXZWvRUsQfJ_>0X+CH>8v{BgIVS~bkhnd4Bhpi3U8TLciZ(;u71HxB^Goc|FOKsUqb& +-0hdXu`Pe~^EKe_X(ffP#Q01C|E7A5a#sC*VTB&jC#X9|-gf>=9@RObuKeSQY4_>8Ke&<&>())lAdO) +XdQ=(v)g;YYuAe32GNKBxpp?*dTLIM$nX?{Gii8!NF_ +yO%iOt9w|d)rII{h!-Pt<8{Tl7l;Q;-$<|4YxN=e!TL%1h5Dw!J%V+?*}>C-OM`a@p9($`TpoNW_*!s +vu$!TYp_ReMaKE9mp{K!M2scC-VhsZfLkuGf$%a%zo}t9>6iL8R!)n88BnKM}TMY*cM+{#YP8*o9k?{ +dzgt4D7!B}eCWjtv7+Q>pYLYjs=7-9{1G~~sQ6(PGqJ_$JzGCg!w=u@F@g_ecx2@MX53mX%*CTwfip0 +KlF7s4vTZiWSfhldXdFDCB(1pbgUzV)UT>r2ZRQ!58NCWrs<;@sY%ngXdl*Ub@96Ib +glJEf(H_|EsX7rPa9VltyG#FLPt}6n?k+AXM`^gUlV>P92ZEer!-ru@1v>yH1!psyP)3woe(T~wj)W4= +*um4zoNPj~Ag5eFr`-Tq6|8!yy47VIdPjvWYh@khHxM@_opqkQ* +VI(9qDB&~c%Kq4PrD4=oMd6?!yuIruPE!nuR`N#em4^+EL+^<{OSf1-akO{}I+^SWlg=9s2J;~f-8(! +zA7bP@V^{Vx5tdb_?|@TB0S!Rv!J2k!{p8+;)6aPY6e9SosVy8R4sRI`T|h8sp1#u{EXtTU`Pd_eWPq +p=5-XS5qH8Y_)gj8(>JW1ow}tP1!t;B3If0FOYgz>a}^0%rxj7q}}hNHbXTBDD+;1-%sXdeGL +OL)2FN67*Y8D=OhW+JV}k+A-Sk)IKcHZr2{wdQc0np4zUnRL84yzw27+@71@blISj^y^nsN{tGMkAzGQc`3v-v|Xqvl!-|d?i3lW9_W8Mpi|($z?{Iupl!Mxx;<37hjd3NkC +VDiREuKt6ZEU}pXkQ~Zw(%6C@|z0ml%IBjtw=0H4Qh04+{Tx_`9HcA!8wA3{V%S*Q&etKk5IL{~mw4f +75_OY7zPb4hp;)I9}66>#A#~3)A&A*o?bFnuG?0CWV^9aj@@nw3+_z_`mPJ$$zu|Hvb(I`=tL*{@mX; +AUPnH+LhM>eh=sz7#8>l^#JPww*~$fcq7nV6QvoZ`L|}1W~b(&=7FFtL8(E*wWGBYw2QRwQk(g+wzs~ +Yeu&;i6m$sg61+0_HEQGi4f%$CM#^v<(ND&D^=|cX^#$sCI{It;`}hy{pX5K&e}VrB|M&cN`hP)G{N{ +gmz^H($0lNajHRCilG!v;+I<7shb=M8mk0NR7K&{8a1~v5>_afa=>HgXwl+q~wvHq$4IsO*^WB$ke&l +xTnt{AEf?#AZE)>L18sV&wRLyS?zIFh?j##Cd5(L()7k#QcTW^ZgVaHqAbn6skSQoCs9#WAP=a=dcCYq;_OSLCQG1Ho-g8s#x6Nd8rNU+T%{>KE(RlGN`dsj +t#k>shdSuxGG7R2`-XGf`hQDr{^Rc$pEF6J`mU9yT*lUT1OGh#JpVlZJ +pVlZJpVlZ`Sbq)P)h>@6aWAK2mtey7Dv>_3eOd_0001R0RS5S003}la4%nWWo~3|axY|Qb98KJVlQ_# +G%jU$W#qkkd{agC0DjXXZTjMdM<6^Z5rU#ssaqedp_)q*xRF#*K&yhH)yl4@Y_QHm&3L7Z?w3TPiZdVlB4Bx!lL`~Cg?{qdo>cV^DK&YU@O&Y3fFi*8>b7zI +Hv!Jn=RLao66xrP7zuLu4Hja@TH_)qHQ^J@+M&F9aW|I2d6!m@|&FT49eN6Fm}J@l~RxaU4cS>PeZFC +TJvZk*|O@Zo#!yDT#^%^54>yvtv<-9F>k)c9Y^c@Ipz1D?|6;;A0?ylv`L?D^o-ned!Bao*Is80^uhM +ixIe2LH?0^C9-U`Ija0vAmya`wXuj-1}6r@ciz?u9C>dj(<4{~ntDe;tDGLekG +CU#8r*Sb^ttb+HCv-%Y2(IG{C`mEC){ayQg{B`;IB3jP{ThjYXK%Q%=&orf8r!NcHr@+`Qz%NBA#)<@ +{8kcRae&MvR4ysQM?8BPE^05#WoCP=K=P~jB&ws%dF^EI%CtvwOGp$9TLV +HnYx?|?8a^*o8a3~Y=H=;q1bJxkCDrb%fAvdf+?E1omb~)^K=6J$W^juvId7KV9`)bG%&ivvaa1-0aR +?OcHMf~GRC?Z%FxI_-_Qm&W7w)F=wX`^mCxfNbQ=3opUokcE#NNv17Y+i+6;aSccX|+`_2)Qjy9_Pf` +bU`Q$Epa;Z*3~$`y6tL!-_)>44$W~|3 +5=Leqz`rrTcn1r!}F%JJsz^M~%sp$9F3AdyYMI!No$1VMZ@LKpYxx=a8j>~SXLw$ayzA##dx=x>Me7k +^2o6kdB0z=FCY$|t?Kbz}!!It=@O*_JpB64@cungAU>vYCz;%$_o7rIeN3jvXBf?dZTdhG9YpOcuFB_ +hp}wjVGc{0v4o96&7LwT+7KJLJ7=2#gnp|-9A18bW +IwcQY&ldTuIzAhUj)|ih$a;cPWRMLvF_dsO%QO#IH_A(q#!v2KkINd(7&PVRZ^O16ReO&gDz0zIMozh +%s&fJDgXV8{gCSS^=SGRq)2`W~{3qY4S$Ys|W*j$2^H2cX$ne2cZ6V-d24xrMDHVXo22O`hVZKoig+L +J7Lb|ZlmbNZSA^yNnSQV&iHwgiTd%u=A9V2fhOZPRVbAxkY54^R^uVl=qKX`d~J7dR_mx>gw2bp1s}Y +`S_ELKAb_a$9uU6PvJ;-VSN?3W3i_AcGleQdwXlo4UHq2S7k3gDaOfXCPQ0g-tIlDYpes{81D}ZOaK= +uPo{mat0O`FGjb0x{=ZR`v6Ls=_>%7+lDM+A+U(~^c7e-R(I*T4#-+KpH18!Scch%F8U%;YS{J%p7~z +Ly!s~q)@>~us2PC*9OyS3=sE=YkpaEVfm#u01_ugppiw6$t9aU=-)eWR|lS@Zkw%{UgT!pzR1s{L +Xp0?b40>wOHK%jeakdP>eiohHk6jW!ibe?}h>)5#n!!_)S2A1V*(OsBk`v{6b(piyfTxz~C=5vcbPHE +y1hj8L^p8$olCxXmM$No?;H)*r%n4HCtu1&Lq}sLu9=NtUR~N6E3wN|4sFWFKzjrbKm(%+E9sX7i*g7 +{tQMMgM8}xBuT9C3Z($M*B`#}lS>W4CpaZ@TYTgT4_U9R!2_>f`@DkEpSeZ5&S%8DcQnUaVAz?(u0`~^yqqNNLk{>dF3w6SDbDIm` +D+@n(g%KbcTpD84yvL9}oijOVy>qc-Dbl%GvoFP=F@JF!wgkkck=Mh}(yG&S!akiscCm%(M7hc>s9g_ +lS(mx@{{A>PO=kr|Ce>{)^K5g%;(K()?nJa)DSQTh>^R$L6qd0>dEdq5ZgE`<)iu_It>zHIgkwK`e9M +evYyqyLH{CuCtWp&lLjWfmx1mvIb^+&l|WM(sA6J0F=afp8(1Ko)_@}fM`Q_)gPwC31%G&CI?4Vf8>djR5c>wId94(qg!oD9!MDn0t1Oisz&+x%e(Vmt-BF_(uI>#T*^iaequ;b5Uveh5D7l~y72sU-ei2JRy3dnU6&P +CwS^nsH+aMr)lQgLh*ldoh~<}1ktAuw2uM69LV5nT@?9cz#yE!OB}5oUG2EO9H&WhgdBhFTq77+EH{c +ykX)WW5Y>+H-XbGY3H=Dz=*Ce%zgShsPH%;G(x5q|+6q=F6VLV|2M-yMwoOoX3jGs8;mYT@qhXVlTI#A-2Fq +#$riTG%$6<&Fm}C-Z$gOLL)d`h_Gv_uV6Z~{N8+K(Rbj{U_wKVItCu5Ny^60Ixk~byt(i&J*a828_j` +7~rNY>HwvM|8khm65@4o?dltW>}NJH))>7K3zS_O$}eRC29sOaxbKt+> +wXfpt-&I@_LLnuQwHVWxH7Q}P|66v#ZZ}~1DYY{ws_9yz?_=~xva(K`u069?A?GT;>sr1Y7n3gq-ffUH_&<35W18PA!R)?Z!W)hZt$jK@bVSUYQkzlU +twgWB@^y|**E0euEK*D^YFnJpUF_>5|HZ#H0{6K6*bG+3;9ji*jwsn0ZULdO-uPr9%b6a9o@I8Rm&TbKqQyZXu&(){xPG(RPfr0vIuyJ +RBjHb2YXPRC$kC`AXhlG%9;mi&u`n0A!e&cfp$>~|dtnEfuQeC#L3u-g-5{>(|#8EcF7A`Ho-^=wG2@ +SrtJ#I{|+qp~pSb%hjXOxglQv@fo!D>CsBOgs@wKQkSt*c7UGOvjB;sQ +7>4n{!D@?^_963wcNjK9w73t2z1$X%^bFDIENK%Hw;+ntNAoczF}Iq4#9$`O1FC`it99gGPzW8$^C9( +K&0zf`0{D47qxr_* +cU4OpE!WI;7AUd9=^B+f6jw`0+gPniTBY>`E8FEq_I9`)9ifP)?bN?v^)VlxCQGwTz54@FNHZ%{8mM# +L@@ML4mcE}U=P0}09?WC|^#`I4`_Mc=g{BSsEPUrW5oq){6}Ujr!mn?z)MmM|4HHo1$Sl#IN=iUkBDp +WYn!(bwHBkFJx)M;bPPj*q%M^d}FL_ldqxVW&?mp#l{zVOm9AOwV!5zGdJXbD%;?j>sWD%C;MdNN*7? +PDka?EayV3Z&VQsn5`(-6}XUg4oj>~sGssCA^|xP1a#+ISYAJNGIk%-l|i5*sLi^s`$xa4`H_ocwNF> +9e$trRhC1GYi@0(LfUgYz>{;}jk9_45-`mqY&7Q%8L`_NdkQ<#^va}ivSsrNaJQ-$tRWT&TprkdxxRx +n*`b!pByumJIhFFc_ywCN6N1XDLmu&I7TEwRhFv$w!hHbb8&Zj3qaq(QV$Rd$OKj3=4oK0mz3Z^aepj +huWcFNh!(N|bDNcWP6&qd4TdjTyD=!WaSBk2;U_mZPh_Yo~sChI-qCtr7`C;Oj$-mA;hCql;Oya0Xo{RWpRh`evWr2!avA2+BG0 +aVP=iP;?KjvxxA_1j0{T2t#-AP#i^+Fr!xjhSV6^E6fe~ +aKv;b_PHz3pFVn}&96GK2-WhCduSs}{=bXh;S7bFuVlrY^IWId2|I)@;>OWS*(Esu_hwcY#bknG +nk*(enB@fV{^O_O{@`-vLoGvb~H?Dg=ir90`gJcRcwY-e*yGZi) +MM?5`()6?G_~+fkDqDJ&KV$?v%sk3FjMx>!Eg5vk8QhrtI#p=Sm?)It!3=6p)sIeu^3MVyr91AFVil; +&=3=GQd_!$u5x|V6I%kAKucO5_Uf@^W&w&H3R*|_S~JiN8b^pk+OfgCr(tE+pafRt58|!AG`LGiQ%@ +Kavw9*a@HHKi0yy%J2J!`RvmX#q?ToLbpnAX&b!OeXMs=$mn=iv?S${=(rXZv@X;Zr-yQ*A6Gp=NvBt +3LW9`A17BqlpNd^J+dqh=^Z1JQZ2}LAyaNS&f@VG@JnaH-df%I?xL0nZ!_>wt6%sbfHzxHmjD|{WnhnC7` +;1y@#MQS~WQa%LLO6084+JAB#deBdvib#&7AB$507TQeY5YMYzo{uw5SK0)tosf{C;mca%J$cY~kQ;m +Wm@%AJU8l%8SX!ECvhZ7Td|qezeXF~fuqut3TLh}=Y7@Vf#B|0O5xi^`Sja3r`6h5CO(0k_6RZ)SokB +MBI;YBpS%zfMQ7{;e8jn45!ES*W@gEs3y5%wu*xdg3)f;Ci_VE0v%~auW#o%y0mbtIU-Wlwt90A~3Eo +>AW0R2mQFTc~I$w;&NN)8&H-uP9{}O)_{X3IHdg=~ACl4nT=aC?^Q#yJx@%GUu7rSEaC;hCi8$P~1(>k%Lo^ +;kRZJhhc@@JjHWm=f_M`5w_(BiZeW7v(?oFMh_Z5*xEk)#VBAI;T(Y&JU?jrJypB#`$bY-a+JOqXKN` +5W-LerazLWQj$KD(|K)k+i;je!3-O&O%H$M5PCpIix`r0^uZt1q!d%Or?ZzsEP1K^X~3EKWQh`P^r0( +pzzT2|?NuO65|ar2N5-z(i1L`z}GH_B`nEPw+RV*5r2~vcxN(M(3GJWJtT^FlgVz^)#bBgy+MxbHOa<3q!5 +Je&a!-twerio!9$AKFq{Q@nPwQs%2{#`6*Z9 +Rmho`e8?G9O=VEZ>H{P8-zRC|Xl9SUSZFFP~G^@$vN|Hbzt!nU19un8N=fZWV;S#z2fT_mpgHRQ_PFr +ZD{(K8wp-D*L`6v=_&UV`GV+DvgxnO%gsqyNH0tWck@ELK-sMzW*O;TXsda>$kM4l@Ye+%6x9dc#j}` +{|dUxq?#XC0}^SZdfR<38VoPCc&Fa=@M&y8ooQHA!6aLyE +Q#3JTllwjS_WzPps5D3y`))O(=|xT#!wau{V ++(&ia}-oq^ODFn(s5p%@X-SGeJZKc0bnlpb3igqQbovXO*cR(?GJPU<9RFBjbmk(LIGsQV;%)sh5(C*gB>`dukil9ufc%4jq{Kk#rtoH@@yZ4P +nDw-#c=B__;6Y|s^P^h73B+UI-na>fo2@ig;sxvk5Z!ze=vu(O=Z6CJkavtH6tMV10jOv_Jgo3Hkt@9 +*MklOlIj8fy(`-&Txx2#C4fHJ(6?1hoGr9_Xa{*|b;e*)zl5Sv5cMeA$F}YJvN@dVyy4-d(FuU7r7b; +-H{NZV*)E?_1YxqVhU1H|ugZEkAZ4)pf8Fmz;qU4jh?k8D8ha)#L9m6t|44Je-67FwkW*MnXZ;Cz&om +^dv)8gqXxwRYj@6BJ@P?pH(LAiN0&gM0L6LEEKdzTHsdBDnQ5QJp((s2h_UH^ozPj#LUG$$1BC!X4ad +376k7p*8+RR}`HoIvp#okp@MOIWW^*#)`W%68qkfIfXpOdzaa{wfUv)PKM*vma-E0=%`MUtgIGyh9GZ +?X;qSuJT}~nF%>P=(2&Er@;;r8bm?$0@1!#2c8^8edu22LMDbQpr_V8i#2W;&X=-{cWyC$hz&|+iY~KK|PS6p3p&x-bh#GVhLgFyqvpHNE2#|5o23IuYV* +#P+7=|ffMsBRnaHfo|9{U~~aO0*f#b-o|PTz_a5`u&`#rn7ODVe-x6Zb*0POdeMc=E=n5&ACSTO$Tm;dZE>Y3*?OJN*sAtiT6Q!n9a4J+FG{Y>M2WOA;(?5{O!@8w<#}pdgZzR-JP{M +e1-&qZ4Qn73R>8xEIRmV-a$gNhPZ^N@Sv-9hOHbIv_a^tlyqACp+3AL4q%+$e568Bw{NWi^7%&$!NeU +$;jMnGcf2=&%4&zyrTUUg>4S)d-eh9)1t4^)O;+`Ub4d&Lc +j-5BlO@~&Ak6`}uK}c2;3Df_0JUA`vY&kFWO`KAd}s#&c9|`MusT|O++sk(7Kr87y~*TrO1?*$Kz`C- +mGv!w?U2d!1Ex)9Y%LvBfk3iu6A_-lYz^!^w^2kc0b$bIbqE!W7T{{lK>l@aAYM<$(QGDamF!&0J$ec +@GWBQ#eLF)C!Z&15Pg-1&{?%Tzah{NkFc~j>84C8POHP5HXd;c;qpK$(NcW_~{)R{&g2gDlKcE#eEtr +-H+}^;m1}=@U=t*zz4HaArpWY9;@GtuFc4?Wu(413(mP{8w66DUTJA|2z0;AE?a}CPe)9fQy<$nw1nls^w4+Mv5YXHz-%q=m|t5lOZ30SIrI6p%UvOnUBFE`V7;7COpBT7QsVX0^w2~z6-+ +(==P+Wvw0^W9VtYax;P@<+k|4cZ1q|iBrS*Ne! +&FZ{WeUwXmbQ?ZtoKvPFIBDMKIygkN;tEeakAq)Fi-BhA~u0}FH7SISZ_3xZO41~>Jufds6iFi`)whB$s80PX;*$l +t<)>x^)qp-2E8y}G2r6Vi@nzvSGvOSlRY_h8u)2YWIFF;2-wk0`+C5Jw$WAjoE3<9}HW@V@>iV%Fze3 ++;!c#Z?db^Yi34|Lm)uffn{CTnP%*KKQGPcSkWB#Jf7FazkHvg46TF3H?=fO&}koif;s5Ia1#jdn8G< +1ZMePPgbGqn1Md^Np_O?!x`-CtgoThOuVE{5F2A$K7L*Ct2xj-(Wbl4U7ies*4PqdH3%F6JH*3Br~1G +fTznmG?j;nc_@#E=JU|SJhYI9#_-T$9vZ|#q$0-X%=AZ!oY!{#QG69~pa#$@_-2bwXr(s{k{QM`p`kB_2~jpot8Xm@ZGJO-JSQBcZYTmfA@FjcM-KqL +W(Ke!U3It=~uVA+__!ACc4w2tBRyRTq1+1JeswDW*Zf53((l{pIL>%*W2lB7YQ-n9Np%9m8}#Hjb!%EyYLa*6)=Yj? +OHNQ0Etr0l4;_5bAED!9^SCd_2skI;Fh)Qs+Ywnt+KIIcD0rbMws)V?YX;Q=amcPO%6yn+zKAoG$#O(D%Hc6 +R%#2#{3hUuB%s910x6Nc>NC%ABrt-x5S>kRikxtshDgN|5)6@67a6Q(L6?V6euIp~sn`3KmKmQ45{W- +$6B%Y1@obONn+&e8_InTG?|82g#`vu|CG=|=E-S*($crP&*2xr>q3}?VUnM79O?n!CBMKR`r5MLrsmW +|E1b(Q&Sza(P~-!HkzE24h)X|-fa>w&S{93eCl`^g&NT}3NRuHRdnO=J7wq8)8KOSa8Nyq%-TTIkOAKJN7`Od +f)9A?0@OTR=w=Gb2vy7KcA%tEf){`E3?1ub!Y5A|FOB|HfwaKHaCQyEvV^=oykZ*=|IIWf&?1$&MbB{+I7#2e0^XfkNO=(#oXLKd5Q58qz=#^fQjBnzF?nn9>v@ +TBs}D|bK6jCB+YK?3lgmc|ul@5Wfq8f3NUQOv7dltfzBKTJ#6UU2hnvaAagEHv6A4o~9(i;%=Pq3)q>FwEhr;#bu@P|-DV@2tNztw#4@!vF +_6pyXYC;mSYOx~B7S~oM((a6(&0zD$Wb|5)b0rvPDIz7UO6>N!I3R(x5o>3 +RD;a2`gbY>3jWWy5uj*CWORSSD*6RS{e@wr+bDWVlWAdOBnfQ<27AutF#T7l;K`QF(?ZW1CpxK*ec-I +jX#0t@K%kW0-QCkAmXrjsEQvTIM!+#lFck(UZ_LEr2lj#yz0=P1ktg*AG{>H?NH3Z19|c6#&>D>sl!= +^@l29NI;}x<@BArZA{1+I9%X4E?IKbh`dfVgPSG#0KzZyian_+<~^NxPfaTw`$S9_9bjt9M6E``GDhv +j*uKz3^o9Y=@3x&$#lD1(%BVxGBAQ(&#K1#balGjfx6`tFuYw6w~|RO>u=+?xq4T`po|PXZt03x#i|g +a;zFzXO&=__q3L!~Xoobl)832ts +$E9W9w+RTyPk5JhKNvmXGmn__@UNTE}24i#F0hn^VeA?qRgo3l|@&~8;*9MFR3bwJ?g!8Ts)>r>8S=g +=DQTn@}j^_#J{IfuJ)vN5AxOM$V?=zxAo7Kbt-w~cIJzDBkp0Ur3dQ+_7G*SZimGN{nPU(vl}4^WutEzab+HnX0>e}WlhjyfH)tuMHR+h +R%rMZ$^_=!XSQFJAOW90uRhw_MA@+YL2@c0%|5l`I$tE39LVQ^6bK +lV!KJ08D?n95KYa`CdH#s*e`(c&W1gv94dPh0fI#rySJ{iln#*$#K6DfCi<_*F&kfIZ`0IfD@SyP534 +c9-cJ0}iy;5u#41bUVes~smX~!Ry37!;xI`O9`(Ars%;S{2?xPAElBM)vzG6~{*Pdbp8!oQ8ODIEPLV +`DKky!#AJ>#GD!MZfNm)Fy8`GG;BMFl=%H|BbV2A;u&2fkr+9M@oyED2oXxp+bIyGr&bhb5IrsV)=bk|uX@YZ +qR2=8riwAPtM=O|}jWXu_aPdIqy?7w=?k^9w<4ZlE1$Xrg_C1siVBg6!G4_A>KEb|cATKz_IheEj$$R-xn7Z#1r4+$ybSV00O7@kiScOb+rC +SW5;bvu$lCCy8LXtg-*jAej@XFb33SE2?YQZv*V5|%%iHuLh{gY`RyDGu +4(os19xGDqZYonPsYG^EYPP+!azIj!jr9X_{yW*xa-(1M^2b&y#*_1m(;yuiyqij>^F|tt)=+GS?_)c +lJD|Di}T6JPX^55nuqO~mCKleVPG`WW>IX=s_tpb8IyTwi=Idb+bQZdTEtZbJk=KxwPC1dsvTCf&YC* +SuHJ7EV%R<1*B!Shthiq>d*%R#bvA*E<&ua*+MB!`Xm|+C-G>7>l9ufU?M4sfQQ!Xf0vKJN45X?9kyg +JBZ!U8(^ixz{VCTI${iFv}wH@z+sut1B>i)6Q$uqr5$ZVN)p#@_EbMOPj69%0nbb)4c)CP4a!P&Z +=atW)#k;*FKp8!SGy!mX@^C$X9SWwvlEY|4}TXIXlWIDWrvkI%s^H}a&8;*5hhF>$`szm-Prc&q>6RP +ADWZnjt6|?3#k^>>n=|Y@YX6cWGwgRq)OK`i&ekDr3bq66g;KsLGe72x!y={;BscDh2Wx)Qg6D^4YeRnH`$Ux +$(@Ra~1ENU8AWSWKF^;@%v~317)NAK6_*e()I^fh|+!NH!YJ8hnhlI%&CAm^@0XLQW`MvrfsZHp+T~P +hTJ1#8z7`mGx%7iuD +Zh&bcTAHyq@1%2|n9;D)v888jBu>-4gb9^OfsfY{KeGl2|&E8+Jbe=&BZcAc^lEf-B2Fm)zE@K6VhI& +Kv1E`pJ&}pK2+_Y>2w61Ij0OyT$MgWTw7(p5T1Uc4}FVNe=#z;je0ZyrRsIAdM +LA`UN*LCb5BQy3#zIHx>k=TEg8Jr7{>|5dM?jbj~fGL#a@FYWw&cX0YBYe#xPXUMz4gGo_P29$%8Yb? +A_a_hioh&jkx&awz1R4c+eC^3pal}qyraB-S*=%%nP~q8(2Z0xf`G`R|A>bA&1R(zpd-n#~SMvpKJ0O +_l1_^$kBf=AEPxmIhD*(DS!BXCCGVg1d%P|r)#cuu1A_VSyw$UEuF?ER#nwdrfVng@RJ$66N^YvhwE!5PkuG-wZKd(rkG~1B0M;~I%Z +SJAf0M}v;}I!9*Ym_DQQ+6cos+IJI7&GRIcdWHA{i99eo`zx&{-~Sf#E&TCyAb~NP~8pZacLc*H|;~> +reN@S0cKdy`qm(R62zM&w~LI*`s|3^sy6?qL-XPGq*O1zO{#~F;)Fp2k+q$h`O%0|D4qwa|hm4!u-_- +9_x~Dc{?DN^r||pjkoN<-I9=33MvZw$&WNrP0`gG;0MJa>&hyc +j@r!Y?}+bPF%!C&(E;)m#bh(5lI(@(ht(pOs~@L*-x4gIUnyjr_RNileAUbSdj)*NO5B`XT0L!sS}#X +L6RnGf*b)-;=03xPlurak7~~MPGwHTH#+clg;!_E1Dg4r+a|9KODr7lWJ5>q%xaB$Rsc73V!-)fJ4 +Bpwl=mz!#vgx5V)g3MBsUd{dF}yL`Lox4Slq;ip*-3jTN~)_Sy?zAAFF-+W>#$J)ZxteQ}Y@$-=FZj5 +n7$|X5GgEzS1o=Fv_H99A4K!a1xZfpy&jb^=Qvba85QmrMEtn@?Z_SF~M^~4gNI@zf!^YPKA+%0u^1% +q-sJ}iMjK9b?oZDrNWTI`ie4ujgU{U9_Qy((m~Ui~g+cQ{lm8!w6Yh{*|zn27@D(N*oW=(hhn&Bc;mB +2V&W=uNPicRCc%5;;ky9Thz!; +xRQFBb=z}KVM{185f>pAWwtrAmes1b#8sd|UgA=Fl8}kHEN(4L?J)+-_-+AGa#>>@BAKyf*5lTj$CaU +FGH|)cg!V7=nk<&|b#mniX2E$z#^WrR>u{smcKy?+0;2tR1>5jKHS>XlnmO=1)j++dWGDB#+eq)cm78 +S(R{G~J6Xq(InKygLR(9x%b?MksXp=!W!0JDOd{Z6zmT?L`+O!oN6VPE7Fu*oamhbYjPW +YCy^)%^fW($1Kq7ueXoTQ~#!q03{B@jr=dhlE}1D3mswKEJb{|LtTIa|U?xt&9PVrqA(M`d~lc@%8~6 +FtMd~*PUnIl_lAcP3&|UCnp82>z0^BPPvNYXFqBU>Q7usTiGuDOsj|8b#noTI?Bb$#Nz1j2S|&LgzbIlQLd!gzBBzXm9XPU^svzDONg?C&GfSGZz?Q`!_3N*tbyZF +!Wk#h%VIQCz+aH#IRJ+)5mFX2D=ps?Z5M4PA5297;rSL-*y$7GQB_rIkWg|QEr3wPNSe+qZp>@hCr&j +surz`fizcdAgjwg&!CK;hFP(lcf6b6$C=0x8v%q$8M7ZC`K_e)EgOjH=`_>ONQ2gHT +KPTy%va$7CjWOt=%G)bC+N>BYche}oy8$7a;kQ1|blr7JMD%aaE)DjlMl*!fFs5WPN8KF|at44TCb>5 +Zm0#Tsx?0)Vdie1LI>`5xl@;WUf{0d%a4gBOc3MkYQhz4lXGuPm{5pI|--AQgrRt!SBz`4yndK@637? +C?;wy4Y?COdxJY0lHZ#wu1BVF{of1K2iz<_n!=bWU9e5-qgSU8}ohpfb9roR|-Nb>0CaLGVsz~y8J6x +WO7^L+q%!3=17*GuUO^qlguWqMy$9t9*l=w&E+OYH~L5mv*X>2i#U-iMOcg%kIthMo9PevEK=Bgl5Hd +S@H{G$H7;QFyv00|L;uEy`l!hw2D?zT%VD*vtPyIx)gSUF^~jaSvDziySLTBvTSq=ZFRXyrq~cQ*VjH +QI`LLqY#iNlxqQ7C$zr*MZ9*yQ~?Xk-IKMaV&byF*?%nuKU!<+B4n=A8wJ0K428rrp$`M)0!hvzP|i! +1X#OzMwA{Y4vIng1V%BTZ|t5u&F)#L~zg@RuE9l=RjR>xq_zh$21{#K<9rm+1CBMknWTCLM6ci=JOl4 +_FJB>Eq)NZCTHDG4G&HoK0M99JaXi +cX4+)tyVxP~>}_1g0|aD+;2qmP19J}>hk=6dLW6RdT=GNwC>?!&Ms61hP3BvE;x2KC`vT7JCO^}0JZ&4h<{qW4eHP{0U*^~)uoJvCFvb^MV~`ShTqh{D+rU?I87Hcpo5LMU4SOBYOjE}b|~fwS8BkF +#BqehZxr}ehQ$|}jQ4(7Bt1EHr;CPQdZfZNN9n>QUsbgskOivDAURxUsK^@^V5dgX5p}^XB*D&YQEjl +^g7qgirp$pRVv}M0*N{Av8-rZ|%VdW#ZE~to2ne}aT-!`f-o(ArM&n`1U08R^8Y&M&(5C++)UUpLickqZ^zDPeoXNVG<`M6<^|HjI$Bjt1C5Cu~WY@MbX +z&JVPD=QJYlc5OyRv@y5N6Uy2M@0ziH$3o%T%y<2l{d%`B^Z?49Lm3u3G&MfZm3TXdx2NUF+3onuk++>-=deBD>4w}E4_>T>@u0F^|2Q%Q3O%_ACwMknGtii +=NUQ{w9ka13baGn;T;L}@&Zd1j-bmI|gYHy6%INNS_%SS_QA=l`Zyt+J@`0N(FyQmqy+(7mJQ7E@=6Ugm2Oh)uKL +`4iyGyR+V+}Fm+vVEaSap8a9zQU2e<-UIYV&n}25i$B5gx8R644}a+Cj;6Fwi_;O#+O`1J?^5^Ke6tQE(g6+cR@9|LRu7b?y=zo&<9G*E2|=n&z%j9l~B{DUAYy-zNI1=s +w_ZXtGf59l(ZlPMQg`qxkRhHbLm1e$|WJuz&_C1Uc02 +cmRu39YE3?gsSSx4fyev3ze_}v||Pv1bRJc!Cst}cC8A(108`LfAN@wPxu_aS^lp$V*I`o!UM}S!o!UruSEEI-K$QYic}PM-rdu<5Nhc| +q=LrSsq)(WB6tyas;?H>e8Hqol+UpKfd0m}khxly0HdrFtv+L{jgLs|P9S +BfEh3vi!PxwruD(^t+bz&%dok^;2nDiaHYWOxj6MUaEJ8h`+G1_{ybm?Q<|HIaOvl=@SD% +vCkJC)(f&F4WEyIRM2=dY{?OO>Lh8Iqu9Ze_T*COS$I*Zg2rH<+L)5RbhQ*X++IPnObSaIowH+-NNg- +mOXsypMqdDo?}f($HjbKAqPR$MIDysPf<_(`Y1GwmUJD4*~kf8X>hL$vrkGLX%Lbg-luIg0sp^SK;(21_G=PVFAq}xgc6dJfjF2M_B@88KBRR;L +?fS%WgwwylQ_G&rXQTb=HuG4$qhvY^7Y>FwhYn7Os$cl0Nw_@&K#ejBvXEVE(=7W_OTu>Mq2U4QpD}9 +~`-RxyYwkhe+~Lw^TSld67F0wmo_*5mfvzYoGddYchTBkA%c&_VMMS}B5tY(1>&QFLx1>2i4XcHV~4( +9-R6bqDiV98sz+-99Q{l}lzfBfO8h1FVD6QB0w?9OO*t-#ja8!Z>Kc8l2Iq(M%IO8ptHx_VM)rQ~D7t +DZLX0y&lNDumGiO<)Q-oe1bBr06(69)4>go^9%5rex~M{gg}<3+FPuRSdHiGV-%C-seZ6nGaLSzBsCJS8=G5EM4w#SGksJyQ49s_B{-5Vilfe2T +D;!BaPf$xwQH4N1qCTOi$R|hux0uLDjLw+g#8G!a!gYjKSz1fPP9FtpIONui=S2 +xN1Wc)WEb<~e>W|%($PV4szA%Q5D|OrChZ&cV*1^JCGTKKPm?;bzfHp8}z?6!6?Up_m$OG2_0hQrFbL +`m$*0bJt&$h@RQyOWCUfRnHGznMmB_O^3sU8*1xDCL~WKtBQmf+oeI=^blPM0m`k +xJRAE^#gvKuzq9EMvE$A-O$^DWBr4fD`eoufsz&u=_T5FzJ?liI+3CL&6o1IR}<9JcKQmh=6N`=&-Hh +Gwx%F{*}a3&lo2WX~fOFL(0%IQ`Dos()EP(%zYO>Pm(8*2)jGcOIrOPUI5M+jo`^Y4}mdj^MTT?pXuL +v4!s045+A!?5CvVbjv1ylFtxfRFpAz?pV-*@Ap#x8oyh20F|GR>wrS=g+vp8np!@_9nm4~>Sl~K2yIZ +Uob8V@5LMlsx-`f|NO4SC3Sd&t!_OPfP7FFkv)utp_->kSxLCbTMy4saS?FzAG5IT)I=-6pEt3?(NYu +c$e4GE|*DV{40bD1&MCb6bjtZB%Oc=ABy!TT3r2-H_l!a4O{G#73Q%&o)YDP(89xo;~lhef#Q_*ks}k +^cVI#rn@}h1h?8_LqfXO~%ktwU_m(m-Q;*ki?oHrRs4Ocbvu5JA7(=l232OHn(7#Hz@1GntHLOCA*nK +Sdl=#bar3NsUQ6T?YVUg{DNj>NU19+kcl@o%eV$`SSn3nxzbjU3OrD^+gKHN%TFC)A>n<-j!$F0^aXW3&SF3Zx +f&V3pb2f%I@xpq$pRRTXp(!QyO5R8ol1SB1wu^N+3d|Nu?nJVyY`*QZjjziN%=Ey*3gx2X5joM$o$hm$94DM7t-=EmuZRwuNSZdJ#p4S~tT_2CvUAHl+H|k=IZBX;zG +~L(pf%I6KBUFm57x_+oqq##4;v4bz)3w$snNeBbm{QmnyO*~6R+Rcs{p{9WD0ntMk7;ctb{*nH*y$$C +qCjMxClYBXuUAh7|0I8$Pf;sZ3Je}L4e1#!v{XXqcG6h1)0fGYlvNhN*^3MZqnQ-{^M(s6pwetIxxU@$BdOSQ?^xv*`?`{*@4qZ0;`Sdr-g +1n{86JpwY>8J7O2ItR`XSZFHo!r)H50>4Vd&j9}sB>=TW@AMc_2eixtVatG~#l!Y9!a1jf2exkad$HD +K#9D_SX}o!v@#e+ic>6ZQ+vhP<&ts;tNW)pa#g!9T%1*5GQ8}DBf}J6bC=bd+jW_;oHBSi4kqP0gZ&8 +M;`FKOave((^V=RH5z;kqj*iVO;I{@NA4uOSI?|}Gx_O8ZzJ`F1a+9i1gMsj_~H*FkVhNw@G2IcIn)W +G9r7n)O|L0w{JEe?LS0fs*T}RxkEeJqYBXIcf;e%OVVZWsfcpSq=cs2#n7u51+T*es(CF;4T3d&6Ss6sHWa%$pP|M~gvmg5 +yH?70$9KK9!Z+(F0z4O%?pYrfGP4CcCg{A=B`W5T7abDV;0s!w*^+xc3Tva{w>!^E($-8}vG;)YVY-({hjVmPU_rA +@pyF^A_zQan-E`kGQJNlzN`FuLJnFfv-_jm0)UZQGT2T2Vedk`*%4|bV&Lv9P&3F+-q&jB99&)=P%Lt-}}#xhN +qiljb!p`Sy_*FJnvO@C{l1>_(}}Xi!osQmxB9X?wLn5KL066{!wsxyQ1%x)PD4r8HLZD?dSEP#Z +u<-56-ruER5vH)H`G{wjst4z*|GA`27~p5o9lBn%CLQo>U@&L~5#M?`;C)+Ceg!q}ZshhF4IN-OxCQg +$CH2Lb%?i9WJ-ZbSby3v}*UcCmMy?ymwF3~xD!(LFHX7f^@M7VzsSo?gxTH2%sDQz3?2S;zhbfKzbuW +pt;W9vF`E4VggvS_CtF?yp#fdBeXj)6*<3F@MZLFrI8(fueW~6KV&{nJfO9I5MB`7h?0(jdyV1U0rST +Bzk;K$XbW0*onTtgeLQ#b$q{3x2?QK5Gs}c@hCF~%K4gCJ#i{9q{+OmArAQnKx*676DI@1(2>s3WNwb +75w}VEh!>K9Njd7@SRrgGySZPCJ!aMAA1pJE{9A0cu+K;wr9PcqkI{qYxN&;`&k;q3C$S^h>p#FRG{{ +8rk@eEYSYdu1cj1$an|#KDc)CyRHJ3#zb$SZV?itzn?@o-MBFsBnI#e8h< +KvoaIZ0%OzWvSB=Cq6Cqmhb8=1EZkWu&-o;j1uuGYicjH~Ee-XQs)%_0Z614fjf9txIjW(+b01xlIfq +-8r?C9w_Ud5XA;_C_XPfRF8|gNZp}ou{Hb59KJ9#}+`UtN1Mlzzjd{g#tE|^mwJCS4Oac9=R_|l~ +p76oi&;C_{U|ob45!PA!#tm|Jn=f~pZ~SKp=(IC>Am2?@UCJ~$a=;4j`S3m|_I^IRkKnIqRb7GAz=sS +V#K3PK`#r^ePqN<=?DshP?Pb3`4ept<2Y8OofDwD~#RU76B?9`>Q9p@N(<)@ba(>p(wQNUU40867nf? +ea0Dr$Dz8fx9{eelowr>Nm&5X$HF`MmUhFHw~cQAES33Sm2buk{ly*pCD7BMJl8Z8>qcJ@^tb7Xy%nAIrG$6MngidFm(Za?fd>@ICc={H{I9T +$aVj@@8K83G1(J8+Lo_>vmnrWOiGo{slfRX0}O*39=}9ZB?$&ZEJ56VpmDDCO(QvGFQd`hU&JLV*nO*Q5XL_)1x0F64Y3V)k8KHvBL=rgu6DPlLqib@%PO +7H6yVXc}MJ?DQ|9@pLx(JgHTUMMGHVysV6j;*1gkjzV*Mub~c$PUh2so3~~+{%s@Uqf+xt6OTD4N+Gb +yNGYH#4>6DPk082m;n%B$-6h$B_0?}W+6F*9@GPh29C!wd{vF27hwlGNMKWzaA08GM`jlh--!9;UuXr +xB5jbq@AW({cK8*leF(NA{zNxe_))dORSvcH5zC6yM2OheI9h>eA`rrY2{cuzJKnO+*2b5kG4n=`Z(*or^C9qUpwpfg9Th*)ElS^wJtKg!t=yvIdv?)NYL +d7S&-?(b0hTm2pSzhKrHZ-!P6h-->{t97wM?M-?jQ|&bdh7)ruEH~Qu#M}(eP-Z=bhSD8xCD`D-Z^aM +m#P9y>nqqhRNIQsf>SI>WJ|$hyCg|5&7K31xRBe&)7obsBNXv@^R`cij7CMOCg1#PV4h&IU7Y7FOln<_>KjOuZUCXxNE%HV@d3Bagp5wH$)b@cM3*on&I +eknqY~}YFUG`jDF>L0l9|-2`n@6zp&X>bQ6+V~-q!(E6y&y2)XBpUcA#fW6eIn+--z=IBn5K?5QO#|W +L*Bok{C^1*-%O0-OK&h0*poN+1vD>tSHxs+6asgppvh>9-c@LK`@@;fDY`BO|IQY$ja1#pzSUNNHypV +dm5F%Tdc41+4geP@=*HA6sU2*asOW*Z;v!>J3m!Vt@GD6G;sX#Eg1lvci!k?jn0usL(t5_Wneo{OJE} +G%uR^(m7Qc~b_IE4K-E4_8Mx80>}95+s6EAE)fX&uJIK^Mck|t4wWma^dK=kMHhv48r1;SF6uF*EK>P)@^8)c +xsCdnH>E%QI)CBZ|!clhpww`Dg6VqooXGIUPkM?HCf9GW3=mrJsbBL3=*XLN!+Ys^}O81emlByW$ndq9@D1i;I3MoK;ePPUS+cSaV|!`}i{62wg-PsN)(o`1qkrC~powdn+xU)& +n85(h1dG0G?YH&4V^V++vKADqv=+o86cokz+w!44s$6l0B$RMCUMM-zPp}G~&zsPqe8$zvSnk)t-m=h +2(0_!`#TK_AFFN)Shy&Dg_x-Pat;TYR_UZ*Z>99UWjd)p*OST5%(yPfU9@P*&F3;y_$o2LTB~7#t@*T +>CK+J!RQ|v0jQ(d8-WGL(Z}&JfBaYtqC{ku!6P4#*avL9Rfis(W4fu)w!8kksq<`Lxy(m)E*M@D&S5how*GB! +Y1$}sqKD=9_dr_*}05inHnu(G)1q7ryFdC9aM7S4oq?NN)byB)h@!BW#$sbxklsSE0lrm(ABwRB1Su3 +K`Qki;8L07JbOuZIo4jA?kOU(5InfEz!k=Uam<%gnfeI2P|af%(}YcOUVSy6}`7wI~0HBx565^EPVR* +-8-(VhNzIc(T!{97S7iP!p?0FvFXYTH(qOtC%jPZ`2{N(U=oGfvSU5syKOnpb)8qH7`HbG%Tu8$8+yb +Tu|ABo*AG4(GfdPt?|AuGjCtgPP#PovT5m*gwy45Gwz4}iK}=i +hCylt_4X+;18c}!zh+4f>BBv_9M}1Z~FSjlq$_@;NVjG`F(XX17GrNKbe5~Q4f;vn83rn9rFulTcX~4 +q90*#(9tFJ!>5{7~fzisT3DEYITbHw27%#Y>&Ved=eqO8{c&#=hI;($uxKJF-~C}=1yjLg_TkhrCl2F +M~50>O-8xu8IaBc^3#yOovQx?L-CtE;$cnOmE;l}c-f7TOS(Jpbo=&UuFc!K`2Rw|xHh9bTTZpXYhbb +N2H-hstjVN=skp1Cbj@#Z&(d-18&Bu@Glmrm?;&qR)@%lMw^NL_oAv-d?C!%ll~91wWI&xhO#=bKl8S}`a5axsy +-zRy6TT$Ag23NAD2!Z)dzo*Tr0xA8TdCH{}L>YZ!~ITNB;x`biVh5YX~-rj4@I6wbgglxu5Y-pTB~gQ +PgtG=%UUW1vwvjLi-*K>nAnSh{aK0@hG%ym_L7eo#@7*5FGQ^c-a7x_&-ijYYw?Sf(_fqn*9hCi^x%z +ego9pH?RqA-@qE5kRQy|KkoWs4|iwLlxS}B=-2>@iJ{jVeE +vH(H5aRp$FQNw0~K!p$|ocQmv1@yR$WA-XqHS#bd4_&wEU+4)4NM4vzB)jxVhh-j8GDZr25GQ_0ue@q +sD6bx2CQjZZf%w;7_KJv}AHqb}yy#hBuY9^xAwoxL@U(}fP8hfQ^6gWhNhpoZ}+p~>!5Tmku(^9>)l! +v3b%`|%#}623h3s-oaN&}#E47EUj$7wb+HB)3+_vP!v2YIq6y*E+B4or`8e1b`ng+~6Ri5@uOTW2UM#TK7mL}l?=U&ES8Ospt_m;Nq3f~_)@Ea;HLY}k7 +0kgzPFcdFDHvP_Kp)5%L*kyjIk3GX03A7?og8lH4#8wzaoy+(Qse}b{bM-vn7tsN1VW^G;!k)-=jV_dEBa0w-`#V*U8PKB>ABj5qBK7t2 +q1*qDz`C2mli;j=eniDyw8-Pn;t?ZwmX(lLQC59McUeyfK@gE}dbaHA(G@XlX8_G^yK92@ulJC}Bw(5 +8i&QOnW~Q=}gxdR=ffa8pH4dHFrQ}gyeYGyBW54S|Uzmmel)ZmV-{in!Q422}xZ7^zajK3qDd@T)EMXafm#sC5*Z6p9D7V*`)Gz**thx{63peE)cXAW1;XqA5%YyMEg8U9!2tG;jMQnb4l;}7uBo3de2^s84J#oe40JG +@rD_%1~!Pg;^W3NJ|pJ};Q?>N49l&{@y*;OWdEVp0mL+@JF3dSX8c{|1mj#zul!052dDD-#jH-}ZCjZ +Csu1bi*-4e{S)M&E=R4@7~Wc&s!yLU`Wdv-Atf3~u7B76J=YayY8#2qUGU1$|IB&R1yqV>#gmuZ;i=c2%%M^NF0fi=u +q%iSf%M=dKT}mNtt*H*uDY~##Z4!6vi2Zq70jyCpxG_ckByBqF2q9jzOJ!YhZUg08u;0B#qc-P<9TeO +1sK--r4eKtUhUuZO-4Q2_*P9&&HH>BD-em?C>cwmh^}kLsLsrGKBi4#F0SIkz93Tdr+8`Mubh1jmIQ; +eIu>Cx^zf>db=V_yXdGy7_TWj<@*dNMiPr@2(a$JxEQ#(Ktd&5#sTtERH(@>}kSyMYZqvX7|{W|B94> +o*<{-Drxxb>{i13gZBlYa=MVx>0NC{VD7b!i^_oV;JH^wkS$5dTrldg>R}Pzu#WLUF$=Nh +_U&ZiWjm@hSH%FMC|b$VB-GQQ4fk9wR$wUhmkyB&8`C7Acnu4@07#eWu3+F7u{x~o8GTr4Ds;;vd7-^ +Kr?zY<~?_b9*wN$TGpfSXuC`FXvi@{yLzQZ<9b&v&a?;I^l13DS9&xO6*_$y0={y8OL{cq`YrdKg54d +*zl2gl=j?+@(<_NVK*@C>dfc)ch-F~1cv&lAjpQJDEujuJR%pu*>g!!P0!q$avY0>qagsm1M#ABQ-k#gOn;z$R +^~ZG<^e^S=+(K`0s)OdfN8}ZR&bq!rFBZ)b#VzsG2snb;(nVve6*;|o^9lN*tE>(K^xf&K4j;p2y-?c +fQ`5$%Ms_>eYGPlR5gp|$%FU#SVu3CN5;jN*AWn~Nbb}g(pg6YR6Z%b2H4Zg-o2&|SD +do1RoBeW)V>{-h}xK=dfNMl+nK0o?jgUiO~I-}miS5mqX1-^M9n}&VinF^pMDli-OMU+&c2sWj&9gYg +m{{xGU~-@bgf#AmUnyn-LTm}Q_?DD6_ZWcgQ92?tIUpaD5^7+oYgG~H%0%rAPj01h=8(>4EI+iI1X%Y +Ef@Ae#R#7V7mk(@X{g@Tnzlq}xr?qX=xdIet+N>&!U0GaN{5TXa*4HSvR{okv@_&hO{?G~m||4#Ay%s +Q%8{eQ!Bl~>%m<|MSxc2b!(sK}!PTSW$C0>bsODLkXIUZ+RTony+UN|CbNe&0p(eT8{1J`OV{iz7I>a +0MVENE>^vCTx0der>@TF&w^8aK?E$>ZT<=l!Jfgt;t(Yx&4C4Ss(GwS#Dq6}NqUX)=A_M-0px9>&8%D +t!&G@fwVjOr@38uxi%H!2vrQSG;l#kR8W7vG+g)h#}J1shV$?ME3ei2W#Wm!iY_@jJBH<1tUS{iq^q` +P5>n8mq*1)Q<_|l!S}5X^P?6ld`HksT}N2IiGo&WO2nk+Md)_xhHk!J+5h{{vK^}XM+&Zb#6jB!xz+9 +icxppvKY36nj9xAj&l~rn^+se7Eh+7>^nng4_~pbQ(1C^S6qLix#E@{*bPl6w-iHpYJF>=L~>uIDQpi +F{=8rsNYqW0ZidYX`l?H|cy?Jm4`O~a75A}k_SczqReRyHqb#budPC_CNYHV}f|J(qYF8(*wS@J`{)~ +dF6tpPVPww`VB`Kt~r4zByyA1cV^}z1PFi*A9b6DHynW$4cJ=?XNo|olLkD+vz*lCz6eDm$#Ua}${$-M`<5d$?B1+|>MC>8Rff_)4juPxsQF#xOg%4`YlZ% +p{c_G^j^+#Aum0v@<4ma(1eGSCJRkGS6hVoWvn`Tl`RUkpG%uUdJ0l^j7%guCRRZ+1=}>^~EIg}no9~ +CXIW=CH<(6aCikZhOj^C;m;=GY%nMmH^S+i|6!#CuZN|hYOHq;P$&ifp5$^wj(XnI)AIp}D;G3~Wzid +rtMFinmw3jeLuoOw1lP`6DsD2OJiIe$T;fsgL$jnDv0=5!Q?gQSScwEp{|s- +ucU5I;ohYTbW(4Hczn~Ttq}Ng8h&mzmug2HcbfLC}K(KIYm6$eO>|c$qZwTnViS@0Xk{6p;r=sutJuY&5;2#3Me=_^XrpUwjtVoBdZIn&Z; +|AimxWdTO4Y$0lxdExwvROl+^Qd>GK{V_?ZlpxVM0ApGez@7{Tg<$Ccfd?#WIv;{U#6gpTTtATH|SUa +B3cCWEQ;uJ6WpSOoko5$?dF49;_QCHeFW9y{yD#X2(%=NidCf_FEnAn1#aKV>G{1TUnhgYM<)jotUs! +Mv8r^Rbrn?)Br(&wwZNY1bW0hkZ6};qN2r)*0d&Y?CmlU +(?ZoFs!m*<0bFr<}8ar9S*(}xF*?JdQ!p@k(&QJ_(Gs|&M>`A@vd{%B|ZFOyC&2Zby`s9qrMsMp(|Gn +(NBG9&Q(VdIfS=d1;`_4{19AA`bb(}ZhMp(-#+3+OL99}j=G>)dB!B4-)Mipvl7WKh~MiCanZ*Jby!ds$0BWpj|UifRZWn_JXfBbba(Jq%l0NJH9daCzCjlKMDXQb~Q5Ep}UuXt``5;zsY1`gw-3AP?C9 +`BnSi3N+IQz3{WQLGKR_|LX6>ko$08^=T~M_YY|4$g>*cU!yR7(Ze`}u0iq;7#CRl~_OX-rVL#u0)mPtB^w4oGd70lwK4+>5$>C#YB+iZ +6B{#6u0^$~mvXe#+_fSpD{qOlYNi<*b}i(UkmRyi(`i&b2_AoiuU>{I(v*6NdD9aQW~S*za?s3N_qO| +o%xOHXZ4;m8Pa(Cf@eu_Fbw%C4O%N>|&dDrRy#V~XBm8&gu>%Qkddm@Kef+XhNQdm-M@yJR6vqeS&J6 +OnYyc>1rai2?t8sCh0q>`@b8E}yy#SmwCzQhgyQlY@#th!V*VKFiL+Fi|9oVWJonmeqr6G}miIqc$J= +Xmiw5F~Uq-r)`SvwmK>>yv5YhJ6o;_g?o!tA#tC&+p3WBP^oLgdP8aRBUZ=$nwMJm9?9_`O^jzp2i$x +=V};4qw6oTVfs=9M%W($UAa`B#hDJ!5^85+~J3ibVT{60D9&RD)gU{IbA)6mRWbY{MRIBmd_A7w*wmP +9tF#;Fvh?wPFd?G4os?)X9wTd#dR4y2~Zlk!&JVl^Nc-|fz@ah`EGh1AUJn)4zNdLUh7Qnr+hDEvk#^ +iF9h0qP*RN|x4a)E9?H*`BUgD!48TN*A9{*6fW_v8ZO+e%y*7nd}Hv8LlztuqBXZ<3*$LtPPT5()Jo( +E;`M5$gS|X~$`lUwa>NazA8-#lt#tAYo2jmsem-7iXYK$+^^pf_})*gH|<9ieF}P97xG!=C7Mj+-O=<<-}>QIVB#o8dZ#|5p^YV;~O +>9RzKkO>VHpVue+%?TK;}6koizIf^Nnz(6bS;~dB?xz}4;{%tW`qV&I+;pUc{ZEQt-Cd}b{>o4W +z4H7(HEtS}I?Uq_Iv;%%gC<a$(B$|d(opRHWkhKl^%xOrLXvqe)8Mo!VCGL}u~`RtKfcG~97tYwERMDdzSTD|^kYI=L$&grX3~ae22Rw4xlUE)aT;)%Uj4E(Ty7 +QZG)ao0sXF^A